@spencerboucher/switchyard 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/README.md +3 -3
  2. package/dist/bridge/lines.js +33 -0
  3. package/dist/bridge/switchyard-terminal.js +155 -23
  4. package/dist/switchyard.mjs +3879 -2658
  5. package/dist/terminal/holder.js +142 -51
  6. package/package.json +1 -1
  7. package/web-dist/apple-touch-icon.png +0 -0
  8. package/web-dist/assets/AutomationView-D7Syv1En.js +2 -0
  9. package/web-dist/assets/AutomationView-D7Syv1En.js.map +1 -0
  10. package/web-dist/assets/Checkbox-D6tRfEeI.js +2 -0
  11. package/web-dist/assets/Checkbox-D6tRfEeI.js.map +1 -0
  12. package/web-dist/assets/Copy-B6XSAIUd.js +2 -0
  13. package/web-dist/assets/Copy-B6XSAIUd.js.map +1 -0
  14. package/web-dist/assets/DangerZone-DfYlxDC1.js +2 -0
  15. package/web-dist/assets/DangerZone-DfYlxDC1.js.map +1 -0
  16. package/web-dist/assets/Field-D-Ty7fKT.js +2 -0
  17. package/web-dist/assets/Field-D-Ty7fKT.js.map +1 -0
  18. package/web-dist/assets/InteractionCard-DF1EcSpm.js +6 -0
  19. package/web-dist/assets/InteractionCard-DF1EcSpm.js.map +1 -0
  20. package/web-dist/assets/Menu-BfOszNC4.js +2 -0
  21. package/web-dist/assets/Menu-BfOszNC4.js.map +1 -0
  22. package/web-dist/assets/Overlay-DUQwh6_b.js +2 -0
  23. package/web-dist/assets/Overlay-DUQwh6_b.js.map +1 -0
  24. package/web-dist/assets/Priority-CHmzfoHg.js +2 -0
  25. package/web-dist/assets/Priority-CHmzfoHg.js.map +1 -0
  26. package/web-dist/assets/{SegmentedControl-D-2BCZzd.js → SegmentedControl-C_hEVQMB.js} +2 -2
  27. package/web-dist/assets/{SegmentedControl-D-2BCZzd.js.map → SegmentedControl-C_hEVQMB.js.map} +1 -1
  28. package/web-dist/assets/Select-Cfql4Nwu.js +2 -0
  29. package/web-dist/assets/Select-Cfql4Nwu.js.map +1 -0
  30. package/web-dist/assets/Switch-DBfzmqkm.js +2 -0
  31. package/web-dist/assets/Switch-DBfzmqkm.js.map +1 -0
  32. package/web-dist/assets/Tabs-BNuL3_Et.js +184 -0
  33. package/web-dist/assets/Tabs-BNuL3_Et.js.map +1 -0
  34. package/web-dist/assets/TextArea-CKybrQyn.js +2 -0
  35. package/web-dist/assets/TextArea-CKybrQyn.js.map +1 -0
  36. package/web-dist/assets/TextLink-OzzyP2-p.js +2 -0
  37. package/web-dist/assets/TextLink-OzzyP2-p.js.map +1 -0
  38. package/web-dist/assets/arrow-down-C-iLrN8I.js +2 -0
  39. package/web-dist/assets/arrow-down-C-iLrN8I.js.map +1 -0
  40. package/web-dist/assets/arrow-up-Dj-VTKx4.js +2 -0
  41. package/web-dist/assets/arrow-up-Dj-VTKx4.js.map +1 -0
  42. package/web-dist/assets/attention-V86Gye3I.js +2 -0
  43. package/web-dist/assets/attention-V86Gye3I.js.map +1 -0
  44. package/web-dist/assets/automations-Cw5Gacgm.js +2 -0
  45. package/web-dist/assets/automations-Cw5Gacgm.js.map +1 -0
  46. package/web-dist/assets/board-B8X7TYYR.js +10 -0
  47. package/web-dist/assets/board-B8X7TYYR.js.map +1 -0
  48. package/web-dist/assets/code-BKroYJmR.js +12 -0
  49. package/web-dist/assets/code-BKroYJmR.js.map +1 -0
  50. package/web-dist/assets/describe-D6KLGKWa.js +5 -0
  51. package/web-dist/assets/describe-D6KLGKWa.js.map +1 -0
  52. package/web-dist/assets/enroll-DwT7AcuS.js +2 -0
  53. package/web-dist/assets/enroll-DwT7AcuS.js.map +1 -0
  54. package/web-dist/assets/index-B3F7WcYf.css +2 -0
  55. package/web-dist/assets/index-hxvDvCS7.js +12 -0
  56. package/web-dist/assets/index-hxvDvCS7.js.map +1 -0
  57. package/web-dist/assets/logic-B46fwD-8.js +2 -0
  58. package/web-dist/assets/logic-B46fwD-8.js.map +1 -0
  59. package/web-dist/assets/more-DQR5uu1c.js +2 -0
  60. package/web-dist/assets/more-DQR5uu1c.js.map +1 -0
  61. package/web-dist/assets/queue-DUg1rS8t.js +2 -0
  62. package/web-dist/assets/queue-DUg1rS8t.js.map +1 -0
  63. package/web-dist/assets/repo-XzzzEI0d.js +2 -0
  64. package/web-dist/assets/repo-XzzzEI0d.js.map +1 -0
  65. package/web-dist/assets/server-BqZ-w6M8.js +2 -0
  66. package/web-dist/assets/server-BqZ-w6M8.js.map +1 -0
  67. package/web-dist/assets/settings-DyUu0tJM.js +8 -0
  68. package/web-dist/assets/settings-DyUu0tJM.js.map +1 -0
  69. package/web-dist/assets/states-ZhrxQa3K.js +56 -0
  70. package/web-dist/assets/states-ZhrxQa3K.js.map +1 -0
  71. package/web-dist/assets/terminal-BOV_MXPZ.js +2 -0
  72. package/web-dist/assets/terminal-BOV_MXPZ.js.map +1 -0
  73. package/web-dist/assets/terminal-login-S5CAd5xA.js +2 -0
  74. package/web-dist/assets/terminal-login-S5CAd5xA.js.map +1 -0
  75. package/web-dist/assets/useBackTo-BIrCq3W2.js +2 -0
  76. package/web-dist/assets/useBackTo-BIrCq3W2.js.map +1 -0
  77. package/web-dist/assets/useNow-Dj7oEiwn.js +2 -0
  78. package/web-dist/assets/useNow-Dj7oEiwn.js.map +1 -0
  79. package/web-dist/assets/useResource-CDGSq2At.js +2 -0
  80. package/web-dist/assets/useResource-CDGSq2At.js.map +1 -0
  81. package/web-dist/icon-192.png +0 -0
  82. package/web-dist/icon-512.png +0 -0
  83. package/web-dist/icon.svg +20 -8
  84. package/web-dist/index.html +3 -4
  85. package/web-dist/manifest.webmanifest +1 -1
  86. package/web-dist/maskable-512.png +0 -0
  87. package/web-dist/sw.js +1 -1
  88. package/web-dist/sw.js.map +1 -1
  89. package/web-dist/assets/AutomationView-BIW_pO0M.js +0 -2
  90. package/web-dist/assets/AutomationView-BIW_pO0M.js.map +0 -1
  91. package/web-dist/assets/Badge-BiDp7NKI.js +0 -2
  92. package/web-dist/assets/Badge-BiDp7NKI.js.map +0 -1
  93. package/web-dist/assets/InteractionCard-CWxyDv81.js +0 -6
  94. package/web-dist/assets/InteractionCard-CWxyDv81.js.map +0 -1
  95. package/web-dist/assets/Menu-BDt1bxwz.js +0 -2
  96. package/web-dist/assets/Menu-BDt1bxwz.js.map +0 -1
  97. package/web-dist/assets/Tabs-ByiPklAw.js +0 -184
  98. package/web-dist/assets/Tabs-ByiPklAw.js.map +0 -1
  99. package/web-dist/assets/TextArea-BYr88SnV.js +0 -2
  100. package/web-dist/assets/TextArea-BYr88SnV.js.map +0 -1
  101. package/web-dist/assets/arrow-left-C6YWM6y6.js +0 -2
  102. package/web-dist/assets/arrow-left-C6YWM6y6.js.map +0 -1
  103. package/web-dist/assets/attention-Bya8XHKI.js +0 -2
  104. package/web-dist/assets/attention-Bya8XHKI.js.map +0 -1
  105. package/web-dist/assets/automations-DiXKRcnE.js +0 -2
  106. package/web-dist/assets/automations-DiXKRcnE.js.map +0 -1
  107. package/web-dist/assets/board-BrLaJwLJ.js +0 -10
  108. package/web-dist/assets/board-BrLaJwLJ.js.map +0 -1
  109. package/web-dist/assets/code-DKLO8bzz.js +0 -11
  110. package/web-dist/assets/code-DKLO8bzz.js.map +0 -1
  111. package/web-dist/assets/copy-oWgGHmkS.js +0 -2
  112. package/web-dist/assets/copy-oWgGHmkS.js.map +0 -1
  113. package/web-dist/assets/describe-DnvH6_fl.js +0 -5
  114. package/web-dist/assets/describe-DnvH6_fl.js.map +0 -1
  115. package/web-dist/assets/dist-BE_V9dwJ.js +0 -56
  116. package/web-dist/assets/dist-BE_V9dwJ.js.map +0 -1
  117. package/web-dist/assets/enroll-DUDpbJoB.js +0 -2
  118. package/web-dist/assets/enroll-DUDpbJoB.js.map +0 -1
  119. package/web-dist/assets/index-DvRcMGEe.css +0 -2
  120. package/web-dist/assets/index-vIzH1m8u.js +0 -11
  121. package/web-dist/assets/index-vIzH1m8u.js.map +0 -1
  122. package/web-dist/assets/logic-xb-QF00E.js +0 -2
  123. package/web-dist/assets/logic-xb-QF00E.js.map +0 -1
  124. package/web-dist/assets/more-BP5x45cs.js +0 -2
  125. package/web-dist/assets/more-BP5x45cs.js.map +0 -1
  126. package/web-dist/assets/now--XjJC37b.js +0 -2
  127. package/web-dist/assets/now--XjJC37b.js.map +0 -1
  128. package/web-dist/assets/plus-BLP-wIYD.js +0 -2
  129. package/web-dist/assets/plus-BLP-wIYD.js.map +0 -1
  130. package/web-dist/assets/save-DEvZPWlS.js +0 -2
  131. package/web-dist/assets/save-DEvZPWlS.js.map +0 -1
  132. package/web-dist/assets/send-BKjswHxB.js +0 -2
  133. package/web-dist/assets/send-BKjswHxB.js.map +0 -1
  134. package/web-dist/assets/server-SxFxIScj.js +0 -2
  135. package/web-dist/assets/server-SxFxIScj.js.map +0 -1
  136. package/web-dist/assets/settings-D8T1esWq.js +0 -7
  137. package/web-dist/assets/settings-D8T1esWq.js.map +0 -1
  138. package/web-dist/assets/shared-CZ7fcu_B.js +0 -3
  139. package/web-dist/assets/shared-CZ7fcu_B.js.map +0 -1
  140. package/web-dist/assets/sliders-horizontal-DAoirila.js +0 -2
  141. package/web-dist/assets/sliders-horizontal-DAoirila.js.map +0 -1
  142. package/web-dist/assets/states--geW2Ntl.js +0 -2
  143. package/web-dist/assets/states--geW2Ntl.js.map +0 -1
  144. package/web-dist/assets/terminal-login-BJxV78au.js +0 -2
  145. package/web-dist/assets/terminal-login-BJxV78au.js.map +0 -1
  146. package/web-dist/assets/trash-C6X2OLrI.js +0 -2
  147. package/web-dist/assets/trash-C6X2OLrI.js.map +0 -1
  148. package/web-dist/assets/useNow-jxdoOC_1.js +0 -2
  149. package/web-dist/assets/useNow-jxdoOC_1.js.map +0 -1
