@bivy/bivy 0.20.9-staging.2 → 0.20.9-staging.21

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 (131) hide show
  1. package/README.md +6 -5
  2. package/bin/bivy.mjs +13 -56
  3. package/bin/cli-commands.mjs +2 -4
  4. package/bin/guides/talk-to-the-user.md +13 -24
  5. package/dist/agent-instructions.js +12 -14
  6. package/dist/agents/pi/integration.js +1 -1
  7. package/dist/apps/remote-preview.js +3 -0
  8. package/dist/apps/service.js +6 -1
  9. package/dist/apps/styles.css +40 -102
  10. package/dist/automation-reseal.js +30 -0
  11. package/dist/certification/generated.js +1 -1
  12. package/dist/device-registry.js +27 -0
  13. package/dist/ephemeral-teardown.js +11 -1
  14. package/dist/exec.js +4 -1
  15. package/dist/runtime/model-catalog.js +16 -0
  16. package/dist/server.js +73 -62
  17. package/dist/session/event-log.js +98 -41
  18. package/dist/session/inline-image-fetch.js +24 -33
  19. package/dist/session/message-components.js +323 -0
  20. package/dist/session/run-terminal.js +9 -7
  21. package/dist/session/session-tokens.js +1 -1
  22. package/dist/session/transcript-persistence.js +106 -11
  23. package/package.json +6 -6
  24. package/web/assets/AutomationsView-Cobo4Kep.js +51 -0
  25. package/web/assets/{ChangesCard-DcSRy5g_.js → ChangesCard-Bo6E8C_y.js} +3 -3
  26. package/web/assets/LibraryView-BTeMc6BO.js +2 -0
  27. package/web/assets/{ProviderConnect-cpGwBMrU.js → ProviderConnect-CsidS7kq.js} +1 -1
  28. package/web/assets/SessionList-B7IbeXSa.js +1 -0
  29. package/web/assets/Settings-BQRQsQ36.js +10 -0
  30. package/web/assets/{Sheet-D-5t3lJ0.js → Sheet-C0BIPbMr.js} +1 -1
  31. package/web/assets/{Terminal-CjMjKB1f.js → Terminal-BTRgonB5.js} +1 -1
  32. package/web/assets/{VoiceSettings-xv6rjaY2.js → VoiceSettings-UZ1SA0lQ.js} +1 -1
  33. package/web/assets/{abnfDiagram-VCTEODGH-BLT3MLyK.js → abnfDiagram-VCTEODGH-CJoWsvVk.js} +1 -1
  34. package/web/assets/architecture-7GRP2DOG-CuzcodTO.js +1 -0
  35. package/web/assets/{architectureDiagram-5GKGNRK7-BGinLETW.js → architectureDiagram-5GKGNRK7-_qpa4O1v.js} +1 -1
  36. package/web/assets/{blockDiagram-I7D4REHJ-BNiY2HLB.js → blockDiagram-I7D4REHJ-DmLgwSr-.js} +1 -1
  37. package/web/assets/{c4Diagram-7LVT6UL2-46aGfRMd.js → c4Diagram-7LVT6UL2-DeZuOOSk.js} +1 -1
  38. package/web/assets/channel-B0OL-aPd.js +1 -0
  39. package/web/assets/{chunk-4HAMMTFA-CRzer-vm.js → chunk-4HAMMTFA-Cr6O6lBG.js} +1 -1
  40. package/web/assets/{chunk-75Z2AOVW-MFkgf2Ar.js → chunk-75Z2AOVW-gSgNIYMY.js} +1 -1
  41. package/web/assets/{chunk-DU6HZSFF-Bpze6ID8.js → chunk-DU6HZSFF-BacnRf2Y.js} +1 -1
  42. package/web/assets/{chunk-F27PBJKO-Dq3OmNXG.js → chunk-F27PBJKO-DRrpfF1z.js} +1 -1
  43. package/web/assets/{chunk-GMAD6QVW-umDWdG9g.js → chunk-GMAD6QVW-DXCi6v6B.js} +1 -1
  44. package/web/assets/{chunk-GVQU2GXP-DuT1Awt9.js → chunk-GVQU2GXP-Yd74hIeT.js} +1 -1
  45. package/web/assets/{chunk-IMKFNOWR-CpFFccVb.js → chunk-IMKFNOWR-D5xz0-QC.js} +1 -1
  46. package/web/assets/{chunk-L3NEJ4N5-0jRWrASa.js → chunk-L3NEJ4N5-BrS0CGPM.js} +1 -1
  47. package/web/assets/{chunk-OSK3NFVY-CBErW4-p.js → chunk-OSK3NFVY-C6d1DSJe.js} +1 -1
  48. package/web/assets/{chunk-P2QGCYS3-BPMii7LM.js → chunk-P2QGCYS3-BrKgIngm.js} +1 -1
  49. package/web/assets/{chunk-POPQ4Y6H-CHTRMb_C.js → chunk-POPQ4Y6H-Bkwx5BZs.js} +1 -1
  50. package/web/assets/{chunk-PWAF6VOD-BOcNKrmu.js → chunk-PWAF6VOD-AeCCeE0F.js} +1 -1
  51. package/web/assets/{chunk-SHT3W25Y-Dvb-oEDN.js → chunk-SHT3W25Y-01NYjozy.js} +1 -1
  52. package/web/assets/{chunk-SVP7TREG-B4AQIUTK.js → chunk-SVP7TREG-CCh7wXAI.js} +1 -1
  53. package/web/assets/{chunk-TICWLB2K-CWzLTsHW.js → chunk-TICWLB2K-CcWKqwdM.js} +1 -1
  54. package/web/assets/classDiagram-ZZMXUADV-D8dSdFQt.js +1 -0
  55. package/web/assets/classDiagram-v2-VYDZK3BY-D8dSdFQt.js +1 -0
  56. package/web/assets/{cynefin-OW5HDTMX-BPkKT48j.js → cynefin-OW5HDTMX-CYYc_tBE.js} +1 -1
  57. package/web/assets/{cynefinDiagram-5FMLGOSQ-Ck2qLmpR.js → cynefinDiagram-5FMLGOSQ-Dnz7OfxK.js} +1 -1
  58. package/web/assets/{dagre-GXQ25YYZ-BPKEs_49.js → dagre-GXQ25YYZ-di5CyaMt.js} +1 -1
  59. package/web/assets/{diagram-S7CK7UJ4-ou-L5HdJ.js → diagram-S7CK7UJ4-BVC93OLB.js} +1 -1
  60. package/web/assets/{diagram-UQ7AKVKN-DihVn6fF.js → diagram-UQ7AKVKN-D7pXHAvQ.js} +1 -1
  61. package/web/assets/{diagram-VSXAHHWV-BkLtxbP7.js → diagram-VSXAHHWV-d0zW-IUz.js} +1 -1
  62. package/web/assets/{diagram-VX7I27RA-BZ-Z-CwP.js → diagram-VX7I27RA-BRlMo9oa.js} +1 -1
  63. package/web/assets/{diagram-Z3DM3KII-BQN-bGqD.js → diagram-Z3DM3KII-BmfntB1i.js} +1 -1
  64. package/web/assets/{ebnfDiagram-PWID7BFC-aKK1a_it.js → ebnfDiagram-PWID7BFC-BxUYvqsz.js} +1 -1
  65. package/web/assets/{erDiagram-RLTQ6QDP-BGsXtJl-.js → erDiagram-RLTQ6QDP-CbUl1Cqa.js} +1 -1
  66. package/web/assets/eventmodeling-NTZA5JFV-sTVSUyNU.js +1 -0
  67. package/web/assets/flowDiagram-HODETNUW-Beo3zBEU.js +1 -0
  68. package/web/assets/{ganttDiagram-EL5Y4UJY-lrYuyNAe.js → ganttDiagram-EL5Y4UJY-CkpR0avQ.js} +1 -1
  69. package/web/assets/{gitGraph-4MIJSDKK-raj_IxZ8.js → gitGraph-4MIJSDKK-CmbJxSaM.js} +1 -1
  70. package/web/assets/{gitGraphDiagram-WWUBYQGX-DzqRGXuk.js → gitGraphDiagram-WWUBYQGX-iyO408KF.js} +1 -1
  71. package/web/assets/index-B4HaCD-n.css +1 -0
  72. package/web/assets/{index-B6GPr2Pt.js → index-fdEPLcPs.js} +2 -2
  73. package/web/assets/{info-A6RAGUB7-DJVi9SAN.js → info-A6RAGUB7--6JCM0xX.js} +1 -1
  74. package/web/assets/{infoDiagram-27XIBGKW-B2HrGywP.js → infoDiagram-27XIBGKW-Dchx6QcB.js} +1 -1
  75. package/web/assets/{ishikawaDiagram-5VMMS53U-CczIkvWw.js → ishikawaDiagram-5VMMS53U-DOY3izUi.js} +1 -1
  76. package/web/assets/{journeyDiagram-3NMN7TZE-D-h-kwep.js → journeyDiagram-3NMN7TZE-oqZgC9oJ.js} +1 -1
  77. package/web/assets/{kanban-definition-UXKFOSKX-GClrFWfH.js → kanban-definition-UXKFOSKX-HCRC0D9X.js} +1 -1
  78. package/web/assets/{line-pweWV0oc.js → line-qcY2eok7.js} +1 -1
  79. package/web/assets/{mermaid-parser.core-C1vHZCtC.js → mermaid-parser.core-Bullp1xl.js} +3 -3
  80. package/web/assets/{mermaid.core-Df8DJ7AE.js → mermaid.core-FBmsAtMC.js} +4 -4
  81. package/web/assets/{mindmap-definition-YA3MSWOX-BpqA307n.js → mindmap-definition-YA3MSWOX-CfgOAkVQ.js} +1 -1
  82. package/web/assets/mount-IY4-2elJ.js +31 -0
  83. package/web/assets/{packet-AYTQ26CC-afE6T0Hc.js → packet-AYTQ26CC-COAmiopo.js} +1 -1
  84. package/web/assets/{pegDiagram-XKGWAZYB-AAEw7Khy.js → pegDiagram-XKGWAZYB-BYafVbeG.js} +1 -1
  85. package/web/assets/{pie-WAS4IAKB-vtwSUVVK.js → pie-WAS4IAKB-ZYe346n6.js} +1 -1
  86. package/web/assets/{pieDiagram-E7YTZNPT-CDg0SkhS.js → pieDiagram-E7YTZNPT-DnRbaA7i.js} +1 -1
  87. package/web/assets/{quadrantDiagram-AXDQQJYC-_o0rOR26.js → quadrantDiagram-AXDQQJYC-B2uxyKLd.js} +1 -1
  88. package/web/assets/{radar-RG4KPBEZ-_Tf7tpz8.js → radar-RG4KPBEZ-DwFlqYgB.js} +1 -1
  89. package/web/assets/{railroad-74A4TZTK-DM_a0HtL.js → railroad-74A4TZTK-DBv5jh9o.js} +1 -1
  90. package/web/assets/railroad-abnf-HS5TGJTU-VQxaaUVU.js +1 -0
  91. package/web/assets/railroad-ebnf-LZEXJU2U-DWKO1s90.js +1 -0
  92. package/web/assets/railroad-peg-WCYAUIDC-DvViPquF.js +1 -0
  93. package/web/assets/{railroadDiagram-O6MQD6OU-BpQZeQ-f.js → railroadDiagram-O6MQD6OU-CIUFwDWd.js} +1 -1
  94. package/web/assets/{requirementDiagram-BXWQKSXE-DC4US4K_.js → requirementDiagram-BXWQKSXE-BXwDlf9Q.js} +1 -1
  95. package/web/assets/{sankeyDiagram-P5KCCOFB-BUJ9KIqV.js → sankeyDiagram-P5KCCOFB-DTiRcy5E.js} +1 -1
  96. package/web/assets/{sequenceDiagram-WJ2MYXX4-By7D5XFY.js → sequenceDiagram-WJ2MYXX4-DFPRDr4a.js} +1 -1
  97. package/web/assets/settingsRoute-3489vHS0.js +1 -0
  98. package/web/assets/{stateDiagram-D77RDMKH-D0BA3EeM.js → stateDiagram-D77RDMKH-CFQ-4xlY.js} +1 -1
  99. package/web/assets/stateDiagram-v2-MP3YSRHH-DIIQkE2r.js +1 -0
  100. package/web/assets/{swimlanes-42K2YHIH-BNUI3ghm.js → swimlanes-42K2YHIH-Bke6VXs0.js} +1 -1
  101. package/web/assets/swimlanesDiagram-VR7AAH4N-Drds9YUy.js +8 -0
  102. package/web/assets/{timeline-definition-24CTP7MA-DVzeoz4F.js → timeline-definition-24CTP7MA-Cs2-dpWN.js} +1 -1
  103. package/web/assets/{treeView-Q6P3EWNA-CnvdZw-U.js → treeView-Q6P3EWNA-Dr8vsD3U.js} +1 -1
  104. package/web/assets/{treemap-WGGIJYW6-Ax_RXzPk.js → treemap-WGGIJYW6-DbvC3nsA.js} +1 -1
  105. package/web/assets/useStore-BDEjghiw.js +23 -0
  106. package/web/assets/{vennDiagram-4TSXK5OY-CNauH8S4.js → vennDiagram-4TSXK5OY-CdUoLWPo.js} +1 -1
  107. package/web/assets/{wardley-WFR3VGLG-q8WnmSMu.js → wardley-WFR3VGLG-BL7j6fb-.js} +1 -1
  108. package/web/assets/{wardleyDiagram-VM6X3IG4-DKOY4P11.js → wardleyDiagram-VM6X3IG4-BEVYmHWI.js} +1 -1
  109. package/web/assets/{xychartDiagram-S5SC5T6Z-m8KaPfml.js → xychartDiagram-S5SC5T6Z-C9zn_1JB.js} +1 -1
  110. package/web/index.html +2 -2
  111. package/web/sw.js +1 -1
  112. package/dist/ephemeral-exec.js +0 -108
  113. package/dist/session/suggestions.js +0 -17
  114. package/web/assets/AutomationsView-DEild20v.js +0 -51
  115. package/web/assets/LibraryView-Cu0tU0gU.js +0 -2
  116. package/web/assets/Settings-BoTU83-i.js +0 -10
  117. package/web/assets/architecture-7GRP2DOG-s28sMQ0-.js +0 -1
  118. package/web/assets/channel-CPSM7rj7.js +0 -1
  119. package/web/assets/classDiagram-ZZMXUADV-CZ-So67n.js +0 -1
  120. package/web/assets/classDiagram-v2-VYDZK3BY-CZ-So67n.js +0 -1
  121. package/web/assets/eventmodeling-NTZA5JFV-Dd2mk6iz.js +0 -1
  122. package/web/assets/flowDiagram-HODETNUW-D7f1jYIL.js +0 -1
  123. package/web/assets/index-D76QD5dl.css +0 -1
  124. package/web/assets/mount-ISRAcaLu.js +0 -33
  125. package/web/assets/railroad-abnf-HS5TGJTU-BzFZIgti.js +0 -1
  126. package/web/assets/railroad-ebnf-LZEXJU2U-BkKCtTE4.js +0 -1
  127. package/web/assets/railroad-peg-WCYAUIDC-CuXWl9dG.js +0 -1
  128. package/web/assets/settingsRoute-DSj-6Pdo.js +0 -1
  129. package/web/assets/stateDiagram-v2-MP3YSRHH-2_bDqGCB.js +0 -1
  130. package/web/assets/swimlanesDiagram-VR7AAH4N-SmXx3nAj.js +0 -8
  131. package/web/assets/useStore-BznE40dl.js +0 -29
