@openagt/dashboard 0.0.0-stage → 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 (610) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -2
  3. package/dist/agent-id.d.ts +13 -0
  4. package/dist/agent-id.d.ts.map +1 -0
  5. package/dist/agent-id.js +20 -0
  6. package/dist/agent-id.js.map +1 -0
  7. package/dist/agent-locks.d.ts +3 -0
  8. package/dist/agent-locks.d.ts.map +1 -0
  9. package/dist/agent-locks.js +40 -0
  10. package/dist/agent-locks.js.map +1 -0
  11. package/dist/agent-view.d.ts +39 -0
  12. package/dist/agent-view.d.ts.map +1 -0
  13. package/dist/agent-view.js +45 -0
  14. package/dist/agent-view.js.map +1 -0
  15. package/dist/bin.d.ts +3 -0
  16. package/dist/bin.d.ts.map +1 -0
  17. package/dist/bin.js +11 -0
  18. package/dist/bin.js.map +1 -0
  19. package/dist/branch-name.d.ts +8 -0
  20. package/dist/branch-name.d.ts.map +1 -0
  21. package/dist/branch-name.js +20 -0
  22. package/dist/branch-name.js.map +1 -0
  23. package/dist/bridge-browser.d.ts +217 -0
  24. package/dist/bridge-browser.d.ts.map +1 -0
  25. package/dist/bridge-browser.js +520 -0
  26. package/dist/bridge-browser.js.map +1 -0
  27. package/dist/browser-stream.d.ts +20 -0
  28. package/dist/browser-stream.d.ts.map +1 -0
  29. package/dist/browser-stream.js +51 -0
  30. package/dist/browser-stream.js.map +1 -0
  31. package/dist/browser.d.ts +16 -0
  32. package/dist/browser.d.ts.map +1 -0
  33. package/dist/browser.js +38 -0
  34. package/dist/browser.js.map +1 -0
  35. package/dist/built-in.d.ts +38 -0
  36. package/dist/built-in.d.ts.map +1 -0
  37. package/dist/built-in.js +119 -0
  38. package/dist/built-in.js.map +1 -0
  39. package/dist/chrome-extension/background.js +532 -0
  40. package/dist/chrome-extension/content.js +1475 -0
  41. package/dist/chrome-extension/driver-plan.js +41 -0
  42. package/dist/chrome-extension/fingerprint.js +43 -0
  43. package/dist/chrome-extension/manifest.json +31 -0
  44. package/dist/chrome-extension/options.html +48 -0
  45. package/dist/chrome-extension/options.js +122 -0
  46. package/dist/cli.d.ts +43 -0
  47. package/dist/cli.d.ts.map +1 -0
  48. package/dist/cli.js +186 -0
  49. package/dist/cli.js.map +1 -0
  50. package/dist/client.d.ts +16 -0
  51. package/dist/client.d.ts.map +1 -0
  52. package/dist/client.js +30 -0
  53. package/dist/client.js.map +1 -0
  54. package/dist/cloud-run-state.d.ts +27 -0
  55. package/dist/cloud-run-state.d.ts.map +1 -0
  56. package/dist/cloud-run-state.js +36 -0
  57. package/dist/cloud-run-state.js.map +1 -0
  58. package/dist/cloud-scratch-refs.d.ts +85 -0
  59. package/dist/cloud-scratch-refs.d.ts.map +1 -0
  60. package/dist/cloud-scratch-refs.js +275 -0
  61. package/dist/cloud-scratch-refs.js.map +1 -0
  62. package/dist/cloud-work.d.ts +66 -0
  63. package/dist/cloud-work.d.ts.map +1 -0
  64. package/dist/cloud-work.js +204 -0
  65. package/dist/cloud-work.js.map +1 -0
  66. package/dist/daemon-runtime.d.ts +42 -0
  67. package/dist/daemon-runtime.d.ts.map +1 -0
  68. package/dist/daemon-runtime.js +183 -0
  69. package/dist/daemon-runtime.js.map +1 -0
  70. package/dist/daemon-services.d.ts +37 -0
  71. package/dist/daemon-services.d.ts.map +1 -0
  72. package/dist/daemon-services.js +126 -0
  73. package/dist/daemon-services.js.map +1 -0
  74. package/dist/daemon-tick.d.ts +68 -0
  75. package/dist/daemon-tick.d.ts.map +1 -0
  76. package/dist/daemon-tick.js +97 -0
  77. package/dist/daemon-tick.js.map +1 -0
  78. package/dist/daemon.d.ts +65 -0
  79. package/dist/daemon.d.ts.map +1 -0
  80. package/dist/daemon.js +202 -0
  81. package/dist/daemon.js.map +1 -0
  82. package/dist/dashboard/activity.d.ts +41 -0
  83. package/dist/dashboard/activity.d.ts.map +1 -0
  84. package/dist/dashboard/activity.js +56 -0
  85. package/dist/dashboard/activity.js.map +1 -0
  86. package/dist/dashboard/agent-handoff.d.ts +244 -0
  87. package/dist/dashboard/agent-handoff.d.ts.map +1 -0
  88. package/dist/dashboard/agent-handoff.js +310 -0
  89. package/dist/dashboard/agent-handoff.js.map +1 -0
  90. package/dist/dashboard/bridge-endpoints.d.ts +158 -0
  91. package/dist/dashboard/bridge-endpoints.d.ts.map +1 -0
  92. package/dist/dashboard/bridge-endpoints.js +382 -0
  93. package/dist/dashboard/bridge-endpoints.js.map +1 -0
  94. package/dist/dashboard/bridge-question.d.ts +33 -0
  95. package/dist/dashboard/bridge-question.d.ts.map +1 -0
  96. package/dist/dashboard/bridge-question.js +20 -0
  97. package/dist/dashboard/bridge-question.js.map +1 -0
  98. package/dist/dashboard/bridge-sessions.d.ts +25 -0
  99. package/dist/dashboard/bridge-sessions.d.ts.map +1 -0
  100. package/dist/dashboard/bridge-sessions.js +46 -0
  101. package/dist/dashboard/bridge-sessions.js.map +1 -0
  102. package/dist/dashboard/bridge-starts.d.ts +61 -0
  103. package/dist/dashboard/bridge-starts.d.ts.map +1 -0
  104. package/dist/dashboard/bridge-starts.js +94 -0
  105. package/dist/dashboard/bridge-starts.js.map +1 -0
  106. package/dist/dashboard/bridge-store.d.ts +179 -0
  107. package/dist/dashboard/bridge-store.d.ts.map +1 -0
  108. package/dist/dashboard/bridge-store.js +262 -0
  109. package/dist/dashboard/bridge-store.js.map +1 -0
  110. package/dist/dashboard/bundle.d.ts +12 -0
  111. package/dist/dashboard/bundle.d.ts.map +1 -0
  112. package/dist/dashboard/bundle.js +22 -0
  113. package/dist/dashboard/bundle.js.map +1 -0
  114. package/dist/dashboard/cache.d.ts +47 -0
  115. package/dist/dashboard/cache.d.ts.map +1 -0
  116. package/dist/dashboard/cache.js +87 -0
  117. package/dist/dashboard/cache.js.map +1 -0
  118. package/dist/dashboard/content-type.d.ts +3 -0
  119. package/dist/dashboard/content-type.d.ts.map +1 -0
  120. package/dist/dashboard/content-type.js +31 -0
  121. package/dist/dashboard/content-type.js.map +1 -0
  122. package/dist/dashboard/dashboard.d.ts +38 -0
  123. package/dist/dashboard/dashboard.d.ts.map +1 -0
  124. package/dist/dashboard/dashboard.js +42 -0
  125. package/dist/dashboard/dashboard.js.map +1 -0
  126. package/dist/dashboard/docs.d.ts +39 -0
  127. package/dist/dashboard/docs.d.ts.map +1 -0
  128. package/dist/dashboard/docs.js +59 -0
  129. package/dist/dashboard/docs.js.map +1 -0
  130. package/dist/dashboard/git-status.d.ts +44 -0
  131. package/dist/dashboard/git-status.d.ts.map +1 -0
  132. package/dist/dashboard/git-status.js +37 -0
  133. package/dist/dashboard/git-status.js.map +1 -0
  134. package/dist/dashboard/http.d.ts +29 -0
  135. package/dist/dashboard/http.d.ts.map +1 -0
  136. package/dist/dashboard/http.js +74 -0
  137. package/dist/dashboard/http.js.map +1 -0
  138. package/dist/dashboard/index.d.ts +24 -0
  139. package/dist/dashboard/index.d.ts.map +1 -0
  140. package/dist/dashboard/index.js +23 -0
  141. package/dist/dashboard/index.js.map +1 -0
  142. package/dist/dashboard/interventions.d.ts +67 -0
  143. package/dist/dashboard/interventions.d.ts.map +1 -0
  144. package/dist/dashboard/interventions.js +169 -0
  145. package/dist/dashboard/interventions.js.map +1 -0
  146. package/dist/dashboard/keyed-watcher.d.ts +29 -0
  147. package/dist/dashboard/keyed-watcher.d.ts.map +1 -0
  148. package/dist/dashboard/keyed-watcher.js +42 -0
  149. package/dist/dashboard/keyed-watcher.js.map +1 -0
  150. package/dist/dashboard/keys.d.ts +31 -0
  151. package/dist/dashboard/keys.d.ts.map +1 -0
  152. package/dist/dashboard/keys.js +37 -0
  153. package/dist/dashboard/keys.js.map +1 -0
  154. package/dist/dashboard/models.d.ts +25 -0
  155. package/dist/dashboard/models.d.ts.map +1 -0
  156. package/dist/dashboard/models.js +30 -0
  157. package/dist/dashboard/models.js.map +1 -0
  158. package/dist/dashboard/module-host.d.ts +44 -0
  159. package/dist/dashboard/module-host.d.ts.map +1 -0
  160. package/dist/dashboard/module-host.js +91 -0
  161. package/dist/dashboard/module-host.js.map +1 -0
  162. package/dist/dashboard/module-serve.d.ts +15 -0
  163. package/dist/dashboard/module-serve.d.ts.map +1 -0
  164. package/dist/dashboard/module-serve.js +45 -0
  165. package/dist/dashboard/module-serve.js.map +1 -0
  166. package/dist/dashboard/open-in-app.d.ts +43 -0
  167. package/dist/dashboard/open-in-app.d.ts.map +1 -0
  168. package/dist/dashboard/open-in-app.js +98 -0
  169. package/dist/dashboard/open-in-app.js.map +1 -0
  170. package/dist/dashboard/open-questions.d.ts +45 -0
  171. package/dist/dashboard/open-questions.d.ts.map +1 -0
  172. package/dist/dashboard/open-questions.js +62 -0
  173. package/dist/dashboard/open-questions.js.map +1 -0
  174. package/dist/dashboard/overview.d.ts +78 -0
  175. package/dist/dashboard/overview.d.ts.map +1 -0
  176. package/dist/dashboard/overview.js +87 -0
  177. package/dist/dashboard/overview.js.map +1 -0
  178. package/dist/dashboard/projects.d.ts +101 -0
  179. package/dist/dashboard/projects.d.ts.map +1 -0
  180. package/dist/dashboard/projects.js +63 -0
  181. package/dist/dashboard/projects.js.map +1 -0
  182. package/dist/dashboard/pull-requests.d.ts +127 -0
  183. package/dist/dashboard/pull-requests.d.ts.map +1 -0
  184. package/dist/dashboard/pull-requests.js +137 -0
  185. package/dist/dashboard/pull-requests.js.map +1 -0
  186. package/dist/dashboard/queue.d.ts +17 -0
  187. package/dist/dashboard/queue.d.ts.map +1 -0
  188. package/dist/dashboard/queue.js +19 -0
  189. package/dist/dashboard/queue.js.map +1 -0
  190. package/dist/dashboard/quota.d.ts +53 -0
  191. package/dist/dashboard/quota.d.ts.map +1 -0
  192. package/dist/dashboard/quota.js +42 -0
  193. package/dist/dashboard/quota.js.map +1 -0
  194. package/dist/dashboard/relay-endpoints.d.ts +32 -0
  195. package/dist/dashboard/relay-endpoints.d.ts.map +1 -0
  196. package/dist/dashboard/relay-endpoints.js +115 -0
  197. package/dist/dashboard/relay-endpoints.js.map +1 -0
  198. package/dist/dashboard/remote-run.d.ts +95 -0
  199. package/dist/dashboard/remote-run.d.ts.map +1 -0
  200. package/dist/dashboard/remote-run.js +235 -0
  201. package/dist/dashboard/remote-run.js.map +1 -0
  202. package/dist/dashboard/rpc-serve.d.ts +106 -0
  203. package/dist/dashboard/rpc-serve.d.ts.map +1 -0
  204. package/dist/dashboard/rpc-serve.js +180 -0
  205. package/dist/dashboard/rpc-serve.js.map +1 -0
  206. package/dist/dashboard/run-inbox.d.ts +31 -0
  207. package/dist/dashboard/run-inbox.d.ts.map +1 -0
  208. package/dist/dashboard/run-inbox.js +51 -0
  209. package/dist/dashboard/run-inbox.js.map +1 -0
  210. package/dist/dashboard/server.d.ts +105 -0
  211. package/dist/dashboard/server.d.ts.map +1 -0
  212. package/dist/dashboard/server.js +231 -0
  213. package/dist/dashboard/server.js.map +1 -0
  214. package/dist/dashboard/static.d.ts +9 -0
  215. package/dist/dashboard/static.d.ts.map +1 -0
  216. package/dist/dashboard/static.js +54 -0
  217. package/dist/dashboard/static.js.map +1 -0
  218. package/dist/dashboard/types.d.ts +135 -0
  219. package/dist/dashboard/types.d.ts.map +1 -0
  220. package/dist/dashboard/types.js +2 -0
  221. package/dist/dashboard/types.js.map +1 -0
  222. package/dist/dashboard/web-start-endpoints.d.ts +32 -0
  223. package/dist/dashboard/web-start-endpoints.d.ts.map +1 -0
  224. package/dist/dashboard/web-start-endpoints.js +75 -0
  225. package/dist/dashboard/web-start-endpoints.js.map +1 -0
  226. package/dist/dashboard-bundle/assets/client-CbBRB9m4.js +9 -0
  227. package/dist/dashboard-bundle/assets/jsx-runtime-By8HlURe.js +1 -0
  228. package/dist/dashboard-bundle/assets/main-B98UOA3_.js +140 -0
  229. package/dist/dashboard-bundle/assets/main-ByRjbCiA.css +2 -0
  230. package/dist/dashboard-bundle/assets/module-v213KWfH.js +21 -0
  231. package/dist/dashboard-bundle/assets/react-CZI7_Jkm.js +1 -0
  232. package/dist/dashboard-bundle/assets/react-dom-cJyBB_A4.js +1 -0
  233. package/dist/dashboard-bundle/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  234. package/dist/dashboard-bundle/host/module.js +1 -0
  235. package/dist/dashboard-bundle/host/react-dom-client.js +1 -0
  236. package/dist/dashboard-bundle/host/react-dom.js +1 -0
  237. package/dist/dashboard-bundle/host/react-jsx-runtime.js +1 -0
  238. package/dist/dashboard-bundle/host/react.js +1 -0
  239. package/dist/dashboard-bundle/index.html +42 -0
  240. package/dist/dashboard-bundle/logo-animated.svg +34 -0
  241. package/dist/dashboard-bundle/logo.svg +16 -0
  242. package/dist/dashboard-rpc/context.d.ts +56 -0
  243. package/dist/dashboard-rpc/context.d.ts.map +1 -0
  244. package/dist/dashboard-rpc/context.js +106 -0
  245. package/dist/dashboard-rpc/context.js.map +1 -0
  246. package/dist/dashboard-rpc/control.d.ts +124 -0
  247. package/dist/dashboard-rpc/control.d.ts.map +1 -0
  248. package/dist/dashboard-rpc/control.js +284 -0
  249. package/dist/dashboard-rpc/control.js.map +1 -0
  250. package/dist/dashboard-rpc/devices.d.ts +9 -0
  251. package/dist/dashboard-rpc/devices.d.ts.map +1 -0
  252. package/dist/dashboard-rpc/devices.js +12 -0
  253. package/dist/dashboard-rpc/devices.js.map +1 -0
  254. package/dist/dashboard-rpc/events-tail.d.ts +68 -0
  255. package/dist/dashboard-rpc/events-tail.d.ts.map +1 -0
  256. package/dist/dashboard-rpc/events-tail.js +257 -0
  257. package/dist/dashboard-rpc/events-tail.js.map +1 -0
  258. package/dist/dashboard-rpc/events.d.ts +39 -0
  259. package/dist/dashboard-rpc/events.d.ts.map +1 -0
  260. package/dist/dashboard-rpc/events.js +47 -0
  261. package/dist/dashboard-rpc/events.js.map +1 -0
  262. package/dist/dashboard-rpc/index.d.ts +29 -0
  263. package/dist/dashboard-rpc/index.d.ts.map +1 -0
  264. package/dist/dashboard-rpc/index.js +40 -0
  265. package/dist/dashboard-rpc/index.js.map +1 -0
  266. package/dist/dashboard-rpc/models.d.ts +4 -0
  267. package/dist/dashboard-rpc/models.d.ts.map +1 -0
  268. package/dist/dashboard-rpc/models.js +8 -0
  269. package/dist/dashboard-rpc/models.js.map +1 -0
  270. package/dist/dashboard-rpc/modules.d.ts +45 -0
  271. package/dist/dashboard-rpc/modules.d.ts.map +1 -0
  272. package/dist/dashboard-rpc/modules.js +79 -0
  273. package/dist/dashboard-rpc/modules.js.map +1 -0
  274. package/dist/dashboard-rpc/preferences.d.ts +41 -0
  275. package/dist/dashboard-rpc/preferences.d.ts.map +1 -0
  276. package/dist/dashboard-rpc/preferences.js +65 -0
  277. package/dist/dashboard-rpc/preferences.js.map +1 -0
  278. package/dist/dashboard-rpc/projects.d.ts +85 -0
  279. package/dist/dashboard-rpc/projects.d.ts.map +1 -0
  280. package/dist/dashboard-rpc/projects.js +129 -0
  281. package/dist/dashboard-rpc/projects.js.map +1 -0
  282. package/dist/dashboard-rpc/quota.d.ts +4 -0
  283. package/dist/dashboard-rpc/quota.d.ts.map +1 -0
  284. package/dist/dashboard-rpc/quota.js +15 -0
  285. package/dist/dashboard-rpc/quota.js.map +1 -0
  286. package/dist/dashboard-rpc/reads.d.ts +185 -0
  287. package/dist/dashboard-rpc/reads.d.ts.map +1 -0
  288. package/dist/dashboard-rpc/reads.js +370 -0
  289. package/dist/dashboard-rpc/reads.js.map +1 -0
  290. package/dist/dashboard-rpc/relay-agent.d.ts +9 -0
  291. package/dist/dashboard-rpc/relay-agent.d.ts.map +1 -0
  292. package/dist/dashboard-rpc/relay-agent.js +21 -0
  293. package/dist/dashboard-rpc/relay-agent.js.map +1 -0
  294. package/dist/dashboard-rpc/relay-dispatch.d.ts +9 -0
  295. package/dist/dashboard-rpc/relay-dispatch.d.ts.map +1 -0
  296. package/dist/dashboard-rpc/relay-dispatch.js +24 -0
  297. package/dist/dashboard-rpc/relay-dispatch.js.map +1 -0
  298. package/dist/dashboard-rpc/stream-forward.d.ts +17 -0
  299. package/dist/dashboard-rpc/stream-forward.d.ts.map +1 -0
  300. package/dist/dashboard-rpc/stream-forward.js +38 -0
  301. package/dist/dashboard-rpc/stream-forward.js.map +1 -0
  302. package/dist/dashboard-rpc/test-context.d.ts +23 -0
  303. package/dist/dashboard-rpc/test-context.d.ts.map +1 -0
  304. package/dist/dashboard-rpc/test-context.js +43 -0
  305. package/dist/dashboard-rpc/test-context.js.map +1 -0
  306. package/dist/driver-names.d.ts +22 -0
  307. package/dist/driver-names.d.ts.map +1 -0
  308. package/dist/driver-names.js +29 -0
  309. package/dist/driver-names.js.map +1 -0
  310. package/dist/error-message.d.ts +8 -0
  311. package/dist/error-message.d.ts.map +1 -0
  312. package/dist/error-message.js +10 -0
  313. package/dist/error-message.js.map +1 -0
  314. package/dist/event-stream.d.ts +33 -0
  315. package/dist/event-stream.d.ts.map +1 -0
  316. package/dist/event-stream.js +104 -0
  317. package/dist/event-stream.js.map +1 -0
  318. package/dist/events.d.ts +236 -0
  319. package/dist/events.d.ts.map +1 -0
  320. package/dist/events.js +5 -0
  321. package/dist/events.js.map +1 -0
  322. package/dist/format-bytes.d.ts +3 -0
  323. package/dist/format-bytes.d.ts.map +1 -0
  324. package/dist/format-bytes.js +18 -0
  325. package/dist/format-bytes.js.map +1 -0
  326. package/dist/has-remote.d.ts +8 -0
  327. package/dist/has-remote.d.ts.map +1 -0
  328. package/dist/has-remote.js +10 -0
  329. package/dist/has-remote.js.map +1 -0
  330. package/dist/index.d.ts +42 -0
  331. package/dist/index.d.ts.map +1 -0
  332. package/dist/index.js +16 -0
  333. package/dist/index.js.map +1 -0
  334. package/dist/install.d.ts +31 -0
  335. package/dist/install.d.ts.map +1 -0
  336. package/dist/install.js +54 -0
  337. package/dist/install.js.map +1 -0
  338. package/dist/jsonl-tail.d.ts +59 -0
  339. package/dist/jsonl-tail.d.ts.map +1 -0
  340. package/dist/jsonl-tail.js +152 -0
  341. package/dist/jsonl-tail.js.map +1 -0
  342. package/dist/loopback-host.d.ts +20 -0
  343. package/dist/loopback-host.d.ts.map +1 -0
  344. package/dist/loopback-host.js +31 -0
  345. package/dist/loopback-host.js.map +1 -0
  346. package/dist/module-server.d.ts +56 -0
  347. package/dist/module-types/dashboard/components/DiffStat.d.ts +6 -0
  348. package/dist/module-types/dashboard/components/DriverModelMenu.d.ts +23 -0
  349. package/dist/module-types/dashboard/components/LinkActions.d.ts +26 -0
  350. package/dist/module-types/dashboard/components/Markdown.d.ts +4 -0
  351. package/dist/module-types/dashboard/components/SettingsRows.d.ts +37 -0
  352. package/dist/module-types/dashboard/components/StartAgentButton.d.ts +39 -0
  353. package/dist/module-types/dashboard/components/ui/badge.d.ts +2 -0
  354. package/dist/module-types/dashboard/components/ui/button.d.ts +10 -0
  355. package/dist/module-types/dashboard/components/ui/card.d.ts +5 -0
  356. package/dist/module-types/dashboard/components/ui/checkbox.d.ts +7 -0
  357. package/dist/module-types/dashboard/components/ui/dropdown-menu.d.ts +16 -0
  358. package/dist/module-types/dashboard/components/ui/input.d.ts +2 -0
  359. package/dist/module-types/dashboard/components/ui/option-label.d.ts +4 -0
  360. package/dist/module-types/dashboard/components/ui/popover.d.ts +8 -0
  361. package/dist/module-types/dashboard/components/ui/scroll-area.d.ts +10 -0
  362. package/dist/module-types/dashboard/components/ui/separator.d.ts +3 -0
  363. package/dist/module-types/dashboard/components/ui/skeleton.d.ts +2 -0
  364. package/dist/module-types/dashboard/components/ui/slider.d.ts +9 -0
  365. package/dist/module-types/dashboard/components/ui/tooltip.d.ts +11 -0
  366. package/dist/module-types/dashboard/lib/agent-settings.d.ts +2 -0
  367. package/dist/module-types/dashboard/lib/draft-handoff.d.ts +15 -0
  368. package/dist/module-types/dashboard/lib/format-date.d.ts +51 -0
  369. package/dist/module-types/dashboard/lib/host-services.d.ts +12 -0
  370. package/dist/module-types/dashboard/lib/models.d.ts +24 -0
  371. package/dist/module-types/dashboard/lib/route.d.ts +38 -0
  372. package/dist/module-types/dashboard/lib/rpc.d.ts +31 -0
  373. package/dist/module-types/dashboard/lib/use-action.d.ts +25 -0
  374. package/dist/module-types/dashboard/lib/use-async.d.ts +45 -0
  375. package/dist/module-types/dashboard/lib/use-modules.d.ts +79 -0
  376. package/dist/module-types/dashboard/lib/utils.d.ts +3 -0
  377. package/dist/module-types/dashboard/module/index.d.ts +335 -0
  378. package/dist/module-types/dashboard/rpc/models.d.ts +2 -0
  379. package/dist/module-types/dashboard/rpc/modules.d.ts +5 -0
  380. package/dist/module-types/src/agent-id.d.ts +12 -0
  381. package/dist/module-types/src/agent-locks.d.ts +2 -0
  382. package/dist/module-types/src/agent-view.d.ts +38 -0
  383. package/dist/module-types/src/bridge-browser.d.ts +216 -0
  384. package/dist/module-types/src/browser-stream.d.ts +19 -0
  385. package/dist/module-types/src/browser.d.ts +15 -0
  386. package/dist/module-types/src/built-in.d.ts +37 -0
  387. package/dist/module-types/src/client.d.ts +15 -0
  388. package/dist/module-types/src/cloud-run-state.d.ts +26 -0
  389. package/dist/module-types/src/dashboard/activity.d.ts +40 -0
  390. package/dist/module-types/src/dashboard/agent-handoff.d.ts +243 -0
  391. package/dist/module-types/src/dashboard/bridge-endpoints.d.ts +157 -0
  392. package/dist/module-types/src/dashboard/bridge-question.d.ts +32 -0
  393. package/dist/module-types/src/dashboard/bridge-store.d.ts +178 -0
  394. package/dist/module-types/src/dashboard/cache.d.ts +46 -0
  395. package/dist/module-types/src/dashboard/content-type.d.ts +2 -0
  396. package/dist/module-types/src/dashboard/dashboard.d.ts +37 -0
  397. package/dist/module-types/src/dashboard/docs.d.ts +38 -0
  398. package/dist/module-types/src/dashboard/git-status.d.ts +43 -0
  399. package/dist/module-types/src/dashboard/http.d.ts +28 -0
  400. package/dist/module-types/src/dashboard/interventions.d.ts +66 -0
  401. package/dist/module-types/src/dashboard/keyed-watcher.d.ts +28 -0
  402. package/dist/module-types/src/dashboard/keys.d.ts +30 -0
  403. package/dist/module-types/src/dashboard/models.d.ts +24 -0
  404. package/dist/module-types/src/dashboard/module-host.d.ts +43 -0
  405. package/dist/module-types/src/dashboard/module-serve.d.ts +14 -0
  406. package/dist/module-types/src/dashboard/open-in-app.d.ts +42 -0
  407. package/dist/module-types/src/dashboard/open-questions.d.ts +44 -0
  408. package/dist/module-types/src/dashboard/overview.d.ts +77 -0
  409. package/dist/module-types/src/dashboard/projects.d.ts +100 -0
  410. package/dist/module-types/src/dashboard/pull-requests.d.ts +126 -0
  411. package/dist/module-types/src/dashboard/queue.d.ts +16 -0
  412. package/dist/module-types/src/dashboard/quota.d.ts +52 -0
  413. package/dist/module-types/src/dashboard/remote-run.d.ts +94 -0
  414. package/dist/module-types/src/dashboard/rpc-serve.d.ts +105 -0
  415. package/dist/module-types/src/dashboard/run-inbox.d.ts +30 -0
  416. package/dist/module-types/src/dashboard/types.d.ts +134 -0
  417. package/dist/module-types/src/dashboard-rpc/context.d.ts +55 -0
  418. package/dist/module-types/src/dashboard-rpc/control.d.ts +123 -0
  419. package/dist/module-types/src/dashboard-rpc/devices.d.ts +8 -0
  420. package/dist/module-types/src/dashboard-rpc/events-tail.d.ts +67 -0
  421. package/dist/module-types/src/dashboard-rpc/events.d.ts +38 -0
  422. package/dist/module-types/src/dashboard-rpc/index.d.ts +28 -0
  423. package/dist/module-types/src/dashboard-rpc/models.d.ts +3 -0
  424. package/dist/module-types/src/dashboard-rpc/modules.d.ts +44 -0
  425. package/dist/module-types/src/dashboard-rpc/preferences.d.ts +40 -0
  426. package/dist/module-types/src/dashboard-rpc/projects.d.ts +84 -0
  427. package/dist/module-types/src/dashboard-rpc/quota.d.ts +3 -0
  428. package/dist/module-types/src/dashboard-rpc/reads.d.ts +184 -0
  429. package/dist/module-types/src/dashboard-rpc/relay-agent.d.ts +8 -0
  430. package/dist/module-types/src/dashboard-rpc/stream-forward.d.ts +16 -0
  431. package/dist/module-types/src/driver-names.d.ts +21 -0
  432. package/dist/module-types/src/error-message.d.ts +7 -0
  433. package/dist/module-types/src/event-stream.d.ts +32 -0
  434. package/dist/module-types/src/events.d.ts +235 -0
  435. package/dist/module-types/src/format-bytes.d.ts +2 -0
  436. package/dist/module-types/src/has-remote.d.ts +7 -0
  437. package/dist/module-types/src/index.d.ts +41 -0
  438. package/dist/module-types/src/jsonl-tail.d.ts +58 -0
  439. package/dist/module-types/src/loopback-host.d.ts +19 -0
  440. package/dist/module-types/src/node-fs.d.ts +32 -0
  441. package/dist/module-types/src/open-choices.d.ts +14 -0
  442. package/dist/module-types/src/openagent-dir.d.ts +10 -0
  443. package/dist/module-types/src/openagent-gitignore.d.ts +11 -0
  444. package/dist/module-types/src/pick-directory.d.ts +29 -0
  445. package/dist/module-types/src/preference-defaults.d.ts +42 -0
  446. package/dist/module-types/src/project-commands.d.ts +23 -0
  447. package/dist/module-types/src/project-errors.d.ts +59 -0
  448. package/dist/module-types/src/project-hooks.d.ts +129 -0
  449. package/dist/module-types/src/project-modules.d.ts +49 -0
  450. package/dist/module-types/src/project-presets.d.ts +29 -0
  451. package/dist/module-types/src/project.d.ts +28 -0
  452. package/dist/module-types/src/publish-levels.d.ts +32 -0
  453. package/dist/module-types/src/quota-boundary.d.ts +64 -0
  454. package/dist/module-types/src/quota-poller.d.ts +82 -0
  455. package/dist/module-types/src/registry.d.ts +226 -0
  456. package/dist/module-types/src/store/agent-checkout.d.ts +53 -0
  457. package/dist/module-types/src/store/agent-store.d.ts +266 -0
  458. package/dist/module-types/src/store/branches.d.ts +163 -0
  459. package/dist/module-types/src/store/git-host.d.ts +113 -0
  460. package/dist/module-types/src/store/index.d.ts +9 -0
  461. package/dist/module-types/src/store/provided.d.ts +16 -0
  462. package/dist/module-types/src/store/queue.d.ts +45 -0
  463. package/dist/module-types/src/store/repository.d.ts +32 -0
  464. package/dist/module-types/src/store/run-record.d.ts +21 -0
  465. package/dist/module-types/src/store/runs.d.ts +107 -0
  466. package/dist/module-types/src/store/tickets.d.ts +72 -0
  467. package/dist/module-types/src/terminal.d.ts +3 -0
  468. package/dist/module-types/src/worktrees.d.ts +89 -0
  469. package/dist/module.css +50 -0
  470. package/dist/node-fs.d.ts +33 -0
  471. package/dist/node-fs.d.ts.map +1 -0
  472. package/dist/node-fs.js +57 -0
  473. package/dist/node-fs.js.map +1 -0
  474. package/dist/open-choices.d.ts +15 -0
  475. package/dist/open-choices.d.ts.map +1 -0
  476. package/dist/open-choices.js +31 -0
  477. package/dist/open-choices.js.map +1 -0
  478. package/dist/openagent-dir.d.ts +11 -0
  479. package/dist/openagent-dir.d.ts.map +1 -0
  480. package/dist/openagent-dir.js +11 -0
  481. package/dist/openagent-dir.js.map +1 -0
  482. package/dist/openagent-gitignore.d.ts +12 -0
  483. package/dist/openagent-gitignore.d.ts.map +1 -0
  484. package/dist/openagent-gitignore.js +19 -0
  485. package/dist/openagent-gitignore.js.map +1 -0
  486. package/dist/pick-directory.d.ts +30 -0
  487. package/dist/pick-directory.d.ts.map +1 -0
  488. package/dist/pick-directory.js +102 -0
  489. package/dist/pick-directory.js.map +1 -0
  490. package/dist/preference-defaults.d.ts +43 -0
  491. package/dist/preference-defaults.d.ts.map +1 -0
  492. package/dist/preference-defaults.js +34 -0
  493. package/dist/preference-defaults.js.map +1 -0
  494. package/dist/project-commands.d.ts +24 -0
  495. package/dist/project-commands.d.ts.map +1 -0
  496. package/dist/project-commands.js +57 -0
  497. package/dist/project-commands.js.map +1 -0
  498. package/dist/project-errors.d.ts +60 -0
  499. package/dist/project-errors.d.ts.map +1 -0
  500. package/dist/project-errors.js +51 -0
  501. package/dist/project-errors.js.map +1 -0
  502. package/dist/project-hooks.d.ts +130 -0
  503. package/dist/project-hooks.d.ts.map +1 -0
  504. package/dist/project-hooks.js +232 -0
  505. package/dist/project-hooks.js.map +1 -0
  506. package/dist/project-modules.d.ts +50 -0
  507. package/dist/project-modules.d.ts.map +1 -0
  508. package/dist/project-modules.js +110 -0
  509. package/dist/project-modules.js.map +1 -0
  510. package/dist/project-pass.d.ts +32 -0
  511. package/dist/project-pass.d.ts.map +1 -0
  512. package/dist/project-pass.js +45 -0
  513. package/dist/project-pass.js.map +1 -0
  514. package/dist/project-presets.d.ts +30 -0
  515. package/dist/project-presets.d.ts.map +1 -0
  516. package/dist/project-presets.js +74 -0
  517. package/dist/project-presets.js.map +1 -0
  518. package/dist/project.d.ts +29 -0
  519. package/dist/project.d.ts.map +1 -0
  520. package/dist/project.js +41 -0
  521. package/dist/project.js.map +1 -0
  522. package/dist/publish-levels.d.ts +33 -0
  523. package/dist/publish-levels.d.ts.map +1 -0
  524. package/dist/publish-levels.js +53 -0
  525. package/dist/publish-levels.js.map +1 -0
  526. package/dist/quota-boundary.d.ts +65 -0
  527. package/dist/quota-boundary.d.ts.map +1 -0
  528. package/dist/quota-boundary.js +135 -0
  529. package/dist/quota-boundary.js.map +1 -0
  530. package/dist/quota-poller.d.ts +83 -0
  531. package/dist/quota-poller.d.ts.map +1 -0
  532. package/dist/quota-poller.js +118 -0
  533. package/dist/quota-poller.js.map +1 -0
  534. package/dist/registry.d.ts +227 -0
  535. package/dist/registry.d.ts.map +1 -0
  536. package/dist/registry.js +364 -0
  537. package/dist/registry.js.map +1 -0
  538. package/dist/remove-files.d.ts +24 -0
  539. package/dist/remove-files.d.ts.map +1 -0
  540. package/dist/remove-files.js +98 -0
  541. package/dist/remove-files.js.map +1 -0
  542. package/dist/request-path.d.ts +10 -0
  543. package/dist/request-path.d.ts.map +1 -0
  544. package/dist/request-path.js +16 -0
  545. package/dist/request-path.js.map +1 -0
  546. package/dist/store/agent-checkout.d.ts +54 -0
  547. package/dist/store/agent-checkout.d.ts.map +1 -0
  548. package/dist/store/agent-checkout.js +61 -0
  549. package/dist/store/agent-checkout.js.map +1 -0
  550. package/dist/store/agent-store.d.ts +267 -0
  551. package/dist/store/agent-store.d.ts.map +1 -0
  552. package/dist/store/agent-store.js +190 -0
  553. package/dist/store/agent-store.js.map +1 -0
  554. package/dist/store/branches.d.ts +164 -0
  555. package/dist/store/branches.d.ts.map +1 -0
  556. package/dist/store/branches.js +187 -0
  557. package/dist/store/branches.js.map +1 -0
  558. package/dist/store/git-host.d.ts +114 -0
  559. package/dist/store/git-host.d.ts.map +1 -0
  560. package/dist/store/git-host.js +103 -0
  561. package/dist/store/git-host.js.map +1 -0
  562. package/dist/store/index.d.ts +10 -0
  563. package/dist/store/index.d.ts.map +1 -0
  564. package/dist/store/index.js +10 -0
  565. package/dist/store/index.js.map +1 -0
  566. package/dist/store/provided.d.ts +17 -0
  567. package/dist/store/provided.d.ts.map +1 -0
  568. package/dist/store/provided.js +37 -0
  569. package/dist/store/provided.js.map +1 -0
  570. package/dist/store/queue.d.ts +46 -0
  571. package/dist/store/queue.d.ts.map +1 -0
  572. package/dist/store/queue.js +61 -0
  573. package/dist/store/queue.js.map +1 -0
  574. package/dist/store/repository.d.ts +33 -0
  575. package/dist/store/repository.d.ts.map +1 -0
  576. package/dist/store/repository.js +25 -0
  577. package/dist/store/repository.js.map +1 -0
  578. package/dist/store/run-record.d.ts +22 -0
  579. package/dist/store/run-record.d.ts.map +1 -0
  580. package/dist/store/run-record.js +108 -0
  581. package/dist/store/run-record.js.map +1 -0
  582. package/dist/store/runs.d.ts +108 -0
  583. package/dist/store/runs.d.ts.map +1 -0
  584. package/dist/store/runs.js +146 -0
  585. package/dist/store/runs.js.map +1 -0
  586. package/dist/store/test-branches.d.ts +18 -0
  587. package/dist/store/test-branches.d.ts.map +1 -0
  588. package/dist/store/test-branches.js +59 -0
  589. package/dist/store/test-branches.js.map +1 -0
  590. package/dist/store/test-runs.d.ts +15 -0
  591. package/dist/store/test-runs.d.ts.map +1 -0
  592. package/dist/store/test-runs.js +37 -0
  593. package/dist/store/test-runs.js.map +1 -0
  594. package/dist/store/tickets.d.ts +73 -0
  595. package/dist/store/tickets.d.ts.map +1 -0
  596. package/dist/store/tickets.js +67 -0
  597. package/dist/store/tickets.js.map +1 -0
  598. package/dist/terminal.d.ts +4 -0
  599. package/dist/terminal.d.ts.map +1 -0
  600. package/dist/terminal.js +97 -0
  601. package/dist/terminal.js.map +1 -0
  602. package/dist/update-check.d.ts +44 -0
  603. package/dist/update-check.d.ts.map +1 -0
  604. package/dist/update-check.js +71 -0
  605. package/dist/update-check.js.map +1 -0
  606. package/dist/worktrees.d.ts +90 -0
  607. package/dist/worktrees.d.ts.map +1 -0
  608. package/dist/worktrees.js +123 -0
  609. package/dist/worktrees.js.map +1 -0
  610. package/package.json +103 -3