@@ -1,3 +0,0 @@
1
- import{_ as e,i as t,m as n,n as r,t as i}from"./jsx-runtime-D13aM9HY.js";import{r as a}from"./Badge-BiDp7NKI.js";import{P as o,T as s,W as c,d as l,g as u,h as d,l as f,m as p,v as m}from"./states--geW2Ntl.js";import{n as h,t as g}from"./server-SxFxIScj.js";import{n as _,r as v,t as y}from"./sliders-horizontal-DAoirila.js";import{t as b}from"./copy-oWgGHmkS.js";import{t as x}from"./key-round-VDbE9E4X.js";import{F as S,P as C,l as w,r as T}from"./index-vIzH1m8u.js";import{r as ee}from"./TextArea-BYr88SnV.js";import{t as te}from"./dist-BE_V9dwJ.js";var E={name:`database-backup`,size:24,node:[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`,key:`msslwz`}],[`path`,{d:`M3 12a9 3 0 0 0 5 2.69`,key:`1ui2ym`}],[`path`,{d:`M21 9.3V5`,key:`6k6cib`}],[`path`,{d:`M3 5v14a9 3 0 0 0 6.47 2.88`,key:`i62tjy`}],[`path`,{d:`M12 12v4h4`,key:`1bxaet`}],[`path`,{d:`M13 20a5 5 0 0 0 9-3 4.5 4.5 0 0 0-4.5-4.5c-1.33 0-2.54.54-3.41 1.41L12 16`,key:`1f4ei9`}]]};E.node;var D=r(E),O={name:`keyboard`,size:24,node:[[`path`,{d:`M10 8h.01`,key:`1r9ogq`}],[`path`,{d:`M12 12h.01`,key:`1mp3jc`}],[`path`,{d:`M14 8h.01`,key:`1primd`}],[`path`,{d:`M16 12h.01`,key:`1l6xoz`}],[`path`,{d:`M18 8h.01`,key:`emo2bl`}],[`path`,{d:`M6 8h.01`,key:`x9i8wu`}],[`path`,{d:`M7 16h10`,key:`wp8him`}],[`path`,{d:`M8 12h.01`,key:`czm47f`}],[`rect`,{width:`20`,height:`16`,x:`2`,y:`4`,rx:`2`,key:`18n3k1`}]]};O.node;var k=r(O),A={name:`monitor-smartphone`,size:24,node:[[`path`,{d:`M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8`,key:`10dyio`}],[`path`,{d:`M10 19v-3.96 3.15`,key:`1irgej`}],[`path`,{d:`M7 19h5`,key:`qswx4l`}],[`rect`,{width:`6`,height:`10`,x:`16`,y:`12`,rx:`2`,key:`1egngj`}]]};A.node;var j=r(A),M={name:`rotate-ccw-clock`,size:24,node:[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M12 7v5l4 2`,key:`1fdv2h`}]],aliases:[`history`]};M.node;var N=r(M),P={name:`stethoscope`,size:24,node:[[`path`,{d:`M11 2v2`,key:`1539x4`}],[`path`,{d:`M5 2v2`,key:`1yf1q8`}],[`path`,{d:`M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1`,key:`rb5t3r`}],[`path`,{d:`M8 15a6 6 0 0 0 12 0v-3`,key:`x18d4x`}],[`circle`,{cx:`20`,cy:`10`,r:`2`,key:`ts1r5v`}]]};P.node;var F=r(P),I={name:`terminal`,size:24,node:[[`path`,{d:`M12 19h8`,key:`baeox8`}],[`path`,{d:`m4 17 6-6-6-6`,key:`1yngyt`}]]};I.node;var L=r(I),R=e(n(),1),z=i(),B=[{path:`hosts`,label:`Hosts`,description:`Execution hosts, capabilities and versions`,icon:g},{path:`devices`,label:`Devices`,description:`Signed-in browsers, apps and terminals`,icon:j},{path:`sign-in`,label:`Sign-in`,description:`Passkeys, single sign-on and signing out`,icon:x},{path:`projects`,label:`Projects`,description:`Repositories, checkouts and workspaces`,icon:_},{path:`profiles`,label:`Pi profiles`,description:`Provider, model and thinking presets`,icon:y},{path:`adapters`,label:`Adapters`,description:`Extension adapters on each host`,icon:m},{path:`notifications`,label:`Notifications`,description:`Push, quiet hours and previews`,icon:S},{path:`backups`,label:`Backups`,description:`Back up and restore the coordinator`,icon:D},{path:`diagnostics`,label:`Diagnostics`,description:`Versions, migrations, events and recent problems`,icon:F},{path:`device`,label:`This device`,description:`Preferences stored on this device`,icon:k}],V=e=>e?`/settings/${e}`:`/settings`;function H({title:e,description:n,actions:r,back:i,testId:a,children:o}){let s=T(),c=i??(s===`mobile`?{to:`/settings`,label:`Settings`}:null);return(0,z.jsxs)(`section`,{"data-testid":a,className:`flex w-full min-w-0 flex-col gap-4 px-4 py-4 md:px-6`,children:[c&&(0,z.jsxs)(t,{to:c.to,className:`tap -ml-2 inline-flex w-fit items-center gap-1 rounded-md px-2 py-1 text-sm font-medium text-accent hover:bg-surface-2`,children:[(0,z.jsx)(v,{"aria-hidden":!0,className:`size-4`}),`Back to `,c.label]}),(0,z.jsxs)(`header`,{className:`flex min-w-0 flex-wrap items-start gap-3`,children:[(0,z.jsxs)(`div`,{className:`min-w-0 flex-[1_1_15rem]`,children:[(0,z.jsx)(`h1`,{className:`break-words text-lg font-semibold`,children:e}),n&&(0,z.jsx)(`p`,{className:`text-sm text-muted`,children:n})]}),r&&(0,z.jsx)(`div`,{className:`flex flex-wrap items-center gap-2`,children:r})]}),o]})}function U({title:e,description:t,actions:n,children:r,className:i}){return(0,z.jsxs)(`section`,{className:d(`min-w-0 rounded-lg border border-border bg-surface p-4`,i),children:[(e||n)&&(0,z.jsxs)(`div`,{className:`mb-3 flex min-w-0 flex-wrap items-start gap-2`,children:[(0,z.jsxs)(`div`,{className:`min-w-0 flex-[1_1_12rem]`,children:[e&&(0,z.jsx)(`h2`,{className:`text-base font-semibold`,children:e}),t&&(0,z.jsx)(`p`,{className:`text-sm text-muted`,children:t})]}),n&&(0,z.jsx)(`div`,{className:`flex flex-wrap items-center gap-2`,children:n})]}),r]})}function W({items:e}){return(0,z.jsx)(`dl`,{className:`grid min-w-0 gap-x-4 gap-y-1 text-sm sm:grid-cols-[minmax(8rem,12rem)_minmax(0,1fr)]`,children:e.map(([e,t],n)=>(0,z.jsxs)(`div`,{className:`contents`,children:[(0,z.jsx)(`dt`,{className:`text-muted`,children:e}),(0,z.jsx)(`dd`,{className:`mb-1 min-w-0 break-words sm:mb-0`,children:t})]},n))})}function ne(){let e=s();return e.state===`live`||e.state===`connecting`?null:(0,z.jsxs)(`p`,{role:`status`,className:`flex items-center gap-1.5 text-sm text-muted`,children:[(0,z.jsx)(N,{"aria-hidden":!0,className:`size-4 shrink-0`}),(0,z.jsxs)(`span`,{children:[`Showing last known data`,e.lastSyncedAt?` from ${p(e.lastSyncedAt)}`:``,`. Changes made elsewhere appear after reconnecting.`]})]})}function G(){return o(e=>e.hydrated)}function K({icon:e,label:t,tone:n=`neutral`,spin:r,className:i}){return(0,z.jsxs)(`span`,{className:d(`inline-flex max-w-full items-center gap-1 rounded-full border px-2 text-xs leading-6 font-medium`,a[n],i),children:[r?(0,z.jsx)(l,{className:`size-3.5`}):(0,z.jsx)(e,{"aria-hidden":!0,className:`size-3.5 shrink-0`}),(0,z.jsx)(`span`,{className:`min-w-0 truncate`,children:t})]})}var q={darwin:`macOS`,linux:`Linux`};function J({host:e}){return e.piVersion?e.piCompatible?(0,z.jsx)(K,{icon:C,tone:`success`,label:`Pi ${e.piVersion} (compatible)`}):(0,z.jsx)(K,{icon:u,tone:`danger`,label:`Pi ${e.piVersion} (incompatible, needs ${te})`}):(0,z.jsx)(K,{icon:u,tone:`warning`,label:`Pi not detected (incompatible)`})}function Y({id:e,label:t,hint:n,error:r,children:i,className:a}){return(0,z.jsxs)(`div`,{className:d(`flex w-full min-w-0 max-w-2xl flex-col gap-1`,a),children:[(0,z.jsx)(`label`,{htmlFor:e,className:`text-sm font-medium`,children:t}),i,n&&(0,z.jsx)(`p`,{id:`${e}-hint`,className:`text-xs text-muted`,children:n}),r&&(0,z.jsxs)(`p`,{id:`${e}-error`,className:`flex items-start gap-1 text-xs text-danger`,children:[(0,z.jsx)(u,{"aria-hidden":!0,className:`mt-0.5 size-3.5 shrink-0`}),(0,z.jsx)(`span`,{className:`min-w-0 whitespace-pre-line break-words`,children:r})]})]})}function X(e,t){let n=[t.hint&&`${e}-hint`,t.error&&`${e}-error`].filter(Boolean);return{"aria-describedby":n.length?n.join(` `):void 0,"aria-invalid":t.error?!0:void 0}}function Z({className:e,children:t,...n}){return(0,z.jsx)(`select`,{className:d(`tap block h-9 w-full min-w-0 rounded-md border border-border bg-surface px-2 text-base text-text md:text-sm`,`focus:border-accent focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-0`,e),...n,children:t})}function re({label:e,description:t,checked:n,onChange:r,disabled:i}){let a=(0,R.useId)();return(0,z.jsxs)(`div`,{className:`flex min-w-0 items-start gap-3`,children:[(0,z.jsx)(`input`,{id:a,type:`checkbox`,role:`switch`,"aria-checked":n,checked:n,disabled:i,onChange:e=>r(e.target.checked),"aria-describedby":t?`${a}-desc`:void 0,className:`peer sr-only`}),(0,z.jsxs)(`label`,{htmlFor:a,className:d(`tap flex min-w-0 flex-1 cursor-pointer items-start gap-3 rounded-md`,`peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-[var(--sy-focus)]`,i&&`cursor-not-allowed opacity-60`),children:[(0,z.jsx)(`span`,{"aria-hidden":!0,className:d(`relative mt-0.5 inline-flex h-6 w-10 shrink-0 items-center rounded-full border transition-colors`,n?`border-accent bg-accent`:`border-border-strong bg-surface-3`),children:(0,z.jsx)(`span`,{className:d(`absolute size-4 rounded-full bg-surface shadow transition-transform`,n?`translate-x-5`:`translate-x-1`)})}),(0,z.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,z.jsxs)(`span`,{className:`block text-sm font-medium`,children:[e,` `,(0,z.jsxs)(`span`,{className:`font-normal text-muted`,children:[`(`,n?`On`:`Off`,`)`]})]}),t&&(0,z.jsx)(`span`,{id:`${a}-desc`,className:`block text-sm text-muted`,children:t})]})]})]})}function ie({label:e,description:t,checked:n,onChange:r}){let i=(0,R.useId)();return(0,z.jsxs)(`div`,{className:`flex min-w-0 items-start gap-2`,children:[(0,z.jsx)(`input`,{id:i,type:`checkbox`,checked:n,onChange:e=>r(e.target.checked),"aria-describedby":t?`${i}-desc`:void 0,className:`tap mt-0.5 size-5 shrink-0 accent-[var(--sy-accent)]`}),(0,z.jsxs)(`label`,{htmlFor:i,className:`min-w-0 flex-1 cursor-pointer text-sm`,children:[(0,z.jsx)(`span`,{className:`block font-medium`,children:e}),t&&(0,z.jsx)(`span`,{id:`${i}-desc`,className:`block text-muted`,children:t})]})]})}function ae(e){let t=e.trim();return t?t.startsWith(`/`)?null:`Use an absolute path that starts with /, e.g. /Users/me/src/app.`:`Enter the path of the checkout on the host.`}function oe(e){if(typeof e!=`object`||!e)return!1;let t=e;return Array.isArray(t.passkeys)&&typeof t.passkeyAvailability==`object`}function se(e){return e.split(`
2
- `).map(e=>e.trim()).filter(Boolean)}function Q({error:e}){return e?(0,z.jsxs)(`p`,{role:`alert`,className:`flex items-start gap-2 rounded-md border border-border bg-danger-soft px-3 py-2 text-sm`,children:[(0,z.jsx)(u,{"aria-hidden":!0,className:`mt-0.5 size-4 shrink-0 text-danger`}),(0,z.jsx)(`span`,{className:`min-w-0 break-words`,children:c(e)})]}):null}async function $(e,t=`Copied to clipboard`){try{return await navigator.clipboard.writeText(e),w.success(t),!0}catch{return w.error(`Could not copy. Select the text and copy it manually.`),!1}}function ce({text:e,label:t=`Copy`,toastMessage:n,size:r=`sm`}){let[i,a]=(0,R.useState)(!1),o=(0,R.useRef)(null);return(0,R.useEffect)(()=>()=>void(o.current&&clearTimeout(o.current)),[]),(0,z.jsx)(f,{size:r,icon:i?(0,z.jsx)(h,{className:`size-4`}):(0,z.jsx)(b,{className:`size-4`}),onClick:async()=>{await $(e,n)&&(a(!0),o.current&&clearTimeout(o.current),o.current=setTimeout(()=>a(!1),2e3))},children:i?`Copied`:t})}function le({text:e,label:t,copyLabel:n=`Copy`}){return(0,z.jsxs)(`figure`,{className:`m-0 flex min-w-0 flex-col gap-2 sm:flex-row sm:items-start`,children:[(0,z.jsx)(`figcaption`,{className:`sr-only`,children:t}),(0,z.jsx)(`pre`,{className:`min-w-0 flex-1 whitespace-pre-wrap break-all rounded-md border border-border bg-surface-2 px-3 py-2 font-mono text-sm`,children:e}),(0,z.jsx)(ce,{text:e,label:n})]})}function ue(e){let[t,n]=(0,R.useState)(()=>Date.now());if((0,R.useEffect)(()=>{if(!e)return;n(Date.now());let t=setInterval(()=>n(Date.now()),1e3);return()=>clearInterval(t)},[e]),!e)return null;let r=Date.parse(e);return Number.isNaN(r)?null:Math.max(0,r-t)}function de(e){let t=Math.ceil(e/1e3);return`${Math.floor(t/60)}:${String(t%60).padStart(2,`0`)}`}function fe({open:e,onClose:t,title:n,description:r,confirmLabel:i,onConfirm:a,busy:o,error:s,danger:c=!0,confirmDisabled:l,disabledReason:u,children:d}){return(0,z.jsx)(ee,{open:e,onClose:o?()=>void 0:t,dismissOnBackdrop:!o,title:n,description:r,footer:(0,z.jsxs)(z.Fragment,{children:[l&&u&&(0,z.jsx)(`p`,{className:`mr-auto min-w-0 flex-1 basis-full text-xs text-muted sm:basis-auto`,children:u}),(0,z.jsx)(f,{onClick:t,disabled:o,children:`Cancel`}),(0,z.jsx)(f,{variant:c?`danger`:`primary`,busy:o,disabled:l,onClick:a,children:i})]}),children:(0,z.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[d,(0,z.jsx)(Q,{error:s})]})})}export{G as C,j as E,ue as S,L as T,X as _,Y as a,V as b,W as c,J as d,B as f,$ as g,re as h,le as i,ne as l,Z as m,ie as n,Q as o,H as p,fe as r,K as s,U as t,q as u,de as v,ae as w,se as x,oe as y};
3
- //# sourceMappingURL=shared-CZ7fcu_B.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shared-CZ7fcu_B.js","names":["__iconData","__iconData","__iconData","__iconData","__iconData","History","useId","useState","useRef","_Fragment","__toESM","Link","require_react","createLucideIcon","require_jsx_runtime","TONE_CLASSES","useSyncStore","useConnection","errorMessage","Spinner","TriangleAlert","cn","Button","formatTime","Puzzle","Check","Server","FolderGit2","ChevronLeft","SlidersHorizontal","Copy","KeyRound","Bell","CircleCheck","toast","useBreakpoint","Dialog","PI_SUPPORTED_RANGE","__iconData$5","DatabaseBackup","__iconData$4","Keyboard","__iconData$3","MonitorSmartphone","__iconData$2","RotateCcwClock","__iconData$1","Stethoscope","__iconData","Terminal","import_react","import_jsx_runtime","SECTIONS","settingsPath","sub","SectionPage","bp","backLink","back","testId","title","description","actions","children","Card","className","KeyValues","items","k","v","i","LastKnownNote","connection","useHydrated","s","InlineStatus","Icon","tone","spin","label","PLATFORM_LABEL","PiCompat","host","Field","id","hint","error","describedBy","ids","opts","SelectInput","rest","Toggle","checked","onChange","disabled","Checkbox","validateAbsolutePath","p","path","isAuthMethods","m","splitLines","text","l","InlineError","copyText","what","CopyButton","copied","setCopied","timer","toastMessage","CopyBlock","copyLabel","useCountdown","now","setNow","iso","at","formatCountdown","ms","ConfirmDialog","busy","onClose","confirmDisabled","disabledReason","danger","onConfirm","confirmLabel"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/database-backup.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/keyboard.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/monitor-smartphone.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/rotate-ccw-clock.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/stethoscope.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/terminal.mjs","../../src/features/settings/shared.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"database-backup\",\n size: 24,\n node: [\n [\"ellipse\", { cx: \"12\", cy: \"5\", rx: \"9\", ry: \"3\", key: \"msslwz\" }],\n [\"path\", { d: \"M3 12a9 3 0 0 0 5 2.69\", key: \"1ui2ym\" }],\n [\"path\", { d: \"M21 9.3V5\", key: \"6k6cib\" }],\n [\"path\", { d: \"M3 5v14a9 3 0 0 0 6.47 2.88\", key: \"i62tjy\" }],\n [\"path\", { d: \"M12 12v4h4\", key: \"1bxaet\" }],\n [\n \"path\",\n {\n d: \"M13 20a5 5 0 0 0 9-3 4.5 4.5 0 0 0-4.5-4.5c-1.33 0-2.54.54-3.41 1.41L12 16\",\n key: \"1f4ei9\"\n }\n ]\n ]\n};\n__iconData.node;\nconst DatabaseBackup = createLucideIcon(__iconData);\n\nexport { __iconData, DatabaseBackup as default };\n//# sourceMappingURL=database-backup.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"keyboard\",\n size: 24,\n node: [\n [\"path\", { d: \"M10 8h.01\", key: \"1r9ogq\" }],\n [\"path\", { d: \"M12 12h.01\", key: \"1mp3jc\" }],\n [\"path\", { d: \"M14 8h.01\", key: \"1primd\" }],\n [\"path\", { d: \"M16 12h.01\", key: \"1l6xoz\" }],\n [\"path\", { d: \"M18 8h.01\", key: \"emo2bl\" }],\n [\"path\", { d: \"M6 8h.01\", key: \"x9i8wu\" }],\n [\"path\", { d: \"M7 16h10\", key: \"wp8him\" }],\n [\"path\", { d: \"M8 12h.01\", key: \"czm47f\" }],\n [\"rect\", { width: \"20\", height: \"16\", x: \"2\", y: \"4\", rx: \"2\", key: \"18n3k1\" }]\n ]\n};\n__iconData.node;\nconst Keyboard = createLucideIcon(__iconData);\n\nexport { __iconData, Keyboard as default };\n//# sourceMappingURL=keyboard.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"monitor-smartphone\",\n size: 24,\n node: [\n [\"path\", { d: \"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8\", key: \"10dyio\" }],\n [\"path\", { d: \"M10 19v-3.96 3.15\", key: \"1irgej\" }],\n [\"path\", { d: \"M7 19h5\", key: \"qswx4l\" }],\n [\"rect\", { width: \"6\", height: \"10\", x: \"16\", y: \"12\", rx: \"2\", key: \"1egngj\" }]\n ]\n};\n__iconData.node;\nconst MonitorSmartphone = createLucideIcon(__iconData);\n\nexport { __iconData, MonitorSmartphone as default };\n//# sourceMappingURL=monitor-smartphone.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"rotate-ccw-clock\",\n size: 24,\n node: [\n [\"path\", { d: \"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"1357e3\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }],\n [\"path\", { d: \"M12 7v5l4 2\", key: \"1fdv2h\" }]\n ],\n aliases: [\"history\"]\n};\n__iconData.node;\nconst RotateCcwClock = createLucideIcon(__iconData);\n\nexport { __iconData, RotateCcwClock as default };\n//# sourceMappingURL=rotate-ccw-clock.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"stethoscope\",\n size: 24,\n node: [\n [\"path\", { d: \"M11 2v2\", key: \"1539x4\" }],\n [\"path\", { d: \"M5 2v2\", key: \"1yf1q8\" }],\n [\"path\", { d: \"M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1\", key: \"rb5t3r\" }],\n [\"path\", { d: \"M8 15a6 6 0 0 0 12 0v-3\", key: \"x18d4x\" }],\n [\"circle\", { cx: \"20\", cy: \"10\", r: \"2\", key: \"ts1r5v\" }]\n ]\n};\n__iconData.node;\nconst Stethoscope = createLucideIcon(__iconData);\n\nexport { __iconData, Stethoscope as default };\n//# sourceMappingURL=stethoscope.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"terminal\",\n size: 24,\n node: [\n [\"path\", { d: \"M12 19h8\", key: \"baeox8\" }],\n [\"path\", { d: \"m4 17 6-6-6-6\", key: \"1yngyt\" }]\n ]\n};\n__iconData.node;\nconst Terminal = createLucideIcon(__iconData);\n\nexport { __iconData, Terminal as default };\n//# sourceMappingURL=terminal.mjs.map\n","import type { Host } from \"@switchyard/protocol\";\nimport { PI_SUPPORTED_RANGE } from \"@switchyard/protocol\";\nimport {\n Bell,\n Check,\n ChevronLeft,\n CircleCheck,\n Copy,\n DatabaseBackup,\n FolderGit2,\n History,\n Keyboard,\n KeyRound,\n type LucideIcon,\n MonitorSmartphone,\n Puzzle,\n Server,\n SlidersHorizontal,\n Stethoscope,\n TriangleAlert,\n} from \"lucide-react\";\nimport { type ReactNode, useEffect, useId, useRef, useState } from \"react\";\nimport { Link } from \"react-router\";\nimport { useBreakpoint } from \"../../app/useBreakpoint\";\nimport { TONE_CLASSES, type Tone } from \"../../components/ui/Badge\";\nimport { Button } from \"../../components/ui/Button\";\nimport { Dialog } from \"../../components/ui/Overlay\";\nimport { Spinner } from \"../../components/ui/Spinner\";\nimport { toast } from \"../../components/ui/Toast\";\nimport { cn } from \"../../lib/cn\";\nimport { formatTime } from \"../../lib/time\";\nimport { errorMessage } from \"../../sync/api\";\nimport { useConnection, useSyncStore } from \"../../sync/store\";\n\n/* ------------------------------------------------------------------ */\n/* Sections */\n/* ------------------------------------------------------------------ */\n\nexport interface SectionDef {\n path: string;\n label: string;\n description: string;\n icon: LucideIcon;\n}\n\nexport const SECTIONS: SectionDef[] = [\n {\n path: \"hosts\",\n label: \"Hosts\",\n description: \"Execution hosts, capabilities and versions\",\n icon: Server,\n },\n {\n path: \"devices\",\n label: \"Devices\",\n description: \"Signed-in browsers, apps and terminals\",\n icon: MonitorSmartphone,\n },\n {\n path: \"sign-in\",\n label: \"Sign-in\",\n description: \"Passkeys, single sign-on and signing out\",\n icon: KeyRound,\n },\n {\n path: \"projects\",\n label: \"Projects\",\n description: \"Repositories, checkouts and workspaces\",\n icon: FolderGit2,\n },\n {\n path: \"profiles\",\n label: \"Pi profiles\",\n description: \"Provider, model and thinking presets\",\n icon: SlidersHorizontal,\n },\n {\n path: \"adapters\",\n label: \"Adapters\",\n description: \"Extension adapters on each host\",\n icon: Puzzle,\n },\n {\n path: \"notifications\",\n label: \"Notifications\",\n description: \"Push, quiet hours and previews\",\n icon: Bell,\n },\n {\n path: \"backups\",\n label: \"Backups\",\n description: \"Back up and restore the coordinator\",\n icon: DatabaseBackup,\n },\n {\n path: \"diagnostics\",\n label: \"Diagnostics\",\n description: \"Versions, migrations, events and recent problems\",\n icon: Stethoscope,\n },\n {\n path: \"device\",\n label: \"This device\",\n description: \"Preferences stored on this device\",\n icon: Keyboard,\n },\n];\n\nexport const settingsPath = (sub?: string) => (sub ? `/settings/${sub}` : \"/settings\");\n\n/* ------------------------------------------------------------------ */\n/* Page scaffolding */\n/* ------------------------------------------------------------------ */\n\n/**\n * A settings page: heading, optional actions and a Back link. Top-level\n * sections show \"Back to Settings\" on mobile only (desktop has the section\n * nav); detail pages pass an explicit `back` shown everywhere.\n */\nexport function SectionPage({\n title,\n description,\n actions,\n back,\n testId,\n children,\n}: {\n title: ReactNode;\n description?: ReactNode;\n actions?: ReactNode;\n back?: { to: string; label: string };\n testId?: string;\n children?: ReactNode;\n}) {\n const bp = useBreakpoint();\n const backLink = back ?? (bp === \"mobile\" ? { to: \"/settings\", label: \"Settings\" } : null);\n return (\n <section data-testid={testId} className=\"flex w-full min-w-0 flex-col gap-4 px-4 py-4 md:px-6\">\n {backLink && (\n <Link\n to={backLink.to}\n className=\"tap -ml-2 inline-flex w-fit items-center gap-1 rounded-md px-2 py-1 text-sm font-medium text-accent hover:bg-surface-2\"\n >\n <ChevronLeft aria-hidden className=\"size-4\" />\n Back to {backLink.label}\n </Link>\n )}\n <header className=\"flex min-w-0 flex-wrap items-start gap-3\">\n <div className=\"min-w-0 flex-[1_1_15rem]\">\n <h1 className=\"break-words text-lg font-semibold\">{title}</h1>\n {description && <p className=\"text-sm text-muted\">{description}</p>}\n </div>\n {actions && <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>}\n </header>\n {children}\n </section>\n );\n}\n\n/** A titled block inside a settings page. */\nexport function Card({\n title,\n description,\n actions,\n children,\n className,\n}: {\n title?: ReactNode;\n description?: ReactNode;\n actions?: ReactNode;\n children?: ReactNode;\n className?: string;\n}) {\n return (\n <section className={cn(\"min-w-0 rounded-lg border border-border bg-surface p-4\", className)}>\n {(title || actions) && (\n <div className=\"mb-3 flex min-w-0 flex-wrap items-start gap-2\">\n <div className=\"min-w-0 flex-[1_1_12rem]\">\n {title && <h2 className=\"text-base font-semibold\">{title}</h2>}\n {description && <p className=\"text-sm text-muted\">{description}</p>}\n </div>\n {actions && <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>}\n </div>\n )}\n {children}\n </section>\n );\n}\n\n/** Key/value list that stacks on narrow screens. */\nexport function KeyValues({ items }: { items: [ReactNode, ReactNode][] }) {\n return (\n <dl className=\"grid min-w-0 gap-x-4 gap-y-1 text-sm sm:grid-cols-[minmax(8rem,12rem)_minmax(0,1fr)]\">\n {items.map(([k, v], i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: static, order-stable list\n <div key={i} className=\"contents\">\n <dt className=\"text-muted\">{k}</dt>\n <dd className=\"mb-1 min-w-0 break-words sm:mb-0\">{v}</dd>\n </div>\n ))}\n </dl>\n );\n}\n\n/** \"Showing last known data\" when the live connection is down (spec 18). */\nexport function LastKnownNote() {\n const connection = useConnection();\n if (connection.state === \"live\" || connection.state === \"connecting\") return null;\n return (\n <p role=\"status\" className=\"flex items-center gap-1.5 text-sm text-muted\">\n <History aria-hidden className=\"size-4 shrink-0\" />\n <span>\n Showing last known data\n {connection.lastSyncedAt ? ` from ${formatTime(connection.lastSyncedAt)}` : \"\"}. Changes\n made elsewhere appear after reconnecting.\n </span>\n </p>\n );\n}\n\n/** Whether store-backed data is available yet. */\nexport function useHydrated(): boolean {\n return useSyncStore((s) => s.hydrated);\n}\n\n/** Icon plus text status, the tone only reinforces. */\nexport function InlineStatus({\n icon: Icon,\n label,\n tone = \"neutral\",\n spin,\n className,\n}: {\n icon: LucideIcon;\n label: ReactNode;\n tone?: Tone;\n spin?: boolean;\n className?: string;\n}) {\n return (\n <span\n className={cn(\n \"inline-flex max-w-full items-center gap-1 rounded-full border px-2 text-xs leading-6 font-medium\",\n TONE_CLASSES[tone],\n className,\n )}\n >\n {spin ? <Spinner className=\"size-3.5\" /> : <Icon aria-hidden className=\"size-3.5 shrink-0\" />}\n <span className=\"min-w-0 truncate\">{label}</span>\n </span>\n );\n}\n\nexport const PLATFORM_LABEL: Record<Host[\"platform\"], string> = {\n darwin: \"macOS\",\n linux: \"Linux\",\n};\n\n/** Pi version plus compatible/incompatible text. */\nexport function PiCompat({ host }: { host: Pick<Host, \"piVersion\" | \"piCompatible\"> }) {\n if (!host.piVersion) {\n return (\n <InlineStatus icon={TriangleAlert} tone=\"warning\" label=\"Pi not detected (incompatible)\" />\n );\n }\n return host.piCompatible ? (\n <InlineStatus icon={CircleCheck} tone=\"success\" label={`Pi ${host.piVersion} (compatible)`} />\n ) : (\n <InlineStatus\n icon={TriangleAlert}\n tone=\"danger\"\n label={`Pi ${host.piVersion} (incompatible, needs ${PI_SUPPORTED_RANGE})`}\n />\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Form controls */\n/* ------------------------------------------------------------------ */\n\n/** Label, control, hint and error. The control must use `id` and `describedBy`. */\nexport function Field({\n id,\n label,\n hint,\n error,\n children,\n className,\n}: {\n id: string;\n label: ReactNode;\n hint?: ReactNode;\n error?: string | null;\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn(\"flex w-full min-w-0 max-w-2xl flex-col gap-1\", className)}>\n <label htmlFor={id} className=\"text-sm font-medium\">\n {label}\n </label>\n {children}\n {hint && (\n <p id={`${id}-hint`} className=\"text-xs text-muted\">\n {hint}\n </p>\n )}\n {error && (\n <p id={`${id}-error`} className=\"flex items-start gap-1 text-xs text-danger\">\n <TriangleAlert aria-hidden className=\"mt-0.5 size-3.5 shrink-0\" />\n <span className=\"min-w-0 whitespace-pre-line break-words\">{error}</span>\n </p>\n )}\n </div>\n );\n}\n\n/** aria-describedby / aria-invalid props for a Field control. */\nexport function describedBy(id: string, opts: { hint?: boolean; error?: string | null }) {\n const ids = [opts.hint && `${id}-hint`, opts.error && `${id}-error`].filter(Boolean);\n return {\n \"aria-describedby\": ids.length ? ids.join(\" \") : undefined,\n \"aria-invalid\": opts.error ? true : undefined,\n } as const;\n}\n\n/** Native select styled like TextInput. */\nexport function SelectInput({\n className,\n children,\n ...rest\n}: React.SelectHTMLAttributes<HTMLSelectElement>) {\n return (\n <select\n className={cn(\n \"tap block h-9 w-full min-w-0 rounded-md border border-border bg-surface px-2 text-base text-text md:text-sm\",\n \"focus:border-accent focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-0\",\n className,\n )}\n {...rest}\n >\n {children}\n </select>\n );\n}\n\n/** On/off switch built on a checkbox, with the state written out. */\nexport function Toggle({\n label,\n description,\n checked,\n onChange,\n disabled,\n}: {\n label: ReactNode;\n description?: ReactNode;\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n}) {\n const id = useId();\n return (\n <div className=\"flex min-w-0 items-start gap-3\">\n <input\n id={id}\n type=\"checkbox\"\n role=\"switch\"\n aria-checked={checked}\n checked={checked}\n disabled={disabled}\n onChange={(e) => onChange(e.target.checked)}\n aria-describedby={description ? `${id}-desc` : undefined}\n className=\"peer sr-only\"\n />\n <label\n htmlFor={id}\n className={cn(\n \"tap flex min-w-0 flex-1 cursor-pointer items-start gap-3 rounded-md\",\n \"peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-[var(--sy-focus)]\",\n disabled && \"cursor-not-allowed opacity-60\",\n )}\n >\n <span\n aria-hidden\n className={cn(\n \"relative mt-0.5 inline-flex h-6 w-10 shrink-0 items-center rounded-full border transition-colors\",\n checked ? \"border-accent bg-accent\" : \"border-border-strong bg-surface-3\",\n )}\n >\n <span\n className={cn(\n \"absolute size-4 rounded-full bg-surface shadow transition-transform\",\n checked ? \"translate-x-5\" : \"translate-x-1\",\n )}\n />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-medium\">\n {label} <span className=\"font-normal text-muted\">({checked ? \"On\" : \"Off\"})</span>\n </span>\n {description && (\n <span id={`${id}-desc`} className=\"block text-sm text-muted\">\n {description}\n </span>\n )}\n </span>\n </label>\n </div>\n );\n}\n\n/** A labelled checkbox (used for explicit confirmations). */\nexport function Checkbox({\n label,\n description,\n checked,\n onChange,\n}: {\n label: ReactNode;\n description?: ReactNode;\n checked: boolean;\n onChange: (checked: boolean) => void;\n}) {\n const id = useId();\n return (\n <div className=\"flex min-w-0 items-start gap-2\">\n <input\n id={id}\n type=\"checkbox\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n aria-describedby={description ? `${id}-desc` : undefined}\n className=\"tap mt-0.5 size-5 shrink-0 accent-[var(--sy-accent)]\"\n />\n <label htmlFor={id} className=\"min-w-0 flex-1 cursor-pointer text-sm\">\n <span className=\"block font-medium\">{label}</span>\n {description && (\n <span id={`${id}-desc`} className=\"block text-muted\">\n {description}\n </span>\n )}\n </label>\n </div>\n );\n}\n\n/** Validate an absolute host path; returns an error message or null. */\nexport function validateAbsolutePath(path: string): string | null {\n const p = path.trim();\n if (!p) return \"Enter the path of the checkout on the host.\";\n if (!p.startsWith(\"/\")) return \"Use an absolute path that starts with /, e.g. /Users/me/src/app.\";\n return null;\n}\n\n/** Shape check for GET /api/auth/methods. */\nexport function isAuthMethods(v: unknown): boolean {\n if (typeof v !== \"object\" || v === null) return false;\n const m = v as { passkeys?: unknown; passkeyAvailability?: unknown };\n return Array.isArray(m.passkeys) && typeof m.passkeyAvailability === \"object\";\n}\n\n/** Split a textarea into trimmed non-empty lines. */\nexport function splitLines(text: string): string[] {\n return text\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean);\n}\n\n/** Inline error message for a failed mutation. */\nexport function InlineError({ error }: { error: unknown }) {\n if (!error) return null;\n return (\n <p\n role=\"alert\"\n className=\"flex items-start gap-2 rounded-md border border-border bg-danger-soft px-3 py-2 text-sm\"\n >\n <TriangleAlert aria-hidden className=\"mt-0.5 size-4 shrink-0 text-danger\" />\n <span className=\"min-w-0 break-words\">{errorMessage(error)}</span>\n </p>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Copy */\n/* ------------------------------------------------------------------ */\n\nexport async function copyText(text: string, what = \"Copied to clipboard\"): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(text);\n toast.success(what);\n return true;\n } catch {\n toast.error(\"Could not copy. Select the text and copy it manually.\");\n return false;\n }\n}\n\nexport function CopyButton({\n text,\n label = \"Copy\",\n toastMessage,\n size = \"sm\",\n}: {\n text: string;\n label?: string;\n toastMessage?: string;\n size?: \"sm\" | \"md\";\n}) {\n const [copied, setCopied] = useState(false);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n useEffect(() => () => void (timer.current && clearTimeout(timer.current)), []);\n return (\n <Button\n size={size}\n icon={copied ? <Check className=\"size-4\" /> : <Copy className=\"size-4\" />}\n onClick={async () => {\n if (await copyText(text, toastMessage)) {\n setCopied(true);\n if (timer.current) clearTimeout(timer.current);\n timer.current = setTimeout(() => setCopied(false), 2000);\n }\n }}\n >\n {copied ? \"Copied\" : label}\n </Button>\n );\n}\n\n/** A monospace command or URL with a copy button; wraps instead of overflowing. */\nexport function CopyBlock({\n text,\n label,\n copyLabel = \"Copy\",\n}: {\n text: string;\n /** Accessible name of the code block. */\n label: string;\n copyLabel?: string;\n}) {\n return (\n <figure className=\"m-0 flex min-w-0 flex-col gap-2 sm:flex-row sm:items-start\">\n <figcaption className=\"sr-only\">{label}</figcaption>\n <pre className=\"min-w-0 flex-1 whitespace-pre-wrap break-all rounded-md border border-border bg-surface-2 px-3 py-2 font-mono text-sm\">\n {text}\n </pre>\n <CopyButton text={text} label={copyLabel} />\n </figure>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Expiry countdown */\n/* ------------------------------------------------------------------ */\n\n/** Milliseconds until `iso`, ticking every second; null without a time. */\nexport function useCountdown(iso: string | null | undefined): number | null {\n const [now, setNow] = useState(() => Date.now());\n useEffect(() => {\n if (!iso) return;\n setNow(Date.now());\n const t = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(t);\n }, [iso]);\n if (!iso) return null;\n const at = Date.parse(iso);\n if (Number.isNaN(at)) return null;\n return Math.max(0, at - now);\n}\n\nexport function formatCountdown(ms: number): string {\n const s = Math.ceil(ms / 1000);\n return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, \"0\")}`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Confirmation */\n/* ------------------------------------------------------------------ */\n\n/**\n * Confirmation dialog for destructive actions. Never closes on its own:\n * the caller closes it after the server acknowledges (no optimistic success).\n */\nexport function ConfirmDialog({\n open,\n onClose,\n title,\n description,\n confirmLabel,\n onConfirm,\n busy,\n error,\n danger = true,\n confirmDisabled,\n disabledReason,\n children,\n}: {\n open: boolean;\n onClose: () => void;\n title: ReactNode;\n description?: ReactNode;\n confirmLabel: string;\n onConfirm: () => void;\n busy?: boolean;\n error?: unknown;\n danger?: boolean;\n confirmDisabled?: boolean;\n /** Shown next to the actions when the confirm button is disabled. */\n disabledReason?: ReactNode;\n children?: ReactNode;\n}) {\n return (\n <Dialog\n open={open}\n onClose={busy ? () => undefined : onClose}\n dismissOnBackdrop={!busy}\n title={title}\n description={description}\n footer={\n <>\n {confirmDisabled && disabledReason && (\n <p className=\"mr-auto min-w-0 flex-1 basis-full text-xs text-muted sm:basis-auto\">\n {disabledReason}\n </p>\n )}\n <Button onClick={onClose} disabled={busy}>\n Cancel\n </Button>\n <Button\n variant={danger ? \"danger\" : \"primary\"}\n busy={busy}\n disabled={confirmDisabled}\n onClick={onConfirm}\n >\n {confirmLabel}\n </Button>\n </>\n }\n >\n <div className=\"flex flex-col gap-3\">\n {children}\n <InlineError error={error} />\n </div>\n </Dialog>\n );\n}\n"],"ignoreList":[0,1,2,3,4,5],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{n as e}from"./jsx-runtime-D13aM9HY.js";var t={name:`chevron-left`,size:24,node:[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]};t.node;var n=e(t),r={name:`folder-git-2`,size:24,node:[[`path`,{d:`M18 19a5 5 0 0 1-5-5v8`,key:`sz5oeg`}],[`path`,{d:`M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v5`,key:`1w6njk`}],[`circle`,{cx:`13`,cy:`12`,r:`2`,key:`1j92g6`}],[`circle`,{cx:`20`,cy:`19`,r:`2`,key:`1obnsp`}]]};r.node;var i=e(r),a={name:`sliders-horizontal`,size:24,node:[[`path`,{d:`M10 5H3`,key:`1qgfaw`}],[`path`,{d:`M12 19H3`,key:`yhmn1j`}],[`path`,{d:`M14 3v4`,key:`1sua03`}],[`path`,{d:`M16 17v4`,key:`1q0r14`}],[`path`,{d:`M21 12h-9`,key:`1o4lsq`}],[`path`,{d:`M21 19h-5`,key:`1rlt1p`}],[`path`,{d:`M21 5h-7`,key:`1oszz2`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M8 12H3`,key:`a7s4jb`}]]};a.node;var o=e(a);export{i as n,n as r,o as t};
2
- //# sourceMappingURL=sliders-horizontal-DAoirila.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sliders-horizontal-DAoirila.js","names":["__iconData","__iconData","createLucideIcon","__iconData$2","ChevronLeft","__iconData$1","FolderGit2","__iconData","SlidersHorizontal"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/chevron-left.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/folder-git-2.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.mjs"],"sourcesContent":["/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"chevron-left\",\n size: 24,\n node: [[\"path\", { d: \"m15 18-6-6 6-6\", key: \"1wnfg3\" }]]\n};\n__iconData.node;\nconst ChevronLeft = createLucideIcon(__iconData);\n\nexport { __iconData, ChevronLeft as default };\n//# sourceMappingURL=chevron-left.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"folder-git-2\",\n size: 24,\n node: [\n [\"path\", { d: \"M18 19a5 5 0 0 1-5-5v8\", key: \"sz5oeg\" }],\n [\n \"path\",\n {\n d: \"M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v5\",\n key: \"1w6njk\"\n }\n ],\n [\"circle\", { cx: \"13\", cy: \"12\", r: \"2\", key: \"1j92g6\" }],\n [\"circle\", { cx: \"20\", cy: \"19\", r: \"2\", key: \"1obnsp\" }]\n ]\n};\n__iconData.node;\nconst FolderGit2 = createLucideIcon(__iconData);\n\nexport { __iconData, FolderGit2 as default };\n//# sourceMappingURL=folder-git-2.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"sliders-horizontal\",\n size: 24,\n node: [\n [\"path\", { d: \"M10 5H3\", key: \"1qgfaw\" }],\n [\"path\", { d: \"M12 19H3\", key: \"yhmn1j\" }],\n [\"path\", { d: \"M14 3v4\", key: \"1sua03\" }],\n [\"path\", { d: \"M16 17v4\", key: \"1q0r14\" }],\n [\"path\", { d: \"M21 12h-9\", key: \"1o4lsq\" }],\n [\"path\", { d: \"M21 19h-5\", key: \"1rlt1p\" }],\n [\"path\", { d: \"M21 5h-7\", key: \"1oszz2\" }],\n [\"path\", { d: \"M8 10v4\", key: \"tgpxqk\" }],\n [\"path\", { d: \"M8 12H3\", key: \"a7s4jb\" }]\n ]\n};\n__iconData.node;\nconst SlidersHorizontal = createLucideIcon(__iconData);\n\nexport { __iconData, SlidersHorizontal as default };\n//# sourceMappingURL=sliders-horizontal.mjs.map\n"],"ignoreList":[0,1,2],"mappings":"A,8CASA,IAAMA,EAAa,CACjB,KAAM,eACN,KAAM,GACN,KAAM,CAAC,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAS,CAAC,CAAC,CACzD,EACAA,EAAW,KACX,IAAMI,EAAcF,EAAiBF,CAAU,ECNzCC,EAAa,CACjB,KAAM,eACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,yBAA0B,IAAK,QAAS,CAAC,EACvD,CACE,OACA,CACE,EAAG,yGACH,IAAK,QACP,CACF,EACA,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAS,CAAC,EACxD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAS,CAAC,CAC1D,CACF,EACAA,EAAW,KACX,IAAMK,EAAaJ,EAAiBD,CAAU,ECjBxCM,EAAa,CACjB,KAAM,qBACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,EACxC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,EACxC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,EAC1C,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,EAC1C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,EACxC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,CAC1C,CACF,EACAA,EAAW,KACX,IAAMC,EAAoBN,EAAiBK,CAAU,E"}
@@ -1,2 +0,0 @@
1
- import{_ as e,i as t,m as n,n as r,t as i}from"./jsx-runtime-D13aM9HY.js";var a=e(n(),1),o=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},s=(e=>e?o(e):o),c=e=>e;function ee(e,t=c){let n=a.useSyncExternalStore(e.subscribe,a.useCallback(()=>t(e.getState()),[e,t]),()=>t(e.getInitialState()));return a.useDebugValue(n),n}var l=e=>{let t=s(e),n=e=>ee(t,e);return Object.assign(n,t),n},u=(e=>e?l(e):l),d=class extends Error{code;status;details;constructor(e,t,n,r){super(t),this.name=`ApiClientError`,this.code=e,this.status=n,this.details=r}};function te(e,t){return e instanceof d&&(t===void 0||e.code===t)}function f(e){return e instanceof Error?e.message:String(e)}var p=new Set;function ne(e){return p.add(e),()=>p.delete(e)}function re(e,t){if(!t)return e;let n=new URLSearchParams;for(let[e,r]of Object.entries(t))r!=null&&n.set(e,String(r));let r=n.toString();return r?`${e}${e.includes(`?`)?`&`:`?`}${r}`:e}async function m(e,t={}){let n=t.method??(t.body===void 0?`GET`:`POST`),r={Accept:`application/json`,"X-Switchyard-Request":`1`,...t.headers},i;t.body!==void 0&&(r[`Content-Type`]=`application/json`,i=JSON.stringify(t.body));let a;try{a=await fetch(re(e,t.query),{method:n,headers:r,body:i,credentials:`include`,signal:t.signal})}catch(e){throw e instanceof DOMException&&e.name===`AbortError`?e:new d(`network`,`Could not reach the coordinator`,0)}let o=await a.text(),s;if(o)try{s=JSON.parse(o)}catch{s=void 0}if(!a.ok){let e=ie(s),t=e?new d(e.code,e.message,a.status,e.details):new d(a.status===401?`unauthorized`:`http`,`Request failed (${a.status}${a.statusText?` ${a.statusText}`:``})`,a.status);if(a.status===401)for(let e of p)e(t.code);throw t}return s}function ie(e){if(!e||typeof e!=`object`)return null;let t=e.error;if(!t||typeof t!=`object`)return null;let{code:n,message:r,details:i}=t;return typeof n==`string`?{code:n,message:typeof r==`string`?r:n,details:i}:null}var h=(e,t,n)=>m(e,{method:`GET`,query:t,signal:n}),ae=(e,t)=>m(e,{method:`POST`,body:t??{}}),oe=(e,t)=>m(e,{method:`PATCH`,body:t}),se=(e,t)=>m(e,{method:`DELETE`,body:t}),ce=new Set([`starting`,`running`,`waiting_input`]);function g(e,t,n){return`${e}:${t}:${n}`}function _(e){return e.node!==null||e.webRenderer}function le(){return{seq:null,hosts:{},projects:{},checkouts:{},workspaces:{},profiles:{},sessions:{},tasks:{},runs:{},automations:{},attention:{},interactions:{},panels:{},devices:{},adapters:{},occurrences:{},diagnostics:[],dispatchPaused:!1}}function ue(){return{...le(),transcripts:{},streaming:{}}}function v(){return{items:[],loaded:!1,loading:!1,hasMore:!1,stale:!1,error:null}}function y(e){let t={};for(let n of e)t[n.id]=n;return t}function b(e,t,n){return{...e,[t]:n}}function x(e,t){if(!(t in e))return e;let n={...e};return delete n[t],n}function S(e,t,n){let r={};for(let e of n.panels)_(e)&&(r[g(e.sessionId,e.adapterId,e.slot)]=e);let i={};for(let[t,n]of Object.entries(e.transcripts))i[t]={...n,stale:!0};return{...e,seq:t,hosts:y(n.hosts),projects:y(n.projects),checkouts:y(n.checkouts),workspaces:y(n.workspaces),profiles:y(n.profiles),sessions:y(n.sessions),tasks:y(n.tasks),runs:y(n.runs),automations:y(n.automations),attention:y(n.attention.filter(e=>e.resolvedAt===null)),interactions:y(n.interactions),panels:r,devices:y(n.devices),adapters:{...n.adapters},dispatchPaused:n.dispatchPaused,transcripts:i,streaming:{}}}function de(e){return{hosts:Object.values(e.hosts),projects:Object.values(e.projects),checkouts:Object.values(e.checkouts),workspaces:Object.values(e.workspaces),profiles:Object.values(e.profiles),sessions:Object.values(e.sessions),tasks:Object.values(e.tasks),runs:Object.values(e.runs),automations:Object.values(e.automations),attention:Object.values(e.attention),interactions:Object.values(e.interactions),panels:Object.values(e.panels),devices:Object.values(e.devices),adapters:e.adapters,dispatchPaused:e.dispatchPaused}}function C(e,t){if(t.length===0)return e;let n=new Map;for(let t of e)n.set(t.id,t);for(let e of t)n.set(e.id,e);return[...n.values()].sort((e,t)=>e.order-t.order||e.id.localeCompare(t.id))}function w(e,t,n,r){let i=e.transcripts[t]??v(),a=!r.older&&i.stale?[]:i.items,o={...i,items:C(a,n),loaded:!0,loading:!1,stale:r.older?i.stale:!1,error:null,hasMore:r.older||!i.loaded||i.stale?r.hasMore:i.hasMore};return{...e,transcripts:{...e.transcripts,[t]:o}}}function fe(e,t){let n=e.transcripts[t.sessionId]??v(),r={...e.transcripts,[t.sessionId]:{...n,items:C(n.items,[t])}},i=x(e.streaming,t.id);return{...e,transcripts:r,streaming:i}}function T(e,t){return e.seq!==null&&t.seq<=e.seq?e:{...me(e,t.type,t.data),seq:t.seq}}function pe(e,t){let n=e;for(let e of[...t].sort((e,t)=>e.seq-t.seq))n=T(n,e);return n}function me(e,t,n){switch(t){case`host.updated`:{let t=n;return{...e,hosts:b(e.hosts,t.id,t)}}case`project.updated`:{let t=n;return{...e,projects:b(e.projects,t.id,t)}}case`project.deleted`:{let t=n;return{...e,projects:x(e.projects,t.id)}}case`checkout.updated`:{let t=n;return{...e,checkouts:b(e.checkouts,t.id,t)}}case`workspace.updated`:{let t=n;return{...e,workspaces:t.archivedAt?x(e.workspaces,t.id):b(e.workspaces,t.id,t)}}case`workspace.removed`:{let t=n;return{...e,workspaces:x(e.workspaces,t.id)}}case`profile.updated`:{let t=n;return{...e,profiles:b(e.profiles,t.id,t)}}case`session.updated`:{let t=n,r={...e,sessions:b(e.sessions,t.id,t)};return ce.has(t.runtime)?r:ge(r,t.id)}case`transcript.item`:return fe(e,n);case`interaction.updated`:{let t=n,r=e.interactions[t.id];return r&&r.revision>t.revision?e:{...e,interactions:b(e.interactions,t.id,t)}}case`panel.updated`:{let t=n,r=g(t.sessionId,t.adapterId,t.slot);return{...e,panels:_(t)?b(e.panels,r,t):x(e.panels,r)}}case`adapters.updated`:{let t=n;return{...e,adapters:{...e.adapters,[t.hostId]:t.adapters}}}case`diagnostic`:{let t=n;return{...e,diagnostics:[...e.diagnostics,t].slice(-100)}}case`task.updated`:{let t=n;return{...e,tasks:b(e.tasks,t.id,t)}}case`task.deleted`:{let t=n;return{...e,tasks:x(e.tasks,t.id)}}case`run.updated`:{let t=n;return{...e,runs:b(e.runs,t.id,t)}}case`automation.updated`:{let t=n;return{...e,automations:b(e.automations,t.id,t)}}case`automation.deleted`:{let t=n,r={...e.occurrences};return delete r[t.id],{...e,automations:x(e.automations,t.id),occurrences:r}}case`occurrence.created`:{let t=n,r=(e.occurrences[t.automationId]??[]).filter(e=>e.id!==t.id);return{...e,occurrences:{...e.occurrences,[t.automationId]:[t,...r].slice(0,50)}}}case`attention.updated`:{let t=n;return{...e,attention:t.resolvedAt?x(e.attention,t.id):b(e.attention,t.id,t)}}case`device.updated`:{let t=n;return{...e,devices:t.revokedAt?x(e.devices,t.id):b(e.devices,t.id,t)}}case`settings.updated`:{let t=n;return{...e,dispatchPaused:t.dispatchPaused}}default:return e}}function he(e,t){let n=e.streaming[t.itemId]??{sessionId:t.sessionId,itemId:t.itemId,order:t.order??null,text:``,thinking:``,toolArgs:``,toolOutput:``},r=t.kind===`text`?`text`:t.kind===`thinking`?`thinking`:t.kind===`tool_args`?`toolArgs`:`toolOutput`,i={...n,order:n.order??t.order??null,[r]:n[r]+t.delta};return{...e,streaming:{...e.streaming,[t.itemId]:i}}}function ge(e,t){let n={},r=!1;for(let[i,a]of Object.entries(e.streaming))a.sessionId===t?r=!0:n[i]=a;return r?{...e,streaming:n}:e}function E(e,t){let n=Array.isArray(e)?e:e.items??[];return{items:n,hasMore:(Array.isArray(e)?void 0:e.hasMore)??n.length>=t}}var D=new Map,O=u()((e,t)=>({...ue(),hydrated:!1,synced:!1,connection:{state:`connecting`,lastSyncedAt:null,attempts:0},hydrateFromCache(n,r,i){t().synced||e(e=>({...S(e,n,r),hydrated:!0,connection:{...e.connection,lastSyncedAt:e.connection.lastSyncedAt??i}}))},applySnapshot(t,n){e(e=>({...S(e,t,n),hydrated:!0,synced:!0,connection:{...e.connection,lastSyncedAt:new Date().toISOString()}}))},applyReplay(t,n){e(e=>{let r=pe(e,n);return{...r,seq:Math.max(r.seq??0,t),hydrated:!0,synced:!0,connection:{...e.connection,lastSyncedAt:new Date().toISOString()}}})},applyEvent(t){e(e=>({...T(e,t),connection:{...e.connection,lastSyncedAt:new Date().toISOString()}}))},applyStream(t){e(e=>he(e,t))},setConnection(t){e(e=>({connection:{...e.connection,...t}}))},upsertInteraction(t){e(e=>{let n=e.interactions[t.id];return n&&n.revision>t.revision?{}:{interactions:{...e.interactions,[t.id]:t}}})},upsertSessionIfMissing(t){e(e=>e.sessions[t.id]?{}:{sessions:{...e.sessions,[t.id]:t}})},loadTranscript(n,r){let i=t().transcripts[n];if(i?.loaded&&!i.stale&&!r?.force)return Promise.resolve();let a=`${n}:newest`,o=D.get(a);if(o)return o;k(e,n,{loading:!0,error:null});let s=h(`/api/sessions/${encodeURIComponent(n)}/transcript`,{limit:200}).then(t=>{let r=E(t,200);e(e=>w(e,n,r.items,{hasMore:r.hasMore??!1,older:!1}))}).catch(t=>k(e,n,{loading:!1,error:f(t)})).finally(()=>D.delete(a));return D.set(a,s),s},loadOlderTranscript(n){let r=t().transcripts[n];if(!r?.loaded||!r.hasMore||r.items.length===0)return Promise.resolve();let i=r.items[0].order,a=`${n}:before:${i}`,o=D.get(a);if(o)return o;k(e,n,{loading:!0,error:null});let s=h(`/api/sessions/${encodeURIComponent(n)}/transcript`,{before:i,limit:200}).then(t=>{let r=E(t,200);e(e=>w(e,n,r.items,{hasMore:r.hasMore??!1,older:!0}))}).catch(t=>k(e,n,{loading:!1,error:f(t)})).finally(()=>D.delete(a));return D.set(a,s),s},reset(){e({...ue(),hydrated:!1,synced:!1,connection:{state:`connecting`,lastSyncedAt:null,attempts:0}})}}));function k(e,t,n){e(e=>({transcripts:{...e.transcripts,[t]:{...e.transcripts[t]??v(),...n}}}))}var _e=O;function ve(e){return Object.values(e).filter(e=>e.resolvedAt===null).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}function ye(e){let t=0;for(let n of Object.values(e))!n.resolvedAt&&!n.acknowledgedAt&&t++;return t}function be(e,t){return Object.values(e).filter(e=>e.sessionId===t&&e.state===`pending`).sort((e,t)=>e.createdAt.localeCompare(t.createdAt))}function A(e,t){return Object.values(e).filter(e=>e.taskId===t).sort((e,t)=>t.attempt-e.attempt||t.createdAt.localeCompare(e.createdAt))}function xe(e,t){return Object.values(e).filter(e=>e.sessionId===t).sort((e,t)=>e.adapterId.localeCompare(t.adapterId)||e.slot.localeCompare(t.slot))}function Se(e,t){return Object.values(e).filter(e=>e.sessionId===t)}var Ce=()=>O(e=>e.connection),we=e=>O(t=>e?t.sessions[e]:void 0),Te=e=>O(t=>e?t.tasks[e]:void 0);function Ee(){let e=O(e=>e.projects);return(0,a.useMemo)(()=>Object.values(e).sort((e,t)=>e.name.localeCompare(t.name)),[e])}function De(){let e=O(e=>e.hosts);return(0,a.useMemo)(()=>Object.values(e).filter(e=>e.revokedAt===null).sort((e,t)=>e.name.localeCompare(t.name)),[e])}function Oe(){let e=O(e=>e.attention);return(0,a.useMemo)(()=>ve(e),[e])}function ke(){return O(e=>ye(e.attention))}function Ae(e){let t=O(e=>e.interactions);return(0,a.useMemo)(()=>e?be(t,e):[],[t,e])}function je(e){let t=O(e=>e.runs);return(0,a.useMemo)(()=>e?A(t,e):[],[t,e])}function Me(e){let t=O(e=>e.panels);return(0,a.useMemo)(()=>e?xe(t,e):[],[t,e])}function Ne(e){let t=O(e=>e.streaming);return(0,a.useMemo)(()=>e?Se(t,e):[],[t,e])}var Pe=v();function Fe(e){let t=O(t=>e?t.transcripts[e]:void 0),n=O(e=>e.loadTranscript),r=!!e&&(!t||(!t.loaded||t.stale)&&!t.loading&&!t.error);return(0,a.useEffect)(()=>{r&&e&&n(e)},[r,e,n]),t??Pe}var j={name:`circle-alert`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]],aliases:[`alert-circle`]};j.node;var M=r(j),N={name:`inbox`,size:24,node:[[`polyline`,{points:`22 12 16 12 14 15 10 15 8 12 2 12`,key:`o97t9d`}],[`path`,{d:`M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`oot6mr`}]]};N.node;var P=r(N),F={name:`message-circle-question-mark`,size:24,node:[[`path`,{d:`M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719`,key:`1sd12s`}],[`path`,{d:`M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3`,key:`1u773s`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]],aliases:[`message-circle-question`]};F.node;var I=r(F),L={name:`puzzle`,size:24,node:[[`path`,{d:`M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z`,key:`w46dr5`}]]};L.node;var R=r(L),z={name:`refresh-cw`,size:24,node:[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]};z.node;var B=r(z),V={name:`server-off`,size:24,node:[[`path`,{d:`M7 2h13a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-5`,key:`bt2siv`}],[`path`,{d:`M10 10 2.5 2.5C2 2 2 2.5 2 5v3a2 2 0 0 0 2 2h6z`,key:`1hjrv1`}],[`path`,{d:`M22 17v-1a2 2 0 0 0-2-2h-1`,key:`1iynyr`}],[`path`,{d:`M4 14a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16.5l1-.5.5.5-8-8H4z`,key:`161ggg`}],[`path`,{d:`M6 18h.01`,key:`uhywen`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]};V.node;var H=r(V),U={name:`triangle-alert`,size:24,node:[[`path`,{d:`m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3`,key:`wmoenq`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]],aliases:[`alert-triangle`]};U.node;var W=r(U);function G(...e){return e.filter(Boolean).join(` `)}var K=typeof Intl<`u`&&`RelativeTimeFormat`in Intl?new Intl.RelativeTimeFormat(void 0,{numeric:`auto`}):null;function q(e,t=Date.now()){if(!e)return`never`;let n=Date.parse(e);if(Number.isNaN(n))return e;let r=Math.round((n-t)/1e3),i=Math.abs(r);return i<30?`just now`:K?i<3600?K.format(Math.round(r/60),`minute`):i<86400?K.format(Math.round(r/3600),`hour`):i<2592e3?K.format(Math.round(r/86400),`day`):new Date(n).toLocaleDateString():new Date(n).toLocaleString()}function J(e){if(e==null)return`unknown`;let t=new Date(e);return Number.isNaN(t.getTime())?String(e):t.toDateString()===new Date().toDateString()?t.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`}):t.toLocaleString(void 0,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`})}function Ie(e){if(e==null||Number.isNaN(e))return``;if(e<1e3)return`${Math.round(e)} ms`;let t=Math.round(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m ${String(t%60).padStart(2,`0`)}s`:`${Math.floor(n/60)}h ${String(n%60).padStart(2,`0`)}m`}var Y=i();function X({className:e,label:t}){return(0,Y.jsxs)(`svg`,{className:G(`size-4 shrink-0 animate-spin`,e),viewBox:`0 0 24 24`,fill:`none`,role:t?`img`:void 0,"aria-label":t,"aria-hidden":!t||void 0,children:[(0,Y.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`,stroke:`currentColor`,strokeOpacity:`0.25`,strokeWidth:`3`}),(0,Y.jsx)(`path`,{d:`M21 12a9 9 0 0 0-9-9`,stroke:`currentColor`,strokeWidth:`3`,strokeLinecap:`round`})]})}var Le={primary:`bg-accent text-accent-fg border-accent hover:bg-accent-hover hover:border-accent-hover`,secondary:`bg-surface text-text border-border hover:bg-surface-2`,ghost:`bg-transparent text-text border-transparent hover:bg-surface-2`,danger:`bg-danger text-danger-fg border-danger hover:bg-danger-hover hover:border-danger-hover`},Re={sm:`h-8 px-2.5 text-sm gap-1.5`,md:`h-9 px-3.5 text-sm gap-2`};function Z(e=`secondary`,t=`md`,n){return G(`tap inline-flex items-center justify-center rounded-md border font-medium whitespace-nowrap select-none`,`transition-colors disabled:opacity-55 disabled:pointer-events-none`,Le[e],Re[t],n)}var Q=(0,a.forwardRef)(function({variant:e=`secondary`,size:t=`md`,icon:n,busy:r,block:i,className:a,children:o,disabled:s,type:c,...ee},l){return(0,Y.jsxs)(`button`,{ref:l,type:c??`button`,disabled:s||r,"aria-busy":r||void 0,className:Z(e,t,G(i&&`w-full`,a)),...ee,children:[r?(0,Y.jsx)(X,{}):n,o]})});function ze({action:e,primary:n=!0}){return`to`in e?(0,Y.jsxs)(t,{to:e.to,className:Z(n?`primary`:`secondary`),children:[e.icon,e.label]}):(0,Y.jsx)(Q,{variant:n?`primary`:`secondary`,icon:e.icon,onClick:e.onClick,children:e.label})}function $({icon:e,title:t,children:n,actions:r,className:i,role:a}){return(0,Y.jsxs)(`div`,{role:a,className:G(`mx-auto flex w-full max-w-md flex-col items-center gap-3 px-4 py-10 text-center`,i),children:[(0,Y.jsx)(`div`,{className:`text-muted`,"aria-hidden":!0,children:e}),(0,Y.jsx)(`h2`,{className:`text-base font-semibold`,children:t}),n&&(0,Y.jsx)(`div`,{className:`text-sm text-muted`,children:n}),r&&(0,Y.jsx)(`div`,{className:`flex flex-wrap justify-center gap-2`,children:r})]})}function Be({label:e=`Loading…`,className:t}){return(0,Y.jsxs)(`div`,{role:`status`,"aria-live":`polite`,className:G(`flex items-center justify-center gap-2 px-4 py-10 text-sm text-muted`,t),children:[(0,Y.jsx)(X,{}),(0,Y.jsx)(`span`,{children:e})]})}function Ve({title:e,description:t,action:n,secondaryAction:r,icon:i,className:a}){return(0,Y.jsx)($,{icon:i??(0,Y.jsx)(P,{className:`size-8`}),title:e,className:a,actions:(n||r)&&(0,Y.jsxs)(Y.Fragment,{children:[n&&(0,Y.jsx)(ze,{action:n}),r&&(0,Y.jsx)(ze,{action:r,primary:!1})]}),children:t})}function He({state:e,lastSyncedAt:t,onRetry:n,className:r}){if(e===`live`||e===`connecting`&&!t)return null;let i=e===`offline`,a=t?J(t):`an earlier session`;return(0,Y.jsxs)(`div`,{role:`status`,"aria-live":`polite`,className:G(`flex items-center gap-2 border-b border-border bg-warning-soft px-3 py-1.5 text-sm text-text`,r),children:[i?(0,Y.jsx)(H,{"aria-hidden":!0,className:`size-4 shrink-0 text-warning`}):(0,Y.jsx)(X,{className:`size-4 text-warning`}),(0,Y.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[i?`Offline`:`Reconnecting…`,` showing last known data from`,` `,(0,Y.jsx)(`time`,{dateTime:t??void 0,children:a})]}),n&&(0,Y.jsx)(`button`,{type:`button`,onClick:n,className:`tap shrink-0 rounded px-2 py-0.5 font-medium text-accent hover:bg-surface-2`,children:`Retry now`})]})}function Ue({hostName:e,connectivity:t=`unreachable`,lastSeenAt:n,detail:r,compact:i,className:a}){let o=t===`reconnecting`?`Host ${e} is reconnecting`:`Host ${e} is unreachable`,s=(0,Y.jsxs)(Y.Fragment,{children:[n?`Last seen ${q(n)}. `:``,r??`Work on this host keeps its last known state; nothing is restarted elsewhere.`]});return i?(0,Y.jsxs)(`div`,{role:`status`,className:G(`flex items-start gap-2 rounded-md border border-border bg-danger-soft px-3 py-2 text-sm`,a),children:[(0,Y.jsx)(H,{"aria-hidden":!0,className:`mt-0.5 size-4 shrink-0 text-danger`}),(0,Y.jsxs)(`div`,{className:`min-w-0`,children:[(0,Y.jsx)(`div`,{className:`font-medium`,children:o}),(0,Y.jsx)(`div`,{className:`text-muted`,children:s})]})]}):(0,Y.jsx)($,{role:`status`,icon:(0,Y.jsx)(H,{className:`size-8`}),title:o,className:a,children:s})}function We({count:e,to:n,onOpen:r,label:i,className:a}){if(e<=0)return null;let o=i??(e===1?`Needs your answer`:`${e} questions need your answer`),s=(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(I,{"aria-hidden":!0,className:`size-4 shrink-0 text-warning`}),(0,Y.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-medium`,children:o}),(0,Y.jsx)(`span`,{className:`shrink-0 text-accent`,children:`Answer`})]}),c=G(`tap flex w-full items-center gap-2 border border-border bg-warning-soft px-3 py-2 text-left text-sm rounded-md`,a);return n?(0,Y.jsx)(t,{to:n,className:c,role:`status`,children:s}):(0,Y.jsx)(`button`,{type:`button`,onClick:r,className:c,children:s})}function Ge({capability:e,reason:t,fallback:n,className:r}){return(0,Y.jsxs)(`div`,{role:`note`,className:G(`flex items-start gap-2 rounded-md border border-border bg-surface-2 px-3 py-2 text-sm`,r),children:[(0,Y.jsx)(R,{"aria-hidden":!0,className:`mt-0.5 size-4 shrink-0 text-muted`}),(0,Y.jsxs)(`div`,{className:`min-w-0`,children:[(0,Y.jsxs)(`div`,{className:`font-medium`,children:[e,` is not available here`]}),(0,Y.jsx)(`div`,{className:`text-muted`,children:t}),n&&(0,Y.jsx)(`div`,{className:`mt-1`,children:n})]})]})}function Ke({title:e=`Something went wrong`,error:t,onRetry:n,compact:r,className:i}){let a=t instanceof Error?t.message:String(t??``);return r?(0,Y.jsxs)(`div`,{role:`alert`,className:G(`flex items-start gap-2 rounded-md border border-border bg-danger-soft px-3 py-2 text-sm`,i),children:[(0,Y.jsx)(W,{"aria-hidden":!0,className:`mt-0.5 size-4 shrink-0 text-danger`}),(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Y.jsx)(`div`,{className:`font-medium`,children:e}),a&&(0,Y.jsx)(`div`,{className:`break-words text-muted`,children:a})]}),n&&(0,Y.jsx)(Q,{size:`sm`,onClick:n,icon:(0,Y.jsx)(B,{className:`size-3.5`}),children:`Retry`})]}):(0,Y.jsx)($,{role:`alert`,icon:(0,Y.jsx)(W,{className:`size-8 text-danger`}),title:e,className:i,actions:n&&(0,Y.jsx)(Q,{variant:`primary`,onClick:n,icon:(0,Y.jsx)(B,{className:`size-4`}),children:`Retry`}),children:(0,Y.jsx)(`span`,{className:`break-words`,children:a})})}function qe({title:e=`Switchyard cannot show this view`,error:t,diagnosticsHref:n=`/settings/diagnostics`,className:r}){let i=t instanceof Error?t.message:String(t??``);return(0,Y.jsx)($,{role:`alert`,icon:(0,Y.jsx)(M,{className:`size-8 text-danger`}),title:e,className:r,actions:(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`a`,{href:n,className:Z(`primary`),children:`Open diagnostics`}),(0,Y.jsx)(Q,{onClick:()=>location.reload(),children:`Reload`})]}),children:(0,Y.jsx)(`span`,{className:`break-words`,children:i})})}export{Ee as A,se as B,_e as C,Oe as D,De as E,Te as F,te as G,oe as H,Fe as I,ne as K,de as L,we as M,Ne as N,Me as O,O as P,d as R,A as S,Ce as T,ae as U,h as V,f as W,B as _,We as a,P as b,Ge as c,X as d,Ie as f,W as g,G as h,Ue as i,je as j,Ae as k,Q as l,J as m,Ke as n,Be as o,q as p,u as q,qe as r,He as s,Ve as t,Z as u,R as v,ke as w,M as x,I as y,m as z};
2
- //# sourceMappingURL=states--geW2Ntl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"states--geW2Ntl.js","names":["useMemo","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","forwardRef","_Fragment","MessageCircleQuestion","__toESM","Link","require_react","createLucideIcon","require_jsx_runtime","import_react","createStoreImpl","state","listeners","setState","nextState","partial","previousState","replace","listener","getState","api","initialState","createState","createStore","identity","arg","useStore","slice","selector","createImpl","useBoundStore","create","ApiClientError","message","code","status","details","isApiError","errorMessage","unauthorizedListeners","onUnauthorized","fn","buildUrl","query","path","params","k","v","qs","method","opts","headers","body","res","text","json","err","parseErrorBody","e","apiGet","apiPost","apiPatch","apiDelete","LIVE_RUNTIMES","panelKey","sessionId","adapterId","slot","keepPanel","p","emptyEntities","emptySyncData","emptyTranscript","byId","out","x","list","put","map","id","value","drop","next","applySnapshot","panels","snap","transcripts","t","a","toSyncState","mergeTranscriptItems","incoming","existing","it","b","applyTranscriptPage","prev","base","items","upsertTranscriptItem","item","streaming","applyEvent","event","reduceEvent","applyEvents","s","events","type","d","data","clearSessionStreams","key","occurrences","o","applyStream","delta","field","changed","normalizePage","limit","inflight","useSyncStore","get","set","seq","savedAt","patch","interaction","session","setTranscript","page","before","syncStore","sortAttention","attention","countAttention","n","pendingInteractionsFor","interactions","i","runsForTask","runs","r","taskId","panelsForSession","streamsForSession","useConnection","useSession","useTask","useProjects","projects","useHosts","hosts","h","useOpenAttention","useAttentionCount","usePendingInteractions","useRunsForTask","usePanels","useStreams","EMPTY_TRANSCRIPT","useTranscript","load","needsLoad","__iconData$6","CircleAlert","__iconData$5","Inbox","__iconData$4","MessageCircleQuestionMark","__iconData$3","Puzzle","__iconData$2","RefreshCw","__iconData$1","ServerOff","__iconData","TriangleAlert","cn","parts","rtf","formatRelative","iso","diff","now","abs","formatTime","formatDuration","ms","m","import_jsx_runtime","Spinner","className","label","VARIANTS","SIZES","buttonClasses","variant","size","extra","Button","rest","disabled","busy","block","icon","children","ActionButton","action","primary","Panel","title","actions","LoadingState","EmptyState","secondaryAction","description","ReconnectingBanner","lastSyncedAt","offline","when","onRetry","HostUnavailable","connectivity","hostName","lastSeenAt","detail","compact","InteractionPending","count","inner","cls","to","onOpen","UnsupportedCapability","capability","reason","fallback","ErrorState","error","FatalError","diagnosticsHref"],"sources":["../../../../node_modules/.pnpm/zustand@5.0.16_@types+react@19.3.0_react@19.3.1/node_modules/zustand/esm/vanilla.mjs","../../../../node_modules/.pnpm/zustand@5.0.16_@types+react@19.3.0_react@19.3.1/node_modules/zustand/esm/react.mjs","../../src/sync/api.ts","../../src/sync/reduce.ts","../../src/sync/store.ts","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/circle-alert.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/inbox.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/message-circle-question-mark.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/puzzle.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/refresh-cw.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/server-off.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/triangle-alert.mjs","../../src/lib/cn.ts","../../src/lib/time.ts","../../src/components/ui/Spinner.tsx","../../src/components/ui/Button.tsx","../../src/components/ui/states.tsx"],"sourcesContent":["const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n","import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n () => selector(api.getInitialState())\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n","import type { ErrorCode } from \"@switchyard/protocol\";\n\n/** Client-side error codes in addition to the protocol's shared codes. */\nexport type ApiClientErrorCode = ErrorCode | \"network\" | \"http\";\n\n/** Every failed REST call rejects with this. `code` is the protocol `ApiError` code. */\nexport class ApiClientError extends Error {\n readonly code: ApiClientErrorCode;\n readonly status: number;\n readonly details?: unknown;\n constructor(code: ApiClientErrorCode, message: string, status: number, details?: unknown) {\n super(message);\n this.name = \"ApiClientError\";\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport function isApiError(e: unknown, code?: ApiClientErrorCode): e is ApiClientError {\n return e instanceof ApiClientError && (code === undefined || e.code === code);\n}\n\n/** Human-readable message for any thrown value. */\nexport function errorMessage(e: unknown): string {\n if (e instanceof Error) return e.message;\n return String(e);\n}\n\ntype Query = Record<string, string | number | boolean | null | undefined>;\n\nexport interface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n body?: unknown;\n query?: Query;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\ntype UnauthorizedListener = (code: ApiClientErrorCode) => void;\nconst unauthorizedListeners = new Set<UnauthorizedListener>();\n\n/** Called when any request comes back 401 (the auth gate redirects to /sign-in). */\nexport function onUnauthorized(fn: UnauthorizedListener): () => void {\n unauthorizedListeners.add(fn);\n return () => unauthorizedListeners.delete(fn);\n}\n\nexport function buildUrl(path: string, query?: Query): string {\n if (!query) return path;\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(query)) {\n if (v === undefined || v === null) continue;\n params.set(k, String(v));\n }\n const qs = params.toString();\n return qs ? `${path}${path.includes(\"?\") ? \"&\" : \"?\"}${qs}` : path;\n}\n\n/**\n * fetch wrapper for the coordinator REST API. Sends cookies, the CSRF header\n * `X-Switchyard-Request: 1`, and JSON bodies; maps `ApiError` bodies to\n * `ApiClientError`.\n */\nexport async function api<T = unknown>(path: string, opts: RequestOptions = {}): Promise<T> {\n const method = opts.method ?? (opts.body === undefined ? \"GET\" : \"POST\");\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n \"X-Switchyard-Request\": \"1\",\n ...opts.headers,\n };\n let body: string | undefined;\n if (opts.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n body = JSON.stringify(opts.body);\n }\n let res: Response;\n try {\n res = await fetch(buildUrl(path, opts.query), {\n method,\n headers,\n body,\n credentials: \"include\",\n signal: opts.signal,\n });\n } catch (e) {\n if (e instanceof DOMException && e.name === \"AbortError\") throw e;\n throw new ApiClientError(\"network\", \"Could not reach the coordinator\", 0);\n }\n const text = await res.text();\n let json: unknown;\n if (text) {\n try {\n json = JSON.parse(text);\n } catch {\n json = undefined;\n }\n }\n if (!res.ok) {\n const err = parseErrorBody(json);\n const e = err\n ? new ApiClientError(err.code, err.message, res.status, err.details)\n : new ApiClientError(\n res.status === 401 ? \"unauthorized\" : \"http\",\n `Request failed (${res.status}${res.statusText ? ` ${res.statusText}` : \"\"})`,\n res.status,\n );\n if (res.status === 401) for (const fn of unauthorizedListeners) fn(e.code);\n throw e;\n }\n return json as T;\n}\n\nfunction parseErrorBody(\n json: unknown,\n): { code: ErrorCode; message: string; details?: unknown } | null {\n if (!json || typeof json !== \"object\") return null;\n const err = (json as { error?: unknown }).error;\n if (!err || typeof err !== \"object\") return null;\n const { code, message, details } = err as {\n code?: unknown;\n message?: unknown;\n details?: unknown;\n };\n if (typeof code !== \"string\") return null;\n return {\n code: code as ErrorCode,\n message: typeof message === \"string\" ? message : code,\n details,\n };\n}\n\nexport const apiGet = <T>(path: string, query?: Query, signal?: AbortSignal) =>\n api<T>(path, { method: \"GET\", query, signal });\nexport const apiPost = <T>(path: string, body?: unknown) =>\n api<T>(path, { method: \"POST\", body: body ?? {} });\nexport const apiPatch = <T>(path: string, body: unknown) => api<T>(path, { method: \"PATCH\", body });\nexport const apiPut = <T>(path: string, body: unknown) => api<T>(path, { method: \"PUT\", body });\nexport const apiDelete = <T>(path: string, body?: unknown) =>\n api<T>(path, { method: \"DELETE\", body });\n","import type {\n AdapterInfo,\n AttentionItem,\n Automation,\n Checkout,\n Device,\n Diagnostic,\n EventData,\n EventEnvelope,\n EventType,\n Host,\n Interaction,\n Occurrence,\n Panel,\n Profile,\n Project,\n Run,\n Session,\n StreamDelta,\n SyncState,\n Task,\n TranscriptItem,\n Workspace,\n} from \"@switchyard/protocol\";\n\n/**\n * Pure reducers for the normalized client state. The zustand store in\n * `store.ts` wraps these; tests exercise them directly.\n */\n\nexport type ById<T> = Record<string, T>;\n\nexport interface EntityState {\n /** Last applied durable event seq (the WS cursor), null before any sync. */\n seq: number | null;\n hosts: ById<Host>;\n projects: ById<Project>;\n checkouts: ById<Checkout>;\n workspaces: ById<Workspace>;\n profiles: ById<Profile>;\n sessions: ById<Session>;\n tasks: ById<Task>;\n runs: ById<Run>;\n automations: ById<Automation>;\n /** Open (unresolved) attention items. Resolved items are dropped. */\n attention: ById<AttentionItem>;\n /** Interactions of any state, so resolution summaries stay visible inline. */\n interactions: ById<Interaction>;\n /** Keyed by `panelKey(sessionId, adapterId, slot)`. */\n panels: ById<Panel>;\n devices: ById<Device>;\n /** Adapters per host id. */\n adapters: Record<string, AdapterInfo[]>;\n /** Occurrences seen live (newest first) per automation id; history loads over REST. */\n occurrences: Record<string, Occurrence[]>;\n /** The latest diagnostics, newest last, bounded. */\n diagnostics: Diagnostic[];\n dispatchPaused: boolean;\n}\n\nexport interface TranscriptState {\n /** Items sorted by `order` ascending, unique by id. */\n items: TranscriptItem[];\n /** True once the newest page has been fetched over REST. */\n loaded: boolean;\n loading: boolean;\n /** Whether older items exist before `items[0]`. */\n hasMore: boolean;\n /** Set after a snapshot resync; the next view reloads the newest page. */\n stale: boolean;\n error: string | null;\n}\n\nexport interface StreamBuffer {\n sessionId: string;\n itemId: string;\n order: number | null;\n text: string;\n thinking: string;\n toolArgs: string;\n toolOutput: string;\n}\n\nexport interface SyncData extends EntityState {\n transcripts: Record<string, TranscriptState>;\n /** Ephemeral stream deltas keyed by item id, appended to the durable item text. */\n streaming: Record<string, StreamBuffer>;\n}\n\nexport const MAX_DIAGNOSTICS = 100;\nconst LIVE_RUNTIMES = new Set<string>([\"starting\", \"running\", \"waiting_input\"]);\nexport const MAX_OCCURRENCES_PER_AUTOMATION = 50;\n\nexport function panelKey(sessionId: string, adapterId: string, slot: string): string {\n return `${sessionId}:${adapterId}:${slot}`;\n}\n\n/** A panel with no node and no web renderer has been removed by its adapter. */\nfunction keepPanel(p: Panel): boolean {\n return p.node !== null || p.webRenderer;\n}\n\nexport function emptyEntities(): EntityState {\n return {\n seq: null,\n hosts: {},\n projects: {},\n checkouts: {},\n workspaces: {},\n profiles: {},\n sessions: {},\n tasks: {},\n runs: {},\n automations: {},\n attention: {},\n interactions: {},\n panels: {},\n devices: {},\n adapters: {},\n occurrences: {},\n diagnostics: [],\n dispatchPaused: false,\n };\n}\n\nexport function emptySyncData(): SyncData {\n return { ...emptyEntities(), transcripts: {}, streaming: {} };\n}\n\nexport function emptyTranscript(): TranscriptState {\n return { items: [], loaded: false, loading: false, hasMore: false, stale: false, error: null };\n}\n\nfunction byId<T extends { id: string }>(list: T[]): ById<T> {\n const out: ById<T> = {};\n for (const x of list) out[x.id] = x;\n return out;\n}\n\nfunction put<T>(map: ById<T>, id: string, value: T): ById<T> {\n return { ...map, [id]: value };\n}\n\nfunction drop<T>(map: ById<T>, id: string): ById<T> {\n if (!(id in map)) return map;\n const next = { ...map };\n delete next[id];\n return next;\n}\n\n/** Replace every entity with a server snapshot. Loaded transcripts are kept but marked stale. */\nexport function applySnapshot<S extends SyncData>(state: S, seq: number, snap: SyncState): S {\n const panels: ById<Panel> = {};\n for (const p of snap.panels)\n if (keepPanel(p)) panels[panelKey(p.sessionId, p.adapterId, p.slot)] = p;\n const transcripts: Record<string, TranscriptState> = {};\n for (const [id, t] of Object.entries(state.transcripts)) transcripts[id] = { ...t, stale: true };\n return {\n ...state,\n seq,\n hosts: byId(snap.hosts),\n projects: byId(snap.projects),\n checkouts: byId(snap.checkouts),\n workspaces: byId(snap.workspaces),\n profiles: byId(snap.profiles),\n sessions: byId(snap.sessions),\n tasks: byId(snap.tasks),\n runs: byId(snap.runs),\n automations: byId(snap.automations),\n attention: byId(snap.attention.filter((a) => a.resolvedAt === null)),\n interactions: byId(snap.interactions),\n panels,\n devices: byId(snap.devices),\n adapters: { ...snap.adapters },\n dispatchPaused: snap.dispatchPaused,\n transcripts,\n streaming: {},\n };\n}\n\n/** Rebuild a SyncState from the entities (used for the offline cache). */\nexport function toSyncState(state: EntityState): SyncState {\n return {\n hosts: Object.values(state.hosts),\n projects: Object.values(state.projects),\n checkouts: Object.values(state.checkouts),\n workspaces: Object.values(state.workspaces),\n profiles: Object.values(state.profiles),\n sessions: Object.values(state.sessions),\n tasks: Object.values(state.tasks),\n runs: Object.values(state.runs),\n automations: Object.values(state.automations),\n attention: Object.values(state.attention),\n interactions: Object.values(state.interactions),\n panels: Object.values(state.panels),\n devices: Object.values(state.devices),\n adapters: state.adapters,\n dispatchPaused: state.dispatchPaused,\n };\n}\n\n/** Insert or replace transcript items by id, keeping `order` ascending. */\nexport function mergeTranscriptItems(\n existing: TranscriptItem[],\n incoming: TranscriptItem[],\n): TranscriptItem[] {\n if (incoming.length === 0) return existing;\n const map = new Map<string, TranscriptItem>();\n for (const it of existing) map.set(it.id, it);\n for (const it of incoming) map.set(it.id, it);\n return [...map.values()].sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));\n}\n\n/** Merge a fetched page into a session transcript. `older` pages only set `hasMore`. */\nexport function applyTranscriptPage<S extends SyncData>(\n state: S,\n sessionId: string,\n items: TranscriptItem[],\n opts: { hasMore: boolean; older: boolean },\n): S {\n const prev = state.transcripts[sessionId] ?? emptyTranscript();\n // A fresh newest page after a resync replaces items, so nothing stale lingers.\n const base = !opts.older && prev.stale ? [] : prev.items;\n const next: TranscriptState = {\n ...prev,\n items: mergeTranscriptItems(base, items),\n loaded: true,\n loading: false,\n stale: opts.older ? prev.stale : false,\n error: null,\n hasMore: opts.older || !prev.loaded || prev.stale ? opts.hasMore : prev.hasMore,\n };\n return { ...state, transcripts: { ...state.transcripts, [sessionId]: next } };\n}\n\nfunction upsertTranscriptItem<S extends SyncData>(state: S, item: TranscriptItem): S {\n const prev = state.transcripts[item.sessionId] ?? emptyTranscript();\n const transcripts = {\n ...state.transcripts,\n [item.sessionId]: { ...prev, items: mergeTranscriptItems(prev.items, [item]) },\n };\n // The durable item is authoritative up to now: drop any buffered deltas for it.\n const streaming = drop(state.streaming, item.id);\n return { ...state, transcripts, streaming };\n}\n\n/**\n * Apply one durable event. Events at or below the current cursor are ignored\n * (replay and live delivery may overlap).\n */\nexport function applyEvent<S extends SyncData>(state: S, event: EventEnvelope): S {\n if (state.seq !== null && event.seq <= state.seq) return state;\n const next = reduceEvent(state, event.type, event.data as never);\n return { ...next, seq: event.seq };\n}\n\nexport function applyEvents<S extends SyncData>(state: S, events: EventEnvelope[]): S {\n let s = state;\n for (const e of [...events].sort((a, b) => a.seq - b.seq)) s = applyEvent(s, e);\n return s;\n}\n\nfunction reduceEvent<S extends SyncData, T extends EventType>(\n state: S,\n type: T,\n data: EventData<T>,\n): S {\n switch (type) {\n case \"host.updated\": {\n const d = data as EventData<\"host.updated\">;\n return { ...state, hosts: put(state.hosts, d.id, d) };\n }\n case \"project.updated\": {\n const d = data as EventData<\"project.updated\">;\n return { ...state, projects: put(state.projects, d.id, d) };\n }\n case \"project.deleted\": {\n const d = data as EventData<\"project.deleted\">;\n return { ...state, projects: drop(state.projects, d.id) };\n }\n case \"checkout.updated\": {\n const d = data as EventData<\"checkout.updated\">;\n return { ...state, checkouts: put(state.checkouts, d.id, d) };\n }\n case \"workspace.updated\": {\n const d = data as EventData<\"workspace.updated\">;\n return {\n ...state,\n workspaces: d.archivedAt ? drop(state.workspaces, d.id) : put(state.workspaces, d.id, d),\n };\n }\n case \"workspace.removed\": {\n const d = data as EventData<\"workspace.removed\">;\n return { ...state, workspaces: drop(state.workspaces, d.id) };\n }\n case \"profile.updated\": {\n const d = data as EventData<\"profile.updated\">;\n return { ...state, profiles: put(state.profiles, d.id, d) };\n }\n case \"session.updated\": {\n const d = data as EventData<\"session.updated\">;\n const next = { ...state, sessions: put(state.sessions, d.id, d) };\n return LIVE_RUNTIMES.has(d.runtime) ? next : clearSessionStreams(next, d.id);\n }\n case \"transcript.item\":\n return upsertTranscriptItem(state, data as EventData<\"transcript.item\">);\n case \"interaction.updated\": {\n const d = data as EventData<\"interaction.updated\">;\n const prev = state.interactions[d.id];\n if (prev && prev.revision > d.revision) return state;\n return { ...state, interactions: put(state.interactions, d.id, d) };\n }\n case \"panel.updated\": {\n const d = data as EventData<\"panel.updated\">;\n const key = panelKey(d.sessionId, d.adapterId, d.slot);\n return {\n ...state,\n panels: keepPanel(d) ? put(state.panels, key, d) : drop(state.panels, key),\n };\n }\n case \"adapters.updated\": {\n const d = data as EventData<\"adapters.updated\">;\n return { ...state, adapters: { ...state.adapters, [d.hostId]: d.adapters } };\n }\n case \"diagnostic\": {\n const d = data as EventData<\"diagnostic\">;\n return { ...state, diagnostics: [...state.diagnostics, d].slice(-MAX_DIAGNOSTICS) };\n }\n case \"task.updated\": {\n const d = data as EventData<\"task.updated\">;\n return { ...state, tasks: put(state.tasks, d.id, d) };\n }\n case \"task.deleted\": {\n const d = data as EventData<\"task.deleted\">;\n return { ...state, tasks: drop(state.tasks, d.id) };\n }\n case \"run.updated\": {\n const d = data as EventData<\"run.updated\">;\n return { ...state, runs: put(state.runs, d.id, d) };\n }\n case \"automation.updated\": {\n const d = data as EventData<\"automation.updated\">;\n return { ...state, automations: put(state.automations, d.id, d) };\n }\n case \"automation.deleted\": {\n const d = data as EventData<\"automation.deleted\">;\n const occurrences = { ...state.occurrences };\n delete occurrences[d.id];\n return { ...state, automations: drop(state.automations, d.id), occurrences };\n }\n case \"occurrence.created\": {\n const d = data as EventData<\"occurrence.created\">;\n const list = (state.occurrences[d.automationId] ?? []).filter((o) => o.id !== d.id);\n return {\n ...state,\n occurrences: {\n ...state.occurrences,\n [d.automationId]: [d, ...list].slice(0, MAX_OCCURRENCES_PER_AUTOMATION),\n },\n };\n }\n case \"attention.updated\": {\n const d = data as EventData<\"attention.updated\">;\n return {\n ...state,\n attention: d.resolvedAt ? drop(state.attention, d.id) : put(state.attention, d.id, d),\n };\n }\n case \"device.updated\": {\n const d = data as EventData<\"device.updated\">;\n return {\n ...state,\n devices: d.revokedAt ? drop(state.devices, d.id) : put(state.devices, d.id, d),\n };\n }\n case \"settings.updated\": {\n const d = data as EventData<\"settings.updated\">;\n return { ...state, dispatchPaused: d.dispatchPaused };\n }\n default:\n return state;\n }\n}\n\n/** Append an ephemeral stream delta to the per-item buffer. */\nexport function applyStream<S extends SyncData>(state: S, delta: StreamDelta): S {\n const prev: StreamBuffer = state.streaming[delta.itemId] ?? {\n sessionId: delta.sessionId,\n itemId: delta.itemId,\n order: delta.order ?? null,\n text: \"\",\n thinking: \"\",\n toolArgs: \"\",\n toolOutput: \"\",\n };\n const field =\n delta.kind === \"text\"\n ? \"text\"\n : delta.kind === \"thinking\"\n ? \"thinking\"\n : delta.kind === \"tool_args\"\n ? \"toolArgs\"\n : \"toolOutput\";\n const next: StreamBuffer = {\n ...prev,\n order: prev.order ?? delta.order ?? null,\n [field]: prev[field] + delta.delta,\n };\n return { ...state, streaming: { ...state.streaming, [delta.itemId]: next } };\n}\n\n/** Drop all stream buffers of a session (for example when it settles). */\nexport function clearSessionStreams<S extends SyncData>(state: S, sessionId: string): S {\n const streaming: Record<string, StreamBuffer> = {};\n let changed = false;\n for (const [id, b] of Object.entries(state.streaming)) {\n if (b.sessionId === sessionId) changed = true;\n else streaming[id] = b;\n }\n return changed ? { ...state, streaming } : state;\n}\n","import type {\n AttentionItem,\n EventEnvelope,\n Interaction,\n Panel,\n Run,\n Session,\n StreamDelta,\n SyncState,\n Task,\n TaskState,\n TranscriptItem,\n} from \"@switchyard/protocol\";\nimport { useEffect, useMemo } from \"react\";\nimport { create } from \"zustand\";\nimport { apiGet, errorMessage } from \"./api\";\nimport {\n applyEvent,\n applyEvents,\n applySnapshot,\n applyStream,\n applyTranscriptPage,\n emptySyncData,\n emptyTranscript,\n type StreamBuffer,\n type SyncData,\n type TranscriptState,\n} from \"./reduce\";\n\nexport type { StreamBuffer, SyncData, TranscriptState } from \"./reduce\";\nexport { panelKey } from \"./reduce\";\n\nexport type ConnectionState = \"connecting\" | \"live\" | \"reconnecting\" | \"offline\";\n\nexport interface ConnectionInfo {\n state: ConnectionState;\n /** When the client last received data from the coordinator (ISO). */\n lastSyncedAt: string | null;\n /** Consecutive failed connection attempts. */\n attempts: number;\n}\n\nexport interface SyncStore extends SyncData {\n /** Some data is present (from the offline cache or the server). */\n hydrated: boolean;\n /** Server data was received during this page load. */\n synced: boolean;\n connection: ConnectionInfo;\n\n hydrateFromCache(seq: number, state: SyncState, savedAt: string): void;\n applySnapshot(seq: number, state: SyncState): void;\n applyReplay(seq: number, events: EventEnvelope[]): void;\n applyEvent(event: EventEnvelope): void;\n applyStream(delta: StreamDelta): void;\n setConnection(patch: Partial<ConnectionInfo>): void;\n /** Store an interaction returned by a REST acknowledgement (answer, 409 already_answered). */\n upsertInteraction(interaction: Interaction): void;\n /** Insert a session from an HTTP response; never replaces one sync already delivered. */\n upsertSessionIfMissing(session: Session): void;\n /** Fetch the newest transcript page (or reload it after a resync). */\n loadTranscript(sessionId: string, opts?: { force?: boolean }): Promise<void>;\n /** Fetch the page before the oldest loaded item. */\n loadOlderTranscript(sessionId: string): Promise<void>;\n /** Clear all data (logout). */\n reset(): void;\n}\n\nexport const TRANSCRIPT_PAGE = 200;\n\ninterface TranscriptPage {\n items: TranscriptItem[];\n hasMore?: boolean;\n}\n\nfunction normalizePage(res: TranscriptPage | TranscriptItem[], limit: number): TranscriptPage {\n const items = Array.isArray(res) ? res : (res.items ?? []);\n const hasMore = Array.isArray(res) ? undefined : res.hasMore;\n return { items, hasMore: hasMore ?? items.length >= limit };\n}\n\nconst inflight = new Map<string, Promise<void>>();\n\nexport const useSyncStore = create<SyncStore>()((set, get) => ({\n ...emptySyncData(),\n hydrated: false,\n synced: false,\n connection: { state: \"connecting\", lastSyncedAt: null, attempts: 0 },\n\n hydrateFromCache(seq, state, savedAt) {\n if (get().synced) return;\n set((s) => ({\n ...applySnapshot(s, seq, state),\n hydrated: true,\n connection: { ...s.connection, lastSyncedAt: s.connection.lastSyncedAt ?? savedAt },\n }));\n },\n applySnapshot(seq, state) {\n set((s) => ({\n ...applySnapshot(s, seq, state),\n hydrated: true,\n synced: true,\n connection: { ...s.connection, lastSyncedAt: new Date().toISOString() },\n }));\n },\n applyReplay(seq, events) {\n set((s) => {\n const next = applyEvents(s, events);\n return {\n ...next,\n seq: Math.max(next.seq ?? 0, seq),\n hydrated: true,\n synced: true,\n connection: { ...s.connection, lastSyncedAt: new Date().toISOString() },\n };\n });\n },\n applyEvent(event) {\n set((s) => ({\n ...applyEvent(s, event),\n connection: { ...s.connection, lastSyncedAt: new Date().toISOString() },\n }));\n },\n applyStream(delta) {\n set((s) => applyStream(s, delta));\n },\n setConnection(patch) {\n set((s) => ({ connection: { ...s.connection, ...patch } }));\n },\n upsertInteraction(interaction) {\n set((s) => {\n const prev = s.interactions[interaction.id];\n if (prev && prev.revision > interaction.revision) return {};\n return { interactions: { ...s.interactions, [interaction.id]: interaction } };\n });\n },\n upsertSessionIfMissing(session) {\n set((s) =>\n s.sessions[session.id] ? {} : { sessions: { ...s.sessions, [session.id]: session } },\n );\n },\n loadTranscript(sessionId, opts) {\n const t = get().transcripts[sessionId];\n if (t?.loaded && !t.stale && !opts?.force) return Promise.resolve();\n const key = `${sessionId}:newest`;\n const existing = inflight.get(key);\n if (existing) return existing;\n setTranscript(set, sessionId, { loading: true, error: null });\n const p = apiGet<TranscriptPage | TranscriptItem[]>(\n `/api/sessions/${encodeURIComponent(sessionId)}/transcript`,\n { limit: TRANSCRIPT_PAGE },\n )\n .then((res) => {\n const page = normalizePage(res, TRANSCRIPT_PAGE);\n set((s) =>\n applyTranscriptPage(s, sessionId, page.items, {\n hasMore: page.hasMore ?? false,\n older: false,\n }),\n );\n })\n .catch((e) => setTranscript(set, sessionId, { loading: false, error: errorMessage(e) }))\n .finally(() => inflight.delete(key));\n inflight.set(key, p);\n return p;\n },\n loadOlderTranscript(sessionId) {\n const t = get().transcripts[sessionId];\n if (!t?.loaded || !t.hasMore || t.items.length === 0) return Promise.resolve();\n const before = t.items[0]!.order;\n const key = `${sessionId}:before:${before}`;\n const existing = inflight.get(key);\n if (existing) return existing;\n setTranscript(set, sessionId, { loading: true, error: null });\n const p = apiGet<TranscriptPage | TranscriptItem[]>(\n `/api/sessions/${encodeURIComponent(sessionId)}/transcript`,\n { before, limit: TRANSCRIPT_PAGE },\n )\n .then((res) => {\n const page = normalizePage(res, TRANSCRIPT_PAGE);\n set((s) =>\n applyTranscriptPage(s, sessionId, page.items, {\n hasMore: page.hasMore ?? false,\n older: true,\n }),\n );\n })\n .catch((e) => setTranscript(set, sessionId, { loading: false, error: errorMessage(e) }))\n .finally(() => inflight.delete(key));\n inflight.set(key, p);\n return p;\n },\n reset() {\n set({\n ...emptySyncData(),\n hydrated: false,\n synced: false,\n connection: { state: \"connecting\", lastSyncedAt: null, attempts: 0 },\n });\n },\n}));\n\nfunction setTranscript(\n set: (fn: (s: SyncStore) => Partial<SyncStore>) => void,\n sessionId: string,\n patch: Partial<TranscriptState>,\n) {\n set((s) => ({\n transcripts: {\n ...s.transcripts,\n [sessionId]: { ...(s.transcripts[sessionId] ?? emptyTranscript()), ...patch },\n },\n }));\n}\n\nexport const syncStore = useSyncStore;\n\n/* ------------------------------------------------------------------ */\n/* Pure selectors (take entity maps; safe to use in useMemo or tests). */\n/* ------------------------------------------------------------------ */\n\nexport const TASK_COLUMNS: TaskState[] = [\"backlog\", \"ready\", \"in_progress\", \"review\", \"done\"];\n\nexport function compareTasks(a: Task, b: Task): number {\n return (\n a.priority - b.priority || a.position - b.position || a.createdAt.localeCompare(b.createdAt)\n );\n}\n\n/** Tasks grouped by state, sorted by (priority, position, createdAt). Hidden routine tasks are omitted. */\nexport function groupTasksByState(\n tasks: Record<string, Task>,\n opts: { projectId?: string | null; includeHidden?: boolean } = {},\n): Record<TaskState, Task[]> {\n const out: Record<TaskState, Task[]> = {\n backlog: [],\n ready: [],\n in_progress: [],\n review: [],\n done: [],\n canceled: [],\n };\n for (const t of Object.values(tasks)) {\n if (opts.projectId && t.projectId !== opts.projectId) continue;\n if (t.hiddenFromBoard && !opts.includeHidden) continue;\n out[t.state].push(t);\n }\n for (const k of Object.keys(out) as TaskState[]) out[k].sort(compareTasks);\n return out;\n}\n\n/** Non-archived sessions, most recent activity first. */\nexport function sortSessions(sessions: Record<string, Session>): Session[] {\n return Object.values(sessions)\n .filter((s) => s.archivedAt === null)\n .sort((a, b) => b.lastActivityAt.localeCompare(a.lastActivityAt));\n}\n\n/** Open attention, newest first. */\nexport function sortAttention(attention: Record<string, AttentionItem>): AttentionItem[] {\n return Object.values(attention)\n .filter((a) => a.resolvedAt === null)\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n}\n\n/** Count shown on the Attention badge: open and not yet acknowledged. */\nexport function countAttention(attention: Record<string, AttentionItem>): number {\n let n = 0;\n for (const a of Object.values(attention)) if (!a.resolvedAt && !a.acknowledgedAt) n++;\n return n;\n}\n\nexport function pendingInteractionsFor(\n interactions: Record<string, Interaction>,\n sessionId: string,\n): Interaction[] {\n return Object.values(interactions)\n .filter((i) => i.sessionId === sessionId && i.state === \"pending\")\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n}\n\nexport function runsForTask(runs: Record<string, Run>, taskId: string): Run[] {\n return Object.values(runs)\n .filter((r) => r.taskId === taskId)\n .sort((a, b) => b.attempt - a.attempt || b.createdAt.localeCompare(a.createdAt));\n}\n\nexport function panelsForSession(panels: Record<string, Panel>, sessionId: string): Panel[] {\n return Object.values(panels)\n .filter((p) => p.sessionId === sessionId)\n .sort((a, b) => a.adapterId.localeCompare(b.adapterId) || a.slot.localeCompare(b.slot));\n}\n\nexport function streamsForSession(\n streaming: Record<string, StreamBuffer>,\n sessionId: string,\n): StreamBuffer[] {\n return Object.values(streaming).filter((b) => b.sessionId === sessionId);\n}\n\n/* ------------------------------------------------------------------ */\n/* Hooks. Each selects stable maps and derives with useMemo. */\n/* ------------------------------------------------------------------ */\n\nexport const useConnection = () => useSyncStore((s) => s.connection);\nexport const useHost = (id: string | null | undefined) =>\n useSyncStore((s) => (id ? s.hosts[id] : undefined));\nexport const useProject = (id: string | null | undefined) =>\n useSyncStore((s) => (id ? s.projects[id] : undefined));\nexport const useWorkspace = (id: string | null | undefined) =>\n useSyncStore((s) => (id ? s.workspaces[id] : undefined));\nexport const useSession = (id: string | null | undefined) =>\n useSyncStore((s) => (id ? s.sessions[id] : undefined));\nexport const useTask = (id: string | null | undefined) =>\n useSyncStore((s) => (id ? s.tasks[id] : undefined));\nexport const useRun = (id: string | null | undefined) =>\n useSyncStore((s) => (id ? s.runs[id] : undefined));\nexport const useAutomation = (id: string | null | undefined) =>\n useSyncStore((s) => (id ? s.automations[id] : undefined));\nexport const useInteraction = (id: string | null | undefined) =>\n useSyncStore((s) => (id ? s.interactions[id] : undefined));\n\nexport function useProjects() {\n const projects = useSyncStore((s) => s.projects);\n return useMemo(\n () => Object.values(projects).sort((a, b) => a.name.localeCompare(b.name)),\n [projects],\n );\n}\n\nexport function useHosts() {\n const hosts = useSyncStore((s) => s.hosts);\n return useMemo(\n () =>\n Object.values(hosts)\n .filter((h) => h.revokedAt === null)\n .sort((a, b) => a.name.localeCompare(b.name)),\n [hosts],\n );\n}\n\nexport function useSessions() {\n const sessions = useSyncStore((s) => s.sessions);\n return useMemo(() => sortSessions(sessions), [sessions]);\n}\n\nexport function useTasksByState(opts: { projectId?: string | null; includeHidden?: boolean } = {}) {\n const tasks = useSyncStore((s) => s.tasks);\n const { projectId, includeHidden } = opts;\n return useMemo(\n () => groupTasksByState(tasks, { projectId, includeHidden }),\n [tasks, projectId, includeHidden],\n );\n}\n\nexport function useOpenAttention() {\n const attention = useSyncStore((s) => s.attention);\n return useMemo(() => sortAttention(attention), [attention]);\n}\n\nexport function useAttentionCount() {\n return useSyncStore((s) => countAttention(s.attention));\n}\n\nexport function usePendingInteractions(sessionId: string | null | undefined) {\n const interactions = useSyncStore((s) => s.interactions);\n return useMemo(\n () => (sessionId ? pendingInteractionsFor(interactions, sessionId) : []),\n [interactions, sessionId],\n );\n}\n\nexport function useRunsForTask(taskId: string | null | undefined) {\n const runs = useSyncStore((s) => s.runs);\n return useMemo(() => (taskId ? runsForTask(runs, taskId) : []), [runs, taskId]);\n}\n\nexport function usePanels(sessionId: string | null | undefined) {\n const panels = useSyncStore((s) => s.panels);\n return useMemo(() => (sessionId ? panelsForSession(panels, sessionId) : []), [panels, sessionId]);\n}\n\nexport function useStreams(sessionId: string | null | undefined) {\n const streaming = useSyncStore((s) => s.streaming);\n return useMemo(\n () => (sessionId ? streamsForSession(streaming, sessionId) : []),\n [streaming, sessionId],\n );\n}\n\nconst EMPTY_TRANSCRIPT = emptyTranscript();\n\n/** Transcript for a session; loads the newest page on mount (and after a resync). */\nexport function useTranscript(sessionId: string | null | undefined): TranscriptState {\n const t = useSyncStore((s) => (sessionId ? s.transcripts[sessionId] : undefined));\n const load = useSyncStore((s) => s.loadTranscript);\n const needsLoad = !!sessionId && (!t || ((!t.loaded || t.stale) && !t.loading && !t.error));\n useEffect(() => {\n if (needsLoad && sessionId) void load(sessionId);\n }, [needsLoad, sessionId, load]);\n return t ?? EMPTY_TRANSCRIPT;\n}\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"circle-alert\",\n size: 24,\n node: [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"8\", y2: \"12\", key: \"1pkeuh\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"16\", y2: \"16\", key: \"4dfq90\" }]\n ],\n aliases: [\"alert-circle\"]\n};\n__iconData.node;\nconst CircleAlert = createLucideIcon(__iconData);\n\nexport { __iconData, CircleAlert as default };\n//# sourceMappingURL=circle-alert.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"inbox\",\n size: 24,\n node: [\n [\"polyline\", { points: \"22 12 16 12 14 15 10 15 8 12 2 12\", key: \"o97t9d\" }],\n [\n \"path\",\n {\n d: \"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\",\n key: \"oot6mr\"\n }\n ]\n ]\n};\n__iconData.node;\nconst Inbox = createLucideIcon(__iconData);\n\nexport { __iconData, Inbox as default };\n//# sourceMappingURL=inbox.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"message-circle-question-mark\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719\",\n key: \"1sd12s\"\n }\n ],\n [\"path\", { d: \"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\", key: \"1u773s\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n ],\n aliases: [\"message-circle-question\"]\n};\n__iconData.node;\nconst MessageCircleQuestionMark = createLucideIcon(__iconData);\n\nexport { __iconData, MessageCircleQuestionMark as default };\n//# sourceMappingURL=message-circle-question-mark.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"puzzle\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z\",\n key: \"w46dr5\"\n }\n ]\n ]\n};\n__iconData.node;\nconst Puzzle = createLucideIcon(__iconData);\n\nexport { __iconData, Puzzle as default };\n//# sourceMappingURL=puzzle.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"refresh-cw\",\n size: 24,\n node: [\n [\"path\", { d: \"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\", key: \"v9h5vc\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }],\n [\"path\", { d: \"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\", key: \"3uifl3\" }],\n [\"path\", { d: \"M8 16H3v5\", key: \"1cv678\" }]\n ]\n};\n__iconData.node;\nconst RefreshCw = createLucideIcon(__iconData);\n\nexport { __iconData, RefreshCw as default };\n//# sourceMappingURL=refresh-cw.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"server-off\",\n size: 24,\n node: [\n [\"path\", { d: \"M7 2h13a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-5\", key: \"bt2siv\" }],\n [\"path\", { d: \"M10 10 2.5 2.5C2 2 2 2.5 2 5v3a2 2 0 0 0 2 2h6z\", key: \"1hjrv1\" }],\n [\"path\", { d: \"M22 17v-1a2 2 0 0 0-2-2h-1\", key: \"1iynyr\" }],\n [\"path\", { d: \"M4 14a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16.5l1-.5.5.5-8-8H4z\", key: \"161ggg\" }],\n [\"path\", { d: \"M6 18h.01\", key: \"uhywen\" }],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n ]\n};\n__iconData.node;\nconst ServerOff = createLucideIcon(__iconData);\n\nexport { __iconData, ServerOff as default };\n//# sourceMappingURL=server-off.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"triangle-alert\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\",\n key: \"wmoenq\"\n }\n ],\n [\"path\", { d: \"M12 9v4\", key: \"juzpu7\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n ],\n aliases: [\"alert-triangle\"]\n};\n__iconData.node;\nconst TriangleAlert = createLucideIcon(__iconData);\n\nexport { __iconData, TriangleAlert as default };\n//# sourceMappingURL=triangle-alert.mjs.map\n","/** Join class names, skipping falsy values. */\nexport function cn(...parts: (string | false | null | undefined)[]): string {\n return parts.filter(Boolean).join(\" \");\n}\n","const rtf =\n typeof Intl !== \"undefined\" && \"RelativeTimeFormat\" in Intl\n ? new Intl.RelativeTimeFormat(undefined, { numeric: \"auto\" })\n : null;\n\n/** \"3 min ago\", \"in 2 h\", \"just now\". */\nexport function formatRelative(iso: string | null | undefined, now = Date.now()): string {\n if (!iso) return \"never\";\n const t = Date.parse(iso);\n if (Number.isNaN(t)) return iso;\n const diff = Math.round((t - now) / 1000);\n const abs = Math.abs(diff);\n if (abs < 30) return \"just now\";\n if (!rtf) return new Date(t).toLocaleString();\n if (abs < 3600) return rtf.format(Math.round(diff / 60), \"minute\");\n if (abs < 86400) return rtf.format(Math.round(diff / 3600), \"hour\");\n if (abs < 86400 * 30) return rtf.format(Math.round(diff / 86400), \"day\");\n return new Date(t).toLocaleDateString();\n}\n\n/** Short local time, with the date when it is not today. */\nexport function formatTime(iso: string | number | null | undefined): string {\n if (iso === null || iso === undefined) return \"unknown\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return String(iso);\n const sameDay = d.toDateString() === new Date().toDateString();\n return sameDay\n ? d.toLocaleTimeString(undefined, { hour: \"2-digit\", minute: \"2-digit\" })\n : d.toLocaleString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\n/** \"1m 05s\" style duration. */\nexport function formatDuration(ms: number | null | undefined): string {\n if (ms === null || ms === undefined || Number.isNaN(ms)) return \"\";\n if (ms < 1000) return `${Math.round(ms)} ms`;\n const s = Math.round(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${String(s % 60).padStart(2, \"0\")}s`;\n return `${Math.floor(m / 60)}h ${String(m % 60).padStart(2, \"0\")}m`;\n}\n","import { cn } from \"../../lib/cn\";\n\nexport function Spinner({ className, label }: { className?: string; label?: string }) {\n return (\n <svg\n className={cn(\"size-4 shrink-0 animate-spin\", className)}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n role={label ? \"img\" : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" strokeOpacity=\"0.25\" strokeWidth=\"3\" />\n <path d=\"M21 12a9 9 0 0 0-9-9\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n","import { type ButtonHTMLAttributes, forwardRef, type ReactNode } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { Spinner } from \"./Spinner\";\n\nexport type ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\";\nexport type ButtonSize = \"sm\" | \"md\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** Icon shown before the label. */\n icon?: ReactNode;\n /** Shows a spinner and sets aria-busy; the button is disabled while busy. */\n busy?: boolean;\n block?: boolean;\n}\n\nconst VARIANTS: Record<ButtonVariant, string> = {\n primary: \"bg-accent text-accent-fg border-accent hover:bg-accent-hover hover:border-accent-hover\",\n secondary: \"bg-surface text-text border-border hover:bg-surface-2\",\n ghost: \"bg-transparent text-text border-transparent hover:bg-surface-2\",\n danger: \"bg-danger text-danger-fg border-danger hover:bg-danger-hover hover:border-danger-hover\",\n};\n\nconst SIZES: Record<ButtonSize, string> = {\n sm: \"h-8 px-2.5 text-sm gap-1.5\",\n md: \"h-9 px-3.5 text-sm gap-2\",\n};\n\nexport function buttonClasses(\n variant: ButtonVariant = \"secondary\",\n size: ButtonSize = \"md\",\n extra?: string,\n): string {\n return cn(\n \"tap inline-flex items-center justify-center rounded-md border font-medium whitespace-nowrap select-none\",\n \"transition-colors disabled:opacity-55 disabled:pointer-events-none\",\n VARIANTS[variant],\n SIZES[size],\n extra,\n );\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = \"secondary\",\n size = \"md\",\n icon,\n busy,\n block,\n className,\n children,\n disabled,\n type,\n ...rest\n },\n ref,\n) {\n return (\n <button\n ref={ref}\n type={type ?? \"button\"}\n disabled={disabled || busy}\n aria-busy={busy || undefined}\n className={buttonClasses(variant, size, cn(block && \"w-full\", className))}\n {...rest}\n >\n {busy ? <Spinner /> : icon}\n {children}\n </button>\n );\n});\n\nexport { Spinner };\n","import {\n CircleAlert,\n Inbox,\n MessageCircleQuestion,\n Puzzle,\n RefreshCw,\n ServerOff,\n TriangleAlert,\n} from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { Link } from \"react-router\";\nimport { cn } from \"../../lib/cn\";\nimport { formatRelative, formatTime } from \"../../lib/time\";\nimport type { ConnectionState } from \"../../sync/store\";\nimport { Button, buttonClasses } from \"./Button\";\nimport { Spinner } from \"./Spinner\";\n\n/*\n * The nine UI states every primary view implements (spec 18):\n * LoadingState, EmptyState, ReconnectingBanner, HostUnavailable,\n * InteractionPending, UnsupportedCapability, ErrorState, FatalError, and\n * toast() for successful mutations (see Toast.tsx).\n */\n\nexport type StateAction =\n | { label: string; onClick: () => void; icon?: ReactNode }\n | { label: string; to: string; icon?: ReactNode };\n\nfunction ActionButton({ action, primary = true }: { action: StateAction; primary?: boolean }) {\n if (\"to\" in action) {\n return (\n <Link to={action.to} className={buttonClasses(primary ? \"primary\" : \"secondary\")}>\n {action.icon}\n {action.label}\n </Link>\n );\n }\n return (\n <Button variant={primary ? \"primary\" : \"secondary\"} icon={action.icon} onClick={action.onClick}>\n {action.label}\n </Button>\n );\n}\n\nfunction Panel({\n icon,\n title,\n children,\n actions,\n className,\n role,\n}: {\n icon: ReactNode;\n title: ReactNode;\n children?: ReactNode;\n actions?: ReactNode;\n className?: string;\n role?: string;\n}) {\n return (\n <div\n role={role}\n className={cn(\n \"mx-auto flex w-full max-w-md flex-col items-center gap-3 px-4 py-10 text-center\",\n className,\n )}\n >\n <div className=\"text-muted\" aria-hidden>\n {icon}\n </div>\n <h2 className=\"text-base font-semibold\">{title}</h2>\n {children && <div className=\"text-sm text-muted\">{children}</div>}\n {actions && <div className=\"flex flex-wrap justify-center gap-2\">{actions}</div>}\n </div>\n );\n}\n\n/** 1. Initial loading. */\nexport function LoadingState({\n label = \"Loading…\",\n className,\n}: {\n label?: string;\n className?: string;\n}) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\n \"flex items-center justify-center gap-2 px-4 py-10 text-sm text-muted\",\n className,\n )}\n >\n <Spinner />\n <span>{label}</span>\n </div>\n );\n}\n\n/** 2. Empty state with a next action. */\nexport function EmptyState({\n title,\n description,\n action,\n secondaryAction,\n icon,\n className,\n}: {\n title: string;\n description?: ReactNode;\n action?: StateAction;\n secondaryAction?: StateAction;\n icon?: ReactNode;\n className?: string;\n}) {\n return (\n <Panel\n icon={icon ?? <Inbox className=\"size-8\" />}\n title={title}\n className={className}\n actions={\n (action || secondaryAction) && (\n <>\n {action && <ActionButton action={action} />}\n {secondaryAction && <ActionButton action={secondaryAction} primary={false} />}\n </>\n )\n }\n >\n {description}\n </Panel>\n );\n}\n\n/** 3. Reconnecting with last-known-data indication. Renders nothing while live. */\nexport function ReconnectingBanner({\n state,\n lastSyncedAt,\n onRetry,\n className,\n}: {\n state: ConnectionState;\n lastSyncedAt: string | null;\n onRetry?: () => void;\n className?: string;\n}) {\n if (state === \"live\" || (state === \"connecting\" && !lastSyncedAt)) return null;\n const offline = state === \"offline\";\n const when = lastSyncedAt ? formatTime(lastSyncedAt) : \"an earlier session\";\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\n \"flex items-center gap-2 border-b border-border bg-warning-soft px-3 py-1.5 text-sm text-text\",\n className,\n )}\n >\n {offline ? (\n <ServerOff aria-hidden className=\"size-4 shrink-0 text-warning\" />\n ) : (\n <Spinner className=\"size-4 text-warning\" />\n )}\n <span className=\"min-w-0 flex-1\">\n {offline ? \"Offline\" : \"Reconnecting…\"} showing last known data from{\" \"}\n <time dateTime={lastSyncedAt ?? undefined}>{when}</time>\n </span>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"tap shrink-0 rounded px-2 py-0.5 font-medium text-accent hover:bg-surface-2\"\n >\n Retry now\n </button>\n )}\n </div>\n );\n}\n\n/** 4. Host unavailable (unreachable or reconnecting). Never claims completion. */\nexport function HostUnavailable({\n hostName,\n connectivity = \"unreachable\",\n lastSeenAt,\n detail,\n compact,\n className,\n}: {\n hostName: string;\n connectivity?: \"reconnecting\" | \"unreachable\";\n lastSeenAt?: string | null;\n detail?: ReactNode;\n /** Inline banner instead of a full panel. */\n compact?: boolean;\n className?: string;\n}) {\n const title =\n connectivity === \"reconnecting\"\n ? `Host ${hostName} is reconnecting`\n : `Host ${hostName} is unreachable`;\n const body = (\n <>\n {lastSeenAt ? `Last seen ${formatRelative(lastSeenAt)}. ` : \"\"}\n {detail ?? \"Work on this host keeps its last known state; nothing is restarted elsewhere.\"}\n </>\n );\n if (compact) {\n return (\n <div\n role=\"status\"\n className={cn(\n \"flex items-start gap-2 rounded-md border border-border bg-danger-soft px-3 py-2 text-sm\",\n className,\n )}\n >\n <ServerOff aria-hidden className=\"mt-0.5 size-4 shrink-0 text-danger\" />\n <div className=\"min-w-0\">\n <div className=\"font-medium\">{title}</div>\n <div className=\"text-muted\">{body}</div>\n </div>\n </div>\n );\n }\n return (\n <Panel\n role=\"status\"\n icon={<ServerOff className=\"size-8\" />}\n title={title}\n className={className}\n >\n {body}\n </Panel>\n );\n}\n\n/** 5. Permission/interaction pending: a strip linking to the first unanswered item. */\nexport function InteractionPending({\n count,\n to,\n onOpen,\n label,\n className,\n}: {\n count: number;\n to?: string;\n onOpen?: () => void;\n label?: string;\n className?: string;\n}) {\n if (count <= 0) return null;\n const text = label ?? (count === 1 ? \"Needs your answer\" : `${count} questions need your answer`);\n const inner = (\n <>\n <MessageCircleQuestion aria-hidden className=\"size-4 shrink-0 text-warning\" />\n <span className=\"min-w-0 flex-1 truncate font-medium\">{text}</span>\n <span className=\"shrink-0 text-accent\">Answer</span>\n </>\n );\n const cls = cn(\n \"tap flex w-full items-center gap-2 border border-border bg-warning-soft px-3 py-2 text-left text-sm rounded-md\",\n className,\n );\n if (to)\n return (\n <Link to={to} className={cls} role=\"status\">\n {inner}\n </Link>\n );\n return (\n <button type=\"button\" onClick={onOpen} className={cls}>\n {inner}\n </button>\n );\n}\n\n/** 6. Unsupported capability: says exactly what is not available and what to do instead. */\nexport function UnsupportedCapability({\n capability,\n reason,\n fallback,\n className,\n}: {\n capability: string;\n reason: ReactNode;\n fallback?: ReactNode;\n className?: string;\n}) {\n return (\n <div\n role=\"note\"\n className={cn(\n \"flex items-start gap-2 rounded-md border border-border bg-surface-2 px-3 py-2 text-sm\",\n className,\n )}\n >\n <Puzzle aria-hidden className=\"mt-0.5 size-4 shrink-0 text-muted\" />\n <div className=\"min-w-0\">\n <div className=\"font-medium\">{capability} is not available here</div>\n <div className=\"text-muted\">{reason}</div>\n {fallback && <div className=\"mt-1\">{fallback}</div>}\n </div>\n </div>\n );\n}\n\n/** 7. Recoverable error with retry. */\nexport function ErrorState({\n title = \"Something went wrong\",\n error,\n onRetry,\n compact,\n className,\n}: {\n title?: string;\n error: unknown;\n onRetry?: () => void;\n compact?: boolean;\n className?: string;\n}) {\n const message = error instanceof Error ? error.message : String(error ?? \"\");\n if (compact) {\n return (\n <div\n role=\"alert\"\n className={cn(\n \"flex items-start gap-2 rounded-md border border-border bg-danger-soft px-3 py-2 text-sm\",\n className,\n )}\n >\n <TriangleAlert aria-hidden className=\"mt-0.5 size-4 shrink-0 text-danger\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"font-medium\">{title}</div>\n {message && <div className=\"break-words text-muted\">{message}</div>}\n </div>\n {onRetry && (\n <Button size=\"sm\" onClick={onRetry} icon={<RefreshCw className=\"size-3.5\" />}>\n Retry\n </Button>\n )}\n </div>\n );\n }\n return (\n <Panel\n role=\"alert\"\n icon={<TriangleAlert className=\"size-8 text-danger\" />}\n title={title}\n className={className}\n actions={\n onRetry && (\n <Button variant=\"primary\" onClick={onRetry} icon={<RefreshCw className=\"size-4\" />}>\n Retry\n </Button>\n )\n }\n >\n <span className=\"break-words\">{message}</span>\n </Panel>\n );\n}\n\n/** 8. Irrecoverable error with a diagnostics link. */\nexport function FatalError({\n title = \"Switchyard cannot show this view\",\n error,\n diagnosticsHref = \"/settings/diagnostics\",\n className,\n}: {\n title?: string;\n error: unknown;\n diagnosticsHref?: string;\n className?: string;\n}) {\n const message = error instanceof Error ? error.message : String(error ?? \"\");\n return (\n <Panel\n role=\"alert\"\n icon={<CircleAlert className=\"size-8 text-danger\" />}\n title={title}\n className={className}\n actions={\n <>\n <a href={diagnosticsHref} className={buttonClasses(\"primary\")}>\n Open diagnostics\n </a>\n <Button onClick={() => location.reload()}>Reload</Button>\n </>\n }\n >\n <span className=\"break-words\">{message}</span>\n </Panel>\n );\n}\n"],"ignoreList":[0,1,5,6,7,8,9,10,11],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{_ as e,a as t,f as n,i as r,m as i,t as a}from"./jsx-runtime-D13aM9HY.js";import{G as o,U as s,V as c,W as l,g as u,l as d,o as f,p}from"./states--geW2Ntl.js";import{T as m,o as h}from"./shared-CZ7fcu_B.js";import{n as g}from"./TextArea-BYr88SnV.js";var _=e(i(),1),v=a();function y(){let[e]=t(),i=n(),a=e.get(`code`)?.trim()??``,[y,b]=(0,_.useState)(``),[x,S]=(0,_.useState)(null),[C,w]=(0,_.useState)(null),[T,E]=(0,_.useState)(null),[D,O]=(0,_.useState)(!1),[k,A]=(0,_.useState)(null);(0,_.useEffect)(()=>{if(!a)return;let e=new AbortController;return S(null),w(null),E(null),c(`/api/auth/terminal/requests/${encodeURIComponent(a)}`,void 0,e.signal).then(t=>!e.signal.aborted&&S(t)).catch(t=>{e.signal.aborted||(o(t)&&t.code===`not_found`?w(l(t)):E(t))}),()=>e.abort()},[a]);let j=async e=>{O(!0),A(null);try{S(await s(`/api/auth/terminal/requests/${encodeURIComponent(a)}/${e}`))}catch(e){A(e)}finally{O(!1)}},M;return M=a?C?(0,v.jsxs)(`div`,{role:`alert`,className:`rounded-md border border-border bg-danger-soft px-3 py-2 text-sm`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-1.5 font-medium`,children:[(0,v.jsx)(u,{"aria-hidden":!0,className:`size-4 shrink-0`}),`Sign-in request not found`]}),(0,v.jsx)(`div`,{className:`text-muted`,children:C})]}):T?(0,v.jsx)(h,{error:T}):x?x.status===`approved`?(0,v.jsxs)(`div`,{role:`status`,className:`flex flex-col gap-3 text-sm`,children:[(0,v.jsx)(`p`,{className:`font-medium`,children:`Terminal signed in. You can close this tab and return to your terminal.`}),(0,v.jsx)(r,{to:`/`,className:`font-medium text-accent underline`,children:`Back to Switchyard`})]}):x.status===`denied`?(0,v.jsx)(`p`,{role:`status`,className:`text-sm font-medium`,children:`Sign-in denied. The terminal was not signed in.`}):(0,v.jsxs)(`div`,{className:`flex flex-col gap-4 text-sm`,children:[(0,v.jsx)(`p`,{className:`text-base font-medium`,children:`Sign in a terminal?`}),(0,v.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-4 gap-y-2`,children:[(0,v.jsx)(`dt`,{className:`text-muted`,children:`Terminal`}),(0,v.jsx)(`dd`,{className:`break-words`,children:x.name}),(0,v.jsx)(`dt`,{className:`text-muted`,children:`Code`}),(0,v.jsx)(`dd`,{"data-testid":`terminal-login-code`,className:`font-mono text-lg tracking-widest`,children:x.userCode}),(0,v.jsx)(`dt`,{className:`text-muted`,children:`From`}),(0,v.jsx)(`dd`,{children:x.requestedFrom}),(0,v.jsx)(`dt`,{className:`text-muted`,children:`Requested`}),(0,v.jsx)(`dd`,{children:p(x.createdAt)})]}),(0,v.jsx)(`p`,{className:`text-muted`,children:`Approve only if you just ran switchyard login and your terminal shows this code.`}),(0,v.jsx)(h,{error:k}),(0,v.jsxs)(`div`,{className:`flex gap-2`,children:[(0,v.jsx)(d,{variant:`primary`,"data-testid":`terminal-login-approve`,busy:D,onClick:()=>void j(`approve`),children:`Approve`}),(0,v.jsx)(d,{"data-testid":`terminal-login-deny`,disabled:D,onClick:()=>void j(`deny`),children:`Deny`})]})]}):(0,v.jsx)(f,{label:`Loading the sign-in request…`}):(0,v.jsxs)(`form`,{className:`flex flex-col gap-3`,onSubmit:e=>{e.preventDefault(),y.trim()&&i(`?code=${encodeURIComponent(y.trim())}`)},children:[(0,v.jsx)(`label`,{htmlFor:`tl-code`,className:`text-sm font-medium`,children:`Code from your terminal`}),(0,v.jsx)(g,{id:`tl-code`,value:y,autoComplete:`off`,onChange:e=>b(e.target.value)}),(0,v.jsx)(d,{type:`submit`,variant:`primary`,disabled:!y.trim(),children:`Continue`})]}),(0,v.jsx)(`div`,{className:`flex min-h-dvh items-start justify-center px-4 py-10 safe-pt safe-pb sm:items-center`,children:(0,v.jsxs)(`div`,{className:`w-full max-w-sm rounded-xl border border-border bg-surface p-5 shadow-sm`,children:[(0,v.jsxs)(`div`,{className:`mb-4 flex items-center gap-3`,children:[(0,v.jsx)(`img`,{src:`/icon.svg`,alt:``,className:`size-10 rounded-lg`}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`h1`,{className:`text-lg font-semibold`,children:`Switchyard`}),(0,v.jsxs)(`p`,{className:`flex items-center gap-1 text-sm text-muted`,children:[(0,v.jsx)(m,{"aria-hidden":!0,className:`size-3.5`}),` Terminal sign-in`]})]})]}),M]})})}export{y as default};
2
- //# sourceMappingURL=terminal-login-BJxV78au.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"terminal-login-BJxV78au.js","names":["useState","__toESM","useSearchParams","useNavigate","Link","require_react","require_jsx_runtime","isApiError","apiPost","apiGet","errorMessage","TriangleAlert","Button","LoadingState","Terminal","InlineError","TextInput","import_react","import_jsx_runtime","TerminalLoginView","params","navigate","code","typed","setTyped","request","setRequest","notFound","setNotFound","loadError","setLoadError","busy","setBusy","actionError","setActionError","ac","r","e","act","action","body","formatRelative"],"sources":["../../src/features/terminal-login/index.tsx"],"sourcesContent":["import type { TerminalLoginRequest } from \"@switchyard/protocol\";\nimport { Terminal, TriangleAlert } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { Link, useNavigate, useSearchParams } from \"react-router\";\nimport { Button } from \"../../components/ui/Button\";\nimport { LoadingState } from \"../../components/ui/states\";\nimport { TextInput } from \"../../components/ui/TextArea\";\nimport { formatRelative } from \"../../lib/time\";\nimport { apiGet, apiPost, errorMessage, isApiError } from \"../../sync/api\";\nimport { InlineError } from \"../settings/shared\";\n\n/** /terminal-login?code=XXXX-XXXX: approve or deny a terminal's `switchyard login`. */\nexport default function TerminalLoginView() {\n const [params] = useSearchParams();\n const navigate = useNavigate();\n const code = params.get(\"code\")?.trim() ?? \"\";\n const [typed, setTyped] = useState(\"\");\n const [request, setRequest] = useState<TerminalLoginRequest | null>(null);\n const [notFound, setNotFound] = useState<string | null>(null);\n const [loadError, setLoadError] = useState<unknown>(null);\n const [busy, setBusy] = useState(false);\n const [actionError, setActionError] = useState<unknown>(null);\n\n useEffect(() => {\n if (!code) return;\n const ac = new AbortController();\n setRequest(null);\n setNotFound(null);\n setLoadError(null);\n apiGet<TerminalLoginRequest>(\n `/api/auth/terminal/requests/${encodeURIComponent(code)}`,\n undefined,\n ac.signal,\n )\n .then((r) => !ac.signal.aborted && setRequest(r))\n .catch((e: unknown) => {\n if (ac.signal.aborted) return;\n if (isApiError(e) && e.code === \"not_found\") setNotFound(errorMessage(e));\n else setLoadError(e);\n });\n return () => ac.abort();\n }, [code]);\n\n const act = async (action: \"approve\" | \"deny\") => {\n setBusy(true);\n setActionError(null);\n try {\n setRequest(\n await apiPost<TerminalLoginRequest>(\n `/api/auth/terminal/requests/${encodeURIComponent(code)}/${action}`,\n ),\n );\n } catch (e) {\n setActionError(e);\n } finally {\n setBusy(false);\n }\n };\n\n let body: React.ReactNode;\n if (!code) {\n body = (\n <form\n className=\"flex flex-col gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n if (typed.trim()) navigate(`?code=${encodeURIComponent(typed.trim())}`);\n }}\n >\n <label htmlFor=\"tl-code\" className=\"text-sm font-medium\">\n Code from your terminal\n </label>\n <TextInput\n id=\"tl-code\"\n value={typed}\n autoComplete=\"off\"\n onChange={(e) => setTyped(e.target.value)}\n />\n <Button type=\"submit\" variant=\"primary\" disabled={!typed.trim()}>\n Continue\n </Button>\n </form>\n );\n } else if (notFound) {\n body = (\n <div\n role=\"alert\"\n className=\"rounded-md border border-border bg-danger-soft px-3 py-2 text-sm\"\n >\n <div className=\"flex items-center gap-1.5 font-medium\">\n <TriangleAlert aria-hidden className=\"size-4 shrink-0\" />\n Sign-in request not found\n </div>\n <div className=\"text-muted\">{notFound}</div>\n </div>\n );\n } else if (loadError) {\n body = <InlineError error={loadError} />;\n } else if (!request) {\n body = <LoadingState label=\"Loading the sign-in request…\" />;\n } else if (request.status === \"approved\") {\n body = (\n <div role=\"status\" className=\"flex flex-col gap-3 text-sm\">\n <p className=\"font-medium\">\n Terminal signed in. You can close this tab and return to your terminal.\n </p>\n <Link to=\"/\" className=\"font-medium text-accent underline\">\n Back to Switchyard\n </Link>\n </div>\n );\n } else if (request.status === \"denied\") {\n body = (\n <p role=\"status\" className=\"text-sm font-medium\">\n Sign-in denied. The terminal was not signed in.\n </p>\n );\n } else {\n body = (\n <div className=\"flex flex-col gap-4 text-sm\">\n <p className=\"text-base font-medium\">Sign in a terminal?</p>\n <dl className=\"grid grid-cols-[auto_1fr] gap-x-4 gap-y-2\">\n <dt className=\"text-muted\">Terminal</dt>\n <dd className=\"break-words\">{request.name}</dd>\n <dt className=\"text-muted\">Code</dt>\n <dd data-testid=\"terminal-login-code\" className=\"font-mono text-lg tracking-widest\">\n {request.userCode}\n </dd>\n <dt className=\"text-muted\">From</dt>\n <dd>{request.requestedFrom}</dd>\n <dt className=\"text-muted\">Requested</dt>\n <dd>{formatRelative(request.createdAt)}</dd>\n </dl>\n <p className=\"text-muted\">\n Approve only if you just ran switchyard login and your terminal shows this code.\n </p>\n <InlineError error={actionError} />\n <div className=\"flex gap-2\">\n <Button\n variant=\"primary\"\n data-testid=\"terminal-login-approve\"\n busy={busy}\n onClick={() => void act(\"approve\")}\n >\n Approve\n </Button>\n <Button\n data-testid=\"terminal-login-deny\"\n disabled={busy}\n onClick={() => void act(\"deny\")}\n >\n Deny\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex min-h-dvh items-start justify-center px-4 py-10 safe-pt safe-pb sm:items-center\">\n <div className=\"w-full max-w-sm rounded-xl border border-border bg-surface p-5 shadow-sm\">\n <div className=\"mb-4 flex items-center gap-3\">\n <img src=\"/icon.svg\" alt=\"\" className=\"size-10 rounded-lg\" />\n <div>\n <h1 className=\"text-lg font-semibold\">Switchyard</h1>\n <p className=\"flex items-center gap-1 text-sm text-muted\">\n <Terminal aria-hidden className=\"size-3.5\" /> Terminal sign-in\n </p>\n </div>\n </div>\n {body}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{n as e}from"./jsx-runtime-D13aM9HY.js";var t={name:`trash`,size:24,node:[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]],aliases:[`trash-2`]};t.node;var n=e(t);export{n as t};
2
- //# sourceMappingURL=trash-C6X2OLrI.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trash-C6X2OLrI.js","names":["createLucideIcon","__iconData","Trash"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/trash.mjs"],"sourcesContent":["/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"trash\",\n size: 24,\n node: [\n [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n ],\n aliases: [\"trash-2\"]\n};\n__iconData.node;\nconst Trash = createLucideIcon(__iconData);\n\nexport { __iconData, Trash as default };\n//# sourceMappingURL=trash.mjs.map\n"],"ignoreList":[0],"mappings":"A,8CASA,IAAMC,EAAa,CACjB,KAAM,QACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,2CAA4C,IAAK,QAAS,CAAC,EACzE,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,EACxC,CAAC,OAAQ,CAAE,EAAG,yCAA0C,IAAK,QAAS,CAAC,CACzE,EACA,QAAS,CAAC,SAAS,CACrB,EACAA,EAAW,KACX,IAAMC,EAAQF,EAAiBC,CAAU,E"}
@@ -1,2 +0,0 @@
1
- import{_ as e,m as t,n,t as r}from"./jsx-runtime-D13aM9HY.js";import{t as i}from"./Badge-BiDp7NKI.js";import{A as a,B as o,E as s,G as c,H as l,P as u,U as d,V as f,W as p,a as m,c as ee,h,i as te,l as g,n as ne}from"./states--geW2Ntl.js";import{t as _}from"./search-C6cn5WOo.js";import{A as v,j as y,l as b,m as x,t as S}from"./index-vIzH1m8u.js";import{a as re,n as ie,r as ae}from"./TextArea-BYr88SnV.js";import{c as C}from"./dist-BE_V9dwJ.js";var w={name:`funnel`,size:24,node:[[`path`,{d:`M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z`,key:`sc7q7i`}]],aliases:[`filter`]};w.node;var oe=n(w),T=e(t(),1),E=e=>`/api/tasks/${encodeURIComponent(e)}`;function D(e){if(!e||typeof e!=`object`)return null;let t=e;return t.task&&typeof t.task==`object`?t.task:typeof t.id==`string`&&typeof t.state==`string`?t:null}function O(e){let t=D(e);return t?(u.setState(e=>{let n=e.tasks[t.id];return n&&n.updatedAt>t.updatedAt?{}:{tasks:{...e.tasks,[t.id]:t}}}),t):null}async function k(e){let t=O(await d(`/api/tasks`,e));if(!t)throw Error(`The coordinator returned an unexpected response`);return t}async function A(e,t){return O(await l(E(e),t))}async function j(e){await o(E(e)),u.setState(t=>{if(!t.tasks[e])return{};let{[e]:n,...r}=t.tasks;return{tasks:r}})}async function M(e,t){return O(await d(`${E(e)}/move`,t))}async function N(e,t,n,r){return O(await d(`${E(e)}/${t}${r??``}`,n))}async function P(e,t){return O(await d(`${E(e)}/request-changes`,{feedback:t}))}function F(e,t){return f(`${E(e)}/eligibility`,void 0,t)}async function I(e,t){let n=await f(`${E(e)}/runs`,void 0,t);return Array.isArray(n)?n:n.runs??[]}async function L(e){await d(`/api/dispatch/pause`,{paused:e}),u.setState({dispatchPaused:e})}function R(e){return!c(e)||e.status!==409&&e.code!==`invalid_transition`?!1:e.details?.needsConfirm===!0||/confirm/i.test(e.message)}function z(e){if(!c(e))return!1;let t=e.details;return Array.isArray(t?.choices)||t?.needsChoice===!0||t?.onRunning===!0||/pause automation or stop execution/i.test(e.message)}var B=[`backlog`,`ready`,`in_progress`,`review`,`done`],V={backlog:`Backlog`,ready:`Ready`,in_progress:`In progress`,review:`Review`,done:`Done`,canceled:`Canceled`},H={search:``,priorities:[],hostId:null,attentionOnly:!1,blockedOnly:!1,showCanceled:!1,showCompleted:!0,sort:`priority`};function U(e){let t=e&&typeof e==`object`?e:{};return{search:typeof t.search==`string`?t.search:``,priorities:Array.isArray(t.priorities)?t.priorities.filter(e=>[0,1,2,3].includes(e)):[],hostId:typeof t.hostId==`string`?t.hostId:null,attentionOnly:t.attentionOnly===!0,blockedOnly:t.blockedOnly===!0,showCanceled:t.showCanceled===!0,showCompleted:t.showCompleted!==!1,sort:t.sort===`updated`||t.sort===`created`?t.sort:`priority`}}function W(e,t){let n=[];e.search.trim()&&n.push({key:`search`,label:`Search: ${e.search.trim()}`,clear:e=>({...e,search:``})});for(let t of e.priorities)n.push({key:`priority-${t}`,label:`Priority: ${C[t]}`,clear:e=>({...e,priorities:e.priorities.filter(e=>e!==t)})});return e.hostId&&n.push({key:`host`,label:`Host: ${t(e.hostId)}`,clear:e=>({...e,hostId:null})}),e.attentionOnly&&n.push({key:`attention`,label:`Needs attention`,clear:e=>({...e,attentionOnly:!1})}),e.blockedOnly&&n.push({key:`blocked`,label:`Blocked`,clear:e=>({...e,blockedOnly:!1})}),e.showCanceled&&n.push({key:`canceled`,label:`Including canceled`,clear:e=>({...e,showCanceled:!1})}),n}function G(e,t){return(e.currentRunId?t[e.currentRunId]:void 0)?.hostId??e.policy.hostId??null}function K(e,t,n){if(e.hiddenFromBoard||n.projectId&&e.projectId!==n.projectId||e.state===`canceled`&&!t.showCanceled)return!1;let r=t.search.trim().toLowerCase();return!(r&&!`${e.title}\n${e.objective}`.toLowerCase().includes(r)||t.priorities.length>0&&!t.priorities.includes(e.priority)||t.hostId&&G(e,n.runs)!==t.hostId||t.attentionOnly&&!n.attentionTaskIds.has(e.id)||t.blockedOnly&&!e.blocked)}function q(e,t){let n=[...e];return t===`updated`?n.sort((e,t)=>t.lastActivityAt.localeCompare(e.lastActivityAt)):t===`created`?n.sort((e,t)=>t.createdAt.localeCompare(e.createdAt)):n.sort((e,t)=>e.priority-t.priority||e.position-t.position||e.createdAt.localeCompare(t.createdAt)),n}function se(e,t,n){let r={backlog:[],ready:[],in_progress:[],review:[],done:[],canceled:[]};for(let i of Object.values(e))K(i,t,n)&&r[i.state].push(i);for(let e of Object.keys(r))r[e]=q(r[e],t.sort);return r}function ce(e){return e.showCanceled?[...B,`canceled`]:B}var J={backlog:[`ready`,`canceled`],ready:[`backlog`,`in_progress`,`canceled`],in_progress:[`review`,`ready`,`backlog`,`canceled`,`done`],review:[`in_progress`,`done`,`ready`,`canceled`],done:[`ready`,`backlog`],canceled:[`backlog`]};function le(e){return!!e&&[`queued`,`dispatching`,`uncertain`,`running`,`waiting_input`,`checking`].includes(e.state)}function ue(e,t){let n=[];e.state!==`review`&&n.push(`The task has not been through review.`),e.acceptanceCriteria.length>0&&n.push(`${e.acceptanceCriteria.length} acceptance ${e.acceptanceCriteria.length===1?`criterion has`:`criteria have`} not been confirmed.`);let r=(e.policy.completion.checks?.length??0)>0,i=t?.checks.filter(e=>e.exitCode!==0)??[];return i.length>0?n.push(`Checks failing: ${i.map(e=>e.command).join(`, `)}.`):r&&(!t||t.checks.length===0)&&n.push(`Required checks have not run.`),e.policy.completion.requireHumanReview&&e.state===`review`&&n.push(`Human review is required: moving to Done accepts the work.`),n}function de(e,t,n){if(e.state===t)return{kind:`noop`};let r=e.state;if(!J[r].includes(t))return{kind:`invalid`,reason:fe(r,t)};if(r===`ready`&&t===`in_progress`)return{kind:`run_now`};if(r===`review`&&t===`in_progress`)return{kind:`new_attempt`};if(r===`in_progress`&&(t===`ready`||t===`backlog`))return{kind:`choose_running`};if(t===`done`){let t=ue(e,n);if(t.length>0)return{kind:`confirm_done`,reasons:t}}return{kind:`move`}}function fe(e,t){let n=V[e],r=V[t];return t===`in_progress`?e===`backlog`?`A Backlog task cannot start directly. Move it to Ready first; the dispatcher starts it when it is eligible.`:`${n} tasks cannot be moved to In progress. Only the dispatcher starts work (Run now from Ready).`:t===`review`?`Only a finished run moves a task to Review. Run the task, or use Done to accept it.`:e===`canceled`?`A canceled task can only be restored to Backlog.`:e===`done`&&t===`canceled`?`A Done task cannot be canceled. Reopen it first.`:e===`backlog`&&t===`done`?`A Backlog task cannot be marked Done. Make it ready and review its work first.`:e===`ready`&&t===`done`?`A task that has not run cannot be marked Done. Run it, or cancel it.`:`Moving from ${n} to ${r} is not allowed.`}function pe(e){return J[e.state]}function me(e,t,n){let r=e.filter(e=>e.id!==n);if(r.length===0)return 1;if(t===null)return r[r.length-1].position+1;let i=r.findIndex(e=>e.id===t);if(i<0)return r[r.length-1].position+1;let a=r[i].position;return((i>0?r[i-1].position:a-2)+a)/2}var Y={dependency:`Waiting on dependencies`,host_offline:`Host offline`,project_limit:`Project run limit reached`,workspace_occupied:`Workspace occupied`,scheduled_time:`Scheduled for later`,invalid_configuration:`Invalid configuration`,dispatch_paused:`Dispatch paused`,project_automation_disabled:`Project automation is off`,not_ready:`Not ready`,already_dispatched:`Already dispatched`,retry_backoff:`Retrying after a failure`};function he(e){return e.eligible?`Will start automatically on ${e.hostName}`:`Will wait: ${e.message||Y[e.wait]}`}function ge(e,t){let{project:n}=e;if(!n)return{eligible:!1,wait:`invalid_configuration`,message:`Choose a project`};if(t.dispatchPaused)return{eligible:!1,wait:`dispatch_paused`,message:`Dispatch is paused; resume it to start new work`};if(!n.automationEnabled)return{eligible:!1,wait:`project_automation_disabled`,message:`Automation is off for ${n.name}`};let r=e.dependencies.map(e=>t.tasks[e]).filter(e=>!!e&&e.state!==`done`);if(r.length>0)return{eligible:!1,wait:`dependency`,message:`Waiting on ${r.map(e=>e.title).join(`, `)}`};if(e.notBefore&&Date.parse(e.notBefore)>Date.now())return{eligible:!1,wait:`scheduled_time`,message:`Scheduled for ${new Date(e.notBefore).toLocaleString()}`};let i=e.hostId??n.defaultHostId,a=i?t.hosts[i]:void 0;return!a||a.revokedAt?{eligible:!1,wait:`invalid_configuration`,message:`No host is configured for this project`}:a.piCompatible?a.connectivity===`connected`?(t.runningByProject[n.id]??0)>=n.maxConcurrentRuns?{eligible:!1,wait:`project_limit`,message:`${n.name} already runs ${n.maxConcurrentRuns} of ${n.maxConcurrentRuns} allowed tasks`}:{eligible:!0,hostId:a.id,hostName:a.name}:{eligible:!1,wait:`host_offline`,message:`${a.name} is offline`}:{eligible:!1,wait:`invalid_configuration`,message:`Pi on ${a.name} is not compatible`}}function _e(e){let t=new Map;for(let n of Object.values(e)){if(n.resolvedAt||!n.taskId)continue;let e=t.get(n.taskId)??[];e.push(n),t.set(n.taskId,e)}return t}function ve(e,t){let n=e.dependencies.length;if(n===0)return null;let r=e.dependencies.filter(e=>t[e]?.state!==`done`).length,i=`${n} ${n===1?`dependency`:`dependencies`}`;return r>0?`${i} (${r} open)`:`${i} (all done)`}var X=r(),Z=`tap h-9 min-w-0 rounded-md border border-border bg-surface px-2 text-base text-text md:text-sm`;function ye({board:e,className:t}){let n=a(),r=(0,T.useId)();return(0,X.jsxs)(`div`,{className:h(`flex min-w-0 items-center gap-2`,t),children:[(0,X.jsx)(`label`,{htmlFor:r,className:`sr-only`,children:`Project`}),(0,X.jsxs)(`select`,{id:r,className:h(Z,`w-full max-w-56`),value:e.projectId??``,onChange:t=>e.setProjectId(t.target.value||null),children:[(0,X.jsx)(`option`,{value:``,children:`All projects`}),n.map(e=>(0,X.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]})}function be({board:e,className:t}){let n=(0,T.useId)();return(0,X.jsxs)(`div`,{className:h(`relative min-w-0`,t),children:[(0,X.jsx)(`label`,{htmlFor:n,className:`sr-only`,children:`Search tasks`}),(0,X.jsx)(_,{"aria-hidden":!0,className:`pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-subtle`}),(0,X.jsx)(ie,{id:n,type:`search`,placeholder:`Search tasks`,className:`pl-8`,value:e.filters.search,onChange:t=>e.setFilters({...e.filters,search:t.target.value})})]})}function xe({board:e}){let t=(0,T.useId)();return(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 text-sm`,children:[(0,X.jsx)(`label`,{htmlFor:t,className:`text-muted`,children:`Sort`}),(0,X.jsxs)(`select`,{id:t,className:Z,value:e.filters.sort,onChange:t=>e.setFilters({...e.filters,sort:t.target.value}),children:[(0,X.jsx)(`option`,{value:`priority`,children:`Priority`}),(0,X.jsx)(`option`,{value:`updated`,children:`Recently updated`}),(0,X.jsx)(`option`,{value:`created`,children:`Newest`})]})]})}function Se({board:e}){return(0,X.jsxs)(`label`,{className:`tap inline-flex items-center gap-2 text-sm`,children:[(0,X.jsx)(`input`,{type:`checkbox`,checked:e.filters.showCompleted,onChange:t=>e.setFilters({...e.filters,showCompleted:t.target.checked})}),`Show completed`]})}function Ce({compact:e}){let t=u(e=>e.dispatchPaused),[n,r]=(0,T.useState)(!1),i=t?y:v;return(0,X.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2 text-sm`,children:[(0,X.jsxs)(`span`,{role:`status`,className:h(`inline-flex items-center gap-1.5 font-medium`,t?`text-warning`:`text-success`),children:[(0,X.jsx)(i,{"aria-hidden":!0,className:`size-4`}),(0,X.jsx)(`span`,{className:`text-text`,children:t?`Automation paused`:`Automation enabled`})]}),(0,X.jsx)(g,{size:`sm`,busy:n,onClick:async()=>{r(!0);try{await L(!t),b.success(t?`Dispatch resumed. Ready tasks start when eligible.`:`Dispatch paused. Running work continues; nothing new starts.`)}catch(e){b.error(`Could not ${t?`resume`:`pause`} dispatch: ${p(e)}`)}finally{r(!1)}},children:t?`Resume dispatch`:e?`Pause`:`Pause dispatch`})]})}function we({value:e,onChange:t,withSort:n}){let r=s(),i=(0,T.useId)(),a=(n,r)=>t({...e,priorities:r?[...e.priorities,n]:e.priorities.filter(e=>e!==n)});return(0,X.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,X.jsxs)(`fieldset`,{className:`flex flex-col gap-1`,children:[(0,X.jsx)(`legend`,{className:`mb-1 text-sm font-medium`,children:`Priority`}),(0,X.jsx)(`div`,{className:`flex flex-wrap gap-x-4`,children:C.map((t,n)=>(0,X.jsxs)(`label`,{className:`tap inline-flex items-center gap-2 text-sm`,children:[(0,X.jsx)(`input`,{type:`checkbox`,checked:e.priorities.includes(n),onChange:e=>a(n,e.target.checked)}),t]},t))})]}),(0,X.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,X.jsx)(`label`,{htmlFor:`${i}-host`,className:`text-sm font-medium`,children:`Host`}),(0,X.jsxs)(`select`,{id:`${i}-host`,className:Z,value:e.hostId??``,onChange:n=>t({...e,hostId:n.target.value||null}),children:[(0,X.jsx)(`option`,{value:``,children:`Any host`}),r.map(e=>(0,X.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,X.jsxs)(`fieldset`,{className:`flex flex-col gap-1`,children:[(0,X.jsx)(`legend`,{className:`mb-1 text-sm font-medium`,children:`Show`}),(0,X.jsxs)(`label`,{className:`tap inline-flex items-center gap-2 text-sm`,children:[(0,X.jsx)(`input`,{type:`checkbox`,checked:e.attentionOnly,onChange:n=>t({...e,attentionOnly:n.target.checked})}),`Only tasks that need attention`]}),(0,X.jsxs)(`label`,{className:`tap inline-flex items-center gap-2 text-sm`,children:[(0,X.jsx)(`input`,{type:`checkbox`,checked:e.blockedOnly,onChange:n=>t({...e,blockedOnly:n.target.checked})}),`Only blocked tasks`]}),(0,X.jsxs)(`label`,{className:`tap inline-flex items-center gap-2 text-sm`,children:[(0,X.jsx)(`input`,{type:`checkbox`,checked:e.showCanceled,onChange:n=>t({...e,showCanceled:n.target.checked})}),`Canceled tasks`]}),(0,X.jsxs)(`label`,{className:`tap inline-flex items-center gap-2 text-sm`,children:[(0,X.jsx)(`input`,{type:`checkbox`,checked:e.showCompleted,onChange:n=>t({...e,showCompleted:n.target.checked})}),`Completed tasks`]})]}),n&&(0,X.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,X.jsx)(`label`,{htmlFor:`${i}-sort`,className:`text-sm font-medium`,children:`Sort`}),(0,X.jsxs)(`select`,{id:`${i}-sort`,className:Z,value:e.sort,onChange:n=>t({...e,sort:n.target.value}),children:[(0,X.jsx)(`option`,{value:`priority`,children:`Priority`}),(0,X.jsx)(`option`,{value:`updated`,children:`Recently updated`}),(0,X.jsx)(`option`,{value:`created`,children:`Newest`})]})]})]})}function Q({board:e,mobile:t}){let[n,r]=(0,T.useState)(!1),[a,o]=(0,T.useState)(e.filters),s=u(e=>e.hosts),c=W(e.filters,e=>s[e]?.name??`host`).filter(e=>e.key!==`search`).length,l=t?re:ae;return(0,X.jsxs)(X.Fragment,{children:[(0,X.jsxs)(g,{icon:(0,X.jsx)(oe,{className:`size-4`}),onClick:()=>{o(e.filters),r(!0)},"aria-label":c?`Filters, ${c} active`:`Filters`,children:[`Filters`,c>0&&(0,X.jsx)(i,{tone:`accent`,children:c})]}),(0,X.jsx)(l,{open:n,onClose:()=>r(!1),title:`Filter tasks`,footer:(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(g,{variant:`ghost`,onClick:()=>o({...H,search:a.search}),children:`Reset`}),(0,X.jsx)(g,{variant:`primary`,onClick:()=>{e.setFilters(a),r(!1)},children:`Show results`})]}),children:(0,X.jsx)(we,{value:a,onChange:o,withSort:t})})]})}function Te({board:e,includeSearch:t}){let n=u(e=>e.hosts),r=W(e.filters,e=>n[e]?.name??`Unknown host`).filter(e=>t||e.key!==`search`);return r.length===0?null:(0,X.jsxs)(`ul`,{"data-testid":`filter-chips`,"aria-label":`Active filters`,className:`flex min-w-0 flex-wrap gap-1.5`,children:[r.map(t=>(0,X.jsx)(`li`,{className:`min-w-0`,children:(0,X.jsxs)(`button`,{type:`button`,onClick:()=>e.setFilters(t.clear(e.filters)),"aria-label":`Remove filter ${t.label}`,className:`tap inline-flex max-w-full items-center gap-1 rounded-full border border-border bg-surface-2 px-2.5 py-0.5 text-xs font-medium`,children:[(0,X.jsx)(`span`,{className:`truncate`,children:t.label}),(0,X.jsx)(x,{"aria-hidden":!0,className:`size-3.5 shrink-0`})]})},t.key)),r.length>1&&(0,X.jsx)(`li`,{children:(0,X.jsx)(`button`,{type:`button`,className:`tap rounded px-2 py-0.5 text-xs font-medium text-accent`,onClick:()=>e.setFilters({...H,sort:e.filters.sort}),children:`Clear all`})})]})}function Ee({board:e}){let t=u(e=>e.tasks),n=u(e=>e.runs),r=u(e=>e.hosts),i=u(e=>e.interactions),{offline:a,pending:o}=(0,T.useMemo)(()=>{let a=new Set,o=new Set;for(let i of Object.values(t)){if(e.projectId&&i.projectId!==e.projectId)continue;i.sessionId&&o.add(i.sessionId);let t=i.currentRunId?n[i.currentRunId]:void 0;if(i.state===`in_progress`&&t?.hostId){let e=r[t.hostId];e&&e.connectivity!==`connected`&&a.add(e.id)}}let s=Object.values(i).filter(e=>e.state===`pending`&&o.has(e.sessionId)).sort((e,t)=>e.createdAt.localeCompare(t.createdAt));return{offline:[...a].map(e=>r[e]),pending:s}},[t,n,r,i,e.projectId]),s=e.now.error,l=[];for(let e of a)l.push((0,X.jsx)(te,{compact:!0,hostName:e.name,connectivity:e.connectivity===`reconnecting`?`reconnecting`:`unreachable`,lastSeenAt:e.lastSeenAt,detail:`Its In progress tasks keep their last known state; nothing is restarted elsewhere.`},`host-${e.id}`));return o.length>0&&l.push((0,X.jsx)(m,{count:o.length,to:S.interaction(o[0].sessionId,o[0].id),label:o.length===1?`A task needs your answer`:`${o.length} questions need your answer`},`pending`)),s!=null&&(c(s)&&s.status===404?l.push((0,X.jsx)(ee,{capability:`Queue details`,reason:`This coordinator does not report why Ready tasks are waiting.`},`now`)):l.push((0,X.jsx)(ne,{compact:!0,title:`Could not load the dispatch queue`,error:p(s),onRetry:e.now.reload},`now`))),l.length===0?null:(0,X.jsx)(`div`,{className:`flex flex-col gap-2 px-4 pt-2`,children:l})}function $(e,t,n={}){let[r,i]=(0,T.useState)(void 0),[a,o]=(0,T.useState)(null),[s,c]=(0,T.useState)(e!==null),[l,u]=(0,T.useState)(0),d=(0,T.useRef)(t);return d.current=t,(0,T.useEffect)(()=>{if(e===null){c(!1);return}let t=new AbortController;return c(!0),d.current(t.signal).then(e=>{t.signal.aborted||(i(e),o(null))}).catch(e=>{t.signal.aborted||e instanceof DOMException&&e.name===`AbortError`||o(e)}).finally(()=>{t.signal.aborted||c(!1)}),()=>t.abort()},[e,l]),(0,T.useEffect)(()=>{if(!n.refreshMs||e===null)return;let t=setInterval(()=>{document.visibilityState===`visible`&&u(e=>e+1)},n.refreshMs);return()=>clearInterval(t)},[n.refreshMs,e]),{data:r,error:a,loading:s,reload:(0,T.useCallback)(()=>u(e=>e+1),[])}}function De(e=!0){let t=$(e?`now`:null,e=>f(`/api/now`,void 0,e),{refreshMs:15e3}),n=u(e=>e.tasks),r=u(e=>e.runs),i=u(e=>e.dispatchPaused),a=(0,T.useRef)(!0),{reload:o}=t;return(0,T.useEffect)(()=>{if(a.current){a.current=!1;return}if(!e)return;let t=setTimeout(o,500);return()=>clearTimeout(t)},[n,r,i,e,o]),t}export{R as A,ge as C,F as D,j as E,P as M,N,I as O,A as P,me as S,k as T,le as _,Ce as a,_e as b,ye as c,H as d,V as f,he as g,ve as h,Se as i,z as j,M as k,be as l,se as m,$ as n,Q as o,Y as p,Ee as r,Te as s,De as t,xe as u,pe as v,ce as w,de as x,U as y};
2
- //# sourceMappingURL=useNow-jxdoOC_1.js.map