@@ -1,10 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/VoiceSettings-xv6rjaY2.js","assets/useStore-BznE40dl.js","assets/rolldown-runtime-hePW80VL.js","assets/index-B6GPr2Pt.js","assets/index-D76QD5dl.css","assets/jsx-runtime-NZYk81nU.js","assets/mount-ISRAcaLu.js","assets/Sheet-D-5t3lJ0.js","assets/ChangesCard-DcSRy5g_.js","assets/StatusDot-dpbztK53.js","assets/settingsRoute-DSj-6Pdo.js","assets/ProviderConnect-cpGwBMrU.js","assets/mount-BjlUftih.css"])))=>i.map(i=>d[i]);
2
- import{D as e,F as t,I as n,M as r,R as i,T as a,V as o,_ as s,b as c,g as l,h as u,j as d,t as f,y as p}from"./index-B6GPr2Pt.js";import{B as m,G as h,H as g,K as _,Nt as v,S as y,St as b,U as x,V as S,W as C,b as w,i as T,n as E,q as D,r as O,t as k,x as A}from"./useStore-BznE40dl.js";import{A as j,M,a as N,f as P,g as ee,h as F,i as te,j as ne,l as re,n as ie,t as I}from"./Sheet-D-5t3lJ0.js";import{t as L}from"./jsx-runtime-NZYk81nU.js";import{r as R,t as z}from"./ProviderConnect-cpGwBMrU.js";import{C as B,T as V,a as H,b as U,c as W,i as ae,o as G,s as oe,x as K}from"./mount-ISRAcaLu.js";function se(e){switch(e){case`available`:return`Available`;case`unavailable`:return`Not available`;case`unknown`:return`Unknown`}}var q=e=>String(e??``).trim().toLowerCase(),ce=e=>String(e??``).trim().toLowerCase()||`default`;function le(e,t){let n=q(e);if(!n)throw Error(`Credential provider is required`);return`credential:v1:${encodeURIComponent(n)}:${encodeURIComponent(ce(t))}`}var ue=e=>{if(typeof e==`number`)return Number.isFinite(e)?e:void 0;let t=e?Date.parse(e):NaN;return Number.isFinite(t)?t:void 0};function de(e){let t=q(e.provider);if(!t||e.configured!==!0&&!e.key)return;let n=ce(e.label),r=ue(e.updatedAt);return{id:le(t,n),provider:t,label:n,kind:`api_key`,origins:[`browser`],availability:{account:e.scope!==`device`,device:!0,nodes:[]},...r==null?{}:{updatedAt:r}}}function fe(e,t){let n=q(e.provider),r=String(t??``).trim();if(!n||!r)return;let i=ce(e.label);return{id:le(n,i),provider:n,label:i,kind:e.kind,origins:[`node`],availability:{account:e.sync===`account`,device:!1,nodes:[r]},...e.expiresAt==null?{}:{expiresAt:e.expiresAt},...e.unattended?{unattended:!0}:{},testable:e.testable,...e.lastVerifiedAt==null?{}:{lastVerifiedAt:e.lastVerifiedAt},...e.lastVerifiedOk==null?{}:{lastVerifiedOk:e.lastVerifiedOk}}}function pe(...e){let t=new Map;for(let n of e)for(let e of n){let n=t.get(e.id);t.set(e.id,n?{...n,...e,origins:[...new Set([...n.origins,...e.origins])].sort(),availability:{account:n.availability.account||e.availability.account,device:n.availability.device||e.availability.device,nodes:[...new Set([...n.availability.nodes,...e.availability.nodes])].sort()}}:{...e,origins:[...new Set(e.origins)].sort(),availability:{...e.availability,nodes:[...new Set(e.availability.nodes)].sort()}})}return[...t.values()].sort((e,t)=>e.id.localeCompare(t.id))}var me=e=>pe(e.map(de).filter(e=>!!e)),he=(e,t)=>pe(e.map(e=>fe(e,t)).filter(e=>!!e)),ge={quick:`Quick`,standard:`Standard`,large:`Large`,memory:`Memory optimized`,gpu:`GPU`};function _e(e){if(e.accelerator)return`gpu`;let t=e.memoryMiB??0,n=e.vcpus??0;return t>=65536?`memory`:t>=32768||n>=8?`large`:t>=8192&&n>=4?`standard`:`quick`}function ve(e){return ge[_e(e)]}var ye=M(),J=v(),Y=L();function be(e){if(!e)return``;let t=e.split(/[\\/]/).filter(Boolean);return t[t.length-1]||e}function X(e){if(!e)return``;let t=Date.now()-e;return t<6e4?`just now`:t<36e5?`${Math.max(1,Math.round(t/6e4))}m ago`:t<864e5?`${Math.round(t/36e5)}h ago`:`${Math.round(t/864e5)}d ago`}var Z=`__all__`;function xe({onDone:e}){let{connection:{nodes:t,currentNodeId:n}}=k(),[r,i]=(0,J.useState)(n??``),[a,o]=(0,J.useState)(Z),[s,c]=(0,J.useState)(Z),[l,u]=(0,J.useState)([]),[d,f]=(0,J.useState)(`loading`),[p,m]=(0,J.useState)(``),[h,g]=(0,J.useState)(null),[_,v]=(0,J.useState)(``),[y,b]=(0,J.useState)(null);(0,J.useEffect)(()=>{let e=!1;async function t(){f(`loading`),m(``);try{r&&r!==n&&await T.connectToNode(r);let t=await T.discoverNativeSessions();e||(u(t),f(`ready`))}catch(t){e||(f(`error`),m(t instanceof Error?t.message:String(t)))}}return t(),()=>{e=!0}},[r]);let x=(0,J.useMemo)(()=>[...new Set(l.map(e=>e.agentName))].sort(),[l]),S=(0,J.useMemo)(()=>[...new Set(l.map(e=>be(e.cwd)).filter(Boolean))].sort(),[l]),C=(0,J.useMemo)(()=>l.filter(e=>a===Z||e.agentName===a).filter(e=>s===Z||be(e.cwd)===s).sort((e,t)=>(t.updatedAt??0)-(e.updatedAt??0)),[l,a,s]);async function w(t,n=!1){g(t.ref),v(``);try{e(await T.importNativeSession(t.runtimeId,t.ref,{acceptDisclosure:n}))}catch(e){if(e instanceof O){b({session:t,text:e.disclosure});return}v(e instanceof Error?e.message:String(e))}finally{g(null)}}let D=(0,J.useMemo)(()=>{let e=[...t];return n&&!e.some(e=>e.id===n)&&e.unshift({id:n,name:`This machine`,online:!0}),e},[t,n]);if(y){let{session:e,text:t}=y;return(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`div`,{className:`picker-section`,children:[(0,Y.jsx)(`div`,{className:`picker-section-label`,children:`Confirm seeded import`}),(0,Y.jsx)(`div`,{className:`import-session-hint`,children:e.title||`Untitled session`}),(0,Y.jsx)(`div`,{className:`import-session-hint`,children:t})]}),(0,Y.jsxs)(`div`,{className:`picker-section`,children:[(0,Y.jsx)(`button`,{className:`btn fork-submit`,disabled:h===e.ref,onClick:()=>b(null),children:`Cancel`}),(0,Y.jsx)(`button`,{className:`btn primary fork-submit`,disabled:h===e.ref,onClick:()=>{b(null),w(e,!0)},children:h===e.ref?`Importing…`:`Import anyway`})]})]})}return(0,Y.jsxs)(Y.Fragment,{children:[D.length>1&&(0,Y.jsxs)(`div`,{className:`picker-section`,children:[(0,Y.jsx)(`div`,{className:`picker-section-label`,children:`Machine`}),(0,Y.jsx)(`div`,{className:`picker-list`,children:D.map(e=>(0,Y.jsx)(I,{active:e.id===r,title:e.name||e.id,meta:e.id===n?`current`:e.online?`online`:`offline`,onClick:()=>i(e.id)},e.id))})]}),x.length>1&&(0,Y.jsxs)(`div`,{className:`picker-section`,children:[(0,Y.jsx)(`div`,{className:`picker-section-label`,children:`Provider`}),(0,Y.jsxs)(`div`,{className:`picker-list`,children:[(0,Y.jsx)(I,{active:a===Z,title:`All providers`,onClick:()=>o(Z)}),x.map(e=>(0,Y.jsx)(I,{active:a===e,title:e,onClick:()=>o(e)},e))]})]}),S.length>1&&(0,Y.jsxs)(`div`,{className:`picker-section`,children:[(0,Y.jsx)(`div`,{className:`picker-section-label`,children:`Repository`}),(0,Y.jsxs)(`div`,{className:`picker-list`,children:[(0,Y.jsx)(I,{active:s===Z,title:`All repositories`,onClick:()=>c(Z)}),S.map(e=>(0,Y.jsx)(I,{active:s===e,title:e,onClick:()=>c(e)},e))]})]}),(0,Y.jsxs)(`div`,{className:`picker-section`,children:[(0,Y.jsx)(`div`,{className:`picker-section-label`,children:`Sessions (newest first)`}),d===`loading`&&(0,Y.jsx)(`div`,{className:`import-session-hint`,children:`Looking for sessions this machine can see…`}),d===`error`&&(0,Y.jsx)(`div`,{className:`fork-error`,role:`alert`,children:p}),d===`ready`&&C.length===0&&(0,Y.jsx)(`div`,{className:`import-session-hint`,children:l.length===0?`No importable sessions found — Bivy already manages everything this machine can see, or no supported provider (Claude Code, Codex) has a session here.`:`No sessions match these filters.`}),(0,Y.jsx)(`div`,{className:`picker-list`,children:C.map(e=>(0,Y.jsx)(I,{title:e.title||`Untitled session`,meta:`${e.agentName} · ${be(e.cwd)||e.cwd||`unknown directory`} · ${X(e.updatedAt)}`,right:e.plan.mode===`follow-only`?(0,Y.jsxs)(`span`,{className:`import-session-follow`,children:[(0,Y.jsx)(E,{title:e.plan.disclosure,children:`Live elsewhere`}),e.resumeCommand&&(0,Y.jsx)(`code`,{className:`import-session-resume-cmd`,title:`Run this in a terminal to follow the live session`,children:e.resumeCommand})]}):(0,Y.jsx)(`button`,{className:`btn sm primary import-session-action`,disabled:h===e.ref,onClick:()=>w(e),children:h===e.ref?`Importing…`:e.plan.mode===`seeded`?`Import…`:`Adopt`})},`${e.runtimeId}:${e.ref}`))}),_&&(0,Y.jsx)(`div`,{className:`fork-error`,role:`alert`,children:_})]})]})}function Se({state:e}){return(0,Y.jsx)(E,{tone:e===`available`?`ok`:e===`unknown`?`warn`:void 0,children:se(e)})}function Ce({agent:e}){return(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{children:e.label}),(0,Y.jsxs)(`span`,{style:{display:`flex`,alignItems:`center`,gap:6},children:[e.supportTier&&(0,Y.jsx)(`span`,{className:`muted small`,children:e.supportTier}),(0,Y.jsx)(E,{tone:e.installed?`ok`:void 0,children:e.installed?`Installed`:`Not installed`})]})]})}function we({online:e}){let{settings:{capabilities:t}}=k(),[n,r]=(0,J.useState)(!1),i=()=>{e&&(r(!0),T.requestCapabilities())};(0,J.useEffect)(()=>{e&&i()},[e]),(0,J.useEffect)(()=>{t&&r(!1)},[t]);let a=t?[...t.agents.maintained,...t.agents.custom]:[],o=a.filter(e=>e.installed).length;return(0,Y.jsxs)(`section`,{className:`settings-section`,children:[(0,Y.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`},children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`Capabilities`}),(0,Y.jsx)(`button`,{className:`btn`,disabled:!e||n,onClick:i,children:n?`Refreshing…`:`Refresh`})]}),!e&&(0,Y.jsx)(`p`,{className:`muted small`,children:`Connect this machine to see what it unlocks for agents.`}),e&&!t&&(0,Y.jsx)(`p`,{className:`muted small`,children:n?`Loading capabilities…`:`No capability data yet.`}),t&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{children:`Operating system`}),(0,Y.jsxs)(`span`,{className:`muted small`,children:[t.os.platform,` `,t.os.arch,` · `,t.os.release]})]}),(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{children:`Docker`}),(0,Y.jsxs)(`span`,{style:{display:`flex`,alignItems:`center`,gap:6},children:[t.docker.detail&&(0,Y.jsx)(`span`,{className:`muted small`,children:t.docker.detail}),(0,Y.jsx)(Se,{state:t.docker.state})]})]}),(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{children:`GPU`}),(0,Y.jsxs)(`span`,{style:{display:`flex`,alignItems:`center`,gap:6},children:[t.gpu.detail&&(0,Y.jsx)(`span`,{className:`muted small`,children:t.gpu.detail}),(0,Y.jsx)(Se,{state:t.gpu.state})]})]}),(0,Y.jsxs)(`h4`,{className:`settings-subhead`,children:[`Agents (`,o,`/`,a.length,` installed)`]}),a.length===0&&(0,Y.jsx)(`p`,{className:`muted small`,children:`No agents known to this machine.`}),t.agents.maintained.map(e=>(0,Y.jsx)(Ce,{agent:e},e.id)),t.agents.custom.length>0&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`p`,{className:`muted small`,children:`Custom`}),t.agents.custom.map(e=>(0,Y.jsx)(Ce,{agent:e},e.id))]}),(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{children:`Model providers configured`}),(0,Y.jsx)(`span`,{className:`muted small`,children:t.providers.configured.length?t.providers.configured.join(`, `):`None`})]}),(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{children:`Local model endpoints`}),(0,Y.jsxs)(`span`,{className:`muted small`,children:[t.providers.localEndpoints.count,` configured`,t.providers.localEndpoints.count>0?` (${t.providers.localEndpoints.withModels} with models)`:``]})]}),(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{children:`Plugins`}),(0,Y.jsx)(`span`,{className:`muted small`,children:t.plugins.length===0?`None installed`:`${t.plugins.filter(e=>e.valid).length}/${t.plugins.length} valid`})]}),(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{children:`Workspaces configured`}),(0,Y.jsx)(`span`,{className:`muted small`,children:t.workspaces.count})]}),(0,Y.jsxs)(`p`,{className:`muted small`,children:[`Updated `,new Date(t.generatedAt).toLocaleTimeString(),`.`]})]})]})}function Te({value:e,onChange:t,options:n,ariaLabel:r}){return(0,Y.jsx)(`div`,{className:`segmented-cards`,role:`radiogroup`,"aria-label":r,children:n.map(n=>(0,Y.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":e===n.id,className:`selectable`,onClick:()=>t(n.id),children:[n.icon&&(0,Y.jsx)(`span`,{className:`segmented-icon`,children:n.icon}),(0,Y.jsx)(`span`,{className:`segmented-label`,children:n.label})]},n.id))})}var Ee=.8;function De(e,t=i,r=new Date){if(!e||t.accountExtension===`hidden`)return{};let a=e=>t.accountExtension===`visible`||n(e,t)===e,s={},c=e.summary?.trim();c&&a(c)&&(s.summary=c);let l=e.meter;if(l&&typeof l.label==`string`&&l.label.trim()&&Number.isFinite(l.used)&&Number.isFinite(l.limit)&&l.limit>0&&a(l.label)){let n=Math.max(0,Math.min(l.used,l.limit)),i=n>=l.limit?`reached`:n/l.limit>=Ee?`near`:`ok`;s.meter={label:l.label.trim(),used:n,limit:l.limit,state:i};let a=l.freesAt?new Date(l.freesAt):null;i!==`ok`&&a&&a>r&&(s.meter.freesNote=`A slot frees up ${ke(a,r)}`);let c=e.actions?.find(e=>e.kind===`primary`);i!==`ok`&&c&&o(t)&&(s.action={id:c.id,label:c.label})}return s}var Oe=864e5;function ke(e,t,n){let r=Math.ceil((e.getTime()-t.getTime())/6e4);if(r<60)return`in ${Math.max(1,r)} min`;let i=e.toLocaleTimeString(n,{hour:`2-digit`,minute:`2-digit`}),a=e=>new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime(),o=Math.round((a(e)-a(t))/Oe);return o===0?`today at ${i}`:o===1?`tomorrow at ${i}`:`${e.toLocaleDateString(n,o<6?{weekday:`short`}:{weekday:`short`,day:`numeric`,month:`short`})} at ${i}`}function Ae(e,t=i){let n=e?.offer;if(!n||!o(t)||typeof n.title!=`string`||!n.title.trim())return;let r=e.actions?.find(e=>e.id===n.action);if(!r)return;let a=e=>typeof e==`string`&&e.trim()?e.trim():void 0;return{title:n.title.trim(),price:a(n.price),description:a(n.description),points:Array.isArray(n.points)?n.points.map(a).filter(e=>!!e):[],action:{id:r.id,label:r.label}}}function je(e,t){let n=t?.meter?.label?.trim().toLowerCase();return n?e.filter(e=>e.label.trim().toLowerCase()!==n):[...e]}var Me={claude:`Claude`,codex:`Codex`,grok:`Grok`},Ne={ready:`Ready to import`,conflict:`Already saved — use another name to keep both`,missing:`No credential file found`,unreadable:`Credential file could not be read`,unsupported:`Login format not supported`},Pe={imported:`Imported`,conflict:`Skipped — credential already exists`,changed:`Login changed — scan again`};function Fe({state:e,onBack:t}){let{currentNodeId:n,nodes:r,status:i}=e.connection,[a,o]=(0,J.useState)(``),[s,c]=(0,J.useState)(`node`),[l,u]=(0,J.useState)(null),[d,f]=(0,J.useState)([]),[p,m]=(0,J.useState)(null),[h,g]=(0,J.useState)(null),[_,v]=(0,J.useState)(null),y=(0,J.useRef)(0),b=()=>{y.current++,u(null),f([]),m(null),v(null),g(null)};(0,J.useEffect)(()=>(b(),()=>{y.current+=1}),[n,i]);let x=r.find(e=>e.id===n)?.name||n||`Connected machine`,S=async()=>{let e=++y.current;g(`scan`),v(null),m(null),u(null);try{let t=await T.previewNativeCredentials(n,a);if(y.current!==e)return;u(t),f(t.items.filter(e=>e.status===`ready`).map(e=>e.agent))}catch(t){y.current===e&&v(t instanceof Error?t.message:`Scan failed.`)}finally{y.current===e&&g(null)}},C=async()=>{if(!l)return;let e=++y.current;g(`import`),v(null);try{let t=await T.importNativeCredentials(n,l.previewId,d,s);if(y.current!==e)return;m(t),u(null),f([]),T.listCredentialRecords(),T.listProviders()}catch(t){y.current===e&&(v(t instanceof Error?t.message:`Import failed. Scan again before retrying.`),u(null))}finally{y.current===e&&g(null)}};return(0,Y.jsxs)(`div`,{className:`settings-form credential-vault`,children:[(0,Y.jsx)(`button`,{autoFocus:T.direct||!r.length,className:`btn link`,disabled:h===`import`,onClick:t,children:`‹ Credentials`}),(0,Y.jsx)(`h3`,{children:`Import from machine`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Bring existing Claude, Codex, or Grok sign-ins into Bivy. Saved credentials are never replaced.`}),(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`native-import-machine`,children:`Source machine`}),(0,Y.jsxs)(`select`,{autoFocus:!T.direct&&r.length>0,id:`native-import-machine`,className:`picker-search`,value:n??``,disabled:T.direct||!!h||!r.length,onChange:e=>{b(),T.switchNode(e.target.value)},children:[!r.some(e=>e.id===n)&&(0,Y.jsx)(`option`,{value:n??``,children:i===`online`?x:`Choose an online machine`}),r.filter(e=>!T.direct||e.id===n).map(e=>(0,Y.jsxs)(`option`,{value:e.id,disabled:!e.online&&e.id!==n,children:[e.name||e.id,e.online?``:` — offline`]},e.id))]}),(0,Y.jsxs)(`p`,{className:`muted small`,children:[T.direct?`Direct connection: imports run on this machine only.`:`Selecting a machine also connects Settings to it.`,` Only logins readable by the Bivy daemon’s OS user can be found.`]}),i!==`online`&&(0,Y.jsx)(`p`,{className:`banner inline`,role:`status`,children:i===`connecting`?`Connecting to machine…`:`Connect an online machine to scan its logins.`}),(0,Y.jsxs)(`details`,{className:`vault-advanced`,children:[(0,Y.jsx)(`summary`,{children:`Keep a second login`}),(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`native-import-label`,children:`Credential name (optional)`}),(0,Y.jsx)(`input`,{id:`native-import-label`,className:`picker-search`,maxLength:100,placeholder:`Default — or Work to keep a second login`,disabled:!!h,value:a,onChange:e=>{o(e.target.value),b()}})]}),(0,Y.jsx)(`button`,{className:`btn`,disabled:i!==`online`||!!h,onClick:()=>void S(),children:h===`scan`?`Scanning…`:l||p?`Scan again`:`Scan for logins`}),h&&(0,Y.jsx)(`p`,{className:`muted`,role:`status`,children:h===`scan`?`Reading login files on the selected machine…`:`Importing selected logins…`}),l&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`h4`,{className:`settings-subhead`,children:[`Logins on `,x]}),(0,Y.jsx)(`div`,{className:`picker-list`,children:l.items.map(e=>(0,Y.jsxs)(`label`,{className:`picker-item`,children:[(0,Y.jsxs)(`span`,{children:[(0,Y.jsx)(`strong`,{children:Me[e.agent]}),(0,Y.jsxs)(`small`,{children:[e.provider?`${e.provider} · ${e.kind===`oauth`?`Subscription sign-in`:`API key`} · `:``,Ne[e.status]]})]}),(0,Y.jsx)(`input`,{type:`checkbox`,"aria-label":`Import ${Me[e.agent]}`,disabled:e.status!==`ready`||!!h,checked:d.includes(e.agent),onChange:t=>f(n=>t.target.checked?[...n,e.agent]:n.filter(t=>t!==e.agent))})]},e.agent))}),!l.items.some(e=>e.status===`ready`)&&(0,Y.jsx)(`p`,{role:`status`,className:`muted`,children:`No new logins to import. Sign in on this machine, or use another credential name if already saved.`}),(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`native-import-scope`,children:`Available on`}),(0,Y.jsxs)(`select`,{id:`native-import-scope`,className:`picker-search`,value:s,disabled:!!h,onChange:e=>c(e.target.value),children:[(0,Y.jsx)(`option`,{value:`node`,children:`Only the source machine`}),(0,Y.jsx)(`option`,{value:`account`,children:`All my machines — end-to-end encrypted`})]}),(0,Y.jsx)(`p`,{className:`muted`,children:s===`account`?`Importing grants account sync, not unattended cloud access. Other machines receive credentials when connected.`:`Imported logins stay in this machine’s encrypted vault. You can enable account sync later.`}),(0,Y.jsx)(`button`,{className:`btn primary block`,disabled:!d.length||!!h||i!==`online`,onClick:()=>void C(),children:h===`import`?`Importing…`:`Import ${d.length||`selected`} login${d.length===1?``:`s`}`})]}),p&&(0,Y.jsxs)(`div`,{className:`banner inline`,role:`status`,children:[p.items.map(e=>(0,Y.jsxs)(`p`,{children:[Me[e.agent],`: `,Pe[e.status]]},e.agent)),p.warning&&(0,Y.jsx)(`p`,{children:p.warning}),p.items.some(e=>e.status===`imported`)&&(0,Y.jsxs)(`p`,{children:[s===`account`?`Saved and eligible for account sync; delivery to other machines is not yet confirmed.`:`Saved only on ${x}.`,a.trim()&&` Select the named credential in model accounts to use it.`]})]}),_&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:_}),(0,Y.jsxs)(`details`,{className:`vault-advanced`,children:[(0,Y.jsx)(`summary`,{children:`What can be imported?`}),(0,Y.jsx)(`p`,{className:`muted`,children:`File-based logins only; OS-keychain-only logins are not supported. Tokens never appear in this preview. Native logins are left untouched.`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Access is not verified. Subscription sign-ins work only with compatible Bivy-managed runtimes. Concurrent OAuth refresh by native CLIs or other machines may require signing in again.`})]})]})}var Ie=b.map(e=>({id:e.id,name:e.name,oauth:e.authMethods.some(e=>e.kind===`oauth`),apiKey:e.authMethods.some(e=>e.kind===`api_key`),reference:e.authMethods.some(e=>e.kind===`reference`),help:e.authMethods.find(e=>e.kind===`api_key`)?.helpUrl})),Q=(e,t)=>`${e}\u0000${t||`default`}`,Le=e=>e.label==="default"?e.providerName:`${e.providerName} — ${e.label}`,Re=e=>e===`oauth`?`Subscription sign-in`:e===`reference`?`Password-manager reference`:e===`environment`?`Environment`:`API key`,ze=e=>e===`account`?`All my machines`:e===`node`?`Only this machine`:`Only this device`;function Be({state:e,initialProvider:t=null}){let n=e.connection.status,r=e.connection.currentNodeId,i=e.connection.nodes,a=e.catalogs.providers,o=e.catalogs.repos,s=e.settings.credentialRecords,c=e.settings.credentialPresets,l=e.settings.localModels,u=e.presentation.oauth,[d,f]=(0,J.useState)([]),[p,m]=(0,J.useState)(()=>t?`add`:`list`),[h,g]=(0,J.useState)(null),[_,v]=(0,J.useState)(``),[b,x]=(0,J.useState)(()=>t??``),[S,C]=(0,J.useState)(`api_key`),[w,D]=(0,J.useState)(``),[O,k]=(0,J.useState)(``),[A,j]=(0,J.useState)(``),[M,P]=(0,J.useState)(``),[ee,F]=(0,J.useState)(`openai-completions`),[te,ne]=(0,J.useState)(``),[re,ie]=(0,J.useState)(!1),[I,L]=(0,J.useState)(null),[R,B]=(0,J.useState)(`account`),[V,H]=(0,J.useState)(e.draft.repo??``),[U,W]=(0,J.useState)(!1),[ae,G]=(0,J.useState)(null),[oe,K]=(0,J.useState)(null),[se,q]=(0,J.useState)(null),[ce,le]=(0,J.useState)(()=>T.getOAuthBrowserRecovery()),ue=(0,J.useRef)(null),de=(0,J.useRef)(p);(0,J.useEffect)(()=>{de.current===`import`&&p===`list`&&ue.current?.focus(),de.current=p},[p]);let fe=()=>T.listEphemeralModelKeys().then(f).catch(()=>f([])),ge=()=>{T.listProviders(),T.listCredentialRecords(),T.getCredentialPresets(),fe()};(0,J.useEffect)(()=>{T.listProviders(),T.listCredentialRecords(),T.getCredentialPresets(),T.listLocalModels(),T.listRepos(),T.listEphemeralModelKeys().then(f).catch(()=>f([]))},[r]);let _e=(0,J.useRef)(null),ve=(0,J.useRef)(null);(0,J.useEffect)(()=>{if(u){_e.current={provider:u.provider||b,label:w.trim().toLowerCase()||`default`};return}if(!_e.current)return;let e=_e.current;_e.current=null,ve.current=Q(e.provider,e.label),G(`Sign-in complete.`),ge()},[u]);let ye=(0,J.useMemo)(()=>{let e=new Map(Ie.map(e=>[e.id,e]));for(let t of a)e.set(t.id,{...e.get(t.id),id:t.id,name:t.name||t.id,oauth:t.oauth});for(let t of s)e.has(t.provider)||e.set(t.provider,{id:t.provider,name:t.provider});for(let t of d)e.has(t.provider)||e.set(t.provider,{id:t.provider,name:t.provider});for(let t of l)e.set(t.id,{id:t.id,name:t.name||t.id});return[...e.values()].sort((e,t)=>e.name.localeCompare(t.name))},[a,s,d,l]),be=e=>ye.find(t=>t.id===e)?.name||e,X=(0,J.useMemo)(()=>{let e=new Map,t=pe(me(d),he(s,r||`current-node`));for(let n of t){let t=s.find(e=>e.provider===n.provider&&e.label===n.label),r=d.find(e=>e.provider===n.provider&&e.label===n.label);e.set(Q(n.provider,n.label),{provider:n.provider,providerName:be(n.provider),label:n.label,kind:n.kind,availability:n.availability.account?`account`:r?.scope===`device`?`device`:`node`,...t?{record:t}:{},...r?{device:r}:{}})}for(let t of a)t.configured&&![...e.values()].some(e=>e.provider===t.id)&&e.set(Q(t.id,`default`),{provider:t.id,providerName:t.name||t.id,label:`default`,kind:t.kind===`oauth`?`oauth`:`environment`,availability:`node`,ambient:!0});for(let t of l)e.has(Q(t.id,`default`))||e.set(Q(t.id,`default`),{provider:t.id,providerName:t.name||t.id,label:`default`,kind:`api_key`,availability:t.scope===`machine`?`node`:`account`});return[...e.values()].sort((e,t)=>e.providerName.localeCompare(t.providerName)||e.label.localeCompare(t.label))},[s,a,r,d,ye,l]),Z=h?X.find(e=>Q(e.provider,e.label)===h):void 0;(0,J.useEffect)(()=>{ve.current&&X.some(e=>Q(e.provider,e.label)===ve.current)&&(g(ve.current),ve.current=null,m(`detail`))},[X]);let xe=(0,J.useMemo)(()=>new Map(X.map(e=>[e.provider,X.filter(t=>t.provider===e.provider).length])),[X]),Se=(e=``)=>{x(e),C(`api_key`),D(``),k(``),j(``),P(``),F(`openai-completions`),ne(``),ie(!1),L(null),B(`account`),K(null),G(null)},Ce=async()=>{let e=b.trim().toLowerCase(),t=w.trim().toLowerCase()||`default`;if(!e)return;let r=!re&&(Ie.some(t=>t.id===e)||a.some(t=>t.id===e)&&!l.some(t=>t.id===e)||X.some(t=>t.provider===e&&!l.some(t=>t.id===e)));if(!r||S===`oauth`||O.trim()){W(!0),K(null),G(null);try{if(!r){if(n!==`online`)throw Error(`Connect a machine to configure a custom model endpoint.`);if(!M.trim())throw Error(`A custom provider needs a base URL.`);let t=await T.saveLocalModel({providerId:e,name:A.trim()||e,baseUrl:M.trim(),api:ee,...O.trim()?{apiKey:O.trim()}:{},models:te.split(/[,\n]/).map(e=>e.trim()).filter(Boolean).map(e=>({id:e,name:e}))});T.listLocalModels(),ge(),G(`Custom provider saved.`),g(Q(t,`default`)),m(`detail`);return}if(S===`oauth`){if(n!==`online`)throw Error(`An online machine is needed to complete subscription sign-in.`);d.some(n=>n.provider===e&&n.label===t)&&await T.removeEphemeralModelKey(e,t),T.startOauth(e,t);return}if(S===`api_key`){let r=s.find(n=>n.provider===e&&n.label===t),i=d.find(n=>n.provider===e&&n.label===t);if(R===`device`&&r&&n!==`online`)throw Error(`Connect a machine to remove its existing copy before making this credential device-only.`);if(R===`account`||R===`device`?await T.setEphemeralModelKey(e,O.trim(),R===`device`?`device`:`account`,t):i&&await T.removeEphemeralModelKey(e,t),R===`device`)r&&await T.removeCredential(e,t);else if(n!==`online`){if(R===`node`)throw Error(`Connect to the machine where this key should be stored.`)}else await T.setCredential(e,t,{key:O.trim(),sync:R===`node`?`node`:`account`})}else{if(n!==`online`)throw Error(`Connect a machine to add a password-manager reference.`);d.some(n=>n.provider===e&&n.label===t)&&await T.removeEphemeralModelKey(e,t),await T.setCredential(e,t,{ref:O.trim(),sync:R===`account`?`account`:`node`})}G(`Credential saved.`),k(``),ge(),g(Q(e,t)),m(`detail`)}catch(e){K(e instanceof Error?e.message:String(e))}finally{W(!1)}}},we=async(e,t,n,r)=>{W(!0),K(null);try{await T.setPresetMapping(e,t,n),G(r),T.getCredentialPresets()}catch(e){K(e instanceof Error?e.message:String(e))}finally{W(!1)}},Te=async e=>{W(!0),K(null);try{l.some(t=>t.id===e.provider)&&T.removeLocalModel(e.provider),e.device&&await T.removeEphemeralModelKey(e.provider,e.label),e.record&&await T.removeCredential(e.provider,e.label),q(null),m(`list`),g(null),ge()}catch(e){K(e instanceof Error?e.message:String(e))}finally{W(!1)}};if(p===`import`)return(0,Y.jsx)(Fe,{state:e,onBack:()=>{m(`list`),ge()}});if(p===`add`){let e=ye.find(e=>e.id===b)??(b?{id:b,name:b}:void 0);if(!e){let e=ye.filter(e=>`${e.name} ${e.id}`.toLowerCase().includes(_.toLowerCase()));return(0,Y.jsxs)(`div`,{className:`settings-form credential-vault`,children:[(0,Y.jsx)(`button`,{className:`btn link`,onClick:()=>m(`list`),children:`‹ Credentials`}),(0,Y.jsx)(`h3`,{children:`Add model access`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Connect a hosted provider or point Bivy at a model server you control.`}),(0,Y.jsxs)(`button`,{className:`custom-provider-card`,onClick:()=>{let e=_.trim().toLowerCase()||`local`;Se(e),x(e),ie(!0)},children:[(0,Y.jsx)(`span`,{className:`custom-provider-card-icon`,"aria-hidden":!0,children:`+`}),(0,Y.jsxs)(`span`,{children:[(0,Y.jsx)(`strong`,{children:`Local server or custom endpoint`}),(0,Y.jsx)(`small`,{children:`Ollama, LM Studio, vLLM, Azure, or another compatible API`})]}),(0,Y.jsx)(`span`,{"aria-hidden":!0,children:`›`})]}),(0,Y.jsx)(`div`,{className:`vault-picker-label`,children:`Hosted providers`}),(0,Y.jsx)(`input`,{autoFocus:!0,className:`picker-search`,placeholder:`Search providers…`,value:_,onChange:e=>v(e.target.value)}),(0,Y.jsxs)(`div`,{className:`picker-list`,children:[e.map(e=>(0,Y.jsxs)(`button`,{className:`picker-item`,onClick:()=>{Se(e.id),x(e.id),e.apiKey===!1&&e.oauth&&C(`oauth`)},children:[(0,Y.jsxs)(`span`,{children:[(0,Y.jsx)(`strong`,{children:e.name}),(0,Y.jsx)(`small`,{children:e.id})]}),(0,Y.jsx)(`span`,{"aria-hidden":!0,children:`›`})]},e.id)),e.length===0&&(0,Y.jsx)(`div`,{className:`picker-empty`,children:`No hosted providers match. Add it as a custom endpoint above.`})]})]})}let t=re||l.some(t=>t.id===e.id)||!Ie.some(t=>t.id===e.id)&&!a.some(t=>t.id===e.id)&&!X.some(t=>t.provider===e.id),n=Z?.provider===e.id,r=n||X.some(t=>t.provider===e.id),i=(0,Y.jsxs)(Y.Fragment,{children:[r&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`label`,{className:`field-label`,htmlFor:`credential-name`,children:[`Name `,(0,Y.jsx)(`span`,{className:`muted`,children:`(optional)`})]}),(0,Y.jsx)(`input`,{id:`credential-name`,className:`picker-search`,placeholder:`e.g. Work — leave empty for the default`,value:w,onChange:e=>D(e.target.value)})]}),S!==`oauth`&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`credential-availability`,children:`Available on`}),(0,Y.jsxs)(`select`,{id:`credential-availability`,className:`picker-search`,value:R,onChange:e=>B(e.target.value),children:[(0,Y.jsx)(`option`,{value:`account`,children:`All my machines — end-to-end encrypted`}),(0,Y.jsx)(`option`,{value:`node`,children:`Only this machine`}),S===`api_key`&&(0,Y.jsx)(`option`,{value:`device`,children:`Only this device`})]})]})]});return(0,Y.jsxs)(`div`,{className:`settings-form credential-vault`,children:[(0,Y.jsx)(`button`,{className:`btn link`,onClick:()=>x(``),children:`‹ Providers`}),(0,Y.jsx)(`h3`,{children:t?`Custom provider`:e.name}),u?.provider===e.id?(0,Y.jsx)(z,{}):(0,Y.jsxs)(Y.Fragment,{children:[t&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`p`,{className:`muted`,children:`Use a local model server or any OpenAI-, Anthropic-, or Azure-compatible endpoint.`}),(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`custom-provider-name`,children:`Display name`}),(0,Y.jsx)(`input`,{id:`custom-provider-name`,className:`picker-search`,placeholder:`My local models`,value:A,onChange:e=>j(e.target.value)}),(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`custom-provider-id`,children:`Provider ID`}),(0,Y.jsx)(`input`,{id:`custom-provider-id`,className:`picker-search`,value:b,disabled:n,onChange:e=>x(e.target.value.toLowerCase())}),(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`custom-provider-endpoint`,children:`Endpoint`}),(0,Y.jsx)(`input`,{id:`custom-provider-endpoint`,className:`picker-search`,placeholder:`https://api.example.com/v1`,value:M,onChange:e=>P(e.target.value)}),(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`custom-provider-api`,children:`API compatibility`}),(0,Y.jsxs)(`select`,{id:`custom-provider-api`,className:`picker-search`,value:ee,onChange:e=>F(e.target.value),children:[(0,Y.jsx)(`option`,{value:`openai-completions`,children:`OpenAI-compatible`}),(0,Y.jsx)(`option`,{value:`openai-responses`,children:`OpenAI Responses`}),(0,Y.jsx)(`option`,{value:`azure-openai-responses`,children:`Azure OpenAI`}),(0,Y.jsx)(`option`,{value:`anthropic-messages`,children:`Anthropic Messages`})]}),(0,Y.jsxs)(`label`,{className:`field-label`,htmlFor:`custom-provider-key`,children:[`API key `,(0,Y.jsx)(`span`,{className:`muted`,children:`(optional)`})]}),(0,Y.jsx)(`input`,{id:`custom-provider-key`,className:`picker-search`,type:`password`,placeholder:`Leave blank for local servers without authentication`,value:O,onChange:e=>k(e.target.value)}),(0,Y.jsx)(`div`,{className:`row-actions`,children:(0,Y.jsx)(`button`,{className:`btn`,disabled:U||!M.trim(),onClick:async()=>{W(!0),K(null),L(null);try{let e=await T.verifyLocalModel(M.trim(),O.trim()||void 0);L(e),e.status===`ready`&&ne(e.models.map(e=>e.id).join(`
3
- `))}catch(e){K(e instanceof Error?e.message:String(e))}finally{W(!1)}},children:U?`Checking…`:`Test endpoint & find models`})}),I&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":I.status===`ready`?`ok`:`danger`,children:I.status===`ready`?`Connected on ${I.machineName}. Found ${I.models.length} model${I.models.length===1?``:`s`}.`:I.detail||`This endpoint could not be reached.`}),(0,Y.jsxs)(`label`,{className:`field-label`,htmlFor:`custom-provider-models`,children:[`Models `,(0,Y.jsx)(`span`,{className:`muted`,children:`(one per line)`})]}),(0,Y.jsx)(`textarea`,{id:`custom-provider-models`,className:`picker-search`,rows:3,placeholder:`model-id`,value:te,onChange:e=>ne(e.target.value)})]}),!t&&(0,Y.jsxs)(`div`,{className:`vault-methods`,role:`group`,"aria-label":`Sign-in method`,children:[e.oauth&&(0,Y.jsx)(`button`,{"aria-pressed":S===`oauth`,className:`btn ${S===`oauth`?`primary`:``}`,onClick:()=>C(`oauth`),children:`Subscription sign-in`}),e.apiKey!==!1&&(0,Y.jsx)(`button`,{"aria-pressed":S===`api_key`,className:`btn ${S===`api_key`?`primary`:``}`,onClick:()=>C(`api_key`),children:`API key`}),e.reference!==!1&&(0,Y.jsx)(`button`,{"aria-pressed":S===`reference`,className:`btn ${S===`reference`?`primary`:``}`,onClick:()=>{C(`reference`),R===`device`&&B(`node`)},children:`Password manager`})]}),!t&&(r?i:S===`oauth`?null:(0,Y.jsxs)(`details`,{className:`vault-advanced`,children:[(0,Y.jsx)(`summary`,{children:`Advanced options`}),i]})),S!==`oauth`&&!t&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`credential-secret`,children:S===`reference`?`Reference`:`API key`}),(0,Y.jsx)(`input`,{id:`credential-secret`,className:`picker-search`,type:S===`reference`?`text`:`password`,placeholder:S===`reference`?`op://Vault/Item/field, env://NAME, or cmd://…`:`Paste API key`,value:O,onChange:e=>k(e.target.value)}),e.help&&S===`api_key`&&(0,Y.jsx)(`a`,{className:`btn link`,href:e.help,target:`_blank`,rel:`noreferrer`,children:`Where to create a key ↗`})]}),(0,Y.jsx)(`button`,{className:`btn primary block`,disabled:U||!t&&S!==`oauth`&&!O.trim()||t&&!M.trim(),onClick:Ce,children:U?`Saving…`:S===`oauth`?`Sign in with ${e.name}`:t?`Save custom provider`:`Save credential`})]}),oe&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:oe})]})}if(p===`detail`&&Z){let e=xe.get(Z.provider)??1,t=(c?.presets?.default?.[Z.provider]??`default`)===Z.label,n=V.trim(),a=n?`project:${n}`:void 0,s=a?c?.presets?.[a]?.[Z.provider]:void 0,u=s===Z.label,d=Object.entries(c?.presets??{}).filter(([e,t])=>e.startsWith(`project:`)&&t?.[Z.provider]===Z.label).map(([e])=>e.slice(8)),f=[...new Set([...o.map(e=>e.slug),...Object.keys(c?.presets??{}).filter(e=>e.startsWith(`project:`)).map(e=>e.slice(8))])].sort();return(0,Y.jsxs)(`div`,{className:`settings-form credential-vault`,children:[se&&(0,Y.jsx)(N,{title:l.some(e=>e.id===se.provider)?`Remove endpoint?`:`Delete credential?`,message:l.some(e=>e.id===se.provider)?`Remove ${Le(se)} and its models?`:`Delete ${Le(se)}? Agents and projects using it will lose access.`,confirmLabel:`Delete`,danger:!0,onCancel:()=>q(null),onConfirm:()=>void Te(se)}),(0,Y.jsx)(`button`,{className:`btn link`,onClick:()=>m(`list`),children:`‹ Credentials`}),(0,Y.jsxs)(`div`,{className:`vault-title-row`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h3`,{children:Le(Z)}),(0,Y.jsx)(`p`,{className:`muted`,children:l.some(e=>e.id===Z.provider)?`Local or custom endpoint`:Re(Z.kind)})]}),(0,Y.jsx)(E,{tone:Z.record?.lastVerifiedOk?`ok`:void 0,children:Z.record?.lastVerifiedOk?`Verified`:Z.ambient?`Provided by environment`:`Saved`})]}),(0,Y.jsxs)(`div`,{className:`vault-detail-grid`,children:[(0,Y.jsx)(`span`,{className:`muted`,children:`Available on`}),(0,Y.jsx)(`strong`,{children:ze(Z.availability)}),(0,Y.jsx)(`span`,{className:`muted`,children:`Used by default`}),(0,Y.jsx)(`strong`,{children:t?`Yes`:`No`}),(0,Y.jsx)(`span`,{className:`muted`,children:`Used by projects`}),(0,Y.jsx)(`strong`,{children:d.length?d.join(`, `):`None explicitly — projects use the default`}),V&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`span`,{className:`muted`,children:`Selected project`}),(0,Y.jsx)(`strong`,{children:u?`Uses this credential`:s?`Uses ${s}`:`Uses provider default`})]}),y&&Z.record&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`span`,{className:`muted`,children:`Unattended runs`}),(0,Y.jsx)(`strong`,{children:Z.record.unattended?`Allowed — encrypted cloud copy enabled`:`Not allowed`})]}),Z.record?.origin===`agent-native`&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`span`,{className:`muted`,children:`Added by`}),(0,Y.jsx)(`strong`,{children:`Agent sign-in`})]}),Z.record?.ref&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`span`,{className:`muted`,children:`Reference`}),(0,Y.jsx)(`code`,{children:Z.record.ref})]})]}),Z.record&&(0,Y.jsxs)(`div`,{className:`row-actions`,children:[Z.record.testable&&(0,Y.jsx)(`button`,{className:`btn`,disabled:U,onClick:async()=>{W(!0),K(null);let e=await T.testCredential(Z.provider,Z.label).catch(()=>({ok:!1,at:Date.now(),reason:`network_error`}));G(e.ok?`Connection verified.`:`Verification failed: ${e.reason||`unknown error`}.`),ge(),W(!1)},children:`Test connection`}),e>1&&!t&&(0,Y.jsx)(`button`,{className:`btn`,disabled:U,onClick:()=>void we(`default`,Z.provider,Z.label,`Now used by default.`),children:`Use by default`}),e>1&&a&&!u&&(0,Y.jsxs)(`button`,{className:`btn`,disabled:U,onClick:()=>void we(a,Z.provider,Z.label,`Assigned to ${n}.`),children:[`Use for `,n]}),a&&u&&(0,Y.jsx)(`button`,{className:`btn`,disabled:U,onClick:()=>void we(a,Z.provider,``,`${n} now uses the provider default.`),children:`Clear project assignment`}),y&&Z.record.sync===`account`&&Z.record.kind!==`reference`&&(0,Y.jsx)(`button`,{className:`btn`,disabled:U,onClick:async()=>{W(!0),K(null);try{await T.setCredentialUnattended(Z.provider,Z.label,!Z.record.unattended),G(Z.record.unattended?`Unattended access revoked and its encrypted cloud copy removed.`:`Unattended access enabled with a separate encrypted cloud copy.`),ge()}catch(e){K(e instanceof Error?e.message:String(e))}finally{W(!1)}},children:Z.record.unattended?`Disable unattended runs`:`Allow unattended runs`})]}),y&&Z.record?.sync===`account`&&Z.record.kind!==`reference`&&(0,Y.jsx)(`p`,{className:`muted vault-custody-note`,children:`To run while all your devices are offline, Bivy stores a separate encrypted copy of this credential in its control plane. This is opt-in, used only for unattended runs, and removed when you disable access.`}),e>1&&(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`credential-project`,children:`Assign for project or repository`}),(0,Y.jsx)(`input`,{id:`credential-project`,className:`picker-search`,list:`credential-project-options`,placeholder:`owner/repository or project ID`,value:V,onChange:e=>H(e.target.value)}),(0,Y.jsx)(`datalist`,{id:`credential-project-options`,children:f.map(e=>(0,Y.jsx)(`option`,{value:e},e))})]}),!Z.ambient&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`details`,{className:`vault-advanced`,children:[(0,Y.jsx)(`summary`,{children:`Replace or change availability`}),(0,Y.jsx)(`p`,{className:`muted small`,children:`Re-enter the secret to replace it or move it. Bivy never displays saved secrets.`}),(0,Y.jsx)(`button`,{className:`btn`,onClick:()=>{let e=l.find(e=>e.id===Z.provider);Se(Z.provider),D(Z.label==="default"?``:Z.label),C(Z.kind===`reference`?`reference`:`api_key`),B(Z.availability),e&&(ie(!0),j(e.name||e.id),P(e.baseUrl),F(e.api),ne(e.models.map(e=>e.id).join(`
4
- `))),m(`add`)},children:`Edit credential`})]}),(0,Y.jsx)(`button`,{className:`btn danger-ghost`,disabled:U,onClick:()=>q(Z),children:l.some(e=>e.id===Z.provider)?`Remove endpoint`:`Delete credential`})]}),ae&&(0,Y.jsx)(`p`,{className:`banner inline`,children:ae}),oe&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:oe}),i.length>0&&(0,Y.jsxs)(`details`,{className:`vault-advanced`,children:[(0,Y.jsx)(`summary`,{children:`Machine availability`}),(0,Y.jsx)(`div`,{className:`picker-list`,children:i.map(e=>{let t=Z.availability===`account`||Z.availability===`node`&&e.id===r,n=t?e.online?`Available`:Z.availability===`account`?`Will sync when online`:`Offline`:`Not available`;return(0,Y.jsxs)(`div`,{className:`picker-item`,children:[(0,Y.jsxs)(`span`,{children:[(0,Y.jsx)(`strong`,{children:e.name||e.id}),(0,Y.jsx)(`small`,{children:n})]}),(0,Y.jsx)(E,{tone:t&&e.online?`ok`:void 0,children:n})]},e.id)})})]})]})}let Ee=X.filter(e=>`${e.providerName} ${e.provider} ${e.label}`.toLowerCase().includes(_.toLowerCase()));return(0,Y.jsxs)(`div`,{className:`settings-form credential-vault`,children:[(0,Y.jsxs)(`div`,{className:`vault-title-row`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h3`,{children:`Your model access`}),(0,Y.jsx)(`p`,{className:`muted settings-intro`,children:`Hosted providers, subscription sign-ins, API keys, and your own model endpoints.`})]}),(0,Y.jsx)(`button`,{className:`btn primary`,onClick:()=>{g(null),Se(),v(``),m(`add`)},children:`+ Add`})]}),(0,Y.jsx)(`button`,{ref:ue,className:`btn`,onClick:()=>m(`import`),children:`Import from machine`}),(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`div`,{className:`settings-toggle-title`,children:`OAuth browser recovery`}),(0,Y.jsx)(`p`,{className:`muted small`,children:`Keep account OAuth refresh tokens end-to-end encrypted on your signed-in devices so a new machine can recover without another machine online.`})]}),(0,Y.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":ce,"aria-label":`Allow OAuth browser recovery`,className:`settings-toggle${ce?` on`:``}`,onClick:()=>{let e=!ce;le(e),T.setOAuthBrowserRecovery(e).catch(()=>le(!e))},children:(0,Y.jsx)(`span`,{className:`settings-toggle-knob`,"aria-hidden":!0})})]}),X.length===0?(0,Y.jsxs)(`div`,{className:`vault-empty`,children:[(0,Y.jsx)(`h4`,{children:`No providers yet`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Add a sign-in, API key, local model, or custom endpoint.`}),(0,Y.jsx)(`button`,{className:`btn primary`,onClick:()=>{g(null),Se(),m(`add`)},children:`Add provider`})]}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`input`,{className:`picker-search`,placeholder:`Search credentials…`,value:_,onChange:e=>v(e.target.value)}),(0,Y.jsx)(`div`,{className:`picker-list vault-items`,children:Ee.map(e=>(0,Y.jsxs)(`button`,{className:`picker-item`,onClick:()=>{g(Q(e.provider,e.label)),G(null),K(null),m(`detail`)},children:[(0,Y.jsxs)(`span`,{children:[(0,Y.jsx)(`strong`,{children:Le(e)}),(0,Y.jsxs)(`small`,{children:[l.some(t=>t.id===e.provider)?`Local or custom endpoint`:Re(e.kind),` · `,ze(e.availability)]})]}),(0,Y.jsxs)(`span`,{className:`vault-row-status`,children:[e.record?.lastVerifiedOk&&(0,Y.jsx)(E,{tone:`ok`,children:`Verified`}),(0,Y.jsx)(`span`,{"aria-hidden":!0,children:`›`})]})]},Q(e.provider,e.label)))})]})]})}var Ve=new TextEncoder;function He(e){return e<1024?`${e} B`:`${(e/1024).toFixed(+(e<10240))} KB`}function Ue({state:e}){let t=e.connection.status===`online`,n=t?e.settings.nodeSettings?.agentInstructions:void 0,r=!t||!e.settings.nodeSettings||!!n,[i,a]=(0,J.useState)(``),[o,s]=(0,J.useState)(null),[c,l]=(0,J.useState)(``),[u,d]=(0,J.useState)(!1),[f,p]=(0,J.useState)(null),[m,h]=(0,J.useState)(!1),[g,_]=(0,J.useState)(!1),[v,y]=(0,J.useState)(!1),b=T.local.cur;(0,J.useEffect)(()=>{t&&T.getNodeSettings()},[t,b]);let x=o!==null&&i!==c,S=!!(n&&o!==null&&n.updatedAt!==o&&n.text!==i),C=()=>{n&&(s(n.updatedAt),l(n.text),p(null))},w=()=>{n&&(a(n.text),s(n.updatedAt),l(n.text),p(null))};if((0,J.useEffect)(()=>{n&&(o===null||!x||n.text===i)?w():n&&n.text===c&&s(n.updatedAt)},[n?.updatedAt,n?.text]),!t)return(0,Y.jsx)(`div`,{className:`settings-form`,children:(0,Y.jsxs)(`div`,{className:`vault-empty`,children:[(0,Y.jsx)(`h4`,{children:`No machine connected`}),(0,Y.jsx)(`p`,{className:`muted small`,children:`Agent instructions are saved through one of your machines. Connect to a machine to edit them.`})]})});if(!r)return(0,Y.jsx)(`div`,{className:`settings-form`,children:(0,Y.jsxs)(`div`,{className:`vault-empty`,children:[(0,Y.jsx)(`h4`,{children:`Update this machine`}),(0,Y.jsx)(`p`,{className:`muted small`,children:`This machine's version of Bivy doesn't support agent instructions yet. Update it, or connect to another machine.`})]})});if(!n||o===null)return(0,Y.jsx)(`div`,{className:`settings-form`,children:(0,Y.jsx)(`p`,{className:`muted`,children:`Loading instructions…`})});let E=Ve.encode(i).length,D=E>n.maxBytes;return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[f&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:f}),S&&(0,Y.jsxs)(`div`,{className:`banner inline`,"data-tone":`warn`,role:`status`,children:[(0,Y.jsx)(`span`,{className:`banner-text`,children:`These instructions were changed on another device. Load that version, or keep your edit and save over it.`}),(0,Y.jsxs)(`span`,{className:`banner-actions`,children:[(0,Y.jsx)(`button`,{type:`button`,className:`btn sm`,onClick:w,children:`Load latest`}),(0,Y.jsx)(`button`,{type:`button`,className:`btn sm ghost`,onClick:C,children:`Keep mine`})]})]}),n.bivyNote!==void 0&&(0,Y.jsx)(`section`,{className:`settings-section`,children:(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`span`,{className:`settings-toggle-title`,children:`Send Bivy's system instructions`}),(0,Y.jsx)(`span`,{className:`muted small`,children:`A short note ahead of your instructions that tells agents they run in Bivy and how to send you files and app previews.`}),(0,Y.jsx)(`button`,{type:`button`,className:`btn link`,onClick:()=>y(!0),children:`View system instructions`})]}),(0,Y.jsx)(V,{checked:n.bivyNote,onChange:async e=>{_(!0),p(null);try{await T.setNodeSettings({agentInstructionsBivyNote:e})}catch(e){p(String(e?.message||e))}finally{_(!1)}},disabled:g,label:`Send Bivy's system instructions`})]})}),v&&(0,Y.jsx)(ie,{title:`Bivy's system instructions`,onClose:()=>y(!1),autoFocusSearch:!1,children:(0,Y.jsxs)(`div`,{className:`settings-form`,children:[(0,Y.jsx)(`p`,{className:`muted small`,children:n.bivyNote?`Every agent session gets this note ahead of your instructions.`:`Turned off: agent sessions don't get this note.`}),(0,Y.jsx)(`pre`,{className:`code-snippet agent-note-text`,children:n.bivyNoteText})]})}),(0,Y.jsxs)(`section`,{className:`settings-section`,children:[(0,Y.jsx)(`p`,{className:`muted small`,children:`Every agent session on all your machines gets these, in addition to the repository's own AGENTS.md or CLAUDE.md. Where they conflict, the repository wins. Changes apply to new sessions.`}),(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`agent-instructions`,children:`Instructions (Markdown)`}),(0,Y.jsx)(`textarea`,{id:`agent-instructions`,className:`picker-search`,rows:16,value:i,placeholder:`How you like agents to work, e.g.
5
- - Prefer small, focused commits.
6
- - Run the tests before saying you're done.`,"aria-describedby":`agent-instructions-size`,"aria-invalid":D||void 0,onChange:e=>{a(e.target.value),h(!1)}}),(0,Y.jsxs)(`p`,{id:`agent-instructions-size`,className:D?`settings-error`:`muted small`,children:[He(E),` of `,He(n.maxBytes),D?` — shorten the instructions to save them.`:``]}),(0,Y.jsxs)(`div`,{className:`row-actions`,children:[(0,Y.jsx)(`button`,{type:`button`,className:`btn primary`,onClick:async()=>{if(!(u||D||!x||S)){d(!0),p(null),h(!1);try{await T.setNodeSettings({agentInstructions:i,agentInstructionsBaseUpdatedAt:o}),h(!0),window.setTimeout(()=>h(!1),1500)}catch(e){p(String(e?.message||e))}finally{d(!1)}}},disabled:u||D||!x||S,children:u?`Saving…`:m?`Saved`:`Save`}),x&&(0,Y.jsx)(`button`,{type:`button`,className:`btn`,onClick:w,disabled:u,children:`Revert`})]})]}),(0,Y.jsxs)(`details`,{className:`settings-section settings-disclosure`,children:[(0,Y.jsx)(`summary`,{className:`settings-disclosure-summary`,children:`How agents receive them`}),(0,Y.jsx)(`div`,{className:`settings-disclosure-body`,children:(0,Y.jsxs)(`p`,{className:`muted small`,children:[`Claude Code, Codex, Pi and OpenCode get them as part of their system instructions. Other agents get them through Bivy's MCP server where it is available, which each agent may weigh differently. They're synced to your other machines end-to-end encrypted, and stored on each machine as `,(0,Y.jsx)(`code`,{children:`AGENTS.md`}),` in Bivy's data directory.`]})})]})]})}var We=(0,J.lazy)(()=>f(()=>import(`./VoiceSettings-xv6rjaY2.js`).then(e=>({default:e.VoiceSettings})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12]))),Ge=[`github`,`linear`,`slack`,`queue`,`webhooks`,`rulesets`];function Ke(e){return e!==null&&Ge.includes(e)}function $({children:e}){return(0,Y.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`20`,height:`20`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.7`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":!0,children:e})}var qe=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,Y.jsx)(`path`,{d:`M12 3v18a9 9 0 0 0 0-18z`,fill:`currentColor`,stroke:`none`})]}),Je=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`circle`,{cx:`7.5`,cy:`15.5`,r:`4.5`}),(0,Y.jsx)(`path`,{d:`m11 12 8-8`}),(0,Y.jsx)(`path`,{d:`m16 5 3 3`}),(0,Y.jsx)(`path`,{d:`m13 8 3 3`})]}),Ye=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`path`,{d:`M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z`}),(0,Y.jsx)(`path`,{d:`M14 3v5h5`}),(0,Y.jsx)(`path`,{d:`M9 13h6M9 17h4`})]}),Xe=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`rect`,{x:`9`,y:`2`,width:`6`,height:`12`,rx:`3`}),(0,Y.jsx)(`path`,{d:`M5 10a7 7 0 0 0 14 0`}),(0,Y.jsx)(`path`,{d:`M12 19v3`})]}),Ze=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`circle`,{cx:`12`,cy:`8`,r:`4`}),(0,Y.jsx)(`path`,{d:`M4 21a8 8 0 0 1 16 0`})]}),Qe=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`path`,{d:`M9 17H7A5 5 0 0 1 7 7h2`}),(0,Y.jsx)(`path`,{d:`M15 7h2a5 5 0 0 1 0 10h-2`}),(0,Y.jsx)(`line`,{x1:`8`,y1:`12`,x2:`16`,y2:`12`})]}),$e=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`rect`,{x:`2`,y:`3`,width:`20`,height:`14`,rx:`2`}),(0,Y.jsx)(`path`,{d:`M8 21h8M12 17v4`})]}),et=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`rect`,{x:`3`,y:`4`,width:`18`,height:`7`,rx:`2`}),(0,Y.jsx)(`rect`,{x:`3`,y:`13`,width:`18`,height:`7`,rx:`2`}),(0,Y.jsx)(`path`,{d:`M7 7.5h.01M7 16.5h.01`})]}),tt=()=>(0,Y.jsx)($,{children:(0,Y.jsx)(`path`,{d:`M13 2 4 14h7l-1 8 9-12h-7l1-8z`})}),nt=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`circle`,{cx:`12`,cy:`12`,r:`4`}),(0,Y.jsx)(`path`,{d:`M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4`})]}),rt=()=>(0,Y.jsx)($,{children:(0,Y.jsx)(`path`,{d:`M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z`})}),it=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`path`,{d:`M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9`}),(0,Y.jsx)(`path`,{d:`M13.7 21a2 2 0 0 1-3.4 0`})]}),at=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`path`,{d:`M12 3v12`}),(0,Y.jsx)(`path`,{d:`m7 10 5 5 5-5`}),(0,Y.jsx)(`path`,{d:`M5 19h14`})]}),ot=()=>(0,Y.jsxs)($,{children:[(0,Y.jsx)(`path`,{d:`M4 12v7a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7`}),(0,Y.jsx)(`path`,{d:`m8 6 4-4 4 4`}),(0,Y.jsx)(`path`,{d:`M12 2v13`})]});function st(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleString(void 0,{dateStyle:`medium`,timeStyle:`short`})}function ct(e){let[t,n]=(0,J.useState)(null);return(0,J.useEffect)(()=>{if(!e)return;let t=!0;return T.fetchMe().then(e=>{t&&n(e)}).catch(()=>{}),()=>{t=!1}},[e]),t}var lt={ok:null,near:`Almost used up`,reached:`Limit reached`};function ut({meter:e,action:t}){let[n,r]=(0,J.useState)(!1),[i,a]=(0,J.useState)(null),o=lt[e.state];return(0,Y.jsxs)(`div`,{className:`settings-account-usage`,"data-state":e.state,children:[(0,Y.jsxs)(`div`,{className:`settings-account-usage-row`,children:[(0,Y.jsx)(`span`,{children:e.label}),(0,Y.jsxs)(`span`,{className:`settings-account-usage-count`,children:[e.used,` of `,e.limit]})]}),(0,Y.jsx)(`div`,{className:`meter`,role:`meter`,"aria-label":e.label,"aria-valuemin":0,"aria-valuemax":e.limit,"aria-valuenow":e.used,"aria-valuetext":`${e.used} of ${e.limit}${o?` — ${o.toLowerCase()}`:``}`,"data-state":e.state,children:(0,Y.jsx)(`span`,{className:`meter-fill`,style:{width:`${e.used/e.limit*100}%`}})}),o&&(0,Y.jsxs)(`span`,{className:`settings-account-usage-status`,children:[(0,Y.jsx)(`span`,{className:`settings-account-usage-note`,children:o}),e.freesNote&&(0,Y.jsx)(`span`,{children:e.freesNote})]}),t&&(0,Y.jsx)(`button`,{type:`button`,className:`btn primary block`,disabled:n,onClick:()=>{r(!0),a(null),T.invokeAccountExtensionAction(t.id).then(({url:e})=>d(e)).catch(e=>a(String(e?.message||e))).finally(()=>r(!1))},children:n?`Opening…`:t.label}),i&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:i})]})}function dt(e){return((e.split(`@`)[0]??``).replace(/[^a-z0-9]/gi,``)||e).slice(0,2).toUpperCase()}var ft={appearance:`Appearance`,notifications:`Notifications`,import:`Import session`,providers:`Models & keys`,models:`Models & keys`,instructions:`Agent instructions`,voice:`Voice`,share:`Share to Bivy`,github:`GitHub App`,linear:`Linear`,slack:`Slack`,queue:`Runs`,webhooks:`Webhooks`,rulesets:`Rulesets`,nodes:`Machines`,ephemeral:`Cloud machine profiles`,account:`Account`,link:`Link a device`},pt={appearance:`theme system light dark`,notifications:`push alerts attention approval permission idle completed`,import:`session transcript file upload migrate`,providers:`model provider api key oauth openai anthropic google login credentials custom endpoint local ollama import claude codex grok machine`,models:`model provider api key oauth ollama local custom endpoint`,instructions:`agents.md claude.md system prompt global instructions rules preferences memory`,voice:`microphone speech transcription read aloud reader text to speech voice tone speed`,share:`share sheet send android ios iphone ipad shortcut link url target`,github:`github app repository installation issue pull request`,linear:`linear workspace issue integration`,slack:`slack workspace channel integration`,queue:`work queue issue run evidence outcome retry lease checks`,webhooks:`webhook trigger secret event`,rulesets:`rules policy routing agent runtime model sandbox`,nodes:`node daemon online offline diagnostics version update storage disk cloud machines experimental unstable`,ephemeral:`cloud machine profiles automation offline teardown retention`,account:`account email devices machines usage`,link:`device qr code phone mobile pair`};function mt({state:e,onClose:t,view:n,onViewChange:r,onImported:i,onRedirectToAutomations:a}){let o=!T.direct,s=ae(`(min-width: 721px)`),c=`appearance`,[l,u]=(0,J.useState)(``),[d,f]=(0,J.useState)(!1),[p,m]=(0,J.useState)(null),h=n??(s?c:null);(0,J.useEffect)(()=>{s&&n===null&&r(c)},[s,n]),(0,J.useEffect)(()=>{Ke(n)&&a?.(n)},[n]);let g=j(t),_=(0,J.useRef)(g);_.current=t,ne(()=>_.current()),(0,J.useEffect)(()=>{let e=document.activeElement;return()=>{e?.focus?.()}},[]);let v=A(),b=y&&v,x=[{label:`Models & keys`,items:[{id:`providers`,label:`Providers & credentials`,icon:(0,Y.jsx)(Je,{})}]},{label:`Agents`,items:[{id:`instructions`,label:`Agent instructions`,icon:(0,Y.jsx)(Ye,{})}]},{label:`Machines`,items:[{id:`nodes`,label:`Machines`,icon:(0,Y.jsx)(et,{})},...b?[{id:`ephemeral`,label:`Cloud machine profiles`,icon:(0,Y.jsx)(tt,{})}]:[],...o?[{id:`link`,label:`Link a device`,icon:(0,Y.jsx)(Qe,{})}]:[]]},{label:`App`,items:[{id:`appearance`,label:`Appearance`,icon:(0,Y.jsx)(qe,{})},{id:`notifications`,label:`Notifications`,icon:(0,Y.jsx)(it,{})},{id:`voice`,label:`Voice`,icon:(0,Y.jsx)(Xe,{})},{id:`import`,label:`Import session`,icon:(0,Y.jsx)(at,{})},{id:`share`,label:`Share to Bivy`,icon:(0,Y.jsx)(ot,{})}]}],S=ct(o),C=S?.account?.email??null,w=De(S?.extension),E={id:`account`,label:C??`Account`,icon:(0,Y.jsx)(Ze,{})},D=l.trim().toLowerCase(),O=e=>!D||`${e.label} ${ft[e.id]} ${pt[e.id]}`.toLowerCase().includes(D),k=o&&O(E),M=k||x.some(e=>e.items.some(O)),ee=e=>`settings-nav-item${h===e||e===`providers`&&h===`models`?` active`:``}`,te=h?ft[h]:`Settings`;return(0,ye.createPortal)((0,Y.jsxs)(`div`,{className:`settings-modal`,role:`dialog`,"aria-modal":`true`,"aria-label":`Settings`,children:[d&&(0,Y.jsx)(N,{title:`Sign out?`,message:`Sign out of Bivy on this device?`,confirmLabel:`Sign out`,danger:!0,onCancel:()=>f(!1),onConfirm:()=>{f(!1),T.signOut().catch(e=>T.store.setError(String(e?.message||e)))}}),(0,Y.jsx)(`div`,{className:`settings-scrim`,onClick:g}),(0,Y.jsxs)(`div`,{className:`settings-panel`,"data-mode":h?`panel`:`menu`,children:[(0,Y.jsxs)(`aside`,{className:`settings-nav`,children:[(0,Y.jsxs)(`div`,{className:`settings-nav-top`,children:[(0,Y.jsx)(`span`,{className:`settings-nav-heading`,children:`Settings`}),(0,Y.jsx)(`button`,{className:`settings-x`,onClick:g,"aria-label":`Close settings`,children:(0,Y.jsx)(F,{})})]}),(0,Y.jsxs)(`div`,{className:`settings-search-wrap`,children:[(0,Y.jsxs)(`svg`,{className:`settings-search-icon`,viewBox:`0 0 24 24`,width:`16`,height:`16`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.8`,strokeLinecap:`round`,"aria-hidden":!0,children:[(0,Y.jsx)(`circle`,{cx:`11`,cy:`11`,r:`7`}),(0,Y.jsx)(`path`,{d:`m21 21-4.3-4.3`})]}),(0,Y.jsx)(`input`,{className:`field settings-search`,type:`search`,placeholder:`Search`,value:l,onChange:e=>u(e.target.value)})]}),(0,Y.jsxs)(`nav`,{className:`settings-nav-groups`,children:[!M&&(0,Y.jsxs)(`div`,{className:`picker-empty`,children:[`No settings match "`,l.trim(),`"`]}),k&&(0,Y.jsxs)(`div`,{className:`settings-account-card`,children:[(0,Y.jsxs)(`button`,{className:ee(`account`),title:C??void 0,onClick:()=>r(`account`),children:[(0,Y.jsx)(`span`,{className:`settings-account-avatar`,"aria-hidden":!0,children:C?dt(C):E.icon}),(0,Y.jsxs)(`span`,{className:`settings-account-text`,children:[(0,Y.jsx)(`span`,{className:`settings-nav-label`,children:E.label}),(0,Y.jsx)(`span`,{className:`settings-account-sub`,children:w.summary??`Account`})]}),(0,Y.jsx)(`span`,{className:`settings-nav-chevron`,children:(0,Y.jsx)(P,{size:18})})]}),w.meter&&(0,Y.jsx)(ut,{meter:w.meter,action:w.action})]}),x.map(e=>{let t=e.items.filter(O);return t.length===0?null:(0,Y.jsxs)(`div`,{className:`settings-nav-group`,children:[(0,Y.jsx)(`div`,{className:`settings-nav-group-label`,children:e.label}),t.map(e=>(0,Y.jsxs)(`button`,{className:ee(e.id),onClick:()=>{e.id===`providers`&&m(null),r(e.id)},children:[(0,Y.jsx)(`span`,{className:`settings-nav-icon`,children:e.icon}),(0,Y.jsx)(`span`,{className:`settings-nav-label`,children:e.label}),(0,Y.jsx)(`span`,{className:`settings-nav-chevron`,children:(0,Y.jsx)(P,{size:18})})]},e.id))]},e.label)})]}),o&&(0,Y.jsx)(`button`,{className:`btn block`,onClick:()=>f(!0),children:`Sign out`}),(0,Y.jsxs)(`div`,{className:`settings-nav-version`,title:`The version of the Bivy app running on this device`,children:[(0,Y.jsxs)(`span`,{children:[`Bivy v`,`0.20.9`]}),st(`2026-10-06T14:19:35.965Z`)&&(0,Y.jsxs)(`span`,{className:`settings-nav-version-updated`,children:[`Updated `,st(`2026-10-06T14:19:35.965Z`)]})]})]}),(0,Y.jsxs)(`section`,{className:`settings-content`,children:[(0,Y.jsxs)(`header`,{className:`settings-head`,children:[h&&(0,Y.jsxs)(`button`,{className:`settings-back`,onClick:()=>r(null),"aria-label":`Back to settings`,children:[(0,Y.jsx)(`span`,{"aria-hidden":!0,children:`‹`}),` Settings`]}),(0,Y.jsx)(`h2`,{className:`settings-head-title`,children:te}),(0,Y.jsx)(`button`,{className:`settings-x settings-x-content`,onClick:g,"aria-label":`Close settings`,children:(0,Y.jsx)(F,{})})]}),(0,Y.jsxs)(`div`,{className:`settings-body`,children:[h===`appearance`&&(0,Y.jsx)(ht,{}),h===`notifications`&&(0,Y.jsx)(bt,{}),h===`import`&&(0,Y.jsx)(gt,{onImported:e=>i?.(e)}),h===`share`&&(0,Y.jsx)(_t,{}),h===`providers`&&(0,Y.jsx)(Be,{state:e,initialProvider:p}),h===`models`&&(0,Y.jsx)(Et,{state:e,onStartWork:t}),h===`instructions`&&(0,Y.jsx)(Ue,{state:e}),h===`voice`&&(0,Y.jsx)(J.Suspense,{fallback:(0,Y.jsx)(`div`,{className:`muted`,children:`Loading voice settings…`}),children:(0,Y.jsx)(We,{state:e,onManageKey:e=>{m(e),r(`providers`)}})}),h===`nodes`&&(0,Y.jsx)(Dt,{state:e,cloudMachinesEnabled:b}),h===`ephemeral`&&y&&(b?(0,Y.jsx)(jt,{}):(0,Y.jsx)(yt,{})),h===`account`&&(0,Y.jsx)(Ft,{}),h===`link`&&(0,Y.jsx)(Lt,{onDone:t})]},h??`menu`)]})]})]}),document.body)}function ht(){let[e,t]=(0,J.useState)(u()),[n,r]=(0,J.useState)(l());(0,J.useEffect)(()=>s(()=>r(l())),[]);let i=[...n?[{id:`machine`,label:`Machine`,icon:(0,Y.jsx)(qe,{})}]:[],{id:`system`,label:`System`,icon:(0,Y.jsx)($e,{})},{id:`light`,label:`Light`,icon:(0,Y.jsx)(nt,{})},{id:`dark`,label:`Dark`,icon:(0,Y.jsx)(rt,{})}];return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[(0,Y.jsx)(`label`,{className:`field-label`,children:`Theme`}),(0,Y.jsx)(Te,{ariaLabel:`Theme`,value:e===`machine`&&!n?`system`:e,options:i,onChange:e=>{p(e),t(e)}}),(0,Y.jsxs)(`p`,{className:`muted`,children:[`Choose how Bivy looks. `,(0,Y.jsx)(`strong`,{children:`System`}),` follows your device's light/dark setting.`,n&&(0,Y.jsxs)(Y.Fragment,{children:[` `,(0,Y.jsx)(`strong`,{children:`Machine`}),` matches this machine's desktop theme, now `,n.name,`, and changes with it.`]})]})]})}function gt({onImported:e}){return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[(0,Y.jsx)(`p`,{className:`muted`,children:`Adopt a Claude Code or Codex session that was started outside Bivy. Only sessions this machine (or another one you pick) can see and safely take over are listed.`}),(0,Y.jsx)(xe,{onDone:e})]})}function _t(){let[e,t]=(0,J.useState)(!1),n=(0,J.useRef)(null);(0,J.useEffect)(()=>()=>{n.current&&clearTimeout(n.current)},[]);let r=`${c()}/share?text=`,i=async()=>{await te(r)&&(t(!0),n.current&&clearTimeout(n.current),n.current=setTimeout(()=>t(!1),1500))};return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[(0,Y.jsx)(`p`,{className:`muted`,children:`Send text or a link from another app straight into a new Bivy session draft.`}),(0,Y.jsxs)(`section`,{className:`settings-section`,children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`Android & desktop`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Install Bivy (Add to Home Screen / Install app) and it appears in the system share sheet automatically. Whatever you share is waiting in the composer as a new session draft.`})]}),(0,Y.jsxs)(`section`,{className:`settings-section`,children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`iPhone & iPad`}),(0,Y.jsx)(`p`,{className:`muted`,children:`iOS doesn't let web apps register in its share sheet, so add a one-time Shortcut that does the same job:`}),(0,Y.jsxs)(`ol`,{className:`eph-steps`,children:[(0,Y.jsxs)(`li`,{children:[`Open the `,(0,Y.jsx)(`strong`,{children:`Shortcuts`}),` app and tap `,(0,Y.jsx)(`strong`,{children:`+`}),` to create a new shortcut.`]}),(0,Y.jsxs)(`li`,{children:[`Add the `,(0,Y.jsx)(`strong`,{children:`URL Encode`}),` action — set its input to the `,(0,Y.jsx)(`em`,{children:`Shortcut Input`}),` variable.`]}),(0,Y.jsxs)(`li`,{children:[`Add the `,(0,Y.jsx)(`strong`,{children:`Open URLs`}),` action, paste the address below into its URL field, and place the `,(0,Y.jsx)(`em`,{children:`URL Encoded Text`}),` variable right after `,(0,Y.jsx)(`code`,{children:`text=`}),`.`]}),(0,Y.jsxs)(`li`,{children:[`Open the shortcut's settings (ⓘ), turn on `,(0,Y.jsx)(`strong`,{children:`Show in Share Sheet`}),`, and name it `,(0,Y.jsx)(`strong`,{children:`Send to Bivy`}),`.`]})]}),(0,Y.jsxs)(`div`,{className:`connect-command`,children:[(0,Y.jsx)(`code`,{tabIndex:0,"aria-label":`Share URL for the iOS Shortcut`,children:r}),(0,Y.jsx)(`button`,{type:`button`,className:`btn sm ghost icon-only${e?` is-copied`:``}`,onClick:()=>void i(),"aria-label":e?`Share URL copied`:`Copy share URL`,title:e?`Copied`:`Copy share URL`,children:e?(0,Y.jsx)(re,{size:16}):(0,Y.jsx)(ee,{size:16})})]}),(0,Y.jsx)(`p`,{className:`muted small`,children:`Sharing opens Bivy in Safari with the shared text in the composer — sign in there once if Safari and the installed app don't share a session.`})]})]})}function vt({enabled:e}){return(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsxs)(`span`,{className:`settings-toggle-title`,children:[`Cloud machines `,(0,Y.jsx)(E,{tone:`warn`,children:`Experimental`})]}),(0,Y.jsx)(`span`,{className:`muted small`,children:`Show cloud machine profiles and automation routing. This feature is experimental and unstable; machines may fail to boot or require manual cleanup in your cloud provider account.`})]}),(0,Y.jsx)(V,{checked:e,onChange:w,label:`Enable experimental cloud machines`})]})}function yt(){let e=A();return(0,Y.jsx)(`div`,{className:`settings-form`,children:(0,Y.jsx)(`section`,{className:`settings-section`,children:(0,Y.jsx)(vt,{enabled:e})})})}function bt(){let[t,n]=(0,J.useState)(null),[r,i]=(0,J.useState)(null),[a,o]=(0,J.useState)(null),[s,c]=(0,J.useState)(null),[l,u]=(0,J.useState)(!1),d=(0,J.useSyncExternalStore)(W,H),f=()=>T.pushStatus().then(n).catch(()=>{});(0,J.useEffect)(()=>{f(),T.getNotificationPreferences().then(e=>{i(e),oe(e)}).catch(()=>{})},[]),(0,J.useEffect)(()=>{if(!a&&!s)return;let e=setTimeout(()=>{o(null),c(null)},5e3);return()=>clearTimeout(e)},[a,s]);let p=!!t?.subscribed,m=async e=>{u(!0),o(null),c(null);try{o(e?await T.enablePush():await T.disablePush())}catch(e){c(String(e.message||e))}finally{u(!1),f()}},h=(e,t)=>{if(!r)return;let n={...r,[e]:t};i(n),T.setNotificationPreferences({[e]:t}).then(e=>{i(e),oe(e)}).catch(e=>{i(r),c(String(e.message||e))})};return T.direct?(0,Y.jsx)(`div`,{className:`settings-form`,children:(0,Y.jsx)(K,{feature:`push`,inSettings:!0})}):t&&!t.supported?(0,Y.jsx)(`div`,{className:`settings-form`,children:(0,Y.jsx)(`p`,{className:`muted`,children:`Push notifications aren't supported on this device or browser.`})}):(0,Y.jsxs)(`div`,{className:`settings-form`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`span`,{className:`settings-toggle-title`,children:`Push notifications`}),(0,Y.jsx)(`p`,{className:`muted`,children:p?`This device receives Bivy push notifications.`:`Turn on to get notified about your sessions on this device.`})]}),(0,Y.jsx)(V,{checked:p,disabled:l,onChange:m,label:`Enable push notifications`})]}),(!e||typeof navigator.setAppBadge==`function`)&&(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`span`,{className:`settings-toggle-title`,children:`App icon badge`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Show the number of sessions that need attention on this device's home screen icon.`})]}),(0,Y.jsx)(V,{checked:d,onChange:G,label:`Show app icon badge`})]}),t?.permission===`denied`&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`warn`,children:`Notifications are blocked in your device or browser settings — allow them there to enable push.`}),a&&(0,Y.jsx)(`div`,{className:`banner inline`,children:a}),s&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:s}),(0,Y.jsx)(`label`,{className:`field-label`,children:`What to notify me about`}),(0,Y.jsx)(`div`,{className:`settings-toggle-list`,"aria-disabled":!p,children:D.map(e=>(0,Y.jsxs)(`div`,{className:`settings-toggle-row${p?``:` disabled`}`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`span`,{className:`settings-toggle-title`,children:e.label}),(0,Y.jsx)(`p`,{className:`muted`,children:e.description})]}),(0,Y.jsx)(V,{checked:!r||r[e.id],disabled:!p||!r,onChange:t=>h(e.id,t),label:e.label})]},e.id))}),(0,Y.jsx)(`p`,{className:`muted`,children:`These choices apply to every device signed in to your account.`})]})}var xt={providerId:``,name:``,baseUrl:``,api:`openai-completions`,apiKey:``,hasSavedApiKey:!1,models:``,editing:!1},St=[{value:`openai-completions`,label:`OpenAI-compatible (Ollama, vLLM, LM Studio, …)`},{value:`azure-openai-responses`,label:`Azure OpenAI`},{value:`openai-responses`,label:`OpenAI Responses`},{value:`anthropic-messages`,label:`Anthropic Messages`}];function Ct(e){return e.split(/[\n,]/).map(e=>e.trim()).filter(Boolean).map(e=>{let[t,...n]=e.split(`|`),r=(t??``).trim(),i=n.join(`|`).trim();return{id:r,...i?{name:i}:{}}}).filter(e=>e.id)}function wt(e){return{providerId:e.id,name:e.name??``,baseUrl:e.baseUrl,api:e.api||`openai-completions`,apiKey:``,hasSavedApiKey:e.hasKey,models:e.models.map(e=>e.name&&e.name!==e.id?`${e.id} | ${e.name}`:e.id).join(`
7
- `),editing:!0}}function Tt(e){return{providerId:e.id,name:e.name,baseUrl:e.baseUrl,api:e.api||`openai-completions`,apiKey:``,hasSavedApiKey:!1,models:``,editing:!1}}function Et({state:e,onStartWork:t}){let[n,r]=(0,J.useState)(null),[i,a]=(0,J.useState)(!1),[o,s]=(0,J.useState)(null),[c,l]=(0,J.useState)(null),[u,d]=(0,J.useState)(null),[f,p]=(0,J.useState)(!1),[m,h]=(0,J.useState)(null),[g,_]=(0,J.useState)(null),[v,y]=(0,J.useState)(null);(0,J.useEffect)(()=>{T.listLocalModels(),T.listLocalModelPresets()},[]);let b=e=>r(t=>({...t??xt,...e})),x=e=>{s(null),l(null),r(e)},S=(e,n)=>{T.newSession(),T.chooseModel({id:n.id,label:n.name||n.id,provider:e}),t()};if(n){let e=n.baseUrl.trim().length>0&&!i,t=St.some(e=>e.value===n.api),u=n.api.toLowerCase().startsWith(`azure`),d=async(e=!1)=>{a(!0),s(null);try{let t=await T.saveLocalModel({providerId:(n.providerId||n.name||`local`).trim(),name:n.name.trim()||void 0,baseUrl:n.baseUrl.trim(),api:n.api.trim()||`openai-completions`,...n.apiKey.trim()?{apiKey:n.apiKey.trim()}:{},models:Ct(n.models)});T.listLocalModels();let i=Ct(n.models);e&&i[0]&&S(t,i[0]),r(null)}catch(e){s(String(e?.message||e))}finally{a(!1)}};return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[(0,Y.jsx)(`button`,{className:`btn link`,onClick:()=>x(null),children:`‹ All endpoints`}),(0,Y.jsx)(`h3`,{children:n.editing?n.name||n.providerId:`Add endpoint`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Verify an OpenAI-compatible server, then import the models it actually reports. Ollama, LM Studio, vLLM, SGLang, and custom endpoints are supported.`}),(0,Y.jsx)(`p`,{className:`muted small`,children:`A localhost endpoint is bound to this connected Machine and will not appear as usable on another Machine. An explicitly entered network endpoint can be shared only where that URL is really reachable.`}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Display name`}),(0,Y.jsx)(`input`,{className:`picker-search`,value:n.name,placeholder:`My local models`,onChange:e=>b({name:e.target.value})}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Identifier`}),(0,Y.jsx)(`input`,{className:`picker-search`,value:n.providerId,placeholder:`ollama`,disabled:n.editing,onChange:e=>b({providerId:e.target.value})}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Base URL`}),(0,Y.jsx)(`input`,{className:`picker-search`,value:n.baseUrl,placeholder:u?`https://YOUR-RESOURCE.openai.azure.com`:`http://localhost:11434/v1`,onChange:e=>b({baseUrl:e.target.value})}),/localhost|127\.0\.0\.1/i.test(n.baseUrl)&&(0,Y.jsxs)(`p`,{className:`muted small`,children:[`⚠ This points at the current machine. Once synced, other machines will only reach it if they also run a server at `,(0,Y.jsx)(`code`,{children:n.baseUrl.match(/localhost|127\.0\.0\.1/i)?.[0]??`localhost`}),` `,`themselves.`]}),(0,Y.jsx)(`label`,{className:`field-label`,children:`API type`}),(0,Y.jsxs)(`select`,{className:`picker-search`,value:t?n.api:`__custom__`,onChange:e=>b({api:e.target.value===`__custom__`?``:e.target.value}),children:[St.map(e=>(0,Y.jsx)(`option`,{value:e.value,children:e.label},e.value)),(0,Y.jsx)(`option`,{value:`__custom__`,children:`Custom…`})]}),!t&&(0,Y.jsx)(`input`,{className:`picker-search`,value:n.api,placeholder:`custom-api-id`,onChange:e=>b({api:e.target.value})}),(0,Y.jsxs)(`label`,{className:`field-label`,children:[`API key `,n.editing?`(leave blank to keep)`:u?`(Azure API key)`:`(optional)`]}),(0,Y.jsx)(`input`,{className:`picker-search`,type:`password`,value:n.apiKey,placeholder:n.hasSavedApiKey?`•••••••• (saved — leave blank to keep)`:u?`Azure OpenAI key`:`local`,onChange:e=>b({apiKey:e.target.value})}),n.hasSavedApiKey&&!n.apiKey&&(0,Y.jsx)(`p`,{className:`muted small`,children:`An API key is saved. Leave this blank to keep it, or enter a new key to replace it.`}),(0,Y.jsx)(`div`,{className:`row-actions`,children:(0,Y.jsx)(`button`,{className:`btn`,disabled:!n.baseUrl.trim()||i,onClick:async()=>{a(!0),s(null),l(null);try{let e=await T.verifyLocalModel(n.baseUrl.trim(),n.apiKey.trim()||void 0);if(l(e),e.status===`ready`){let t=[...Ct(n.models),...e.models].filter((e,t,n)=>n.findIndex(t=>t.id===e.id)===t);b({models:t.map(e=>e.name&&e.name!==e.id?`${e.id} | ${e.name}`:e.id).join(`
8
- `)})}}catch(e){s(String(e?.message||e))}finally{a(!1)}},children:i?`Verifying…`:`Verify endpoint & list models`})}),c&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":c.status===`ready`?`ok`:`danger`,children:c.status===`ready`?`Verified on ${c.machineName}: ${c.models.length} model${c.models.length===1?``:`s`} available.`:`${c.status.replace(`_`,` `)}: ${c.detail||`No compatible catalog was returned.`}`}),(0,Y.jsxs)(`label`,{className:`field-label`,children:[`Models — one per line (`,(0,Y.jsx)(`code`,{children:`id`}),` or `,(0,Y.jsx)(`code`,{children:`id | Name`}),`)`]}),(0,Y.jsx)(`textarea`,{className:`picker-search`,rows:4,value:n.models,placeholder:u?`my-gpt-4o-deployment | GPT-4o`:`llama3.1
9
- qwen2.5-coder | Qwen 2.5 Coder`,onChange:e=>b({models:e.target.value})}),u&&(0,Y.jsxs)(`p`,{className:`muted`,children:[`Azure routes by `,(0,Y.jsx)(`em`,{children:`deployment`}),`: set each model’s id to your deployment name. The key is sent as the`,(0,Y.jsx)(`code`,{children:` api-key`}),` header and `,(0,Y.jsx)(`code`,{children:`api-version`}),` is handled automatically.`]}),(0,Y.jsxs)(`div`,{className:`row-actions`,children:[(0,Y.jsx)(`button`,{className:`btn primary`,disabled:!e,onClick:()=>void d(!1),children:i?`Saving…`:n.editing?`Save changes`:`Import models`}),Ct(n.models).length>0&&(0,Y.jsx)(`button`,{className:`btn`,disabled:!e,onClick:()=>void d(!0),children:`Import & use in new session`}),(0,Y.jsx)(`button`,{className:`btn`,onClick:()=>x(null),children:`Cancel`})]}),o&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:o})]})}return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[v&&(0,Y.jsx)(N,{title:v.title,message:v.message,confirmLabel:`Remove`,danger:!0,onCancel:()=>y(null),onConfirm:()=>{v.action(),y(null)}}),(0,Y.jsx)(`h3`,{children:`Model endpoints`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Connect OpenAI-compatible servers (Ollama, LM Studio, vLLM, SGLang, Azure…) and import the models they report. Localhost endpoints stay tied to the Machine that hosts them.`}),e.settings.localModels.length===0?(0,Y.jsxs)(`div`,{className:`vault-empty`,children:[(0,Y.jsx)(`h4`,{children:`No endpoints yet`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Add an OpenAI-compatible server, or discover one running on this Machine below.`}),(0,Y.jsx)(`button`,{className:`btn primary`,onClick:()=>x({...xt}),children:`Add endpoint`})]}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`div`,{className:`picker-list vault-items`,children:e.settings.localModels.map(e=>(0,Y.jsx)(I,{title:e.name||e.id,meta:`${e.baseUrl} · ${e.modelCount} model${e.modelCount===1?``:`s`}${e.hasKey?` · key`:``} · ${e.scope===`machine`?`hosted by ${e.machineName||`one Machine`}`:`network endpoint`}${e.availableOnThisMachine?``:` · unavailable on this Machine`}`,right:(0,Y.jsxs)(`div`,{className:`row-actions`,children:[e.availableOnThisMachine&&e.models[0]&&(0,Y.jsx)(`button`,{className:`btn sm`,onClick:t=>{t.stopPropagation(),S(e.id,e.models[0])},children:`Use`}),(0,Y.jsx)(`button`,{className:`btn danger-ghost sm`,onClick:t=>{t.stopPropagation(),y({title:`Remove endpoint?`,message:`Remove ${e.name||e.id}? This also removes its models.`,action:()=>{T.removeLocalModel(e.id),setTimeout(()=>T.listLocalModels(),400)}})},children:`Remove`})]}),onClick:()=>x(wt(e))},e.id))}),(0,Y.jsx)(`button`,{className:`btn primary block`,onClick:()=>x({...xt}),children:`+ Add endpoint`})]}),(0,Y.jsxs)(`div`,{className:`settings-section`,children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`Find models on this Machine`}),(0,Y.jsx)(`p`,{className:`muted small`,children:`Discover checks a short, fixed list of common localhost ports on the connected Machine only — it never scans your LAN. Localhost models stay tied to the Machine that hosts them.`}),(0,Y.jsx)(`button`,{className:`btn block`,disabled:f,onClick:async()=>{p(!0),h(null);try{let e=await T.discoverLocalModels();d(e.endpoints),_(e.machineName)}catch(e){h(String(e?.message||e))}finally{p(!1)}},children:f?`Discovering on this Machine…`:`Discover on this Machine`}),g&&(0,Y.jsxs)(`p`,{className:`muted small`,children:[`Results from `,(0,Y.jsx)(`strong`,{children:g}),`. They do not describe other Machines.`]}),m&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:m}),u&&(0,Y.jsx)(`div`,{className:`picker-list`,children:u.map(e=>(0,Y.jsx)(I,{title:e.name||e.baseUrl,meta:e.status===`ready`?`${e.models.length} model${e.models.length===1?``:`s`} available on ${e.machineName}`:`${e.status.replace(`_`,` `)} · ${e.detail||`No compatible response`}`,right:e.status===`ready`?(0,Y.jsx)(E,{tone:`ok`,children:`Import`}):e.status===`auth_required`?(0,Y.jsx)(E,{tone:`warn`,children:`Add key`}):(0,Y.jsx)(E,{tone:`warn`,children:e.status.replace(`_`,` `)}),onClick:e.status===`ready`||e.status===`auth_required`?()=>x({...Tt({id:e.candidateId||`local`,name:e.name||`Local models`,baseUrl:e.baseUrl,api:e.api}),models:e.models.map(e=>e.name===e.id?e.id:`${e.id} | ${e.name}`).join(`
10
- `)}):void 0},e.candidateId||e.baseUrl))}),e.settings.localModelPresets.length>0&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`Quick add`}),(0,Y.jsx)(`div`,{className:`row-actions`,style:{flexWrap:`wrap`},children:e.settings.localModelPresets.map(e=>(0,Y.jsx)(`button`,{className:`btn`,title:e.note,onClick:()=>x(Tt(e)),children:e.name},e.id))})]})]})]})}function Dt({state:e,cloudMachinesEnabled:t}){let n=!T.direct,[r,i]=(0,J.useState)([]),[a,o]=(0,J.useState)(null),[s,c]=(0,J.useState)(null),[l,u]=(0,J.useState)(!1),[d,f]=(0,J.useState)(null),[p,m]=(0,J.useState)(null),[h,g]=(0,J.useState)([]),[_,v]=(0,J.useState)(!1),[b,x]=(0,J.useState)(!1),S=T.local.cur,C=r.find(e=>e.id===S),w=typeof C?.lastSeenAt==`string`?Date.parse(C.lastSeenAt):NaN,D=C?.online?`Connected now.`:Number.isFinite(w)?`Last contact ${new Date(w).toLocaleString()}. The daemon may be stopped, updating, asleep, or unable to reach the control plane.`:`This machine has not completed a control-plane heartbeat yet. Check that the Bivy service is running and can reach the network.`,O=()=>{T.getNodeSettings(),n&&T.listNodes().then(i).catch(()=>{})};(0,J.useEffect)(O,[n]),(0,J.useEffect)(()=>{if(!n)return;let e=()=>T.listNodeClaims().then(e=>{g(e),p&&e.find(e=>e.id===p.id)?.status!==`pending`&&m(null)}).catch(()=>{});if(e(),!p)return;let t=window.setInterval(e,3e3);return()=>window.clearInterval(t)},[n,p]);let k=e.connection.status===`online`;(0,J.useEffect)(()=>{n&&k&&T.getNodeSettings()},[n,k,S]);let A=k?e.settings.nodeSettings:null,j=A?`${A.name}|${A.defaultAgent}|${A.githubIssuePrompt}`:``;(0,J.useEffect)(()=>{o(A)},[j]);let M=e.catalogs.runtimes.filter(e=>String(e.status??`available`)===`available`),N=e.catalogs.runtimes.find(e=>e.id===a?.defaultAgent)?.capabilities?.modelSelection!==!1,P=e.catalogs.models,ee=async()=>{if(a&&!l){u(!0),f(null),c(null);try{await T.setNodeSettings({name:a.name,defaultAgent:a.defaultAgent,defaultModel:N?a.defaultModel:null,defaultSandbox:a.defaultSandbox,githubMaxConcurrent:a.githubMaxConcurrent,githubIssuePrompt:a.githubIssuePrompt,sessionSync:a.sessionSync,worktreeSync:a.worktreeSync,syncStandbyNodeId:a.syncStandbyNodeId??``,sessionResumeMode:a.sessionResumeMode,autoAttachToolImages:a.autoAttachToolImages,appScreenshots:a.appScreenshots===!0}),c(`Saved`),setTimeout(()=>c(null),1500)}catch(e){f(String(e?.message||e))}finally{u(!1)}}},F=h.filter(e=>e.id!==p?.id).slice(0,5);return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[d&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:d}),k&&(0,Y.jsx)(U,{},S||`direct`),n&&(0,Y.jsxs)(`section`,{className:`settings-section`,children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`Connect a machine`}),(0,Y.jsx)(`p`,{className:`muted small`,children:`Create a one-time command, then run it on a macOS or Linux machine. It expires after 10 minutes and can enroll only one machine.`}),p?.command?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`div`,{className:`repo-connect-command`,children:[(0,Y.jsx)(`code`,{children:p.command}),(0,Y.jsx)(`button`,{type:`button`,className:`btn sm ghost${b?` is-copied`:``}`,onClick:()=>{navigator.clipboard.writeText(p.command||``).then(()=>{x(!0),window.setTimeout(()=>x(!1),1500)})},children:b?`Copied`:`Copy`})]}),(0,Y.jsx)(`div`,{className:`card-actions`,children:(0,Y.jsx)(`button`,{type:`button`,className:`btn`,onClick:()=>{v(!0),T.revokeNodeClaim(p.id).then(()=>(m(null),T.listNodeClaims().then(g))).catch(e=>f(String(e?.message||e))).finally(()=>v(!1))},disabled:_,children:`Revoke`})})]}):(0,Y.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:_,onClick:()=>{v(!0),f(null),T.createNodeClaim().then(e=>{m(e),g(t=>[e,...t.filter(t=>t.id!==e.id)])}).catch(e=>f(String(e?.message||e))).finally(()=>v(!1))},children:_?`Creating…`:`Create install command`}),F.length>0&&(0,Y.jsx)(`div`,{className:`picker-list`,children:F.map(e=>(0,Y.jsx)(I,{title:`Install command · ${e.status}`,meta:e.nodeId?`Used by ${e.nodeId}`:`Expires ${new Date(e.expiresAt).toLocaleTimeString()}`,right:e.status===`pending`?(0,Y.jsx)(`button`,{type:`button`,className:`btn sm danger-ghost`,onClick:t=>{t.stopPropagation(),T.revokeNodeClaim(e.id).then(()=>T.listNodeClaims().then(g)).catch(e=>f(String(e?.message||e)))},children:`Revoke`}):void 0},e.id))})]}),n&&(0,Y.jsxs)(`section`,{className:`settings-section`,children:[(0,Y.jsx)(`label`,{className:`field-label`,htmlFor:`node-settings-node`,children:`Machine`}),(0,Y.jsxs)(`select`,{id:`node-settings-node`,className:`picker-search`,value:S??``,disabled:r.length===0,onChange:e=>{let t=e.target.value;t&&t!==S&&(T.switchNode(t),o(null))},children:[r.length===0&&(0,Y.jsx)(`option`,{value:``,children:`No machines found`}),r.map(e=>(0,Y.jsxs)(`option`,{value:e.id,children:[e.name||e.id,e.online?``:` (offline)`]},e.id))]}),C&&(0,Y.jsx)(`p`,{className:`muted small${C.online?``:` warn-text`}`,children:D}),(0,Y.jsxs)(`p`,{className:`muted small`,children:[`Run `,(0,Y.jsx)(`code`,{children:`bivy update`}),` on the machine to update or repair its service, then refresh this list.`]})]}),y&&(0,Y.jsx)(`section`,{className:`settings-section`,children:(0,Y.jsx)(vt,{enabled:t})}),(0,Y.jsx)(we,{online:k}),k?a?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`section`,{className:`settings-section`,children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`Identity`}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Machine name`}),(0,Y.jsx)(`input`,{className:`picker-search`,value:a.name,onChange:e=>o({...a,name:e.target.value}),placeholder:`My Mac`})]}),(0,Y.jsxs)(`section`,{className:`settings-section`,children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`Session defaults`}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Default agent`}),(0,Y.jsxs)(`select`,{className:`picker-search`,value:a.defaultAgent,onChange:e=>o({...a,defaultAgent:e.target.value}),children:[M.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.displayName||e.name||e.id},e.id)),!M.some(e=>e.id===a.defaultAgent)&&(0,Y.jsx)(`option`,{value:a.defaultAgent,children:a.defaultAgent})]}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Default model`}),N?(0,Y.jsxs)(`select`,{className:`picker-search`,value:a.defaultModel?a.defaultModel.id:``,onChange:e=>{let t=P.find(t=>t.id===e.target.value);o({...a,defaultModel:t?{provider:String(t.provider??``),id:t.id}:null})},children:[(0,Y.jsx)(`option`,{value:``,children:`Default (agent decides)`}),P.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.label||e.id},e.id)),a.defaultModel&&!P.some(e=>e.id===a.defaultModel.id)&&(0,Y.jsx)(`option`,{value:a.defaultModel.id,children:a.defaultModel.id})]}):(0,Y.jsx)(`p`,{className:`muted`,children:`This agent selects its own model — nothing to set.`}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Default sandbox mode`}),(0,Y.jsx)(`div`,{className:`seg-row`,children:R.map(e=>(0,Y.jsx)(`button`,{type:`button`,className:`selectable`,"aria-pressed":a.defaultSandbox===e.id,onClick:()=>o({...a,defaultSandbox:e.id}),title:e.hint,children:e.label},e.id))}),(0,Y.jsx)(`p`,{className:`muted small`,children:R.find(e=>e.id===a.defaultSandbox)?.hint})]}),(0,Y.jsxs)(`details`,{className:`settings-section settings-disclosure`,children:[(0,Y.jsx)(`summary`,{className:`settings-disclosure-summary`,children:`GitHub`}),(0,Y.jsxs)(`div`,{className:`settings-disclosure-body`,children:[(0,Y.jsx)(`label`,{className:`field-label`,children:`GitHub session limit`}),(0,Y.jsx)(`input`,{className:`picker-search`,type:`number`,min:0,value:a.githubMaxConcurrent,onChange:e=>o({...a,githubMaxConcurrent:Math.max(0,Math.floor(Number(e.target.value)||0))})}),(0,Y.jsx)(`p`,{className:`muted small`,children:`Maximum GitHub-triggered Runs this machine handles at once; the rest wait until a slot frees. 0 = unlimited.`}),(0,Y.jsx)(`label`,{className:`field-label`,children:`GitHub issue prompt`}),(0,Y.jsx)(`textarea`,{className:`picker-search`,rows:8,value:a.githubIssuePrompt,onChange:e=>o({...a,githubIssuePrompt:e.target.value})}),(0,Y.jsx)(`p`,{className:`muted small`,children:`The instructions sent to the agent as its first message when it picks up a GitHub issue (after the issue's own title/description/link). The default asks it to understand the issue, do thorough work, run tests/linter/type-checks, and open its own pull request when done — edit freely, or clear and save to restore the default.`}),(0,Y.jsx)(`div`,{className:`row-actions`,children:(0,Y.jsx)(`button`,{className:`btn`,onClick:()=>{a&&A&&(f(null),T.setNodeSettings({githubIssuePrompt:``}).then(O).catch(e=>f(String(e?.message||e))))},children:`Reset to default`})})]})]}),(0,Y.jsxs)(`details`,{className:`settings-section settings-disclosure`,children:[(0,Y.jsx)(`summary`,{className:`settings-disclosure-summary`,children:`Session resume`}),(0,Y.jsxs)(`div`,{className:`settings-disclosure-body`,children:[(0,Y.jsx)(`label`,{className:`field-label`,children:`After a restart interrupts a session`}),(0,Y.jsx)(`div`,{className:`seg-row`,children:[{id:`auto`,label:`Auto-resume`,hint:`The agent automatically continues the interrupted turn when the machine restarts.`},{id:`manual`,label:`Manual`,hint:`The interrupted session waits and offers a one-tap Resume when you open it.`}].map(e=>(0,Y.jsx)(`button`,{type:`button`,className:`selectable`,"aria-pressed":a.sessionResumeMode===e.id,onClick:()=>o({...a,sessionResumeMode:e.id}),title:e.hint,children:e.label},e.id))}),(0,Y.jsx)(`p`,{className:`muted small`,children:a.sessionResumeMode===`manual`?`Interrupted sessions wait for you to tap Resume — nothing runs on its own. GitHub issue automation still resumes automatically.`:`The agent picks up an interrupted turn on its own after the machine restarts.`})]})]}),(0,Y.jsxs)(`details`,{className:`settings-section settings-disclosure`,children:[(0,Y.jsx)(`summary`,{className:`settings-disclosure-summary`,children:`Attachments`}),(0,Y.jsx)(`div`,{className:`settings-disclosure-body`,children:(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`span`,{className:`settings-toggle-title`,children:`Auto-attach images from tool results`}),(0,Y.jsx)(`span`,{className:`muted small`,children:`When a tool the agent runs returns an image — a screenshot from a browser-automation tool, say — show it in the chat automatically, with no explicit attach step. Bounded per turn so a chatty tool can't flood the chat.`})]}),(0,Y.jsx)(V,{checked:a.autoAttachToolImages,onChange:e=>o({...a,autoAttachToolImages:e}),label:`Enable auto-attach for tool images`})]})})]}),(0,Y.jsxs)(`details`,{className:`settings-section settings-disclosure`,children:[(0,Y.jsx)(`summary`,{className:`settings-disclosure-summary`,children:`App previews`}),(0,Y.jsx)(`div`,{className:`settings-disclosure-body`,children:(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`span`,{className:`settings-toggle-title`,children:`Let agents screenshot their app previews`}),(0,Y.jsxs)(`span`,{className:`muted small`,children:[`Agents can run `,(0,Y.jsx)(`code`,{children:`bivy app shot`}),` to see their previews at phone and desktop widths, in light and dark, before they say they’re done. It uses Chrome or Chromium on this machine and a few hundred MB of memory while it runs. Also used for before/after comparisons in previews.`]})]}),(0,Y.jsx)(V,{checked:a.appScreenshots===!0,onChange:e=>o({...a,appScreenshots:e}),label:`Let agents screenshot their app previews`})]})})]}),(0,Y.jsxs)(`details`,{className:`settings-section settings-disclosure`,children:[(0,Y.jsx)(`summary`,{className:`settings-disclosure-summary`,children:`Session sync`}),(0,Y.jsxs)(`div`,{className:`settings-disclosure-body`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`span`,{className:`settings-toggle-title`,children:`Keep sessions synced to a standby machine`}),(0,Y.jsx)(`span`,{className:`muted small`,children:`Warm-replicate each session's transcript to another of your machines over the encrypted relay, so a session can be picked up elsewhere if this machine goes offline. Data stays machine-to-machine; the control plane never sees it.`})]}),(0,Y.jsx)(V,{checked:a.sessionSync,onChange:e=>o({...a,sessionSync:e,worktreeSync:e?a.worktreeSync:!1}),label:`Enable session sync`})]}),(0,Y.jsxs)(`div`,{className:`settings-toggle-row${a.sessionSync?``:` disabled`}`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`span`,{className:`settings-toggle-title`,children:`Also sync the workspace (git checkpoints)`}),(0,Y.jsx)(`span`,{className:`muted small`,children:`Ship each turn's git checkpoint too, so the promoted session keeps its working tree and can continue coding — not just show history. Needs session sync; ignored for non-git workspaces.`})]}),(0,Y.jsx)(V,{checked:a.worktreeSync,disabled:!a.sessionSync,onChange:e=>o({...a,worktreeSync:e}),label:`Enable worktree sync`})]}),a.sessionSync&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`label`,{className:`field-label`,children:`Standby machine`}),(0,Y.jsxs)(`select`,{className:`picker-search`,value:a.syncStandbyNodeId??``,onChange:e=>o({...a,syncStandbyNodeId:e.target.value||void 0}),children:[(0,Y.jsx)(`option`,{value:``,children:`Choose a machine to replicate to…`}),r.filter(e=>e.id!==S).map(e=>(0,Y.jsx)(`option`,{value:e.id,children:(e.name||e.id)+(e.online?``:` (offline)`)},e.id)),a.syncStandbyNodeId&&!r.some(e=>e.id===a.syncStandbyNodeId)&&(0,Y.jsx)(`option`,{value:a.syncStandbyNodeId,children:a.syncStandbyNodeId})]}),(0,Y.jsxs)(`p`,{className:`muted small`,children:[`Sessions on this machine warm-replicate to the standby over the encrypted relay. If this machine goes offline, open the session on the standby and choose “Continue here”.`,r.filter(e=>e.id!==S).length===0&&` Add a second machine to enable this.`]})]})]})]}),(0,Y.jsxs)(`div`,{className:`row-actions settings-save-actions`,children:[(0,Y.jsx)(`button`,{className:`btn primary`,disabled:l,onClick:ee,children:l?`Saving…`:`Save`}),s&&(0,Y.jsx)(E,{tone:`ok`,children:s})]})]}):(0,Y.jsx)(`p`,{className:`muted`,children:`Loading machine settings…`}):(0,Y.jsx)(`p`,{className:`muted`,children:e.connection.status===`offline`?`This machine is offline — its settings aren't reachable until it reconnects.`:`Connecting to this machine…`})]})}var Ot=[{v:30,label:`30 min`},{v:60,label:`1 hour`},{v:180,label:`3 hours`},{v:480,label:`8 hours`}];function kt(e){return e.teardownOnAgentFinish?`runs until the agent finishes`:e.ttlMinutes?`destroys ${e.ttlMinutes} min after launch`:`provider-default lifetime`}function At(e){return[m.find(t=>t.id===e.provider)?.name,e.region,e.size,kt(e)].filter(Boolean).join(` · `)}function jt(){let[e,t]=(0,J.useState)([]),[n,r]=(0,J.useState)([]),[i,a]=(0,J.useState)({k:`list`}),o=()=>T.listEphemeralKeys().then(t).catch(()=>{}),s=()=>T.listEphemeralConfigs().then(r).catch(()=>{}),c=async()=>{try{let[e,t]=await Promise.all([T.listEphemeralSetups(),T.listEphemeralConfigs()]);if(!e.length)return;let n=new Set(t.map(e=>`${e.provider} ${e.name}`));for(let t of e)n.has(`${t.provider} ${t.name}`)||await T.createEphemeralConfig({provider:t.provider,name:t.name,region:t.region??null,size:t.size??null,ttlMinutes:t.ttlMinutes??null,teardownOnAgentFinish:t.teardownOnAgentFinish===!0}),await T.removeEphemeralSetup(t.id).catch(()=>{});s()}catch{}};(0,J.useEffect)(()=>{T.signedIn&&(o(),s(),c())},[]);let l=()=>{a({k:`list`}),s(),o()};if(!T.signedIn)return(0,Y.jsxs)(`div`,{className:`settings-form machine-profiles`,children:[(0,Y.jsx)(`div`,{className:`vault-title-row`,children:(0,Y.jsx)(`div`,{children:(0,Y.jsx)(`h3`,{children:`Cloud machine profiles`})})}),(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`warn`,children:`Experimental and unstable — cloud machines may fail to boot or require manual cleanup.`}),(0,Y.jsxs)(`div`,{className:`vault-empty`,children:[(0,Y.jsx)(`h4`,{children:`Cloud machines need an account`}),(0,Y.jsx)(`p`,{className:`muted`,children:`A profile and its provider credential are stored on your account, so any signed-in device — or an automation — can launch a temporary machine. This device is paired to your machine directly, without an account.`}),(0,Y.jsx)(`p`,{className:`muted`,children:T.solo?`Sign in here to add this machine to an account — on Bivy Cloud or on a control plane you host yourself.`:`Open the Bivy app from a control plane — Bivy Cloud or one you host yourself — and sign in there.`}),T.solo&&(0,Y.jsx)(`button`,{type:`button`,className:`btn primary`,onClick:B,children:`Sign in or create an account`}),(0,Y.jsx)(`a`,{className:`btn`,href:`https://github.com/bivysh/bivy/blob/main/docs/self-host.md`,target:`_blank`,rel:`noopener`,children:`Self-hosting guide`})]})]});if(i.k===`add`)return(0,Y.jsx)(Mt,{keys:e,onBack:()=>a({k:`list`}),onPick:e=>a({k:`editor`,provider:e,setupId:null})});if(i.k===`editor`){let e=m.find(e=>e.id===i.provider);return e?(0,Y.jsxs)(`div`,{className:`settings-form machine-profiles`,children:[(0,Y.jsx)(`button`,{className:`btn link`,onClick:l,children:`‹ Cloud machine profiles`}),(0,Y.jsx)(Pt,{providerId:e.id,initialSetupId:i.setupId,onKeysChanged:o,onSetupsChanged:s,onBack:l})]}):(0,Y.jsxs)(`div`,{className:`settings-form machine-profiles`,children:[(0,Y.jsx)(`button`,{className:`btn link`,onClick:l,children:`‹ Cloud machine profiles`}),(0,Y.jsx)(E,{tone:`warn`,children:`Unsupported provider`}),(0,Y.jsxs)(`p`,{className:`muted`,children:[`This profile uses `,i.provider,`, which Bivy no longer supports. It cannot launch a new machine.`]}),i.setupId&&(0,Y.jsx)(`button`,{className:`btn danger-ghost`,onClick:()=>{T.removeEphemeralConfig(i.setupId).then(l)},children:`Remove profile`})]})}return(0,Y.jsxs)(`div`,{className:`settings-form machine-profiles`,children:[(0,Y.jsxs)(`div`,{className:`vault-title-row`,children:[(0,Y.jsx)(`div`,{children:(0,Y.jsx)(`h3`,{children:`Cloud machine profiles`})}),(0,Y.jsx)(`button`,{className:`btn primary`,onClick:()=>a({k:`add`}),children:`Add profile`})]}),(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`warn`,children:`Experimental and unstable — cloud machines may fail to boot or require manual cleanup.`}),(0,Y.jsx)(`p`,{className:`muted`,children:`A profile tells Bivy where to create a temporary machine. Pick one for a chat, or let an automation use it while you're offline. Your cloud provider bills the compute directly.`}),n.length===0?(0,Y.jsxs)(`div`,{className:`vault-empty`,children:[(0,Y.jsx)(`h4`,{children:`No cloud profiles yet`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Add a provider and choose the region, server size, and when the machine should be destroyed.`}),(0,Y.jsx)(`button`,{className:`btn primary`,onClick:()=>a({k:`add`}),children:`Add your first profile`})]}):(0,Y.jsx)(`div`,{className:`picker-list vault-items`,children:n.map(e=>(0,Y.jsx)(I,{title:e.name,meta:At(e),right:S(e.provider)?(0,Y.jsx)(`span`,{className:`picker-meta`,"aria-hidden":!0,children:`›`}):(0,Y.jsx)(E,{tone:`warn`,children:`Unsupported`}),onClick:()=>a({k:`editor`,provider:e.provider,setupId:e.id})},e.id))}),!T.direct&&n.length>0&&(0,Y.jsx)(Nt,{})]})}function Mt({keys:e,onBack:t,onPick:n}){let r=m.find(e=>e.id===`fly`)??m[0],i=m.filter(e=>e.id!==r?.id),a=(t,n)=>n?(0,Y.jsx)(E,{tone:`accent`,children:`Server-managed`}):e.find(e=>e.id===t)?.configured?(0,Y.jsx)(E,{tone:`ok`,children:`Token saved`}):(0,Y.jsx)(E,{children:`Not set up`});return(0,Y.jsxs)(`div`,{className:`settings-form machine-profiles`,children:[(0,Y.jsx)(`button`,{className:`btn link`,onClick:t,children:`‹ Cloud machine profiles`}),(0,Y.jsx)(`h3`,{children:`Add a cloud profile`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Choose a cloud provider. Bivy will create a temporary machine there when work starts and destroy it automatically.`}),r&&(0,Y.jsxs)(`button`,{type:`button`,className:`custom-provider-card`,onClick:()=>n(r.id),children:[(0,Y.jsx)(`span`,{className:`custom-provider-card-icon`,"aria-hidden":!0,children:`✦`}),(0,Y.jsxs)(`span`,{children:[(0,Y.jsxs)(`strong`,{children:[r.name,` · Recommended`]}),(0,Y.jsx)(`small`,{children:r.blurb})]}),e.find(e=>e.id===r.id)?.configured?(0,Y.jsx)(E,{tone:`ok`,children:`Token saved`}):(0,Y.jsx)(`span`,{className:`picker-meta`,"aria-hidden":!0,children:`›`})]}),(0,Y.jsx)(`p`,{className:`vault-picker-label`,children:`Other providers`}),(0,Y.jsx)(`div`,{className:`picker-list`,children:i.map(e=>(0,Y.jsx)(I,{title:e.name,meta:e.blurb,right:a(e.id,e.hostedOnly),onClick:()=>n(e.id)},e.id))})]})}function Nt(){let[e,t]=(0,J.useState)([]),[n,r]=(0,J.useState)([]),[i,a]=(0,J.useState)(!1),[o,s]=(0,J.useState)(null),[c,l]=(0,J.useState)(null),[u,d]=(0,J.useState)(null),[,f]=(0,J.useState)(0),p=async()=>{let[e,n]=await Promise.all([T.listHostedMachines(),T.listHostedAudit()]);t(e),r(n)};(0,J.useEffect)(()=>{p().catch(e=>s(String(e?.message||e)))},[]),(0,J.useEffect)(()=>{let e=setInterval(()=>f(e=>e+1),15e3);return()=>clearInterval(e)},[]);let m=async(e,t)=>{if(!i){a(!0),s(null),l(null);try{await e(),await p(),l(t)}catch(e){s(String(e?.message||e))}finally{a(!1)}}};return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[u&&(0,Y.jsx)(N,{title:`Destroy hosted machine?`,message:`Destroy ${u.name||u.nodeId||u.id} at ${u.provider} now? Active work on it will stop.`,confirmLabel:`Destroy now`,danger:!0,onCancel:()=>d(null),onConfirm:()=>{let e=u.nodeId;d(null),e&&m(()=>T.destroyHostedMachine(e),`Machine destroyed and removed from inventory.`)}}),(0,Y.jsxs)(`details`,{className:`vault-advanced`,children:[(0,Y.jsxs)(`summary`,{children:[`Active cloud machines (`,e.length,`)`]}),e.length===0?(0,Y.jsx)(`p`,{className:`muted small`,children:`No automation machines are running.`}):(0,Y.jsx)(`div`,{className:`picker-list`,children:e.map(e=>{let t=x(e.provider),r=t?.sizes.find(t=>t.id===e.size),a=g(r,e.createdAt,e.ttlMinutes),o=n.find(t=>t.nodeId===e.nodeId&&(t.action===`reconcile_failed`||t.action===`provision_failed`&&/destroy|reap|teardown|settled/i.test(t.detail||``))),s=h(e,!!o),c=a&&t?`${_(a.accrued,t.currency)} accrued`:`cost via provider bill`;return(0,Y.jsx)(I,{title:(0,Y.jsxs)(Y.Fragment,{children:[e.name||e.nodeId||e.id,` `,(0,Y.jsx)(E,{tone:o?`danger`:s===`ready`?`ok`:void 0,children:s.replaceAll(`-`,` `)})]}),meta:[e.provider,e.region,e.size,c,e.ttlMinutes?`TTL ${e.ttlMinutes}m`:null].filter(Boolean).join(` · `),right:(0,Y.jsx)(`button`,{type:`button`,className:`btn sm danger-ghost`,disabled:!e.nodeId||i,onClick:t=>{t.stopPropagation(),d(e)},children:`Destroy`})},`${e.provider}:${e.id}`)})})]}),(0,Y.jsxs)(`details`,{className:`vault-advanced`,children:[(0,Y.jsx)(`summary`,{children:`Offline automation activity`}),n.some(e=>e.action===`reconcile_failed`)&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:`A machine couldn't be reconciled or deleted. It stays tracked for retry — check the events below and your provider console.`}),n.length===0?(0,Y.jsx)(`p`,{className:`muted small`,children:`No offline automation activity yet.`}):(0,Y.jsx)(`div`,{className:`picker-list`,children:n.slice(0,10).map((e,t)=>(0,Y.jsx)(I,{title:e.action.replaceAll(`_`,` `),meta:[e.provider,e.nodeId,e.detail,e.at?new Date(e.at).toLocaleString():null].filter(Boolean).join(` · `)},`${e.at}:${e.action}:${t}`))})]}),o&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:o}),c&&(0,Y.jsx)(`div`,{className:`banner inline`,children:c})]})}function Pt({providerId:e,initialSetupId:t,onKeysChanged:n,onSetupsChanged:r,onBack:i}){let a=m.find(t=>t.id===e),o=x(e),[s,c]=(0,J.useState)(null),[l,u]=(0,J.useState)(``),[d,f]=(0,J.useState)(!1),[p,h]=(0,J.useState)(null),g=!!p?.providers.includes(e),[_,v]=(0,J.useState)(o.defaultRegion),[y,b]=(0,J.useState)(o.sizes),[S,w]=(0,J.useState)(o.defaultSize),[D,O]=(0,J.useState)(60),[k,A]=(0,J.useState)(!1),[j,M]=(0,J.useState)(null),[P,ee]=(0,J.useState)(``),[F,te]=(0,J.useState)([]),[ne,re]=(0,J.useState)(null),[ie,L]=(0,J.useState)(null),[R,z]=(0,J.useState)(null),[B,H]=(0,J.useState)(!1),U=()=>T.listEphemeralMachines().then(t=>te(t.filter(t=>t.provider===e))).catch(()=>{}),W=e=>{M(e?.id??null),ee(e?.name??``),v(e?.region||o.defaultRegion),w(e?.size||o.defaultSize),O(e?.ttlMinutes??60),A(e?.teardownOnAgentFinish===!0)};(0,J.useEffect)(()=>{T.getEphemeralToken(e).then(e=>f(!!e)).catch(()=>{}),(a.hostedOnly||!T.direct)&&T.getHostedProvisioning().then(h).catch(()=>{}),T.listEphemeralConfigs().then(e=>{W(t?e.find(e=>e.id===t)??null:null)}).catch(()=>{}),U()},[e,t]),(0,J.useEffect)(()=>{if(!(a.hostedOnly?g:d))return;let t=!0;return T.listEphemeralSizes(e,_).then(e=>{t&&e.length&&(b(e),w(t=>e.some(e=>e.id===t)?t:e.some(e=>e.id===o.defaultSize)?o.defaultSize:e[0]?.id??o.defaultSize))}).catch(()=>{}),()=>{t=!1}},[g,d,e,_]);let ae=async()=>{if(!B){H(!0),z(null);try{let t=l.trim();a.hostedOnly?(await T.validateHostedProviderCredential(e,t,_),h(await T.setHostedProvisioning({providerTokens:{[e]:t}})),L(`Credential checked and stored securely.`)):(await T.setEphemeralToken(e,t),f(!0),n(),L(`Token saved on this device.`)),u(``)}catch(e){z(String(e.message||e))}finally{H(!1)}}},G=async()=>{if(!B){H(!0),z(null);try{let t={name:P.trim(),region:_,size:S,ttlMinutes:D,teardownOnAgentFinish:k};if(j)await T.updateEphemeralConfig(j,t);else{let n=await T.createEphemeralConfig({provider:e,...t});M(n.id)}r(),re(`Saved`),setTimeout(()=>re(null),1500)}catch(e){z(String(e.message||e))}finally{H(!1)}}},oe=!!(p?.enabled&&p.validatedProviders.includes(e)),K=(p?.validatedProviders??[]).filter(t=>t!==e),se=async t=>{if(!B&&p){H(!0),z(null),L(null);try{if(t){if(a.hostedOnly){let t=await T.setHostedProvisioning({enabled:!0});if(h(t),!t.validatedProviders.includes(e))throw Error(`The ${a.name} credential hasn't been checked yet — reconnect ${a.name} to validate it.`)}else{let t=(await T.getEphemeralToken(e)).trim();if(!t)throw Error(`No ${a.name} token is saved on this device — connect ${a.name} first.`);await T.validateHostedProviderCredential(e,t,_),h(await T.setHostedProvisioning({enabled:!0,providerTokens:{[e]:t}}))}L(`Automations can start ${a.name} profiles while you're offline.`)}else a.hostedOnly?(h(await T.setHostedProvisioning({enabled:!1})),L(`Offline automations turned off.`)):(h(await T.setHostedProvisioning({providerTokens:{[e]:``},...K.length?{}:{enabled:!1}})),L(`Bivy's server no longer holds your ${a.name} credential.`))}catch(e){z(String(e.message||e))}finally{H(!1)}}},q=y.find(e=>e.id===S),ce=C(q,D,o.currency),le=k?`Destroyed when the agent finishes (TTL ${D} min backstop)`:`Destroyed ${D} min after launch`,ue=s&&(0,Y.jsx)(N,{title:s.title,message:s.message,confirmLabel:s.label||`Remove`,danger:!0,onCancel:()=>c(null),onConfirm:()=>{s.action(),c(null)}});return(a.hostedOnly?g:d)?(0,Y.jsxs)(`div`,{className:`settings-form`,children:[ue,(0,Y.jsxs)(`div`,{className:`vault-title-row`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h3`,{children:j?P||`${a.name} profile`:`New ${a.name} profile`}),(0,Y.jsxs)(`p`,{className:`muted small`,children:[a.name,` · `,a.hostedOnly?`server-managed credential saved`:`token saved on this device`]})]}),(0,Y.jsxs)(E,{tone:`ok`,children:[a.name,` connected`]})]}),(0,Y.jsxs)(`div`,{className:`vault-detail-grid`,children:[(0,Y.jsx)(`span`,{className:`muted`,children:`Provider`}),(0,Y.jsx)(`strong`,{children:a.name}),(0,Y.jsx)(`span`,{className:`muted`,children:`Lifecycle`}),(0,Y.jsx)(`strong`,{children:le}),(0,Y.jsx)(`span`,{className:`muted`,children:`Compute class`}),(0,Y.jsx)(`strong`,{children:q?ve(q):`Provider default`}),(0,Y.jsx)(`span`,{className:`muted`,children:`Est. cost`}),(0,Y.jsx)(`strong`,{children:ce?`${ce} · billed by ${a.name}`:`provider's live rate · billed by ${a.name}`})]}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Name`}),(0,Y.jsx)(`input`,{className:`picker-search`,value:P,onChange:e=>ee(e.target.value),placeholder:`e.g. EU quick tasks`}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Region`}),(0,Y.jsx)(`select`,{className:`picker-search`,value:_,onChange:e=>v(e.target.value),children:o.regions.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.label},e.id))}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Server type`}),(0,Y.jsx)(`select`,{className:`picker-search`,value:S,onChange:e=>w(e.target.value),children:y.map(e=>(0,Y.jsxs)(`option`,{value:e.id,children:[ve(e),` · `,e.label,e.id===o.defaultSize?` · Recommended`:``]},e.id))}),(0,Y.jsx)(`label`,{className:`field-label`,children:`Auto-destroy after`}),(0,Y.jsx)(`select`,{className:`picker-search`,value:D,onChange:e=>O(Number(e.target.value)),children:Ot.map(e=>(0,Y.jsx)(`option`,{value:e.v,children:e.label},e.v))}),(0,Y.jsxs)(`label`,{className:`checkbox-row`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,checked:k,onChange:e=>A(e.target.checked)}),(0,Y.jsxs)(`span`,{children:[`Destroy as soon as the agent finishes `,(0,Y.jsx)(`span`,{className:`muted small`,children:`(the machine handles teardown; the TTL stays a safety fallback)`})]})]}),(0,Y.jsx)(`div`,{className:`banner inline`,children:`The repo this machine works on comes from the composer when you launch — it isn't set here.`}),(0,Y.jsx)(`div`,{className:`row-actions`,children:(0,Y.jsx)(`button`,{className:`btn primary`,disabled:B||!P.trim(),onClick:G,children:B?`Saving…`:j?`Save profile`:`Create profile`})}),ne&&(0,Y.jsx)(`div`,{className:`banner inline`,children:ne}),p&&(0,Y.jsxs)(`section`,{className:`offline-runs-card`,"aria-labelledby":`offline-runs-title`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Y.jsx)(`div`,{className:`settings-toggle-title`,id:`offline-runs-title`,children:`Run automations while I'm offline`}),(0,Y.jsxs)(`p`,{className:`muted small`,children:[`Automations can start this profile even when none of your devices are online. Uses the `,a.name,` credential you saved for this profile — `,a.hostedOnly?`already held encrypted on Bivy's server`:`an encrypted copy is kept on Bivy's server`,` — and every use is recorded.`,a.hostedOnly?` Because ${a.name} is server-managed, this switch applies to offline automations for your whole account.`:` Applies to every profile that uses ${a.name}.`]})]}),(0,Y.jsx)(V,{checked:oe,disabled:B||!p.encryptionReady,onChange:e=>void se(e),label:`Run automations while I am offline`})]}),!p.encryptionReady&&(0,Y.jsxs)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:[`Not available yet: this Bivy server has no encryption key for stored credentials. There's no setting for it in the app — whoever runs the control plane sets `,(0,Y.jsx)(`code`,{children:`HOSTED_CREDENTIAL_KEY`}),` in its environment and restarts it.`,` `,(0,Y.jsx)(`a`,{href:`https://github.com/bivysh/bivy/blob/main/docs/self-host.md#offline-automations-encrypted-credential-storage`,target:`_blank`,rel:`noopener`,children:`How to enable it`})]})]}),ie&&(0,Y.jsx)(`div`,{className:`banner inline`,children:ie}),R&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:R}),F.length>0&&(0,Y.jsxs)(`details`,{className:`vault-advanced`,open:!0,children:[(0,Y.jsxs)(`summary`,{children:[`Running machines (`,F.length,`)`]}),(0,Y.jsx)(`div`,{className:`picker-list`,children:F.map(e=>(0,Y.jsx)(I,{title:e.name||e.id,meta:[e.region,e.ip,e.repo,e.status].filter(Boolean).join(` · `),right:(0,Y.jsx)(`button`,{type:`button`,className:`btn sm danger-ghost`,onClick:t=>{t.stopPropagation(),c({title:`Destroy machine?`,message:`Destroy ${e.name||e.id} now? This can't be undone.`,label:`Destroy`,action:()=>T.destroyEphemeral(e).then(U).catch(e=>z(String(e?.message||e)))})},children:`Destroy`})},e.id))})]}),(0,Y.jsxs)(`details`,{className:`vault-advanced`,children:[(0,Y.jsx)(`summary`,{children:`Danger zone`}),(0,Y.jsxs)(`div`,{className:`row-actions`,children:[j&&(0,Y.jsx)(`button`,{className:`btn danger-ghost`,onClick:()=>c({title:`Remove profile?`,message:`Remove ${P||`this profile`}? Running machines are not affected.`,label:`Remove`,action:()=>T.removeEphemeralConfig(j).then(()=>{r(),i()})}),children:`Remove profile`}),!a.hostedOnly&&(0,Y.jsxs)(`button`,{className:`btn danger-ghost`,onClick:()=>c({title:`Forget provider token?`,message:g?`Forget the ${a.name} token on this device? Bivy's server also drops its offline-automation copy.`:`Forget the ${a.name} token on this device?`,action:()=>T.removeEphemeralToken(e).then(async()=>{f(!1),n(),g&&await T.setHostedProvisioning({providerTokens:{[e]:``},...K.length?{}:{enabled:!1}}).then(h).catch(e=>z(String(e?.message||e)))})}),children:[`Forget `,a.name,` token`]})]})]})]}):(0,Y.jsxs)(`div`,{className:`settings-form`,children:[ue,(0,Y.jsxs)(`h3`,{children:[`Connect `,a.name]}),(0,Y.jsx)(`p`,{className:`muted`,children:a.blurb}),(0,Y.jsx)(`ol`,{className:`eph-steps`,children:a.steps.map((e,t)=>(0,Y.jsx)(`li`,{children:e},t))}),(0,Y.jsx)(`div`,{className:`row-actions`,children:a.links.map(e=>(0,Y.jsx)(`a`,{className:`btn ghost`,href:e.url,target:`_blank`,rel:`noopener`,children:e.label},e.url))}),(0,Y.jsx)(`label`,{className:`field-label`,children:a.tokenLabel}),(0,Y.jsx)(`input`,{className:`picker-search`,type:`password`,value:l,onChange:e=>u(e.target.value),placeholder:`Paste token`}),(0,Y.jsx)(`div`,{className:`row-actions`,children:(0,Y.jsx)(`button`,{className:`btn primary`,disabled:!l.trim()||B,onClick:ae,children:B?`Saving…`:`Save token`})}),(0,Y.jsx)(`p`,{className:`muted small`,children:a.hostedOnly?`Bivy's server stores this credential securely so it can always delete the ${a.name} machine and stop billing.`:`End-to-end encrypted in your key vault, synced to your signed-in devices, and sent only to ${a.name}.`}),R&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:R}),ie&&(0,Y.jsx)(`div`,{className:`banner inline`,children:ie})]})}function Ft(){let[e,n]=(0,J.useState)(null),[s,c]=(0,J.useState)([]),[l,u]=(0,J.useState)([]),[f,p]=(0,J.useState)(null),[m,h]=(0,J.useState)(null),[g,_]=(0,J.useState)(null),v=()=>T.fetchMe().then(n).catch(()=>{}),y=()=>T.listDevices().then(u).catch(()=>{});(0,J.useEffect)(()=>{T.fetchMe().then(n).catch(e=>p(String(e.message||e))),T.listNodes().then(c).catch(()=>{}),y()},[]);let b=je(t(e?.extension?.facts),e?.extension),x=De(e?.extension),S=Ae(e?.extension),C=(o()?e?.extension?.actions??[]:[]).filter(e=>e.id!==S?.action.id),w=e=>{h(e),T.invokeAccountExtensionAction(e).then(({url:e})=>d(e)).catch(e=>p(String(e?.message||e))).finally(()=>h(null))};return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[g&&(0,Y.jsx)(N,{title:g.title,message:g.message,confirmLabel:g.label||`Remove`,danger:!0,onCancel:()=>_(null),onConfirm:()=>{g.action(),_(null)}}),f&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:f}),e?.account?.email&&(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{className:`muted`,children:`Signed in as`}),(0,Y.jsx)(`strong`,{children:e.account.email})]}),a()&&(0,Y.jsxs)(`div`,{className:`settings-section`,children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:`Subscriptions`}),(0,Y.jsx)(`button`,{type:`button`,className:`btn`,disabled:m!==null,onClick:()=>{h(`native-subscriptions`),r(T.local.s).then(v).catch(()=>p(`Could not open subscriptions. Please try again.`)).finally(()=>h(null))},children:m===`native-subscriptions`?`Opening…`:`Manage subscriptions`}),(0,Y.jsx)(`p`,{className:`muted`,children:`Purchases and restores are handled by your app store.`})]}),e?.extension&&(b.length>0||x.meter||C.length>0)&&(0,Y.jsxs)(`div`,{className:`settings-section`,children:[(0,Y.jsx)(`h4`,{className:`settings-subhead`,children:e.extension.title||`Account service`}),(0,Y.jsx)(`div`,{children:b.map(e=>(0,Y.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Y.jsx)(`span`,{className:`muted`,children:e.label}),(0,Y.jsx)(`strong`,{children:e.value})]},e.id))}),x.meter&&(0,Y.jsx)(ut,{meter:x.meter}),C.length>0&&(0,Y.jsx)(`div`,{className:`card-actions`,children:C.map(e=>(0,Y.jsx)(`button`,{type:`button`,className:`btn ${e.kind===`primary`?`primary`:``}`,disabled:m!==null,onClick:()=>w(e.id),children:m===e.id?`Opening…`:e.label},e.id))})]}),S&&(0,Y.jsxs)(`section`,{className:`card account-offer`,"data-tone":`accent`,"aria-labelledby":`account-offer-title`,children:[(0,Y.jsxs)(`div`,{className:`card-head`,children:[(0,Y.jsx)(`span`,{className:`card-title`,id:`account-offer-title`,children:S.title}),S.price&&(0,Y.jsx)(`span`,{className:`account-offer-price`,children:S.price})]}),S.description&&(0,Y.jsx)(`p`,{className:`card-sub`,children:S.description}),S.points.length>0&&(0,Y.jsx)(`ul`,{className:`account-offer-points`,children:S.points.map(e=>(0,Y.jsxs)(`li`,{children:[(0,Y.jsx)(`span`,{className:`account-offer-check`,"aria-hidden":!0,children:(0,Y.jsx)(re,{size:16})}),e]},e))}),(0,Y.jsx)(`button`,{type:`button`,className:`btn primary block`,disabled:m!==null,onClick:()=>w(S.action.id),children:m===S.action.id?`Opening…`:S.action.label})]}),(0,Y.jsxs)(`div`,{className:`settings-section`,children:[(0,Y.jsxs)(`h4`,{className:`settings-subhead`,children:[`Enrolled machines`,s.length>0&&(0,Y.jsxs)(`span`,{className:`muted`,children:[` · `,s.length]})]}),(0,Y.jsxs)(`div`,{className:`picker-list`,children:[s.length===0&&(0,Y.jsx)(`div`,{className:`picker-empty`,children:`No machines enrolled yet.`}),s.map(e=>(0,Y.jsx)(I,{active:e.id===T.local.cur,title:e.name||e.id,meta:e.online?`Online`:`Offline`,right:(0,Y.jsx)(`button`,{type:`button`,className:`btn sm danger-ghost`,onClick:t=>{t.stopPropagation(),_({title:`Remove machine?`,message:`Remove ${e.name||e.id} from your account?`,action:()=>T.removeNode(e.id).then(()=>T.listNodes().then(c))})},children:`Remove`}),onClick:()=>T.switchNode(e.id)},e.id))]})]}),(0,Y.jsxs)(`div`,{className:`settings-section`,children:[(0,Y.jsxs)(`h4`,{className:`settings-subhead`,children:[`Signed-in devices`,l.length>0&&(0,Y.jsxs)(`span`,{className:`muted`,children:[` · `,l.length]})]}),(0,Y.jsxs)(`div`,{className:`picker-list`,children:[l.length===0&&(0,Y.jsx)(`div`,{className:`picker-empty`,children:`No paired devices.`}),l.map(e=>{let t=T.isCurrentDevice(e.id);return(0,Y.jsx)(I,{title:`${e.label||`Device`}${t?` (this device)`:``}`,meta:`Last active ${It(e.updatedAt)}`,right:(0,Y.jsx)(`button`,{type:`button`,className:`btn sm danger-ghost`,onClick:n=>{n.stopPropagation(),_({title:t?`Sign out this device?`:`Sign out device?`,message:t?`This device will need to sign in again.`:`Sign out ${e.label||`this device`}?`,label:`Sign out`,action:()=>T.removeDevice(e.id).then(()=>{y(),v()}).catch(e=>p(String(e.message||e)))})},children:`Sign out`})},e.id)})]})]}),(0,Y.jsx)(`div`,{className:`settings-section`,children:(0,Y.jsx)(`button`,{className:`btn danger-ghost block`,disabled:m!==null,onClick:()=>_({title:`Delete account?`,message:i.accountDeletionMessage??`This permanently deletes your Bivy account and its data. This cannot be undone.`,label:`Delete account`,action:()=>{h(`delete-account`),T.deleteAccount().then(()=>T.signOut()).catch(e=>p(String(e?.message||e))).finally(()=>h(null))}}),children:m===`delete-account`?`Deleting…`:`Delete account`})})]})}function It(e){let t=Date.parse(e);return Number.isNaN(t)?`recently`:new Date(t).toLocaleDateString(void 0,{month:`short`,day:`numeric`})}function Lt({onDone:e}){let[t,n]=(0,J.useState)(``),[r,i]=(0,J.useState)(null);return(0,Y.jsxs)(`div`,{className:`settings-form`,children:[(0,Y.jsx)(`p`,{className:`muted`,children:`Paste a device-link URL or code from another Bivy client to add its machine here.`}),(0,Y.jsx)(`textarea`,{className:`picker-search`,rows:4,value:t,onChange:e=>{n(e.target.value),i(null)},placeholder:`https://…#… or code`}),(0,Y.jsx)(`button`,{className:`btn primary`,disabled:!t.trim(),onClick:()=>{T.applyLinkPayload(t.trim())?e():i(`That didn't look like a valid device link.`)},children:`Link`}),r&&(0,Y.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:r})]})}export{mt as Settings};
@@ -1 +0,0 @@
1
- import"./chunk-FOHPRMQF-DzxwRta7.js";import{M as e}from"./mermaid-parser.core-C1vHZCtC.js";export{e as createArchitectureServices};
@@ -1 +0,0 @@
1
- import{at as e,ot as t}from"./chunk-DU6HZSFF-Bpze6ID8.js";var n=(n,r)=>t.lang.round(e.parse(n)[r]);export{n as t};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./src-B6xuSHsQ.js";import"./chunk-DU6HZSFF-Bpze6ID8.js";import"./chunk-75Z2AOVW-MFkgf2Ar.js";import"./chunk-PWAF6VOD-BOcNKrmu.js";import"./chunk-GMAD6QVW-umDWdG9g.js";import"./chunk-P2QGCYS3-BPMii7LM.js";import"./chunk-4HAMMTFA-CRzer-vm.js";import"./chunk-GVQU2GXP-DuT1Awt9.js";import"./chunk-OSK3NFVY-CBErW4-p.js";import"./chunk-F27PBJKO-Dq3OmNXG.js";import"./chunk-XXDRQBXY-DqAYeljN.js";import"./chunk-POPQ4Y6H-CHTRMb_C.js";import"./chunk-L3NEJ4N5-0jRWrASa.js";import{i as t,n,r,t as i}from"./chunk-TICWLB2K-CWzLTsHW.js";import"./mermaid.core-Df8DJ7AE.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./src-B6xuSHsQ.js";import"./chunk-DU6HZSFF-Bpze6ID8.js";import"./chunk-75Z2AOVW-MFkgf2Ar.js";import"./chunk-PWAF6VOD-BOcNKrmu.js";import"./chunk-GMAD6QVW-umDWdG9g.js";import"./chunk-P2QGCYS3-BPMii7LM.js";import"./chunk-4HAMMTFA-CRzer-vm.js";import"./chunk-GVQU2GXP-DuT1Awt9.js";import"./chunk-OSK3NFVY-CBErW4-p.js";import"./chunk-F27PBJKO-Dq3OmNXG.js";import"./chunk-XXDRQBXY-DqAYeljN.js";import"./chunk-POPQ4Y6H-CHTRMb_C.js";import"./chunk-L3NEJ4N5-0jRWrASa.js";import{i as t,n,r,t as i}from"./chunk-TICWLB2K-CWzLTsHW.js";import"./mermaid.core-Df8DJ7AE.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
@@ -1 +0,0 @@
1
- import"./chunk-FOHPRMQF-DzxwRta7.js";import{O as e}from"./mermaid-parser.core-C1vHZCtC.js";export{e as createEventModelingServices};
@@ -1 +0,0 @@
1
- import"./src-B6xuSHsQ.js";import"./chunk-DU6HZSFF-Bpze6ID8.js";import"./chunk-75Z2AOVW-MFkgf2Ar.js";import"./chunk-PWAF6VOD-BOcNKrmu.js";import"./chunk-GMAD6QVW-umDWdG9g.js";import"./chunk-P2QGCYS3-BPMii7LM.js";import"./chunk-4HAMMTFA-CRzer-vm.js";import"./chunk-GVQU2GXP-DuT1Awt9.js";import"./chunk-OSK3NFVY-CBErW4-p.js";import"./chunk-F27PBJKO-Dq3OmNXG.js";import"./chunk-XXDRQBXY-DqAYeljN.js";import"./chunk-POPQ4Y6H-CHTRMb_C.js";import"./chunk-L3NEJ4N5-0jRWrASa.js";import{n as e}from"./chunk-SHT3W25Y-Dvb-oEDN.js";import"./mermaid.core-Df8DJ7AE.js";export{e as diagram};