@@ -0,0 +1,262 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { continuationPrompt } from '@openagt/agent-driver';
3
+ import { CLOUD_SESSION_WINDOW_MS } from '../cloud-run-state.js';
4
+ /** How long a collected answer stays with the Driver that collected it before it is offered again. */
5
+ export const ANSWER_CLAIM_TTL_MS = 90_000;
6
+ /** Most transcript entries kept per session, oldest dropped first. */
7
+ const MAX_SESSION_EVENTS = 300;
8
+ /**
9
+ * What a cloud session is told when the user picks a `stop` option (#358, #1554). It lives on
10
+ * claude.ai where nothing of ours can end it, so the bridge types this instead of a continuation:
11
+ * the decision, and that the user is taking over from here.
12
+ */
13
+ export function takeoverPrompt(question, answer) {
14
+ return `You paused to ask: "${question}". The user chose: ${answer}. Stop here: the user is taking over and will come back with fresh instructions.`;
15
+ }
16
+ /** How recently the extension must have spoken to count as present. */
17
+ const EXTENSION_ALIVE_WINDOW_MS = 3 * 60_000;
18
+ export class BridgeQuestions {
19
+ bySession = new Map();
20
+ contact;
21
+ /**
22
+ * Note that something reached the bridge, whatever the outcome.
23
+ *
24
+ * Failures are recorded too, and that is the point: an extension that is misconfigured looks
25
+ * exactly like one that is not installed, because both leave no question behind. A refused
26
+ * request at least proves something is trying.
27
+ */
28
+ recordContact(route, status) {
29
+ this.contact = { at: new Date().toISOString(), route, status };
30
+ }
31
+ versionState;
32
+ /**
33
+ * What version the extension last claimed and whether it was refused for it (#1519).
34
+ *
35
+ * The accepted claims are recorded too, which is what clears a blocked banner: the moment an
36
+ * updated extension gets through, the last word is no longer a refusal.
37
+ */
38
+ recordVersion(got, expected, blocked) {
39
+ this.versionState = { got, expected, blocked, at: new Date().toISOString() };
40
+ }
41
+ /** The last version claim, or undefined while nothing has stated one. */
42
+ version() {
43
+ return this.versionState;
44
+ }
45
+ helloState;
46
+ /** What the injected page script last said about itself. */
47
+ recordHello(hello) {
48
+ this.helloState = hello;
49
+ }
50
+ /** The page script's last report, or undefined if none has ever arrived. */
51
+ hello() {
52
+ return this.helloState;
53
+ }
54
+ /** The last contact, or undefined if nothing has ever reached the bridge. */
55
+ lastContact() {
56
+ return this.contact;
57
+ }
58
+ statusBySession = new Map();
59
+ /**
60
+ * What claude.ai's session list last said about a session (#1332), as the Driver tab read it.
61
+ *
62
+ * This is the read-back a web run's own record cannot give: the run ends at its hand-off, so
63
+ * the record says `done` whether the session is parked on its user or finished hours ago.
64
+ */
65
+ recordStatus(status) {
66
+ this.statusBySession.set(status.sessionId, status);
67
+ }
68
+ /** The session's last list status, or undefined while the Driver has never reported one. */
69
+ status(sessionId) {
70
+ return this.statusBySession.get(sessionId);
71
+ }
72
+ /**
73
+ * Whether the session is waiting on a human: the bridge holds the question it is parked on, or
74
+ * claude.ai's list shows it awaiting input — a question asked in prose carries no block for
75
+ * the bridge to hold, and the list is the only thing that says the session stopped for it.
76
+ *
77
+ * A list status older than the session window no longer counts: the Driver stops reading a
78
+ * session past the window, so its last word would otherwise stand forever.
79
+ */
80
+ waiting(sessionId, now = new Date()) {
81
+ if (this.bySession.has(sessionId))
82
+ return true;
83
+ const status = this.statusBySession.get(sessionId);
84
+ return status?.status === 'awaiting' && now.getTime() - Date.parse(status.at) <= CLOUD_SESSION_WINDOW_MS;
85
+ }
86
+ /**
87
+ * Whether an extension is around (#1328): something reached the bridge and was let in within
88
+ * the window. The worker polls every half minute while it lives, so a longer silence means
89
+ * there is nobody to drain a request.
90
+ */
91
+ extensionAlive(now = new Date(), windowMs = EXTENSION_ALIVE_WINDOW_MS) {
92
+ const contact = this.contact;
93
+ if (!contact || contact.status >= 400)
94
+ return false;
95
+ return now.getTime() - Date.parse(contact.at) <= windowMs;
96
+ }
97
+ eventsBySession = new Map();
98
+ /**
99
+ * Record one transcript entry, keyed by its position.
100
+ *
101
+ * Keyed rather than appended because the page is re-read on every DOM change, so the same
102
+ * message arrives repeatedly and a growing list would be mostly duplicates. Position also lets
103
+ * a later read replace an earlier one, which is what a message still being streamed needs.
104
+ */
105
+ recordEvent(event) {
106
+ let bySeq = this.eventsBySession.get(event.sessionId);
107
+ if (!bySeq) {
108
+ bySeq = new Map();
109
+ this.eventsBySession.set(event.sessionId, bySeq);
110
+ }
111
+ bySeq.set(event.seq, event);
112
+ // Bound it: a long session would otherwise grow without limit in a daemon that never restarts.
113
+ if (bySeq.size > MAX_SESSION_EVENTS) {
114
+ for (const seq of [...bySeq.keys()].sort((a, b) => a - b).slice(0, bySeq.size - MAX_SESSION_EVENTS))
115
+ bySeq.delete(seq);
116
+ }
117
+ }
118
+ /** That session's transcript so far, in order. */
119
+ events(sessionId) {
120
+ return [...(this.eventsBySession.get(sessionId)?.values() ?? [])].sort((a, b) => a.seq - b.seq);
121
+ }
122
+ answersBySession = new Map();
123
+ /** The fingerprint of the question each session's `sent` answer resolved. */
124
+ answeredBySession = new Map();
125
+ /**
126
+ * Record the question a session is parked on, replacing any earlier one for that session.
127
+ *
128
+ * A question identical to one an answer was already delivered for is dropped: the extension's
129
+ * worker forgets what it sent when it restarts, and the answered block stays in the page's DOM,
130
+ * so the same question would otherwise resurface as parked right after being answered.
131
+ */
132
+ record(question) {
133
+ if (this.answeredBySession.get(question.sessionId) === fingerprint(question))
134
+ return;
135
+ const previous = this.bySession.get(question.sessionId);
136
+ // A genuinely new question means the session moved on: an undelivered pick for the old one
137
+ // must not be typed into it, and a resolved one no longer says anything about this question.
138
+ // Only a re-report of the question currently parked keeps its queued answer alive.
139
+ if (!previous || fingerprint(previous) !== fingerprint(question)) {
140
+ this.answersBySession.delete(question.sessionId);
141
+ this.answeredBySession.delete(question.sessionId);
142
+ }
143
+ this.bySession.set(question.sessionId, question);
144
+ }
145
+ /**
146
+ * Queue an answer picked in the dashboard (#1237). Refuses anything but labels of the question
147
+ * currently parked — exactly one unless the question is `multi` — so the only text this can
148
+ * ever put in a composer is composed from what the session itself offered.
149
+ */
150
+ queueAnswer(sessionId, labels) {
151
+ const question = this.bySession.get(sessionId);
152
+ if (!question)
153
+ return 'that session has no parked question';
154
+ const picked = question.options.filter(option => labels.includes(option.label));
155
+ if (picked.length !== labels.length || new Set(labels).size !== labels.length)
156
+ return 'every label must be one of the question options';
157
+ if (!question.multi && picked.length !== 1)
158
+ return 'pick exactly one option';
159
+ // Worded as a local run's answer is (agent-driver's continuation prompt): the labels joined, `(none)` for an
160
+ // empty multi-select, and a stopping pick hands the session over instead of continuing it.
161
+ const answer = picked.length ? picked.map(option => option.label).join(', ') : '(none)';
162
+ const text = picked.some(option => option.stop) ? takeoverPrompt(question.title, answer) : continuationPrompt(question.title, answer);
163
+ const queued = { id: randomUUID(), sessionId, labels, text, queuedAt: new Date().toISOString(), state: 'queued' };
164
+ this.answersBySession.set(sessionId, queued);
165
+ return queued;
166
+ }
167
+ /** Withdraw a queued answer. Too late once a Driver has collected it or the extension has delivered it. */
168
+ cancelAnswer(sessionId, now = Date.now()) {
169
+ const answer = this.answersBySession.get(sessionId);
170
+ if (!answer || answer.state !== 'queued' || this.claimed(answer, now))
171
+ return false;
172
+ this.answersBySession.delete(sessionId);
173
+ return true;
174
+ }
175
+ /** The answer waiting for the extension to deliver, if any — collected by a Driver or not. */
176
+ pendingAnswer(sessionId) {
177
+ const answer = this.answersBySession.get(sessionId);
178
+ return answer?.state === 'queued' ? answer : undefined;
179
+ }
180
+ /** Whether a Driver holds the answer: collected, and not so long ago that it is presumed lost. */
181
+ claimed(answer, now) {
182
+ return answer.claimedAt !== undefined && now - Date.parse(answer.claimedAt) < ANSWER_CLAIM_TTL_MS;
183
+ }
184
+ /**
185
+ * Hand the queued answer to the Driver asking, once (#1332): the next Driver asking within the
186
+ * claim's lifetime gets nothing, so a session served by two browsers is not answered twice. A
187
+ * claim nobody acknowledged — the Driver died mid-delivery — expires, and the answer is offered
188
+ * again.
189
+ */
190
+ claimAnswer(sessionId, now = Date.now()) {
191
+ const answer = this.pendingAnswer(sessionId);
192
+ if (!answer || this.claimed(answer, now))
193
+ return undefined;
194
+ answer.claimedAt = new Date(now).toISOString();
195
+ return answer;
196
+ }
197
+ /**
198
+ * Every session with an answer waiting to be delivered. The Driver serves these whatever the
199
+ * session window says: the page reports whichever session the user is on, so a pick can be for
200
+ * a session no listed run carries, and one nothing serves would sit queued forever.
201
+ */
202
+ pendingAnswerSessions() {
203
+ return [...this.answersBySession.values()].filter(answer => answer.state === 'queued').map(answer => answer.sessionId);
204
+ }
205
+ /** The session's answer in whatever state, for the dashboard to render. */
206
+ answer(sessionId) {
207
+ return this.answersBySession.get(sessionId);
208
+ }
209
+ /**
210
+ * The extension's word on what happened to a delivery. On success the question is resolved:
211
+ * it is dropped, and re-reports of the same block are ignored (see {@link record}).
212
+ */
213
+ resolveAnswer(sessionId, id, ok, note) {
214
+ const answer = this.answersBySession.get(sessionId);
215
+ if (!answer || answer.id !== id || answer.state !== 'queued')
216
+ return;
217
+ this.answersBySession.set(sessionId, { ...answer, state: ok ? 'sent' : 'failed', ...(note ? { note } : {}) });
218
+ if (!ok)
219
+ return;
220
+ const question = this.bySession.get(sessionId);
221
+ if (question)
222
+ this.answeredBySession.set(sessionId, fingerprint(question));
223
+ this.bySession.delete(sessionId);
224
+ }
225
+ /** The question that session is parked on, if the bridge has reported one. */
226
+ get(sessionId) {
227
+ return this.bySession.get(sessionId);
228
+ }
229
+ /** Every parked question, newest first. */
230
+ list() {
231
+ return [...this.bySession.values()].sort((a, b) => b.receivedAt.localeCompare(a.receivedAt));
232
+ }
233
+ /** Drop a session's question, once it is answered or its agent is gone. */
234
+ clear(sessionId) {
235
+ this.bySession.delete(sessionId);
236
+ this.eventsBySession.delete(sessionId);
237
+ this.answersBySession.delete(sessionId);
238
+ this.answeredBySession.delete(sessionId);
239
+ this.statusBySession.delete(sessionId);
240
+ }
241
+ }
242
+ /** What makes two reports the same question: the text shown, not when it arrived. */
243
+ function fingerprint(question) {
244
+ return JSON.stringify([question.title, question.options, question.recommended ?? null, question.multi ?? false]);
245
+ }
246
+ /**
247
+ * The daemon's one store. A module singleton rather than a {@link DashboardContext} field
248
+ * because both ends live in the same process but reach it by different routes: the bridge
249
+ * endpoint writes from the raw HTTP handler, and the dashboard reads from an RPC, which is
250
+ * handed only what the wired context carries.
251
+ */
252
+ let instance;
253
+ export function bridgeQuestions() {
254
+ if (!instance)
255
+ instance = new BridgeQuestions();
256
+ return instance;
257
+ }
258
+ /** Replace the store. Tests only: a module singleton would otherwise leak between them. */
259
+ export function resetBridgeQuestions() {
260
+ instance = undefined;
261
+ }
262
+ //# sourceMappingURL=bridge-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-store.js","sourceRoot":"","sources":["../../src/dashboard/bridge-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Locate the built dashboard bundle (#405): `dist/dashboard-bundle`, where Vite
3
+ * writes it. Returns the directory only when its `index.html` exists, else undefined (the caller
4
+ * then serves the legacy page.ts). Shared by the daemon and the per-agent foreground dashboard (#427).
5
+ *
6
+ * One path, because there is one layout. The dashboard used to be its own package, so a published
7
+ * install read a copy of the bundle under this package's dist while the workspace read the original
8
+ * under the other package's — two candidates, a copy step, and a turbo task to sequence them. Now
9
+ * Vite writes here directly and both cases are the same directory (A7).
10
+ */
11
+ export declare function resolveDashboardBundle(): Promise<string | undefined>;
12
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/dashboard/bundle.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO1E"}
@@ -0,0 +1,22 @@
1
+ import { stat } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /**
5
+ * Locate the built dashboard bundle (#405): `dist/dashboard-bundle`, where Vite
6
+ * writes it. Returns the directory only when its `index.html` exists, else undefined (the caller
7
+ * then serves the legacy page.ts). Shared by the daemon and the per-agent foreground dashboard (#427).
8
+ *
9
+ * One path, because there is one layout. The dashboard used to be its own package, so a published
10
+ * install read a copy of the bundle under this package's dist while the workspace read the original
11
+ * under the other package's — two candidates, a copy step, and a turbo task to sequence them. Now
12
+ * Vite writes here directly and both cases are the same directory (A7).
13
+ */
14
+ export async function resolveDashboardBundle() {
15
+ // Resolved from the package root rather than from this module, so the answer is the same
16
+ // directory whether this is running out of `dist/`, `dist-test/`, or `src/` — all three sit one
17
+ // level under the package, and the bundle is only ever built once, into `dist/`.
18
+ const here = dirname(fileURLToPath(import.meta.url)); // <pkg>/{dist,dist-test,src}/dashboard
19
+ const dir = join(here, '..', '..', 'dist', 'dashboard-bundle');
20
+ return (await stat(join(dir, 'index.html')).then(s => s.isFile()).catch(() => false)) ? dir : undefined;
21
+ }
22
+ //# sourceMappingURL=bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/dashboard/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,yFAAyF;IACzF,gGAAgG;IAChG,iFAAiF;IACjF,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA,CAAC,uCAAuC;IAC5F,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC9D,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;AACzG,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * A read-through cache for the dashboard's slow reads (#1028).
3
+ *
4
+ * The dashboard polls. Every session view asks for its branch's PR, twice (the worktree bar and
5
+ * the handoff summary), on every navigation and again every ten seconds — and a git host read costs
6
+ * about 600ms against a local git read's ten. So the same answer was being bought over and over,
7
+ * and the panel waited for it each time.
8
+ *
9
+ * Three behaviours, and each one is load-bearing:
10
+ * - **single flight** — concurrent asks for the same key share one call, so two panels and a
11
+ * poll tick do not become three subprocesses
12
+ * - **stale while revalidate** — once a value exists it is returned immediately, and refreshed
13
+ * in the background when it is older than `ttlMs`; nobody waits twice for the same answer
14
+ * - **a budget on the cold ask** — the first ask waits only `budgetMs` for the answer before
15
+ * reporting `pending`, so a slow lookup delays one panel's extra detail rather than the page
16
+ *
17
+ * `pending` is not "failed": it means the answer is on its way and the next read will have it.
18
+ * A caller that must not act on a half-answer (offering to open a PR that may already exist)
19
+ * uses it to hold off.
20
+ */
21
+ /** What a cached read answers with: the value, and whether it is still being fetched. */
22
+ export interface Cached<T> {
23
+ value: T | undefined;
24
+ /** True when no value is known yet and a read is still running. */
25
+ pending: boolean;
26
+ }
27
+ /** Clock seam, so the tests do not sleep. */
28
+ export type Now = () => number;
29
+ export interface CacheOptions {
30
+ /** How old a value may be before a background refresh is started. */
31
+ ttlMs?: number;
32
+ /** How long a first, uncached ask waits before reporting `pending`. */
33
+ budgetMs?: number;
34
+ now?: Now;
35
+ }
36
+ /**
37
+ * Read `key` through the cache, calling `load` when it is missing or stale.
38
+ *
39
+ * A failed load is not cached: it leaves whatever was there (a panel keeps showing the last PR it
40
+ * knew about rather than dropping it because the git host hiccuped) and the next read tries again.
41
+ */
42
+ export declare function cachedRead<T>(key: string, load: () => Promise<T>, options?: CacheOptions): Promise<Cached<T>>;
43
+ /** Drop what is cached under `key`, so the next read is a fresh one. */
44
+ export declare function invalidate(key: string): void;
45
+ /** Test seam: forget everything. */
46
+ export declare function clearCache(): void;
47
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/dashboard/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,yFAAyF;AACzF,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,GAAG,SAAS,CAAA;IACpB,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,6CAA6C;AAC7C,MAAM,MAAM,GAAG,GAAG,MAAM,MAAM,CAAA;AAE9B,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,GAAG,CAAA;CACV;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAgBvH;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,oCAAoC;AACpC,wBAAgB,UAAU,IAAI,IAAI,CAEjC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * A read-through cache for the dashboard's slow reads (#1028).
3
+ *
4
+ * The dashboard polls. Every session view asks for its branch's PR, twice (the worktree bar and
5
+ * the handoff summary), on every navigation and again every ten seconds — and a git host read costs
6
+ * about 600ms against a local git read's ten. So the same answer was being bought over and over,
7
+ * and the panel waited for it each time.
8
+ *
9
+ * Three behaviours, and each one is load-bearing:
10
+ * - **single flight** — concurrent asks for the same key share one call, so two panels and a
11
+ * poll tick do not become three subprocesses
12
+ * - **stale while revalidate** — once a value exists it is returned immediately, and refreshed
13
+ * in the background when it is older than `ttlMs`; nobody waits twice for the same answer
14
+ * - **a budget on the cold ask** — the first ask waits only `budgetMs` for the answer before
15
+ * reporting `pending`, so a slow lookup delays one panel's extra detail rather than the page
16
+ *
17
+ * `pending` is not "failed": it means the answer is on its way and the next read will have it.
18
+ * A caller that must not act on a half-answer (offering to open a PR that may already exist)
19
+ * uses it to hold off.
20
+ */
21
+ const entries = new Map();
22
+ /**
23
+ * Read `key` through the cache, calling `load` when it is missing or stale.
24
+ *
25
+ * A failed load is not cached: it leaves whatever was there (a panel keeps showing the last PR it
26
+ * knew about rather than dropping it because the git host hiccuped) and the next read tries again.
27
+ */
28
+ export async function cachedRead(key, load, options = {}) {
29
+ const { ttlMs = 60_000, budgetMs = 150, now = Date.now } = options;
30
+ const entry = entries.get(key);
31
+ // A known value answers straight away. Refresh it in the background when it has aged out, so
32
+ // the cost of being current is never paid by the caller that happens to ask.
33
+ if (entry?.has) {
34
+ if (now() - entry.at >= ttlMs && !entry.inflight)
35
+ void refresh(key, load, now);
36
+ return { value: entry.value, pending: false };
37
+ }
38
+ // Nothing known yet: join the running read, or start one, and wait a moment for it.
39
+ const inflight = entry?.inflight ?? refresh(key, load, now);
40
+ const settled = await withBudget(inflight, budgetMs);
41
+ if (settled.done)
42
+ return { value: settled.value, pending: false };
43
+ return { value: undefined, pending: true };
44
+ }
45
+ /** Drop what is cached under `key`, so the next read is a fresh one. */
46
+ export function invalidate(key) {
47
+ entries.delete(key);
48
+ }
49
+ /** Test seam: forget everything. */
50
+ export function clearCache() {
51
+ entries.clear();
52
+ }
53
+ function refresh(key, load, now) {
54
+ const inflight = load()
55
+ .then(value => {
56
+ entries.set(key, { value, has: true, at: now() });
57
+ return value;
58
+ })
59
+ .catch(error => {
60
+ // Keep the last good value; only the in-flight marker goes.
61
+ const current = entries.get(key);
62
+ if (current?.has)
63
+ entries.set(key, { value: current.value, has: true, at: current.at });
64
+ else
65
+ entries.delete(key);
66
+ throw error;
67
+ });
68
+ const current = entries.get(key);
69
+ entries.set(key, { ...(current ?? { has: false, at: 0 }), inflight });
70
+ // The rejection is reported to whoever awaited it; nothing else must see an unhandled one.
71
+ inflight.catch(() => { });
72
+ return inflight;
73
+ }
74
+ /** Resolve as soon as `promise` does, or give up waiting after `ms`. */
75
+ async function withBudget(promise, ms) {
76
+ let timer;
77
+ const timeout = new Promise(resolve => {
78
+ timer = setTimeout(() => resolve({ done: false }), ms);
79
+ });
80
+ try {
81
+ return await Promise.race([promise.then(value => ({ done: true, value })).catch(() => ({ done: false })), timeout]);
82
+ }
83
+ finally {
84
+ clearTimeout(timer);
85
+ }
86
+ }
87
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/dashboard/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** The content type for a file path (by its extension), or `application/octet-stream`. */
2
+ export declare function contentTypeFor(path: string): string;
3
+ //# sourceMappingURL=content-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-type.d.ts","sourceRoot":"","sources":["../../src/dashboard/content-type.ts"],"names":[],"mappings":"AA4BA,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,31 @@
1
+ import { extname } from 'node:path';
2
+ /**
3
+ * Content types for the files OpenAgent's two static servers hand out — the dashboard
4
+ * bundle (static.ts) and a project's on-demand Preview (preview.ts). One table so the two
5
+ * cannot drift apart, which they had: each was missing extensions the other listed. The two
6
+ * servers keep their own policies (SPA fallback + immutable cache vs 403 + stream); only this
7
+ * lookup is shared. Unknown extensions fall back to `application/octet-stream`.
8
+ */
9
+ const CONTENT_TYPES = {
10
+ '.html': 'text/html; charset=utf-8',
11
+ '.js': 'text/javascript; charset=utf-8',
12
+ '.mjs': 'text/javascript; charset=utf-8',
13
+ '.css': 'text/css; charset=utf-8',
14
+ '.json': 'application/json; charset=utf-8',
15
+ '.svg': 'image/svg+xml',
16
+ '.ico': 'image/x-icon',
17
+ '.png': 'image/png',
18
+ '.jpg': 'image/jpeg',
19
+ '.jpeg': 'image/jpeg',
20
+ '.gif': 'image/gif',
21
+ '.webp': 'image/webp',
22
+ '.woff': 'font/woff',
23
+ '.woff2': 'font/woff2',
24
+ '.map': 'application/json; charset=utf-8',
25
+ '.webmanifest': 'application/manifest+json',
26
+ };
27
+ /** The content type for a file path (by its extension), or `application/octet-stream`. */
28
+ export function contentTypeFor(path) {
29
+ return CONTENT_TYPES[extname(path).toLowerCase()] ?? 'application/octet-stream';
30
+ }
31
+ //# sourceMappingURL=content-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-type.js","sourceRoot":"","sources":["../../src/dashboard/content-type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC;;;;;;GAMG;AACH,MAAM,aAAa,GAA2B;IAC5C,OAAO,EAAE,0BAA0B;IACnC,KAAK,EAAE,gCAAgC;IACvC,MAAM,EAAE,gCAAgC;IACxC,MAAM,EAAE,yBAAyB;IACjC,OAAO,EAAE,iCAAiC;IAC1C,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,cAAc;IACtB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;IACtB,MAAM,EAAE,iCAAiC;IACzC,cAAc,EAAE,2BAA2B;CAC5C,CAAA;AAED,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,0BAA0B,CAAA;AACjF,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { ProjectSummary } from './projects.js';
2
+ import { type ProjectQueue } from './queue.js';
3
+ import { type ActiveAgent, type OverviewDeps } from './overview.js';
4
+ /** One project's rollup row. */
5
+ export interface ProjectStat {
6
+ projectId: string;
7
+ /** Whether the repo has any ticket in `tickets/` (#958) — presence only, not a count. */
8
+ hasTickets: boolean;
9
+ /** Whether one of the project's packages provides tickets at all (#1774): without one, there is nothing to populate. */
10
+ providesTickets: boolean;
11
+ }
12
+ /** The dashboard page payload (#471). */
13
+ export interface DashboardData {
14
+ totals: {
15
+ projects: number;
16
+ openTodos: number;
17
+ };
18
+ /** Agents going right now, most-recently-updated first (from {@link buildOverview}). */
19
+ active: ActiveAgent[];
20
+ /** Every registered project, most-recently-active first. */
21
+ projects: ProjectStat[];
22
+ /** The per-project agent queue (from {@link collectQueue}): the projects that have one, with their open entries. */
23
+ queue: ProjectQueue[];
24
+ }
25
+ /** Injectable readers so {@link buildDashboard} is unit-testable off disk. */
26
+ export interface DashboardDeps extends OverviewDeps {
27
+ /** Whether a project has tickets (#958). Defaults to the provider's list being non-empty (false on any error). */
28
+ tickets?: (cwd: string) => Promise<boolean>;
29
+ /** Whether a project's packages provide tickets (#1774). Defaults to the provider lookup (false on any error). */
30
+ providesTickets?: (cwd: string) => Promise<boolean>;
31
+ }
32
+ /**
33
+ * Build the Overview dashboard: the {@link buildOverview} rollup (working now / queue) plus the
34
+ * per-project ticket presence the onboarding checklist reads. Forgiving — a project whose state
35
+ * cannot be read simply contributes nothing.
36
+ */
37
+ export declare function buildDashboard(projects: ProjectSummary[], deps?: DashboardDeps): Promise<DashboardData>;
38
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAE5D,OAAO,EAAiB,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAYlF,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,yFAAyF;IACzF,UAAU,EAAE,OAAO,CAAA;IACnB,wHAAwH;IACxH,eAAe,EAAE,OAAO,CAAA;CACzB;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;IACD,wFAAwF;IACxF,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,4DAA4D;IAC5D,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,oHAAoH;IACpH,KAAK,EAAE,YAAY,EAAE,CAAA;CACtB;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,kHAAkH;IAClH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,kHAAkH;IAClH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACpD;AAYD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAyBjH"}
@@ -0,0 +1,42 @@
1
+ import { collectQueue } from './queue.js';
2
+ import { projectTickets } from '../store/tickets.js';
3
+ import { buildOverview } from './overview.js';
4
+ /** Whether the provider one of the project's packages declares (#1774) lists any ticket; no provider, no tickets. */
5
+ async function hasProvidedTickets(cwd) {
6
+ try {
7
+ const source = await projectTickets(cwd);
8
+ return source !== undefined && (await source.list()).length > 0;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ /**
15
+ * Build the Overview dashboard: the {@link buildOverview} rollup (working now / queue) plus the
16
+ * per-project ticket presence the onboarding checklist reads. Forgiving — a project whose state
17
+ * cannot be read simply contributes nothing.
18
+ */
19
+ export async function buildDashboard(projects, deps = {}) {
20
+ const hasTicketsFor = deps.tickets ?? hasProvidedTickets;
21
+ const providesTicketsFor = deps.providesTickets ?? (cwd => projectTickets(cwd).then(source => source !== undefined, () => false));
22
+ // Compute the queue once and hand it to buildOverview so the backlog is read a single time.
23
+ const queue = await (deps.queue ?? (p => collectQueue(p)))(projects);
24
+ const overview = await buildOverview(projects, { ...deps, queue: async () => queue });
25
+ // Most-recently-active first: the checklist takes the head of this list as the project to act
26
+ // on, so the order is the output here even though the timestamp itself is not.
27
+ const ordered = [...projects].sort((a, b) => (b.lastActivityAt ?? '').localeCompare(a.lastActivityAt ?? ''));
28
+ const projectStats = [];
29
+ for (const project of ordered) {
30
+ projectStats.push({ projectId: project.id, hasTickets: await hasTicketsFor(project.path), providesTickets: await providesTicketsFor(project.path) });
31
+ }
32
+ return {
33
+ totals: {
34
+ projects: projects.length,
35
+ openTodos: overview.queueOpen,
36
+ },
37
+ active: overview.active,
38
+ projects: projectStats,
39
+ queue,
40
+ };
41
+ }
42
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/dashboard/dashboard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAqB,MAAM,YAAY,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAuC,MAAM,eAAe,CAAA;AA2ClF,qHAAqH;AACrH,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAA;QACxC,OAAO,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAA0B,EAAE,IAAI,GAAkB,EAAE;IACvF,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,IAAI,kBAAkB,CAAA;IACxD,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,KAAK,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEjI,4FAA4F;IAC5F,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IACpE,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,CAAA;IAErF,8FAA8F;IAC9F,+EAA+E;IAC/E,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,CAAA;IAC5G,MAAM,YAAY,GAAkB,EAAE,CAAA;IACtC,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;QAC9B,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACtJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE;YACN,QAAQ,EAAE,QAAQ,CAAC,MAAM;YACzB,SAAS,EAAE,QAAQ,CAAC,SAAS;SAC9B;QACD,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,QAAQ,EAAE,YAAY;QACtB,KAAK;KACN,CAAA;AACH,CAAC"}