@alexjbarnes/cockpit 0.3.0 → 0.3.1

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 (220) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +1 -1
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/server/app/(app)/changes/page_client-reference-manifest.js +1 -1
  6. package/.next/server/app/(app)/reviews/[owner]/[repo]/[number]/page_client-reference-manifest.js +1 -1
  7. package/.next/server/app/(app)/sessions/[id]/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found.html +1 -1
  17. package/.next/server/app/_not-found.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  24. package/.next/server/app/agents.html +1 -1
  25. package/.next/server/app/agents.rsc +1 -1
  26. package/.next/server/app/agents.segments/!KGFwcCk/agents/__PAGE__.segment.rsc +1 -1
  27. package/.next/server/app/agents.segments/!KGFwcCk/agents.segment.rsc +1 -1
  28. package/.next/server/app/agents.segments/!KGFwcCk.segment.rsc +1 -1
  29. package/.next/server/app/agents.segments/_full.segment.rsc +1 -1
  30. package/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  31. package/.next/server/app/agents.segments/_index.segment.rsc +1 -1
  32. package/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
  33. package/.next/server/app/changes.html +1 -1
  34. package/.next/server/app/changes.rsc +2 -2
  35. package/.next/server/app/changes.segments/!KGFwcCk/changes/__PAGE__.segment.rsc +2 -2
  36. package/.next/server/app/changes.segments/!KGFwcCk/changes.segment.rsc +1 -1
  37. package/.next/server/app/changes.segments/!KGFwcCk.segment.rsc +1 -1
  38. package/.next/server/app/changes.segments/_full.segment.rsc +2 -2
  39. package/.next/server/app/changes.segments/_head.segment.rsc +1 -1
  40. package/.next/server/app/changes.segments/_index.segment.rsc +1 -1
  41. package/.next/server/app/changes.segments/_tree.segment.rsc +1 -1
  42. package/.next/server/app/claude-md/edit.html +1 -1
  43. package/.next/server/app/claude-md/edit.rsc +1 -1
  44. package/.next/server/app/claude-md/edit.segments/!KGFwcCk/claude-md/edit/__PAGE__.segment.rsc +1 -1
  45. package/.next/server/app/claude-md/edit.segments/!KGFwcCk/claude-md/edit.segment.rsc +1 -1
  46. package/.next/server/app/claude-md/edit.segments/!KGFwcCk/claude-md.segment.rsc +1 -1
  47. package/.next/server/app/claude-md/edit.segments/!KGFwcCk.segment.rsc +1 -1
  48. package/.next/server/app/claude-md/edit.segments/_full.segment.rsc +1 -1
  49. package/.next/server/app/claude-md/edit.segments/_head.segment.rsc +1 -1
  50. package/.next/server/app/claude-md/edit.segments/_index.segment.rsc +1 -1
  51. package/.next/server/app/claude-md/edit.segments/_tree.segment.rsc +1 -1
  52. package/.next/server/app/claude-md.html +1 -1
  53. package/.next/server/app/claude-md.rsc +1 -1
  54. package/.next/server/app/claude-md.segments/!KGFwcCk/claude-md/__PAGE__.segment.rsc +1 -1
  55. package/.next/server/app/claude-md.segments/!KGFwcCk/claude-md.segment.rsc +1 -1
  56. package/.next/server/app/claude-md.segments/!KGFwcCk.segment.rsc +1 -1
  57. package/.next/server/app/claude-md.segments/_full.segment.rsc +1 -1
  58. package/.next/server/app/claude-md.segments/_head.segment.rsc +1 -1
  59. package/.next/server/app/claude-md.segments/_index.segment.rsc +1 -1
  60. package/.next/server/app/claude-md.segments/_tree.segment.rsc +1 -1
  61. package/.next/server/app/commands.html +1 -1
  62. package/.next/server/app/commands.rsc +1 -1
  63. package/.next/server/app/commands.segments/!KGFwcCk/commands/__PAGE__.segment.rsc +1 -1
  64. package/.next/server/app/commands.segments/!KGFwcCk/commands.segment.rsc +1 -1
  65. package/.next/server/app/commands.segments/!KGFwcCk.segment.rsc +1 -1
  66. package/.next/server/app/commands.segments/_full.segment.rsc +1 -1
  67. package/.next/server/app/commands.segments/_head.segment.rsc +1 -1
  68. package/.next/server/app/commands.segments/_index.segment.rsc +1 -1
  69. package/.next/server/app/commands.segments/_tree.segment.rsc +1 -1
  70. package/.next/server/app/files.html +1 -1
  71. package/.next/server/app/files.rsc +1 -1
  72. package/.next/server/app/files.segments/!KGFwcCk/files/__PAGE__.segment.rsc +1 -1
  73. package/.next/server/app/files.segments/!KGFwcCk/files.segment.rsc +1 -1
  74. package/.next/server/app/files.segments/!KGFwcCk.segment.rsc +1 -1
  75. package/.next/server/app/files.segments/_full.segment.rsc +1 -1
  76. package/.next/server/app/files.segments/_head.segment.rsc +1 -1
  77. package/.next/server/app/files.segments/_index.segment.rsc +1 -1
  78. package/.next/server/app/files.segments/_tree.segment.rsc +1 -1
  79. package/.next/server/app/hooks.html +1 -1
  80. package/.next/server/app/hooks.rsc +1 -1
  81. package/.next/server/app/hooks.segments/!KGFwcCk/hooks/__PAGE__.segment.rsc +1 -1
  82. package/.next/server/app/hooks.segments/!KGFwcCk/hooks.segment.rsc +1 -1
  83. package/.next/server/app/hooks.segments/!KGFwcCk.segment.rsc +1 -1
  84. package/.next/server/app/hooks.segments/_full.segment.rsc +1 -1
  85. package/.next/server/app/hooks.segments/_head.segment.rsc +1 -1
  86. package/.next/server/app/hooks.segments/_index.segment.rsc +1 -1
  87. package/.next/server/app/hooks.segments/_tree.segment.rsc +1 -1
  88. package/.next/server/app/inbox.html +1 -1
  89. package/.next/server/app/inbox.rsc +1 -1
  90. package/.next/server/app/inbox.segments/!KGFwcCk/inbox/__PAGE__.segment.rsc +1 -1
  91. package/.next/server/app/inbox.segments/!KGFwcCk/inbox.segment.rsc +1 -1
  92. package/.next/server/app/inbox.segments/!KGFwcCk.segment.rsc +1 -1
  93. package/.next/server/app/inbox.segments/_full.segment.rsc +1 -1
  94. package/.next/server/app/inbox.segments/_head.segment.rsc +1 -1
  95. package/.next/server/app/inbox.segments/_index.segment.rsc +1 -1
  96. package/.next/server/app/inbox.segments/_tree.segment.rsc +1 -1
  97. package/.next/server/app/index.html +1 -1
  98. package/.next/server/app/index.rsc +1 -1
  99. package/.next/server/app/index.segments/!KGFwcCk/__PAGE__.segment.rsc +1 -1
  100. package/.next/server/app/index.segments/!KGFwcCk.segment.rsc +1 -1
  101. package/.next/server/app/index.segments/_full.segment.rsc +1 -1
  102. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  103. package/.next/server/app/index.segments/_index.segment.rsc +1 -1
  104. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  105. package/.next/server/app/jobs.html +1 -1
  106. package/.next/server/app/jobs.rsc +1 -1
  107. package/.next/server/app/jobs.segments/!KGFwcCk/jobs/__PAGE__.segment.rsc +1 -1
  108. package/.next/server/app/jobs.segments/!KGFwcCk/jobs.segment.rsc +1 -1
  109. package/.next/server/app/jobs.segments/!KGFwcCk.segment.rsc +1 -1
  110. package/.next/server/app/jobs.segments/_full.segment.rsc +1 -1
  111. package/.next/server/app/jobs.segments/_head.segment.rsc +1 -1
  112. package/.next/server/app/jobs.segments/_index.segment.rsc +1 -1
  113. package/.next/server/app/jobs.segments/_tree.segment.rsc +1 -1
  114. package/.next/server/app/login.html +1 -1
  115. package/.next/server/app/login.rsc +1 -1
  116. package/.next/server/app/login.segments/_full.segment.rsc +1 -1
  117. package/.next/server/app/login.segments/_head.segment.rsc +1 -1
  118. package/.next/server/app/login.segments/_index.segment.rsc +1 -1
  119. package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
  120. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  121. package/.next/server/app/login.segments/login.segment.rsc +1 -1
  122. package/.next/server/app/mcp-servers.html +1 -1
  123. package/.next/server/app/mcp-servers.rsc +1 -1
  124. package/.next/server/app/mcp-servers.segments/!KGFwcCk/mcp-servers/__PAGE__.segment.rsc +1 -1
  125. package/.next/server/app/mcp-servers.segments/!KGFwcCk/mcp-servers.segment.rsc +1 -1
  126. package/.next/server/app/mcp-servers.segments/!KGFwcCk.segment.rsc +1 -1
  127. package/.next/server/app/mcp-servers.segments/_full.segment.rsc +1 -1
  128. package/.next/server/app/mcp-servers.segments/_head.segment.rsc +1 -1
  129. package/.next/server/app/mcp-servers.segments/_index.segment.rsc +1 -1
  130. package/.next/server/app/mcp-servers.segments/_tree.segment.rsc +1 -1
  131. package/.next/server/app/reviews.html +1 -1
  132. package/.next/server/app/reviews.rsc +1 -1
  133. package/.next/server/app/reviews.segments/!KGFwcCk/reviews/__PAGE__.segment.rsc +1 -1
  134. package/.next/server/app/reviews.segments/!KGFwcCk/reviews.segment.rsc +1 -1
  135. package/.next/server/app/reviews.segments/!KGFwcCk.segment.rsc +1 -1
  136. package/.next/server/app/reviews.segments/_full.segment.rsc +1 -1
  137. package/.next/server/app/reviews.segments/_head.segment.rsc +1 -1
  138. package/.next/server/app/reviews.segments/_index.segment.rsc +1 -1
  139. package/.next/server/app/reviews.segments/_tree.segment.rsc +1 -1
  140. package/.next/server/app/settings/appearance.html +1 -1
  141. package/.next/server/app/settings/appearance.rsc +1 -1
  142. package/.next/server/app/settings/appearance.segments/!KGFwcCk/settings/appearance/__PAGE__.segment.rsc +1 -1
  143. package/.next/server/app/settings/appearance.segments/!KGFwcCk/settings/appearance.segment.rsc +1 -1
  144. package/.next/server/app/settings/appearance.segments/!KGFwcCk/settings.segment.rsc +1 -1
  145. package/.next/server/app/settings/appearance.segments/!KGFwcCk.segment.rsc +1 -1
  146. package/.next/server/app/settings/appearance.segments/_full.segment.rsc +1 -1
  147. package/.next/server/app/settings/appearance.segments/_head.segment.rsc +1 -1
  148. package/.next/server/app/settings/appearance.segments/_index.segment.rsc +1 -1
  149. package/.next/server/app/settings/appearance.segments/_tree.segment.rsc +1 -1
  150. package/.next/server/app/settings/notifications.html +1 -1
  151. package/.next/server/app/settings/notifications.rsc +1 -1
  152. package/.next/server/app/settings/notifications.segments/!KGFwcCk/settings/notifications/__PAGE__.segment.rsc +1 -1
  153. package/.next/server/app/settings/notifications.segments/!KGFwcCk/settings/notifications.segment.rsc +1 -1
  154. package/.next/server/app/settings/notifications.segments/!KGFwcCk/settings.segment.rsc +1 -1
  155. package/.next/server/app/settings/notifications.segments/!KGFwcCk.segment.rsc +1 -1
  156. package/.next/server/app/settings/notifications.segments/_full.segment.rsc +1 -1
  157. package/.next/server/app/settings/notifications.segments/_head.segment.rsc +1 -1
  158. package/.next/server/app/settings/notifications.segments/_index.segment.rsc +1 -1
  159. package/.next/server/app/settings/notifications.segments/_tree.segment.rsc +1 -1
  160. package/.next/server/app/settings/providers/new.html +1 -1
  161. package/.next/server/app/settings/providers/new.rsc +1 -1
  162. package/.next/server/app/settings/providers/new.segments/!KGFwcCk/settings/providers/new/__PAGE__.segment.rsc +1 -1
  163. package/.next/server/app/settings/providers/new.segments/!KGFwcCk/settings/providers/new.segment.rsc +1 -1
  164. package/.next/server/app/settings/providers/new.segments/!KGFwcCk/settings/providers.segment.rsc +1 -1
  165. package/.next/server/app/settings/providers/new.segments/!KGFwcCk/settings.segment.rsc +1 -1
  166. package/.next/server/app/settings/providers/new.segments/!KGFwcCk.segment.rsc +1 -1
  167. package/.next/server/app/settings/providers/new.segments/_full.segment.rsc +1 -1
  168. package/.next/server/app/settings/providers/new.segments/_head.segment.rsc +1 -1
  169. package/.next/server/app/settings/providers/new.segments/_index.segment.rsc +1 -1
  170. package/.next/server/app/settings/providers/new.segments/_tree.segment.rsc +1 -1
  171. package/.next/server/app/settings/providers.html +1 -1
  172. package/.next/server/app/settings/providers.rsc +1 -1
  173. package/.next/server/app/settings/providers.segments/!KGFwcCk/settings/providers/__PAGE__.segment.rsc +1 -1
  174. package/.next/server/app/settings/providers.segments/!KGFwcCk/settings/providers.segment.rsc +1 -1
  175. package/.next/server/app/settings/providers.segments/!KGFwcCk/settings.segment.rsc +1 -1
  176. package/.next/server/app/settings/providers.segments/!KGFwcCk.segment.rsc +1 -1
  177. package/.next/server/app/settings/providers.segments/_full.segment.rsc +1 -1
  178. package/.next/server/app/settings/providers.segments/_head.segment.rsc +1 -1
  179. package/.next/server/app/settings/providers.segments/_index.segment.rsc +1 -1
  180. package/.next/server/app/settings/providers.segments/_tree.segment.rsc +1 -1
  181. package/.next/server/app/settings/session.html +1 -1
  182. package/.next/server/app/settings/session.rsc +1 -1
  183. package/.next/server/app/settings/session.segments/!KGFwcCk/settings/session/__PAGE__.segment.rsc +1 -1
  184. package/.next/server/app/settings/session.segments/!KGFwcCk/settings/session.segment.rsc +1 -1
  185. package/.next/server/app/settings/session.segments/!KGFwcCk/settings.segment.rsc +1 -1
  186. package/.next/server/app/settings/session.segments/!KGFwcCk.segment.rsc +1 -1
  187. package/.next/server/app/settings/session.segments/_full.segment.rsc +1 -1
  188. package/.next/server/app/settings/session.segments/_head.segment.rsc +1 -1
  189. package/.next/server/app/settings/session.segments/_index.segment.rsc +1 -1
  190. package/.next/server/app/settings/session.segments/_tree.segment.rsc +1 -1
  191. package/.next/server/app/settings.html +1 -1
  192. package/.next/server/app/settings.rsc +1 -1
  193. package/.next/server/app/settings.segments/!KGFwcCk/settings/__PAGE__.segment.rsc +1 -1
  194. package/.next/server/app/settings.segments/!KGFwcCk/settings.segment.rsc +1 -1
  195. package/.next/server/app/settings.segments/!KGFwcCk.segment.rsc +1 -1
  196. package/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  197. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  198. package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  199. package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  200. package/.next/server/app/skills.html +1 -1
  201. package/.next/server/app/skills.rsc +1 -1
  202. package/.next/server/app/skills.segments/!KGFwcCk/skills/__PAGE__.segment.rsc +1 -1
  203. package/.next/server/app/skills.segments/!KGFwcCk/skills.segment.rsc +1 -1
  204. package/.next/server/app/skills.segments/!KGFwcCk.segment.rsc +1 -1
  205. package/.next/server/app/skills.segments/_full.segment.rsc +1 -1
  206. package/.next/server/app/skills.segments/_head.segment.rsc +1 -1
  207. package/.next/server/app/skills.segments/_index.segment.rsc +1 -1
  208. package/.next/server/app/skills.segments/_tree.segment.rsc +1 -1
  209. package/.next/server/app-paths-manifest.json +1 -1
  210. package/.next/server/chunks/7782.js +1 -1
  211. package/.next/server/middleware-build-manifest.js +1 -1
  212. package/.next/server/pages/404.html +1 -1
  213. package/.next/server/pages/500.html +1 -1
  214. package/.next/server/server-reference-manifest.json +1 -1
  215. package/.next/static/chunks/{48273-bbd15bac6733dfc4.js → 48273-fb393846bb4333c0.js} +1 -1
  216. package/README.md +12 -3
  217. package/bin/cockpit-hook-bridge.mjs +93 -24
  218. package/package.json +1 -1
  219. /package/.next/static/{zr8XZzqb74eHitdlkpo-C → I-rxZaJEzhe3ZUTjSqB11}/_buildManifest.js +0 -0
  220. /package/.next/static/{zr8XZzqb74eHitdlkpo-C → I-rxZaJEzhe3ZUTjSqB11}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-e31bb45fa59caed8.js"/><script src="/_next/static/chunks/4bd1b696-7281820e82fc5615.js" async=""></script><script src="/_next/static/chunks/93794-5f89a674d8cefcff.js" async=""></script><script src="/_next/static/chunks/main-app-6ef98a75f3b6a5ff.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-e31bb45fa59caed8.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n4:I[90484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[90484,[],\"ViewportBoundary\"]\na:I[90484,[],\"MetadataBoundary\"]\nc:I[27123,[],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"zr8XZzqb74eHitdlkpo-C\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-e31bb45fa59caed8.js"/><script src="/_next/static/chunks/4bd1b696-7281820e82fc5615.js" async=""></script><script src="/_next/static/chunks/93794-5f89a674d8cefcff.js" async=""></script><script src="/_next/static/chunks/main-app-6ef98a75f3b6a5ff.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-e31bb45fa59caed8.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n4:I[90484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[90484,[],\"ViewportBoundary\"]\na:I[90484,[],\"MetadataBoundary\"]\nc:I[27123,[],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"I-rxZaJEzhe3ZUTjSqB11\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
@@ -1 +1 @@
1
- {"node":{},"edge":{},"encryptionKey":"x1WEIlEGxgLP9wi9tv12udCRKNeNXPtLYNNRrK0L2YI="}
1
+ {"node":{},"edge":{},"encryptionKey":"08cs7sq4cAHryZTP5b9eePC4nzM/URhNrgUKxYKykc8="}
@@ -3,4 +3,4 @@ ${e.content}
3
3
  </file>`).join("\n\n")+(s?"\n\n"+s:"")),eg.current&&/^\/btw\s/i.test(s.trim())){let e=s.trim().replace(/^\/btw\s+/i,"");if(!e)return;Z({question:e,answer:null,loading:!0,error:null}),fetch("/api/btw",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({question:e,context:eb.current.filter(e=>"user"===e.role||"assistant"===e.role).slice(-20).map(e=>({role:e.role,content:e.content.slice(0,2e3)})),model:ev.current,cwd:t})}).then(e=>e.json()).then(e=>{e.error?Z(t=>t?{...t,loading:!1,error:e.error}:null):Z(t=>t?{...t,loading:!1,answer:e.answer}:null)}).catch(e=>{Z(t=>t?{...t,loading:!1,error:e.message}:null)});return}if(eg.current){ek.current.push({text:s,images:r,documents:a,textFiles:l}),n({type:"message:send",sessionId:e,text:i,images:r?.length?r:void 0,documents:a?.length?a:void 0});return}ed&&(ek.current=[],ec([]),eu(!1),eo(!1));let c={id:"user-"+Date.now(),role:"user",content:s,toolUses:[],blocks:[],timestamp:Date.now(),images:r?.length?r:void 0,documents:a?.length?a:void 0,textFiles:l?.length?l:void 0};o(e=>[...e,c]),F([]);let d=s.replace(/^\[Attached [^\]]+\]\n*/gm,"").trim();d&&!d.startsWith("/")&&et(e=>e[0]===d?e:[d,...e.filter(e=>e!==d)]),n({type:"message:send",sessionId:e,text:i,images:r?.length?r:void 0,documents:a?.length?a:void 0})},[n,e,ed,t]),eI=(0,c.useCallback)(()=>{n({type:"session:interrupt",sessionId:e})},[n,e]),eq=(0,c.useCallback)((t,s,r,a)=>{n({type:"permission:response",sessionId:e,requestId:t,allowed:s,permissionMode:r,suggestionIndex:a}),h(e=>e.filter(e=>e.requestId!==t))},[n,e]),eD=(0,c.useCallback)((t,s)=>{console.log("[question-debug] respondToQuestion",t),n({type:"question:response",sessionId:e,requestId:t,answers:s}),g(e=>(console.log("[question-debug] marking answered, current pending:",e.map(e=>({id:e.requestId,answered:e.answered}))),e.map(e=>e.requestId===t?{...e,answered:!0}:e)))},[n,e]),[eE,e_]=(0,c.useState)(null),eT=(0,c.useCallback)((t,s)=>{v(null),w(t),void 0!==s&&k(s),n({type:"session:set_model",sessionId:e,model:t,contextSize:s})},[n,e]),eM=(0,c.useCallback)(async(t,s)=>{let n=t.replace(/\[.*\]$/,"");if(!(n.startsWith("claude")||null!==(0,u.AX)(n)))return void eT(t,s);try{let n=await fetch(`/api/sessions/thinking?sessionId=${encodeURIComponent(e)}`),r=await n.json();if(r.hasNonAnthropicThinking){v(null),e_({pending:!0,targetModel:t,models:r.models,contextSize:s});return}}catch{}eT(t,s)},[e,eT]),eR=(0,c.useCallback)((e,t)=>{eM(e,t)},[eM]),eU=(0,c.useCallback)(async()=>{if(!eE)return;let{targetModel:t,contextSize:s}=eE;await fetch("/api/sessions/thinking",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:e})}),e_(null),eT(t,s)},[eE,e,eT]),eP=(0,c.useCallback)(()=>{e_(null)},[]),ez=(0,c.useCallback)((t,s)=>{"main"===t&&w(s),n({type:"session:set_model_slot",sessionId:e,slot:t,modelId:s})},[n,e]),eL=(0,c.useCallback)(t=>{A(t),n({type:"permission:set_bypass",sessionId:e,enabled:t})},[n,e]),eF=(0,c.useCallback)(t=>{I(t),n({type:"session:set_plan_mode",sessionId:e,enabled:t})},[n,e]),eO=(0,c.useCallback)(t=>{D(t),o(e=>[...e,{id:"thinking-"+Date.now(),role:"system",content:`Thinking: ${t}`,toolUses:[],blocks:[],timestamp:Date.now()}]),n({type:"session:set_thinking",sessionId:e,level:t})},[n,e]),eW=(0,c.useCallback)(()=>{n({type:"message:cancel_queued",sessionId:e})},[n,e]),eB=(0,c.useCallback)(t=>{n({type:"message:delete_queued",sessionId:e,messageId:t})},[n,e]),eH=(0,c.useCallback)(t=>{n({type:"message:edit_queued",sessionId:e,messageId:t})},[n,e]),eQ=(0,c.useCallback)(()=>{n({type:"message:resume_queue",sessionId:e})},[n,e]),eJ=(0,c.useCallback)(()=>{ex(null)},[]),eK=(0,c.useCallback)(()=>{if(X?.answer){let e=Date.now();o(t=>[...t,{id:`btw-q-${e}`,role:"user",content:`[side question] ${X.question}`,toolUses:[],blocks:[],timestamp:e},{id:`btw-a-${e}`,role:"assistant",content:X.answer,toolUses:[],blocks:[],timestamp:e+1}])}Z(null)},[X]),eY=(0,c.useCallback)(()=>{z(null),n({type:"message:send",sessionId:e,text:"Continue from where you left off."})},[n,e]);return{messages:l,historyLoaded:E,isResponding:i,errorActive:ep,pendingPermissions:p,pendingQuestions:f,modelPicker:b,currentModel:j,currentContextSize:y,bypassActive:S,planMode:$,thinkingLevel:q,contextUsage:T,rateLimitStatus:R,apiError:P,suggestions:L,sessionName:O,initData:B,activeModelId:Q,hasQueuedMessage:el,queuedMessages:ei,queuePaused:ed,backgroundTasks:K,todos:V,btw:X,promptHistory:ee,hasMoreHistory:es,loadingMore:er,requestMoreHistory:eC,sendMessage:e$,interrupt:eI,respondToPermission:eq,respondToQuestion:eD,setModel:eR,setModelSlot:ez,setBypassAll:eL,setPlanMode:eF,setThinkingLevel:eO,cancelQueuedMessage:eW,deleteQueuedMessage:eB,editQueuedMessage:eH,resumeQueue:eQ,restoredText:em,clearRestoredText:eJ,dismissBtw:eK,retry:eY,currentRuntime:N,setRuntime:(0,c.useCallback)(t=>{C(t),n({type:"session:set_runtime",sessionId:e,runtime:t})},[n,e]),restartSession:(0,c.useCallback)(()=>{n({type:"session:restart",sessionId:e})},[n,e]),thinkingCheck:eE,confirmThinkingStrip:eU,cancelThinkingCheck:eP}}(e,t,v),{settings:eb}=(0,p.t)(),ev=(0,i.useRouter)(),{setHeader:ej,setBackgroundTasks:eN,setTodos:eC,setInitData:eA,setRuntime:e$}=(0,g.E2)(),eI=(0,c.useRef)(null),eq=(0,c.useRef)(!0),[eD,e_]=(0,c.useState)(!1),eT=(0,c.useRef)(0),[eU,ez]=(0,c.useState)(50),eW=(0,c.useRef)(0),eB=(0,c.useRef)(0),{selectedIds:eH,selectionMode:eQ,enterSelection:eJ,toggleSelect:eK,clearSelection:eY,copySelected:eV}=function(){let[e,t]=(0,c.useState)(new Set),s=e.size>0,n=(0,c.useCallback)(e=>{t(new Set([e]))},[]),r=(0,c.useCallback)(e=>{t(t=>{let s=new Set(t);return s.has(e)?s.delete(e):s.add(e),s})},[]),a=(0,c.useCallback)(()=>{t(new Set)},[]),l=(0,c.useCallback)(async s=>{let n=s.filter(t=>e.has(t.id)&&"system"!==t.role).map(d).filter(Boolean).join("\n\n---\n\n");if(n)if(navigator.clipboard?.writeText)await navigator.clipboard.writeText(n);else{let e=document.createElement("textarea");e.value=n,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e)}t(new Set)},[e]);return{selectedIds:e,selectionMode:s,enterSelection:n,toggleSelect:r,clearSelection:a,copySelected:l}}(),eG=(0,c.useRef)(new Set),[eX,eZ]=(0,c.useState)(!1),[e0,e1]=(0,c.useState)([]);(0,c.useEffect)(()=>{eZ(matchMedia("(pointer: coarse)").matches)},[]),(0,c.useEffect)(()=>{fetch("/api/providers").then(e=>e.json()).then(e=>{Array.isArray(e)&&e1(e)}).catch(()=>{})},[]);let e5=(0,c.useMemo)(()=>{let e=new Set;return y.filter(t=>!e.has(t.id)&&(e.add(t.id),!0))},[y]),e3=Math.max(0,e5.length-eU),e2=(0,c.useMemo)(()=>e5.slice(e3),[e5,e3]),e4=e3>0;(0,c.useEffect)(()=>{ez(50)},[]);let{send:e8}=(0,x.h)(),e6=(0,c.useCallback)(t=>{e8({type:"message:send",sessionId:e,text:`/rename ${t}`})},[e8,e]);(0,c.useEffect)(()=>{ej({title:U||s||(t?(0,h.uk)(t):"")||"Session",onRename:e6})},[U,s,t,ej,e6]),(0,c.useEffect)(()=>{eN(W)},[W,eN]),(0,c.useEffect)(()=>{eC(B)},[B,eC]),(0,c.useEffect)(()=>{eA(P)},[P,eA]),(0,c.useEffect)(()=>{e$(em)},[em,e$]),(0,c.useLayoutEffect)(()=>{let e=eI.current;if(!e||0===eB.current)return;let t=e.scrollHeight-eB.current;t>0&&(e.scrollTop+=t,eT.current=Date.now()+150),eB.current=0},[]);let e7=(0,c.useCallback)(()=>{if(Date.now()<eT.current)return;let e=eI.current;if(!e)return;let t=e.scrollHeight-e.scrollTop-e.clientHeight;eq.current=t<80,e_(t>300),e.scrollTop<800&&Date.now()>eW.current&&(eW.current=Date.now()+100,e4?(eB.current=e.scrollHeight,ez(e=>e+30)):J&&!K&&(eB.current=e.scrollHeight,Y()))},[e4,J,K,Y]),e9=(0,c.useCallback)(()=>{let e=eI.current;e&&(e.scrollTop=e.scrollHeight),eT.current=Date.now()+150,e_(!1)},[]);(0,c.useEffect)(()=>{eq.current&&e9()},[y,N,A,S,e9]),(0,c.useEffect)(()=>{if(!k)return;let e="cockpit:scrollPos:"+window.location.pathname,t=sessionStorage.getItem(e);if(!t)return;sessionStorage.removeItem(e);let s=Number(t),n=eI.current;n&&s>0&&(eq.current=!1,requestAnimationFrame(()=>{n.scrollTop=s}))},[k]),(0,c.useEffect)(()=>{let e=window.visualViewport;if(!e)return;let t=()=>{eq.current&&e9()};return e.addEventListener("resize",t),()=>e.removeEventListener("resize",t)},[e9]),(0,c.useEffect)(()=>{if(eX)return;let e=eI.current,t=()=>{document.activeElement?.closest("textarea, input, [contenteditable]")||document.activeElement!==e&&(e?.focus({preventScroll:!0}),eq.current&&e9())},s=()=>{"visible"===document.visibilityState&&eq.current&&e9()};return e?.addEventListener("pointermove",t),window.addEventListener("focus",t),document.addEventListener("visibilitychange",s),()=>{e?.removeEventListener("pointermove",t),window.removeEventListener("focus",t),document.removeEventListener("visibilitychange",s)}},[eX,e9]),(0,c.useEffect)(()=>{let e=e=>{if("Escape"!==e.key||!(N||C)||document.querySelector(".fixed.inset-0.z-50"))return;let t=e.target?.tagName;"TEXTAREA"!==t&&"INPUT"!==t&&(e.preventDefault(),G())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[N,C,G]);let te=(0,c.useRef)(!1),tt=(0,c.useCallback)((e,t,s,n)=>{eq.current=!0,b&&!te.current&&0===y.length?(te.current=!0,V(`${e}
4
4
 
5
5
  ---
6
- ${b}`,t,s,n)):V(e,t,s,n)},[V,b,y.length]);(0,c.useEffect)(()=>{j&&j(e=>tt(e))},[j,tt]);let ts=(0,c.useCallback)(()=>{V("/compact")},[V]),tn=(0,c.useCallback)(()=>{eV(e5)},[eV,e5]),tr=(0,c.useCallback)(async()=>{if(!t)return;eg();let e=eh?.targetModel;try{let s=await fetch("/api/sessions",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cwd:t,runtime:em,model:e})});if(s.ok){let e=await s.json();ev.push(`/sessions/${e.sessionId}?cwd=${encodeURIComponent(t)}`)}}catch{}},[t,em,eh?.targetModel,eg,ev]);return(0,n.jsxs)("div",{className:(0,f.cn)("flex flex-col flex-1 min-h-0",w),children:[(0,n.jsx)("div",{ref:eI,"data-chat-scroll":!0,tabIndex:eX?void 0:-1,className:"flex-1 min-h-0 overflow-y-auto p-4 outline-none",onScroll:e7,children:(0,n.jsxs)("div",{className:"mx-auto max-w-3xl lg:max-w-4xl xl:max-w-5xl 2xl:max-w-6xl space-y-4",children:[0===e5.length&&(0,n.jsx)("div",{className:"flex flex-col items-center pt-20 text-sm text-muted-foreground",children:k?(0,n.jsx)("p",{children:"Send a message to start the conversation."}):(0,n.jsx)(r.A,{className:"h-5 w-5 animate-spin"})}),(e4||K)&&(0,n.jsx)("div",{className:"flex justify-center py-2",children:(0,n.jsx)(r.A,{className:"h-4 w-4 animate-spin text-muted-foreground"})}),e2.map((e,t)=>{let s=t>0&&"__compacted__"===e2[t-1].content;if("assistant"===e.role){let{before:t,questionBlock:r,after:a}=function(e){let t=e.findIndex(e=>"tool_use"===e.type&&"AskUserQuestion"===e.toolUse.name);if(t<0)return{before:e,questionBlock:null,after:[]};let s=e[t];return{before:e.slice(0,t),questionBlock:s,after:e.slice(t+1).filter(e=>"tool_use"!==e.type||"AskUserQuestion"!==e.toolUse.name)}}(e.blocks||[]);if(r){let l=A.find(()=>!0),o=!!r.toolUse.output;return console.log(`[question-debug] Place1 render: msgId=${e.id.slice(0,8)}, hasOutput=${o}, pending=${!!l}, pendingCount=${A.length}`),(0,n.jsxs)("div",{"data-message-id":e.id,className:"space-y-4",children:[t.length>0&&(0,n.jsx)(ey.s,{message:{...e,blocks:t,content:""},collapsedByDefault:s,expandedToolIds:eG,selectionMode:eQ,selected:eH.has(e.id),onEnterSelection:eJ,onToggleSelect:eK}),(0,n.jsx)("div",{className:"flex w-full justify-start",children:(0,n.jsx)("div",{className:"max-w-[85%]",children:o?(0,n.jsx)(eR,{tool:r.toolUse}):l?(0,n.jsx)(eP,{questions:eM(l.questions),onSubmit:Z,requestId:l.requestId}):null})}),a.length>0&&(0,n.jsx)(ey.s,{message:{...e,blocks:a,content:""},collapsedByDefault:!1,expandedToolIds:eG,selectionMode:eQ,selected:eH.has(e.id),onEnterSelection:eJ,onToggleSelect:eK})]},e.id)}}return(0,n.jsx)("div",{"data-message-id":e.id,className:"space-y-4",children:(0,n.jsx)(ey.s,{message:e,collapsedByDefault:s,expandedToolIds:eG,selectionMode:eQ,selected:eH.has(e.id),onEnterSelection:eJ,onToggleSelect:eK})},e.id)}),(N||C)&&0===S.length&&!A.some(e=>!e.answered)&&(0,n.jsxs)("div",{className:"flex items-center gap-2 text-muted-foreground",children:[(0,n.jsx)(r.A,{className:"h-4 w-4 animate-spin"}),C&&!N&&(0,n.jsx)("span",{className:"text-xs text-red-500",children:"API error, retrying..."}),M&&(0,n.jsx)("span",{className:"text-xs",children:"Rate limited, retrying..."})]}),R&&!N&&!C&&(0,n.jsx)("div",{className:"flex w-full justify-start",children:(0,n.jsxs)("div",{className:"max-w-[85%] rounded-lg border border-red-500/30 bg-red-500/5 px-4 py-3",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2 text-red-500 mb-1",children:[(0,n.jsx)(a.A,{className:"h-4 w-4 shrink-0"}),(0,n.jsx)("span",{className:"text-sm font-medium",children:"API Error"})]}),(0,n.jsx)("p",{className:"text-xs text-muted-foreground mb-3",children:R}),(0,n.jsxs)("button",{onClick:eu,className:"flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-xs hover:bg-muted transition-colors",children:[(0,n.jsx)(l.A,{className:"h-3 w-3"}),"Retry"]})]})}),S.map(e=>"ExitPlanMode"===e.toolName?(0,n.jsx)(eE,{permission:e,bypassActive:D,onRespond:X,onSendMessage:V,onSetBypass:et,onSetPlanMode:es},e.requestId):(0,n.jsx)(eS,{permission:e,onRespond:X},e.requestId)),A.length>0&&!e2.some(e=>"assistant"===e.role&&(e.blocks||[]).some(e=>"tool_use"===e.type&&"AskUserQuestion"===e.toolUse.name))&&A.map(e=>(0,n.jsx)("div",{className:"flex w-full justify-start",children:(0,n.jsx)("div",{className:"max-w-[85%]",children:(0,n.jsx)(eP,{questions:eM(e.questions),onSubmit:Z,requestId:e.requestId})})},e.requestId)),null!==$&&(0,n.jsx)(ek,{currentModel:$,currentContextSize:q,activeModelId:z,onSelect:(e,t)=>ee(e,t),providers:e0}),(0,n.jsx)(eF,{open:null!==eh,models:eh?.models??[],onStrip:ef,onNewSession:tr,onCancel:eg}),(0,n.jsx)("div",{})]})}),eQ&&(0,n.jsx)(eL,{count:eH.size,onCopy:tn,onCancel:eY}),eD&&(0,n.jsx)("div",{className:"relative z-10 flex justify-center pointer-events-none",style:{marginTop:-52},children:(0,n.jsx)("button",{onClick:()=>{e9(),eq.current=!0,e_(!1)},className:"pointer-events-auto rounded-full border bg-background/90 backdrop-blur p-3 shadow-md text-muted-foreground hover:text-foreground transition-colors",children:(0,n.jsx)(o.A,{className:"h-5 w-5"})})}),(0,n.jsx)("div",{className:"shrink-0",children:(0,n.jsx)(ew,{sessionId:e,promptHistory:Q,onSend:tt,onInterrupt:G,isResponding:N||C,bypassActive:D,onSetBypass:et,planMode:E,onSetPlanMode:es,thinkingLevel:_,onSetThinking:en,currentModel:I,currentContextSize:q,onSetModel:ee,contextUsage:T,dismissKeyboard:eb.dismissKeyboardOnSend,cwd:t,onCompact:ts,initData:P,hasQueuedMessage:L,queuedMessages:F,queuePaused:O,onCancelQueued:er,onDeleteQueued:ea,onEditQueued:el,onResumeQueue:eo,restoredText:ei,onClearRestoredText:ec,btw:H,onDismissBtw:ed,currentRuntime:em,onSetRuntime:ex,onRestart:ep,providers:e0})})]})}}}]);
6
+ ${b}`,t,s,n)):V(e,t,s,n)},[V,b,y.length]);(0,c.useEffect)(()=>{j&&j(e=>tt(e))},[j,tt]);let ts=(0,c.useCallback)(()=>{V("/compact")},[V]),tn=(0,c.useCallback)(()=>{eV(e5)},[eV,e5]),tr=(0,c.useCallback)(async()=>{if(!t)return;eg();let e=eh?.targetModel;try{let s=await fetch("/api/sessions",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cwd:t,runtime:em,model:e})});if(s.ok){let e=await s.json();ev.push(`/sessions/${e.sessionId}?cwd=${encodeURIComponent(t)}`)}}catch{}},[t,em,eh?.targetModel,eg,ev]);return(0,n.jsxs)("div",{className:(0,f.cn)("flex flex-col flex-1 min-h-0",w),children:[(0,n.jsx)("div",{ref:eI,"data-chat-scroll":!0,tabIndex:eX?void 0:-1,className:"flex-1 min-h-0 overflow-y-auto p-4 outline-none",onScroll:e7,children:(0,n.jsxs)("div",{className:"mx-auto max-w-3xl lg:max-w-4xl xl:max-w-5xl 2xl:max-w-6xl space-y-4",children:[0===e5.length&&(0,n.jsx)("div",{className:"flex flex-col items-center pt-20 text-sm text-muted-foreground",children:k?(0,n.jsx)("p",{children:"Send a message to start the conversation."}):(0,n.jsx)(r.A,{className:"h-5 w-5 animate-spin"})}),(e4||K)&&(0,n.jsx)("div",{className:"flex justify-center py-2",children:(0,n.jsx)(r.A,{className:"h-4 w-4 animate-spin text-muted-foreground"})}),e2.map((e,t)=>{let s=t>0&&"__compacted__"===e2[t-1].content;if("assistant"===e.role){let{before:t,questionBlock:r,after:a}=function(e){let t=e.findIndex(e=>"tool_use"===e.type&&"AskUserQuestion"===e.toolUse.name);if(t<0)return{before:e,questionBlock:null,after:[]};let s=e[t];return{before:e.slice(0,t),questionBlock:s,after:e.slice(t+1).filter(e=>"tool_use"!==e.type||"AskUserQuestion"!==e.toolUse.name)}}(e.blocks||[]);if(r){let l=A.find(e=>!e.answered),o=!!r.toolUse.output;return console.log(`[question-debug] Place1 render: msgId=${e.id.slice(0,8)}, hasOutput=${o}, pending=${!!l}, pendingCount=${A.length}`),(0,n.jsxs)("div",{"data-message-id":e.id,className:"space-y-4",children:[t.length>0&&(0,n.jsx)(ey.s,{message:{...e,blocks:t,content:""},collapsedByDefault:s,expandedToolIds:eG,selectionMode:eQ,selected:eH.has(e.id),onEnterSelection:eJ,onToggleSelect:eK}),(0,n.jsx)("div",{className:"flex w-full justify-start",children:(0,n.jsx)("div",{className:"max-w-[85%]",children:o?(0,n.jsx)(eR,{tool:r.toolUse}):l?(0,n.jsx)(eP,{questions:eM(l.questions),onSubmit:Z,requestId:l.requestId}):null})}),a.length>0&&(0,n.jsx)(ey.s,{message:{...e,blocks:a,content:""},collapsedByDefault:!1,expandedToolIds:eG,selectionMode:eQ,selected:eH.has(e.id),onEnterSelection:eJ,onToggleSelect:eK})]},e.id)}}return(0,n.jsx)("div",{"data-message-id":e.id,className:"space-y-4",children:(0,n.jsx)(ey.s,{message:e,collapsedByDefault:s,expandedToolIds:eG,selectionMode:eQ,selected:eH.has(e.id),onEnterSelection:eJ,onToggleSelect:eK})},e.id)}),(N||C)&&0===S.length&&!A.some(e=>!e.answered)&&(0,n.jsxs)("div",{className:"flex items-center gap-2 text-muted-foreground",children:[(0,n.jsx)(r.A,{className:"h-4 w-4 animate-spin"}),C&&!N&&(0,n.jsx)("span",{className:"text-xs text-red-500",children:"API error, retrying..."}),M&&(0,n.jsx)("span",{className:"text-xs",children:"Rate limited, retrying..."})]}),R&&!N&&!C&&(0,n.jsx)("div",{className:"flex w-full justify-start",children:(0,n.jsxs)("div",{className:"max-w-[85%] rounded-lg border border-red-500/30 bg-red-500/5 px-4 py-3",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2 text-red-500 mb-1",children:[(0,n.jsx)(a.A,{className:"h-4 w-4 shrink-0"}),(0,n.jsx)("span",{className:"text-sm font-medium",children:"API Error"})]}),(0,n.jsx)("p",{className:"text-xs text-muted-foreground mb-3",children:R}),(0,n.jsxs)("button",{onClick:eu,className:"flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-xs hover:bg-muted transition-colors",children:[(0,n.jsx)(l.A,{className:"h-3 w-3"}),"Retry"]})]})}),S.map(e=>"ExitPlanMode"===e.toolName?(0,n.jsx)(eE,{permission:e,bypassActive:D,onRespond:X,onSendMessage:V,onSetBypass:et,onSetPlanMode:es},e.requestId):(0,n.jsx)(eS,{permission:e,onRespond:X},e.requestId)),A.some(e=>!e.answered)&&!e2.some(e=>"assistant"===e.role&&(e.blocks||[]).some(e=>"tool_use"===e.type&&"AskUserQuestion"===e.toolUse.name&&!e.toolUse.output))&&A.filter(e=>!e.answered).map(e=>(0,n.jsx)("div",{className:"flex w-full justify-start",children:(0,n.jsx)("div",{className:"max-w-[85%]",children:(0,n.jsx)(eP,{questions:eM(e.questions),onSubmit:Z,requestId:e.requestId})})},e.requestId)),null!==$&&(0,n.jsx)(ek,{currentModel:$,currentContextSize:q,activeModelId:z,onSelect:(e,t)=>ee(e,t),providers:e0}),(0,n.jsx)(eF,{open:null!==eh,models:eh?.models??[],onStrip:ef,onNewSession:tr,onCancel:eg}),(0,n.jsx)("div",{})]})}),eQ&&(0,n.jsx)(eL,{count:eH.size,onCopy:tn,onCancel:eY}),eD&&(0,n.jsx)("div",{className:"relative z-10 flex justify-center pointer-events-none",style:{marginTop:-52},children:(0,n.jsx)("button",{onClick:()=>{e9(),eq.current=!0,e_(!1)},className:"pointer-events-auto rounded-full border bg-background/90 backdrop-blur p-3 shadow-md text-muted-foreground hover:text-foreground transition-colors",children:(0,n.jsx)(o.A,{className:"h-5 w-5"})})}),(0,n.jsx)("div",{className:"shrink-0",children:(0,n.jsx)(ew,{sessionId:e,promptHistory:Q,onSend:tt,onInterrupt:G,isResponding:N||C,bypassActive:D,onSetBypass:et,planMode:E,onSetPlanMode:es,thinkingLevel:_,onSetThinking:en,currentModel:I,currentContextSize:q,onSetModel:ee,contextUsage:T,dismissKeyboard:eb.dismissKeyboardOnSend,cwd:t,onCompact:ts,initData:P,hasQueuedMessage:L,queuedMessages:F,queuePaused:O,onCancelQueued:er,onDeleteQueued:ea,onEditQueued:el,onResumeQueue:eo,restoredText:ei,onClearRestoredText:ec,btw:H,onDismissBtw:ed,currentRuntime:em,onSetRuntime:ex,onRestart:ep,providers:e0})})]})}}}]);
package/README.md CHANGED
@@ -17,7 +17,9 @@ Three things follow:
17
17
  2. **Many Claude Code sessions running at once.** Switch between projects without juggling tmux panes. Sessions live on the server, so closing the browser does not kill them. The chat view stitches across `/clear` so long threads keep their full visual history.
18
18
  3. **Cron-driven Claude Code.** Schedule a prompt, walk away. Each run produces a transcript that renders the same as a live session.
19
19
 
20
- Inside a session: a diff viewer for code changes (split or inline), a file viewer with syntax highlighting, global search across all sessions (Ctrl+Shift+F), and plan-mode approvals when Claude proposes a plan. The sidebar shows collapsible sections for sessions, reviews, file changes, and file trees, with status beacons so you can tell at a glance which sessions are working, waiting, or idle.
20
+ Inside a session: a tabbed, split-pane layout holding the chat, a diff viewer for code changes (split or inline), a file viewer with syntax highlighting, and an embedded terminal. Plus global search across all sessions (Ctrl+Shift+F), searchable prompt history on the up arrow, and plan-mode approvals when Claude proposes a plan. The sidebar shows collapsible sections for sessions, reviews, file changes, and file trees, with status beacons so you can tell at a glance which sessions are working, waiting, or idle.
21
+
22
+ Choose your model per session: built-in Haiku, Sonnet, and Opus, or your own Anthropic-compatible providers (proxies and gateways), with a 200K or 1M context selector. Each session can run in Stream mode (headless) or PTY mode, which drives the real Claude Code CLI through a pseudo-terminal.
21
23
 
22
24
  It also takes care of things you usually hand-edit: agents, skills, hooks, MCP servers, CLAUDE.md memory. All editable from the UI.
23
25
 
@@ -80,6 +82,11 @@ Tested on Linux and macOS. Windows is unverified.
80
82
  | `PORT` | Port the server listens on | `3001` |
81
83
  | `HOST` | Bind address | `0.0.0.0` |
82
84
  | `COCKPIT_RESET_PASSWORD` | Set to `true` to reset password on next startup | `false` |
85
+ | `COCKPIT_CONFIG_DIR` | Cockpit config location (password, providers, defaults, jobs, inbox) | `~/.cockpit` |
86
+ | `CLAUDE_CONFIG_DIR` | Claude config and transcripts Cockpit reads | `~/.claude` |
87
+ | `COCKPIT_DEBUG` | Set to `1` to write a structured debug log | unset |
88
+
89
+ Setting `COCKPIT_CONFIG_DIR` and `CLAUDE_CONFIG_DIR` together lets you run isolated instances side by side. See [Settings](docs/settings.md#environment-variables) for the full list.
83
90
 
84
91
  ## Remote access
85
92
 
@@ -91,10 +98,12 @@ To restrict Cockpit to the host machine only, set `HOST=127.0.0.1`.
91
98
 
92
99
  ## Documentation
93
100
 
94
- - [Sessions](docs/sessions.md): chat, sidebar, attachments, plan mode, diffs, file view, todos, search, session linking
101
+ - [Sessions](docs/sessions.md): chat, runtime modes, tabbed layout, sidebar, attachments, plan mode, diffs, file view, prompt history, todos, search, session linking
102
+ - [Model providers](docs/providers.md): built-in and custom Anthropic-compatible providers, context sizes, model slots
103
+ - [Embedded terminal](docs/terminal.md): in-browser shell with themes and mobile support
95
104
  - [PR reviews](docs/pr-reviews.md): GitHub PR browsing and review sessions
96
105
  - [Scheduled jobs](docs/scheduled-jobs.md): cron-driven Claude Code runs
97
- - [Settings](docs/settings.md): auth, models, themes, notifications, inbox, agents, skills, hooks, MCP servers, CLAUDE.md
106
+ - [Settings](docs/settings.md): auth, models, providers, themes, notifications, inbox, updates, agents, skills, hooks, MCP servers, CLAUDE.md
98
107
 
99
108
  ## Development
100
109
 
@@ -11,10 +11,24 @@
11
11
  * COCKPIT_HOOK_TOKEN per-session token
12
12
  * COCKPIT_SESSION_ID cockpit's internal session id
13
13
  *
14
+ * Optional tuning (milliseconds):
15
+ * COCKPIT_PERMISSION_HOOK_TIMEOUT_MS how long to wait for a permission/question
16
+ * answer before giving up (default 24h)
17
+ * COCKPIT_HOOK_TIMEOUT_MS how long to wait for any other hook (default 60s)
18
+ *
14
19
  * Usage: cockpit-hook-bridge <eventName>
15
20
  * eventName ∈ {PreToolUse, PostToolUse, Stop, UserPromptSubmit, Notification, PermissionRequest}
21
+ *
22
+ * NOTE: this uses node:http directly rather than the global fetch(). fetch is
23
+ * undici, whose default headersTimeout/bodyTimeout are 5 minutes, so a held
24
+ * PermissionRequest response (the CLI blocks while the user decides) was aborted
25
+ * after 5 minutes — the CLI then hung with no decision and the user's eventual
26
+ * answer landed on a dead socket. node:http only times out on the explicit cap
27
+ * below, so a permission prompt can wait as long as the CLI's own hook timeout.
16
28
  */
17
29
 
30
+ import { request as httpRequest } from "node:http";
31
+
18
32
  const eventName = process.argv[2];
19
33
  if (!eventName) {
20
34
  process.stderr.write("cockpit-hook-bridge: missing event name argument\n");
@@ -29,6 +43,29 @@ if (!url || !token || !sessionId) {
29
43
  process.exit(0);
30
44
  }
31
45
 
46
+ function envMs(name, fallback) {
47
+ const raw = process.env[name];
48
+ if (!raw) return fallback;
49
+ const n = Number(raw);
50
+ return Number.isFinite(n) && n > 0 ? n : fallback;
51
+ }
52
+
53
+ // A permission/question can block on the user for a long time. Match the CLI's
54
+ // own permission hook timeout (24h) rather than fetch's hidden 5-minute ceiling.
55
+ const TIMEOUT_MS =
56
+ eventName === "PermissionRequest"
57
+ ? envMs("COCKPIT_PERMISSION_HOOK_TIMEOUT_MS", 24 * 60 * 60 * 1000)
58
+ : envMs("COCKPIT_HOOK_TIMEOUT_MS", 60 * 1000);
59
+
60
+ function permissionDenyJson(message) {
61
+ return JSON.stringify({
62
+ hookSpecificOutput: {
63
+ hookEventName: "PermissionRequest",
64
+ decision: { behavior: "deny", message },
65
+ },
66
+ });
67
+ }
68
+
32
69
  async function readStdin() {
33
70
  if (process.stdin.isTTY) return "";
34
71
  process.stdin.setEncoding("utf8");
@@ -37,14 +74,51 @@ async function readStdin() {
37
74
  return body;
38
75
  }
39
76
 
40
- const TIMEOUT_MS = eventName === "PermissionRequest" ? 10 * 60 * 1000 : 60 * 1000;
77
+ /**
78
+ * POST the payload and resolve with { status, body }. Rejects on transport
79
+ * error or when the request exceeds TIMEOUT_MS with no response.
80
+ */
81
+ function postHook(target, payload) {
82
+ return new Promise((resolve, reject) => {
83
+ let parsed;
84
+ try {
85
+ parsed = new URL(target);
86
+ } catch (err) {
87
+ reject(err);
88
+ return;
89
+ }
41
90
 
42
- function permissionDenyJson() {
43
- return JSON.stringify({
44
- hookSpecificOutput: {
45
- hookEventName: "PermissionRequest",
46
- decision: { behavior: "deny", message: "hook bridge timed out waiting for cockpit" },
47
- },
91
+ const req = httpRequest(
92
+ {
93
+ protocol: parsed.protocol,
94
+ hostname: parsed.hostname,
95
+ port: parsed.port,
96
+ path: parsed.pathname + parsed.search,
97
+ method: "POST",
98
+ headers: {
99
+ "Content-Type": "application/json",
100
+ "Content-Length": Buffer.byteLength(payload),
101
+ "X-Cockpit-Session": sessionId,
102
+ "X-Cockpit-Token": token,
103
+ },
104
+ },
105
+ (res) => {
106
+ res.setEncoding("utf8");
107
+ let data = "";
108
+ res.on("data", (chunk) => {
109
+ data += chunk;
110
+ });
111
+ res.on("end", () => resolve({ status: res.statusCode ?? 0, body: data }));
112
+ },
113
+ );
114
+
115
+ // The socket sits idle while the user decides; this is the only ceiling on
116
+ // how long we wait for the response.
117
+ req.setTimeout(TIMEOUT_MS, () => {
118
+ req.destroy(Object.assign(new Error("timed out waiting for cockpit"), { code: "ETIMEDOUT" }));
119
+ });
120
+ req.on("error", reject);
121
+ req.end(payload);
48
122
  });
49
123
  }
50
124
 
@@ -54,38 +128,33 @@ async function main() {
54
128
 
55
129
  let res;
56
130
  try {
57
- res = await fetch(target, {
58
- method: "POST",
59
- headers: {
60
- "Content-Type": "application/json",
61
- "X-Cockpit-Session": sessionId,
62
- "X-Cockpit-Token": token,
63
- },
64
- body: body || "{}",
65
- signal: AbortSignal.timeout(TIMEOUT_MS),
66
- });
131
+ res = await postHook(target, body || "{}");
67
132
  } catch (err) {
68
133
  const msg = err && err.message ? err.message : String(err);
69
- const isTimeout = err && err.name === "TimeoutError";
70
- process.stderr.write(`cockpit-hook-bridge: request ${isTimeout ? "timed out" : "failed"}: ${msg}\n`);
71
- if (isTimeout && eventName === "PermissionRequest") {
72
- process.stdout.write(permissionDenyJson());
134
+ const timedOut = err && err.code === "ETIMEDOUT";
135
+ process.stderr.write(`cockpit-hook-bridge: request ${timedOut ? "timed out" : "failed"}: ${msg}\n`);
136
+ // A permission request must always yield a decision, or the CLI hangs.
137
+ if (eventName === "PermissionRequest") {
138
+ process.stdout.write(permissionDenyJson(`hook bridge ${timedOut ? "timed out waiting for" : "could not reach"} cockpit`));
73
139
  }
74
140
  process.exit(0);
75
141
  }
76
142
 
77
- if (!res.ok) {
143
+ if (res.status < 200 || res.status >= 300) {
78
144
  process.stderr.write(`cockpit-hook-bridge: router returned ${res.status}\n`);
79
145
  if (eventName === "PermissionRequest") {
80
- process.stdout.write(permissionDenyJson());
146
+ process.stdout.write(permissionDenyJson(`hook router returned ${res.status}`));
81
147
  }
82
148
  process.exit(0);
83
149
  }
84
150
 
85
151
  let parsed;
86
152
  try {
87
- parsed = await res.json();
153
+ parsed = JSON.parse(res.body);
88
154
  } catch {
155
+ if (eventName === "PermissionRequest") {
156
+ process.stdout.write(permissionDenyJson("hook router sent an unreadable response"));
157
+ }
89
158
  process.exit(0);
90
159
  }
91
160
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexjbarnes/cockpit",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Web UI for Claude Code",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Alex Barnes (https://github.com/alexjbarnes)",