@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,364 @@
1
+ import { basename, dirname, join, resolve } from 'node:path';
2
+ import { randomBytes } from 'node:crypto';
3
+ import { isDriverName } from './driver-names.js';
4
+ import { isPublishPick } from './publish-levels.js';
5
+ import { nodeFs } from './node-fs.js';
6
+ /** The cap on saved custom presets, and the per-field lengths — enough for real prompts, bounded
7
+ * so a hand-edited or hostile registry can't bloat the home file. */
8
+ const CUSTOM_PRESET_LIMITS = { count: 30, label: 80, prompt: 20_000 };
9
+ /** The cap on the projects `startFrom` lists, for the same reason. */
10
+ const START_FROM_LIMIT = 200;
11
+ /** The registry file name: a single file under `$XDG_CONFIG_HOME` (dotted under `$HOME`). */
12
+ export const REGISTRY_FILE = 'openagent.json';
13
+ /** Owner read/write only: the file holds the daemon token (#1051). */
14
+ export const REGISTRY_FILE_MODE = 0o600;
15
+ /**
16
+ * Deterministic, URL-safe id for a project path: the sanitized basename plus a
17
+ * short hash of the full path, so two repos named alike still get distinct ids.
18
+ * Pure; same path always yields the same id.
19
+ */
20
+ export function projectId(path) {
21
+ // djb2, rendered as base36: short, stable, URL-safe. Not cryptographic.
22
+ let hash = 5381;
23
+ for (let i = 0; i < path.length; i++) {
24
+ hash = ((hash * 33) ^ path.charCodeAt(i)) >>> 0;
25
+ }
26
+ const name = basename(path)
27
+ .toLowerCase()
28
+ .replace(/[^a-z0-9-]/g, '-');
29
+ return `${name}-${hash.toString(36)}`;
30
+ }
31
+ /**
32
+ * The registry file path, resolved from `env` (injectable so tests never touch
33
+ * the real home): `$XDG_CONFIG_HOME/openagent.json` when set, else the
34
+ * dotted `$HOME/.openagent.json`. A single file, not a directory (#390).
35
+ */
36
+ export function registryPath(env) {
37
+ if (env.XDG_CONFIG_HOME)
38
+ return join(env.XDG_CONFIG_HOME, REGISTRY_FILE);
39
+ return join(env.HOME ?? '', '.' + REGISTRY_FILE);
40
+ }
41
+ /** A {@link RegistryFs} backed by `node:fs/promises`. See {@link nodeFs}. */
42
+ export function nodeRegistryFs() {
43
+ const { read, write, mkdir, rename, chmod } = nodeFs();
44
+ return { read, write, mkdir, rename, chmod };
45
+ }
46
+ /** True when `value` is a well-formed {@link ProjectRecord}. */
47
+ function isRecord(value) {
48
+ if (typeof value !== 'object' || value === null)
49
+ return false;
50
+ const record = value;
51
+ return typeof record.id === 'string' && typeof record.path === 'string' && typeof record.addedAt === 'string';
52
+ }
53
+ /** Keep well-formed records, deduped by resolved path (first wins). */
54
+ function dedupeProjects(values) {
55
+ const seen = new Set();
56
+ const projects = [];
57
+ for (const value of values) {
58
+ if (!isRecord(value))
59
+ continue;
60
+ const key = resolve(value.path);
61
+ if (seen.has(key))
62
+ continue;
63
+ seen.add(key);
64
+ projects.push(value);
65
+ }
66
+ return projects;
67
+ }
68
+ /**
69
+ * Every boolean preference, as a `Record` over {@link BooleanPreferenceKey} so the compiler
70
+ * enforces completeness in both directions (#944): a typo fails as an unknown property, and
71
+ * omitting a newly added boolean preference fails as a missing one. A plain `as const` array
72
+ * only caught the first — an omission made {@link sanitizePreferences} silently drop the new
73
+ * preference on every save, the write-then-vanish failure shape for a settings file.
74
+ */
75
+ const BOOLEAN_PREFERENCES = {
76
+ notifyBrowser: true,
77
+ notifyNewActivity: true,
78
+ notifyHumanIntervention: true,
79
+ bridge: true,
80
+ bridgeBrowser: true,
81
+ onboardingDismissed: true,
82
+ postMergeCleanup: true,
83
+ };
84
+ const PREFERENCE_KEYS = Object.keys(BOOLEAN_PREFERENCES);
85
+ /** Keep only the known preference fields, so a hand-edited or browser-supplied
86
+ * object never lands junk (or the wrong type) in the user's home file. */
87
+ /** The color themes the dashboard offers (#725); anything else means the default `system`. */
88
+ const KNOWN_THEMES = ['system', 'light', 'dark'];
89
+ function sanitizePreferences(value) {
90
+ if (typeof value !== 'object' || value === null)
91
+ return {};
92
+ const input = value;
93
+ const preferences = {};
94
+ for (const key of PREFERENCE_KEYS) {
95
+ if (typeof input[key] === 'boolean')
96
+ preferences[key] = input[key];
97
+ }
98
+ // `model` (#628) is a free-form string preference; the rest are booleans. A blank string is "no
99
+ // choice", same as absent, so it is dropped rather than persisted. So is the literal word
100
+ // "Default": that was a picker *label* whose stored value was empty (#1143), and a file carrying
101
+ // it as the value — hand-edited, or written by a build that mistook the two — would otherwise be
102
+ // handed to the CLI as `--model Default` and fail the turn on a word nobody chose.
103
+ const model = typeof input['model'] === 'string' ? input['model'].trim() : '';
104
+ if (model && model.toLowerCase() !== 'default')
105
+ preferences.model = model;
106
+ // `driver` (#650) is constrained to the known set so junk never reaches the agent; the set is the
107
+ // shared node-free vocabulary (driver-names.ts).
108
+ if (isDriverName(input['driver']))
109
+ preferences.driver = input['driver'];
110
+ // `publish` is constrained to the picks the launcher's menu lists.
111
+ if (isPublishPick(input['publish']))
112
+ preferences.publish = input['publish'];
113
+ const startFrom = sanitizeStartFrom(input['startFrom']);
114
+ if (Object.keys(startFrom).length)
115
+ preferences.startFrom = startFrom;
116
+ // `editor` (#727) is a free-form CLI name, trimmed and length-capped so junk / a huge string
117
+ // never lands in the file. A blank string is "no choice" (fall back to env / `code`), so dropped.
118
+ if (typeof input['editor'] === 'string' && input['editor'].trim())
119
+ preferences.editor = input['editor'].trim().slice(0, 100);
120
+ // `theme` (#725) is constrained to the known set; anything else (incl. absent) means the default
121
+ // `system`, so it is simply dropped rather than persisted.
122
+ if (typeof input['theme'] === 'string' && KNOWN_THEMES.includes(input['theme']))
123
+ preferences.theme = input['theme'];
124
+ const customPresets = sanitizeCustomPresets(input['customPresets']);
125
+ if (customPresets.length)
126
+ preferences.customPresets = customPresets;
127
+ return preferences;
128
+ }
129
+ /**
130
+ * Keep only the projects set to start from the local branch: a map from a project's id to the one
131
+ * word `local`. Any other value is dropped (the main branch is the absent entry), and the map is
132
+ * capped at {@link START_FROM_LIMIT} projects. An id is not checked against the project list: a
133
+ * project removed and added again has the same id, and its pick with it.
134
+ */
135
+ function sanitizeStartFrom(value) {
136
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
137
+ return {};
138
+ const ids = Object.entries(value).filter(([id, from]) => id !== '' && from === 'local').map(([id]) => id);
139
+ return Object.fromEntries(ids.slice(0, START_FROM_LIMIT).map(id => [id, 'local']));
140
+ }
141
+ /**
142
+ * Keep only well-formed custom presets (#626): each needs a non-empty id, label, and prompt;
143
+ * label/prompt are trimmed and length-capped, the list capped at {@link CUSTOM_PRESET_LIMITS.count},
144
+ * and duplicate ids dropped. A malformed entry is skipped, not thrown — a bad registry never breaks the read.
145
+ */
146
+ export function sanitizeCustomPresets(value) {
147
+ if (!Array.isArray(value))
148
+ return [];
149
+ const out = [];
150
+ const seen = new Set();
151
+ for (const raw of value) {
152
+ if (out.length >= CUSTOM_PRESET_LIMITS.count)
153
+ break;
154
+ if (typeof raw !== 'object' || raw === null)
155
+ continue;
156
+ const { id, label, prompt } = raw;
157
+ if (typeof id !== 'string' || typeof label !== 'string' || typeof prompt !== 'string')
158
+ continue;
159
+ const trimmedId = id.trim();
160
+ const trimmedLabel = label.trim().slice(0, CUSTOM_PRESET_LIMITS.label);
161
+ const trimmedPrompt = prompt.trim().slice(0, CUSTOM_PRESET_LIMITS.prompt);
162
+ if (!trimmedId || !trimmedLabel || !trimmedPrompt || seen.has(trimmedId))
163
+ continue;
164
+ seen.add(trimmedId);
165
+ out.push({ id: trimmedId, label: trimmedLabel, prompt: trimmedPrompt });
166
+ }
167
+ return out;
168
+ }
169
+ /**
170
+ * Read the whole registry. Forgiving: a missing / unreadable / malformed file — or one in a shape
171
+ * this no longer writes — yields an empty registry, never throws. Projects are deduped by resolved
172
+ * path and unknown preference fields are dropped.
173
+ */
174
+ export async function readRegistry(fs = nodeRegistryFs(), env = process.env) {
175
+ const empty = { projects: [], preferences: {} };
176
+ let parsed;
177
+ try {
178
+ parsed = JSON.parse(await fs.read(registryPath(env)));
179
+ }
180
+ catch {
181
+ return empty;
182
+ }
183
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
184
+ return empty;
185
+ const obj = parsed;
186
+ const projects = Array.isArray(obj.projects) ? dedupeProjects(obj.projects) : [];
187
+ return {
188
+ projects,
189
+ preferences: sanitizePreferences(obj.preferences),
190
+ // #1051: kept only as a non-empty string, so a hand-edited registry can't smuggle a junk token.
191
+ ...(typeof obj.daemonToken === 'string' && obj.daemonToken ? { daemonToken: obj.daemonToken } : {}),
192
+ };
193
+ }
194
+ /**
195
+ * Write the registry back as pretty object-form JSON, creating the parent dir.
196
+ *
197
+ * Atomic (#991): the JSON goes to a temp file beside the real one and is then renamed over it,
198
+ * the same shape #922 gave the daemon state file. A direct write truncates first, so a crash, a
199
+ * kill or a full disk mid-write left a half file — and {@link readRegistry} reports a malformed
200
+ * file as an empty registry, so every project and preference vanished silently. A failed write
201
+ * now only ever damages the temp file. The temp is left behind on failure rather than swept up:
202
+ * one stray file is the cheaper half of that trade.
203
+ *
204
+ * Written owner-only (#1095): the file carries the daemon token, so a default-umask 0644 in a
205
+ * shared home would hand it to every other account on the machine.
206
+ * The mode is set on the temp file, before the rename — narrowing after it would leave a window
207
+ * where the real path is readable. Best-effort: a filesystem with no permission bits still writes.
208
+ */
209
+ async function writeRegistry(registry, fs, env) {
210
+ const file = registryPath(env);
211
+ const { projects, preferences, daemonToken } = registry;
212
+ const contents = {
213
+ projects,
214
+ preferences,
215
+ ...(daemonToken ? { daemonToken } : {}),
216
+ };
217
+ const json = JSON.stringify(contents, null, 2);
218
+ await fs.mkdir(dirname(file));
219
+ const restrict = (path) => fs.chmod?.(path, REGISTRY_FILE_MODE).catch(() => { });
220
+ if (!fs.rename) {
221
+ await fs.write(file, json);
222
+ await restrict(file);
223
+ return;
224
+ }
225
+ const temp = `${file}.${process.pid}.tmp`;
226
+ await fs.write(temp, json);
227
+ await restrict(temp);
228
+ await fs.rename(temp, file);
229
+ }
230
+ /**
231
+ * Serializes the read-modify-write mutators below (#991). Each reads the whole registry, edits it
232
+ * and writes it back, and one daemon runs several concurrently: `daemon.ts` and `daemon-runtime.ts`
233
+ * both call {@link addProject} while the dashboard's savePreferences RPC writes through
234
+ * {@link registryPreferencesStore}. Interleaved, the later write was computed from a read taken
235
+ * before the earlier one landed, so it silently dropped it. One tail promise for the module, not
236
+ * one per file: the writes are small, and the registry is a single file per machine anyway.
237
+ */
238
+ let mutations = Promise.resolve();
239
+ function serialize(mutate) {
240
+ const result = mutations.then(mutate);
241
+ // A rejected mutation must not poison the queue, and must not surface as an unhandled rejection
242
+ // here — the caller still gets `result`, which carries the error.
243
+ mutations = result.then(() => { }, () => { });
244
+ return result;
245
+ }
246
+ /**
247
+ * Read the registry's project list. Forgiving: a missing / unreadable / malformed
248
+ * file yields `[]`, never throws. Deduped by resolved path, first wins.
249
+ */
250
+ export async function listProjects(fs = nodeRegistryFs(), env = process.env) {
251
+ return (await readRegistry(fs, env)).projects;
252
+ }
253
+ /**
254
+ * Register a project. Idempotent by resolved path: when the path is already
255
+ * registered, the existing record is returned untouched (addedAt survives);
256
+ * otherwise the new record is appended and the file written back (preferences preserved).
257
+ */
258
+ export async function addProject(path, addedAt, fs = nodeRegistryFs(), env = process.env) {
259
+ return serialize(async () => {
260
+ const absolute = resolve(path);
261
+ const registry = await readRegistry(fs, env);
262
+ const existing = registry.projects.find(project => resolve(project.path) === absolute);
263
+ if (existing)
264
+ return existing;
265
+ const record = { id: projectId(absolute), path: absolute, addedAt };
266
+ registry.projects.push(record);
267
+ await writeRegistry(registry, fs, env);
268
+ return record;
269
+ });
270
+ }
271
+ /**
272
+ * Take a project off the list, by id. Answers the record that was removed, or `undefined` when
273
+ * no project has that id. Only the list changes: nothing in the project's folder is touched, so
274
+ * a project whose folder is gone is removed like any other.
275
+ */
276
+ export async function removeProject(id, fs = nodeRegistryFs(), env = process.env) {
277
+ return serialize(async () => {
278
+ const registry = await readRegistry(fs, env);
279
+ const removed = registry.projects.find(project => project.id === id);
280
+ if (!removed)
281
+ return undefined;
282
+ registry.projects = registry.projects.filter(project => project.id !== id);
283
+ await writeRegistry(registry, fs, env);
284
+ return removed;
285
+ });
286
+ }
287
+ /** The user's dashboard preferences (#410), or `{}` when none are stored. */
288
+ export async function readPreferences(fs = nodeRegistryFs(), env = process.env) {
289
+ return (await readRegistry(fs, env)).preferences;
290
+ }
291
+ /** Persist the dashboard preferences (#410), sanitized, preserving the project list. */
292
+ export async function writePreferences(preferences, fs = nodeRegistryFs(), env = process.env) {
293
+ return serialize(async () => {
294
+ const registry = await readRegistry(fs, env);
295
+ await writeRegistry({ ...registry, preferences: sanitizePreferences(preferences) }, fs, env);
296
+ });
297
+ }
298
+ /**
299
+ * Merge `patch` over the stored preferences (#1148) and return the result.
300
+ *
301
+ * The counterpart to {@link writePreferences}, which replaces the whole block: a client that
302
+ * sends its entire snapshot replays every value it happens to hold, so a dashboard tab opened
303
+ * before someone else's change silently reverted it on the tab's next write, whatever key that
304
+ * write was actually about. Sending only the changed keys makes a write touch only what it names.
305
+ *
306
+ * Clearing needs no sentinel: {@link sanitizePreferences} already drops blank strings and empty
307
+ * lists, so `{ editor: '' }` merges in as blank and comes out absent, which is how the dashboard
308
+ * clears the editor today.
309
+ */
310
+ export async function patchPreferences(patch, fs = nodeRegistryFs(), env = process.env) {
311
+ return serialize(async () => {
312
+ const registry = await readRegistry(fs, env);
313
+ const preferences = sanitizePreferences({ ...registry.preferences, ...patch });
314
+ await writeRegistry({ ...registry, preferences }, fs, env);
315
+ return preferences;
316
+ });
317
+ }
318
+ /**
319
+ * The shared daemon token (#1051): read the persisted one, or generate + persist it now. Called
320
+ * only on a non-loopback bind, so a loopback-only machine never grows one. Serialized with the
321
+ * other mutators so two concurrent binds can't each write a different token. `base64url` of 32
322
+ * random bytes: URL-safe, so it drops straight into a `?token=` without encoding.
323
+ */
324
+ export async function ensureDaemonToken(fs = nodeRegistryFs(), env = process.env) {
325
+ return serialize(async () => {
326
+ const registry = await readRegistry(fs, env);
327
+ if (registry.daemonToken)
328
+ return registry.daemonToken;
329
+ const daemonToken = randomBytes(32).toString('base64url');
330
+ await writeRegistry({ ...registry, daemonToken }, fs, env);
331
+ return daemonToken;
332
+ });
333
+ }
334
+ /** The persisted daemon token (#1051), or `undefined` when none exists. A pure read, so a process
335
+ * that only prints the reachable URL never generates one. */
336
+ export async function readDaemonToken(fs = nodeRegistryFs(), env = process.env) {
337
+ return (await readRegistry(fs, env)).daemonToken;
338
+ }
339
+ /** A {@link PreferencesStore} bound to the real registry file, wired by the daemon so the
340
+ * dashboard's preferences RPCs read/write the user's home file.
341
+ *
342
+ * `onChange` is handed **the keys the caller wrote**, not the merged result, so a listener can
343
+ * tell "this write switched the setting on" from "it was already on and something else changed"
344
+ * (#1161). It runs after the write has landed, and its failure is swallowed: the save succeeded,
345
+ * and a listener must not be able to report otherwise: a setting saved in the browser has to
346
+ * reach the daemon's own services without a restart.
347
+ */
348
+ export function registryPreferencesStore(fs = nodeRegistryFs(), env = process.env, onChange) {
349
+ const changed = (written, result) => {
350
+ try {
351
+ onChange?.(written);
352
+ }
353
+ catch {
354
+ // The write landed; a listener that throws is not the writer's problem.
355
+ }
356
+ return result;
357
+ };
358
+ return {
359
+ read: () => readPreferences(fs, env),
360
+ save: async (preferences) => changed(preferences, await writePreferences(preferences, fs, env)),
361
+ patch: async (patch) => changed(patch, await patchPreferences(patch, fs, env)),
362
+ };
363
+ }
364
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type GitRunner } from '@openagt/agent-data';
2
+ import type { CleanupReport } from './dashboard/types.js';
3
+ /**
4
+ * What OpenAgent left in a project's folder, removed: what a person asks for with the box in the
5
+ * "Remove project" dialog. Three owners, each removing its own:
6
+ *
7
+ * - every tool that declares a `cleanup` command: asked to run it, and its answer passed on. One
8
+ * that refuses or fails ends the pass there: the records and the dashboard's directory stay.
9
+ * The runner refuses while a run is alive, the scheduler while one set to keep running is.
10
+ * - the agents' records: the `agent-data` checkout and local branch, and the person's answer to
11
+ * "share the records". Left alone when another project on the list is a checkout of the same
12
+ * repository, since the branch is the repository's and that project still reads it.
13
+ * - the dashboard's own directory, `.openagent/`: every file git does not track.
14
+ *
15
+ * Never the remote, a commit, a branch with work on it or a file git tracks. Nothing here throws:
16
+ * what could not be done is a line in `failed`.
17
+ */
18
+ export interface RemoveFilesOptions {
19
+ /** Another project on the list that is a checkout of the same repository, by its folder. */
20
+ recordsUsedBy?: string | undefined;
21
+ git?: GitRunner;
22
+ }
23
+ export declare function removeProjectFiles(root: string, opts?: RemoveFilesOptions): Promise<CleanupReport>;
24
+ //# sourceMappingURL=remove-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-files.d.ts","sourceRoot":"","sources":["../src/remove-files.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6E,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAI/H,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,kBAAkB;IACjC,4FAA4F;IAC5F,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,GAAG,CAAC,EAAE,SAAS,CAAA;CAChB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiC5G"}
@@ -0,0 +1,98 @@
1
+ import { lstat, readdir, rm, rmdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { DATA_BRANCH, clearSharing, nodeGitRunner, removeFileBranch, SHARE_SETTING } from '@openagt/agent-data';
4
+ import { OPENAGENT_DIR } from './openagent-dir.js';
5
+ import { runCleanups } from './built-in.js';
6
+ import { errorMessage } from './error-message.js';
7
+ export async function removeProjectFiles(root, opts = {}) {
8
+ const git = opts.git ?? nodeGitRunner();
9
+ const report = { removed: [], kept: [], failed: [] };
10
+ // The tools first: the runner refuses while a run of this machine is alive, and then nothing
11
+ // of the records or the dashboard's directory may go from under that run.
12
+ const tools = await runCleanups(root);
13
+ report.removed.push(...tools.removed);
14
+ report.kept.push(...tools.kept);
15
+ report.failed.push(...tools.failed);
16
+ if (tools.failed.length > 0) {
17
+ const reason = 'a clean-up before it did not finish';
18
+ report.kept.push({ path: `branch ${DATA_BRANCH}`, reason }, { path: OPENAGENT_DIR, reason });
19
+ return report;
20
+ }
21
+ if (opts.recordsUsedBy !== undefined) {
22
+ report.kept.push({ path: `branch ${DATA_BRANCH}`, reason: `another project on the list uses it: ${opts.recordsUsedBy}` });
23
+ }
24
+ else {
25
+ const records = await removeFileBranch(root, DATA_BRANCH, { git });
26
+ if (!records.ok)
27
+ report.failed.push(`the agents' records: ${records.error}`);
28
+ else {
29
+ report.removed.push(...records.removed);
30
+ // The records' checkout was another tool's "not mine" a moment ago; now it is gone.
31
+ report.kept = report.kept.filter(kept => !records.removed.includes(kept.path));
32
+ report.kept.push(...records.kept);
33
+ // The answer goes with the records it was about; while anything of them stays, so does it.
34
+ if (records.kept.length === 0 && (await clearSharing(root, git)))
35
+ report.removed.push(`setting ${SHARE_SETTING}`);
36
+ }
37
+ }
38
+ await removeOwnDirectory(root, git, report);
39
+ return report;
40
+ }
41
+ /** The dashboard's directory: every file in it that git does not track, then each directory left empty. */
42
+ async function removeOwnDirectory(root, git, report) {
43
+ const dir = join(root, OPENAGENT_DIR);
44
+ const entry = await lstat(dir).catch(() => undefined);
45
+ if (!entry)
46
+ return;
47
+ // A link is followed nowhere: what it points at may lie outside the project.
48
+ if (!entry.isDirectory()) {
49
+ report.kept.push({ path: OPENAGENT_DIR, reason: 'not made by OpenAgent' });
50
+ return;
51
+ }
52
+ let tracked;
53
+ try {
54
+ tracked = new Set((await git(['ls-files', '-z', '--', OPENAGENT_DIR], root)).split('\0').filter(Boolean).map(folded));
55
+ }
56
+ catch (err) {
57
+ // Without git's word on what it tracks, nothing is removed.
58
+ report.failed.push(`${OPENAGENT_DIR}: ${errorMessage(err)}`);
59
+ return;
60
+ }
61
+ try {
62
+ const files = [];
63
+ // The whole directory in one line when it went; else the files that did.
64
+ if (await emptyOut(root, OPENAGENT_DIR, tracked, report, files))
65
+ report.removed.push(OPENAGENT_DIR);
66
+ else
67
+ report.removed.push(...files);
68
+ }
69
+ catch (err) {
70
+ report.failed.push(`${OPENAGENT_DIR}: ${errorMessage(err)}`);
71
+ }
72
+ }
73
+ /**
74
+ * Remove what git does not track under `rel` (a directory, from the project's root) and then the
75
+ * directory itself when nothing is left in it. Answers whether the directory went. A tracked file
76
+ * is named in the report's `kept`, a removed one in `files`; a link is removed as a link, never
77
+ * followed.
78
+ */
79
+ async function emptyOut(root, rel, tracked, report, files) {
80
+ for (const name of await readdir(join(root, rel))) {
81
+ const path = `${rel}/${name}`;
82
+ if ((await lstat(join(root, path))).isDirectory())
83
+ await emptyOut(root, path, tracked, report, files);
84
+ else if (tracked.has(folded(path)))
85
+ report.kept.push({ path, reason: 'git tracks it' });
86
+ else {
87
+ await rm(join(root, path), { force: true });
88
+ files.push(path);
89
+ }
90
+ }
91
+ // rmdir, never a recursive remove: whatever is left in it keeps it.
92
+ return rmdir(join(root, rel)).then(() => true, () => false);
93
+ }
94
+ /** A path as a file system that ignores case and Unicode form names it: two spellings of one tracked file are the same file here. */
95
+ function folded(path) {
96
+ return path.normalize('NFC').toLowerCase();
97
+ }
98
+ //# sourceMappingURL=remove-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-files.js","sourceRoot":"","sources":["../src/remove-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ /**
3
+ * A request's pathname, parsed defensively (#938). Node hands the request target through
4
+ * verbatim, including absolute-form targets a proxy client may send (`GET http://[ ...`),
5
+ * and `new URL` throws on those synchronously inside the request handler — an uncaught
6
+ * exception that takes the whole daemon down. `undefined` means "no parseable path":
7
+ * answer 400 (or serve the fallback), never throw.
8
+ */
9
+ export declare function requestPathname(req: IncomingMessage): string | undefined;
10
+ //# sourceMappingURL=request-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-path.d.ts","sourceRoot":"","sources":["../src/request-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAEhD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAMxE"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * A request's pathname, parsed defensively (#938). Node hands the request target through
3
+ * verbatim, including absolute-form targets a proxy client may send (`GET http://[ ...`),
4
+ * and `new URL` throws on those synchronously inside the request handler — an uncaught
5
+ * exception that takes the whole daemon down. `undefined` means "no parseable path":
6
+ * answer 400 (or serve the fallback), never throw.
7
+ */
8
+ export function requestPathname(req) {
9
+ try {
10
+ return new URL(req.url ?? '/', 'http://localhost').pathname;
11
+ }
12
+ catch {
13
+ return undefined;
14
+ }
15
+ }
16
+ //# sourceMappingURL=request-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-path.js","sourceRoot":"","sources":["../src/request-path.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,GAAoB;IAClD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAA;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { type BranchesFor, type Checkout } from './branches.js';
2
+ import { type AnyDiaryLine, type RunsFor } from './runs.js';
3
+ /**
4
+ * A run's checkout, as the project's branches provider lists it, or `undefined` when it lists
5
+ * none for the id. The provider's list is shared for a few seconds; a run that is not in it may
6
+ * have started a moment ago, so a miss asks once more, fresh (`branches.ts` bounds how fresh).
7
+ */
8
+ export declare function findCheckout(projectCwd: string, agentId: string, branches: BranchesFor, opts?: {
9
+ cached?: boolean;
10
+ }): Promise<Checkout | undefined>;
11
+ /**
12
+ * The checkout an agent id resolves to (#738/#797): the agent's own checkout while the project's
13
+ * branches provider lists one for it, else the project root. The list is asked fresh on a miss:
14
+ * a run that just started has its checkout before its tool has written the card (#766), and the
15
+ * event stream resolves its path once, when the browser opens it.
16
+ *
17
+ * An unknown or finished `agentId` falls back to the project root rather than failing: the
18
+ * run's checkout may already be gone, and the project's own state is still the sane thing to
19
+ * act on. This is the one resolution every run-addressed surface shares — the daemon's serve
20
+ * targets and previews, and each dashboard RPC — so the fallback rules cannot drift apart.
21
+ */
22
+ export declare function resolveAgentCheckout(projectCwd: string, agentId: string | undefined, branches?: BranchesFor): Promise<string>;
23
+ /**
24
+ * Where a run's diary is, for a reader that follows it: a file while the run has a checkout, the
25
+ * finished run's lines once it has none, or nowhere yet (`pending`): the run was started a moment
26
+ * ago and its tool has not made the checkout, so the reader asks again shortly.
27
+ */
28
+ export type AgentDiarySource = {
29
+ file: string;
30
+ } | {
31
+ finished: AnyDiaryLine[];
32
+ } | {
33
+ pending: true;
34
+ };
35
+ /**
36
+ * The diary a run-scoped subscribe should follow (#1472, #1774): the run's own `<id>.jsonl`.
37
+ * While the run has a checkout it is a file there, under the checkout's `.openagent/`,
38
+ * written by the run's tool as the agent works. Once the run is recorded and its checkout
39
+ * reclaimed, it is the finished run's diary, whole, from the project's runs provider. A run that
40
+ * has neither yet was started a moment ago: its tool has not made the checkout, so the diary is
41
+ * nowhere yet, and the tail asks again (`../dashboard-rpc/events-tail.ts`). A project with no
42
+ * runs provider answers the same for a finished run: nowhere, where nothing more comes.
43
+ *
44
+ * `cached` answers from the shared lists only, never asking the checkouts fresh on a miss: for a
45
+ * reader that asks about a finished run for as long as it is open, in case it is resumed.
46
+ *
47
+ * Only the events tails resolve here; every other run-addressed surface keeps
48
+ * {@link resolveAgentCheckout}'s root fallback, where the project's own state is the sane
49
+ * thing to act on.
50
+ */
51
+ export declare function resolveAgentDiary(projectCwd: string, agentId: string | undefined, runs?: RunsFor, branches?: BranchesFor, opts?: {
52
+ cached?: boolean;
53
+ }): Promise<AgentDiarySource | undefined>;
54
+ //# sourceMappingURL=agent-checkout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-checkout.d.ts","sourceRoot":"","sources":["../../src/store/agent-checkout.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAA;AAChF,OAAO,EAAwB,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAA;AAGjF;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAM7J;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,GAAE,WAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAGpJ;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,CAAA;AAElG;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,GAAE,OAAqB,EAC3B,QAAQ,GAAE,WAA6B,EACvC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9B,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAMvC"}