@made-by-moonlight/athene-web 0.9.2

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 (302) hide show
  1. package/.next/BUILD_ID +1 -0
  2. package/.next/app-build-manifest.json +448 -0
  3. package/.next/app-path-routes-manifest.json +47 -0
  4. package/.next/build-manifest.json +33 -0
  5. package/.next/export-marker.json +6 -0
  6. package/.next/images-manifest.json +58 -0
  7. package/.next/next-minimal-server.js.nft.json +1 -0
  8. package/.next/next-server.js.nft.json +1 -0
  9. package/.next/package.json +1 -0
  10. package/.next/prerender-manifest.json +172 -0
  11. package/.next/react-loadable-manifest.json +61 -0
  12. package/.next/required-server-files.json +335 -0
  13. package/.next/routes-manifest.json +234 -0
  14. package/.next/server/app/_not-found/page.js +2 -0
  15. package/.next/server/app/_not-found/page.js.nft.json +1 -0
  16. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  17. package/.next/server/app/_not-found.html +1 -0
  18. package/.next/server/app/_not-found.meta +8 -0
  19. package/.next/server/app/_not-found.rsc +24 -0
  20. package/.next/server/app/api/backlog/route.js +1 -0
  21. package/.next/server/app/api/backlog/route.js.nft.json +1 -0
  22. package/.next/server/app/api/backlog/route_client-reference-manifest.js +1 -0
  23. package/.next/server/app/api/browse-directory/route.js +1 -0
  24. package/.next/server/app/api/browse-directory/route.js.nft.json +1 -0
  25. package/.next/server/app/api/browse-directory/route_client-reference-manifest.js +1 -0
  26. package/.next/server/app/api/filesystem/browse/route.js +1 -0
  27. package/.next/server/app/api/filesystem/browse/route.js.nft.json +1 -0
  28. package/.next/server/app/api/filesystem/browse/route_client-reference-manifest.js +1 -0
  29. package/.next/server/app/api/issues/route.js +1 -0
  30. package/.next/server/app/api/issues/route.js.nft.json +1 -0
  31. package/.next/server/app/api/issues/route_client-reference-manifest.js +1 -0
  32. package/.next/server/app/api/observability/route.js +1 -0
  33. package/.next/server/app/api/observability/route.js.nft.json +1 -0
  34. package/.next/server/app/api/observability/route_client-reference-manifest.js +1 -0
  35. package/.next/server/app/api/orchestrators/route.js +1 -0
  36. package/.next/server/app/api/orchestrators/route.js.nft.json +1 -0
  37. package/.next/server/app/api/orchestrators/route_client-reference-manifest.js +1 -0
  38. package/.next/server/app/api/projects/[id]/route.js +5 -0
  39. package/.next/server/app/api/projects/[id]/route.js.nft.json +1 -0
  40. package/.next/server/app/api/projects/[id]/route_client-reference-manifest.js +1 -0
  41. package/.next/server/app/api/projects/reload/route.js +1 -0
  42. package/.next/server/app/api/projects/reload/route.js.nft.json +1 -0
  43. package/.next/server/app/api/projects/reload/route_client-reference-manifest.js +1 -0
  44. package/.next/server/app/api/projects/route.js +1 -0
  45. package/.next/server/app/api/projects/route.js.nft.json +1 -0
  46. package/.next/server/app/api/projects/route_client-reference-manifest.js +1 -0
  47. package/.next/server/app/api/prs/[id]/merge/route.js +1 -0
  48. package/.next/server/app/api/prs/[id]/merge/route.js.nft.json +1 -0
  49. package/.next/server/app/api/prs/[id]/merge/route_client-reference-manifest.js +1 -0
  50. package/.next/server/app/api/reviews/execute/route.js +1 -0
  51. package/.next/server/app/api/reviews/execute/route.js.nft.json +1 -0
  52. package/.next/server/app/api/reviews/execute/route_client-reference-manifest.js +1 -0
  53. package/.next/server/app/api/reviews/findings/route.js +1 -0
  54. package/.next/server/app/api/reviews/findings/route.js.nft.json +1 -0
  55. package/.next/server/app/api/reviews/findings/route_client-reference-manifest.js +1 -0
  56. package/.next/server/app/api/reviews/route.js +1 -0
  57. package/.next/server/app/api/reviews/route.js.nft.json +1 -0
  58. package/.next/server/app/api/reviews/route_client-reference-manifest.js +1 -0
  59. package/.next/server/app/api/reviews/send/route.js +1 -0
  60. package/.next/server/app/api/reviews/send/route.js.nft.json +1 -0
  61. package/.next/server/app/api/reviews/send/route_client-reference-manifest.js +1 -0
  62. package/.next/server/app/api/runtime/terminal/route.js +1 -0
  63. package/.next/server/app/api/runtime/terminal/route.js.nft.json +1 -0
  64. package/.next/server/app/api/runtime/terminal/route_client-reference-manifest.js +1 -0
  65. package/.next/server/app/api/sessions/[id]/kill/route.js +1 -0
  66. package/.next/server/app/api/sessions/[id]/kill/route.js.nft.json +1 -0
  67. package/.next/server/app/api/sessions/[id]/kill/route_client-reference-manifest.js +1 -0
  68. package/.next/server/app/api/sessions/[id]/message/route.js +1 -0
  69. package/.next/server/app/api/sessions/[id]/message/route.js.nft.json +1 -0
  70. package/.next/server/app/api/sessions/[id]/message/route_client-reference-manifest.js +1 -0
  71. package/.next/server/app/api/sessions/[id]/remap/route.js +1 -0
  72. package/.next/server/app/api/sessions/[id]/remap/route.js.nft.json +1 -0
  73. package/.next/server/app/api/sessions/[id]/remap/route_client-reference-manifest.js +1 -0
  74. package/.next/server/app/api/sessions/[id]/restore/route.js +1 -0
  75. package/.next/server/app/api/sessions/[id]/restore/route.js.nft.json +1 -0
  76. package/.next/server/app/api/sessions/[id]/restore/route_client-reference-manifest.js +1 -0
  77. package/.next/server/app/api/sessions/[id]/route.js +1 -0
  78. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -0
  79. package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -0
  80. package/.next/server/app/api/sessions/[id]/send/route.js +1 -0
  81. package/.next/server/app/api/sessions/[id]/send/route.js.nft.json +1 -0
  82. package/.next/server/app/api/sessions/[id]/send/route_client-reference-manifest.js +1 -0
  83. package/.next/server/app/api/sessions/patches/route.js +1 -0
  84. package/.next/server/app/api/sessions/patches/route.js.nft.json +1 -0
  85. package/.next/server/app/api/sessions/patches/route_client-reference-manifest.js +1 -0
  86. package/.next/server/app/api/sessions/route.js +1 -0
  87. package/.next/server/app/api/sessions/route.js.nft.json +1 -0
  88. package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -0
  89. package/.next/server/app/api/setup-labels/route.js +1 -0
  90. package/.next/server/app/api/setup-labels/route.js.nft.json +1 -0
  91. package/.next/server/app/api/setup-labels/route_client-reference-manifest.js +1 -0
  92. package/.next/server/app/api/spawn/route.js +1 -0
  93. package/.next/server/app/api/spawn/route.js.nft.json +1 -0
  94. package/.next/server/app/api/spawn/route_client-reference-manifest.js +1 -0
  95. package/.next/server/app/api/update/route.js +1 -0
  96. package/.next/server/app/api/update/route.js.nft.json +1 -0
  97. package/.next/server/app/api/update/route_client-reference-manifest.js +1 -0
  98. package/.next/server/app/api/verify/route.js +1 -0
  99. package/.next/server/app/api/verify/route.js.nft.json +1 -0
  100. package/.next/server/app/api/verify/route_client-reference-manifest.js +1 -0
  101. package/.next/server/app/api/version/route.js +1 -0
  102. package/.next/server/app/api/version/route.js.nft.json +1 -0
  103. package/.next/server/app/api/version/route_client-reference-manifest.js +1 -0
  104. package/.next/server/app/api/webhooks/[...slug]/route.js +1 -0
  105. package/.next/server/app/api/webhooks/[...slug]/route.js.nft.json +1 -0
  106. package/.next/server/app/api/webhooks/[...slug]/route_client-reference-manifest.js +1 -0
  107. package/.next/server/app/apple-icon/route.js +1 -0
  108. package/.next/server/app/apple-icon/route.js.nft.json +1 -0
  109. package/.next/server/app/apple-icon/route_client-reference-manifest.js +1 -0
  110. package/.next/server/app/apple-icon.body +0 -0
  111. package/.next/server/app/apple-icon.meta +1 -0
  112. package/.next/server/app/dev/terminal-test/page.js +15 -0
  113. package/.next/server/app/dev/terminal-test/page.js.nft.json +1 -0
  114. package/.next/server/app/dev/terminal-test/page_client-reference-manifest.js +1 -0
  115. package/.next/server/app/dev/terminal-test.html +1 -0
  116. package/.next/server/app/dev/terminal-test.meta +7 -0
  117. package/.next/server/app/dev/terminal-test.rsc +28 -0
  118. package/.next/server/app/icon/route.js +1 -0
  119. package/.next/server/app/icon/route.js.nft.json +1 -0
  120. package/.next/server/app/icon/route_client-reference-manifest.js +1 -0
  121. package/.next/server/app/icon-192/route.js +1 -0
  122. package/.next/server/app/icon-192/route.js.nft.json +1 -0
  123. package/.next/server/app/icon-192/route_client-reference-manifest.js +1 -0
  124. package/.next/server/app/icon-512/route.js +1 -0
  125. package/.next/server/app/icon-512/route.js.nft.json +1 -0
  126. package/.next/server/app/icon-512/route_client-reference-manifest.js +1 -0
  127. package/.next/server/app/icon.body +0 -0
  128. package/.next/server/app/icon.meta +1 -0
  129. package/.next/server/app/manifest.webmanifest/route.js +16 -0
  130. package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -0
  131. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -0
  132. package/.next/server/app/manifest.webmanifest.body +1 -0
  133. package/.next/server/app/manifest.webmanifest.meta +1 -0
  134. package/.next/server/app/page.js +2 -0
  135. package/.next/server/app/page.js.nft.json +1 -0
  136. package/.next/server/app/page_client-reference-manifest.js +1 -0
  137. package/.next/server/app/projects/[projectId]/page.js +2 -0
  138. package/.next/server/app/projects/[projectId]/page.js.nft.json +1 -0
  139. package/.next/server/app/projects/[projectId]/page_client-reference-manifest.js +1 -0
  140. package/.next/server/app/projects/[projectId]/sessions/[id]/page.js +2 -0
  141. package/.next/server/app/projects/[projectId]/sessions/[id]/page.js.nft.json +1 -0
  142. package/.next/server/app/projects/[projectId]/sessions/[id]/page_client-reference-manifest.js +1 -0
  143. package/.next/server/app/projects/[projectId]/settings/page.js +2 -0
  144. package/.next/server/app/projects/[projectId]/settings/page.js.nft.json +1 -0
  145. package/.next/server/app/projects/[projectId]/settings/page_client-reference-manifest.js +1 -0
  146. package/.next/server/app/prs/page.js +2 -0
  147. package/.next/server/app/prs/page.js.nft.json +1 -0
  148. package/.next/server/app/prs/page_client-reference-manifest.js +1 -0
  149. package/.next/server/app/review/page.js +2 -0
  150. package/.next/server/app/review/page.js.nft.json +1 -0
  151. package/.next/server/app/review/page_client-reference-manifest.js +1 -0
  152. package/.next/server/app/reviews/page.js +2 -0
  153. package/.next/server/app/reviews/page.js.nft.json +1 -0
  154. package/.next/server/app/reviews/page_client-reference-manifest.js +1 -0
  155. package/.next/server/app/sessions/[id]/page.js +2 -0
  156. package/.next/server/app/sessions/[id]/page.js.nft.json +1 -0
  157. package/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -0
  158. package/.next/server/app/test-direct/page.js +2 -0
  159. package/.next/server/app/test-direct/page.js.nft.json +1 -0
  160. package/.next/server/app/test-direct/page_client-reference-manifest.js +1 -0
  161. package/.next/server/app/test-direct.html +1 -0
  162. package/.next/server/app/test-direct.meta +7 -0
  163. package/.next/server/app/test-direct.rsc +28 -0
  164. package/.next/server/app-paths-manifest.json +47 -0
  165. package/.next/server/chunks/1215.js +1 -0
  166. package/.next/server/chunks/1271.js +1 -0
  167. package/.next/server/chunks/2106.js +1 -0
  168. package/.next/server/chunks/2347.js +3 -0
  169. package/.next/server/chunks/2899.js +1 -0
  170. package/.next/server/chunks/2914.js +1 -0
  171. package/.next/server/chunks/4033.js +1 -0
  172. package/.next/server/chunks/4148.js +942 -0
  173. package/.next/server/chunks/4422.js +32 -0
  174. package/.next/server/chunks/5053.js +1 -0
  175. package/.next/server/chunks/5689.js +1 -0
  176. package/.next/server/chunks/6148.js +9 -0
  177. package/.next/server/chunks/6582.js +25 -0
  178. package/.next/server/chunks/7002.js +1 -0
  179. package/.next/server/chunks/7486.js +9 -0
  180. package/.next/server/chunks/8803.js +6 -0
  181. package/.next/server/chunks/9472.js +847 -0
  182. package/.next/server/chunks/9493.js +1 -0
  183. package/.next/server/chunks/9561.js +22 -0
  184. package/.next/server/chunks/966.js +1 -0
  185. package/.next/server/functions-config-manifest.json +4 -0
  186. package/.next/server/interception-route-rewrite-manifest.js +1 -0
  187. package/.next/server/middleware-build-manifest.js +1 -0
  188. package/.next/server/middleware-manifest.json +6 -0
  189. package/.next/server/middleware-react-loadable-manifest.js +1 -0
  190. package/.next/server/next-font-manifest.js +1 -0
  191. package/.next/server/next-font-manifest.json +1 -0
  192. package/.next/server/pages/404.html +1 -0
  193. package/.next/server/pages/500.html +1 -0
  194. package/.next/server/pages/_app.js +1 -0
  195. package/.next/server/pages/_app.js.nft.json +1 -0
  196. package/.next/server/pages/_document.js +1 -0
  197. package/.next/server/pages/_document.js.nft.json +1 -0
  198. package/.next/server/pages/_error.js +19 -0
  199. package/.next/server/pages/_error.js.nft.json +1 -0
  200. package/.next/server/pages-manifest.json +6 -0
  201. package/.next/server/server-reference-manifest.js +1 -0
  202. package/.next/server/server-reference-manifest.json +1 -0
  203. package/.next/server/webpack-runtime.js +1 -0
  204. package/.next/static/chunks/0f200859.359176a445d2791f.js +10 -0
  205. package/.next/static/chunks/1089-c6d7995c7c19039a.js +1 -0
  206. package/.next/static/chunks/1461-af7c54935f21d56d.js +1 -0
  207. package/.next/static/chunks/2073-4192de0bb00cc993.js +1 -0
  208. package/.next/static/chunks/3764.4c736d9a181489a4.js +1 -0
  209. package/.next/static/chunks/4115-1a4fa80ec67a29d3.js +1 -0
  210. package/.next/static/chunks/4751.6c71bfc0c4520627.js +1 -0
  211. package/.next/static/chunks/503.f7ff284457dd9c40.js +1 -0
  212. package/.next/static/chunks/5204.7de7e266895bced7.js +1 -0
  213. package/.next/static/chunks/6835.7a29fa4b665b7c2f.js +1 -0
  214. package/.next/static/chunks/7008-0d9bee1bf4bfcbea.js +1 -0
  215. package/.next/static/chunks/7317.685aa5231218e8d3.js +1 -0
  216. package/.next/static/chunks/8204-7c7837ed694da99c.js +1 -0
  217. package/.next/static/chunks/8713-d3d663f55dc00e48.js +1 -0
  218. package/.next/static/chunks/8759-490573536f93f85c.js +1 -0
  219. package/.next/static/chunks/88a6fc35-f836b4b72df5eafa.js +1 -0
  220. package/.next/static/chunks/9531-a5175e55fa0db48d.js +1 -0
  221. package/.next/static/chunks/9876-de0c5a1a319b4e8e.js +1 -0
  222. package/.next/static/chunks/app/_not-found/page-6add9dacf1870b4b.js +1 -0
  223. package/.next/static/chunks/app/api/backlog/route-6add9dacf1870b4b.js +1 -0
  224. package/.next/static/chunks/app/api/browse-directory/route-6add9dacf1870b4b.js +1 -0
  225. package/.next/static/chunks/app/api/filesystem/browse/route-6add9dacf1870b4b.js +1 -0
  226. package/.next/static/chunks/app/api/issues/route-6add9dacf1870b4b.js +1 -0
  227. package/.next/static/chunks/app/api/observability/route-6add9dacf1870b4b.js +1 -0
  228. package/.next/static/chunks/app/api/orchestrators/route-6add9dacf1870b4b.js +1 -0
  229. package/.next/static/chunks/app/api/projects/[id]/route-6add9dacf1870b4b.js +1 -0
  230. package/.next/static/chunks/app/api/projects/reload/route-6add9dacf1870b4b.js +1 -0
  231. package/.next/static/chunks/app/api/projects/route-6add9dacf1870b4b.js +1 -0
  232. package/.next/static/chunks/app/api/prs/[id]/merge/route-6add9dacf1870b4b.js +1 -0
  233. package/.next/static/chunks/app/api/reviews/execute/route-6add9dacf1870b4b.js +1 -0
  234. package/.next/static/chunks/app/api/reviews/findings/route-6add9dacf1870b4b.js +1 -0
  235. package/.next/static/chunks/app/api/reviews/route-6add9dacf1870b4b.js +1 -0
  236. package/.next/static/chunks/app/api/reviews/send/route-6add9dacf1870b4b.js +1 -0
  237. package/.next/static/chunks/app/api/runtime/terminal/route-6add9dacf1870b4b.js +1 -0
  238. package/.next/static/chunks/app/api/sessions/[id]/kill/route-6add9dacf1870b4b.js +1 -0
  239. package/.next/static/chunks/app/api/sessions/[id]/message/route-6add9dacf1870b4b.js +1 -0
  240. package/.next/static/chunks/app/api/sessions/[id]/remap/route-6add9dacf1870b4b.js +1 -0
  241. package/.next/static/chunks/app/api/sessions/[id]/restore/route-6add9dacf1870b4b.js +1 -0
  242. package/.next/static/chunks/app/api/sessions/[id]/route-6add9dacf1870b4b.js +1 -0
  243. package/.next/static/chunks/app/api/sessions/[id]/send/route-6add9dacf1870b4b.js +1 -0
  244. package/.next/static/chunks/app/api/sessions/patches/route-6add9dacf1870b4b.js +1 -0
  245. package/.next/static/chunks/app/api/sessions/route-6add9dacf1870b4b.js +1 -0
  246. package/.next/static/chunks/app/api/setup-labels/route-6add9dacf1870b4b.js +1 -0
  247. package/.next/static/chunks/app/api/spawn/route-6add9dacf1870b4b.js +1 -0
  248. package/.next/static/chunks/app/api/update/route-6add9dacf1870b4b.js +1 -0
  249. package/.next/static/chunks/app/api/verify/route-6add9dacf1870b4b.js +1 -0
  250. package/.next/static/chunks/app/api/version/route-6add9dacf1870b4b.js +1 -0
  251. package/.next/static/chunks/app/api/webhooks/[...slug]/route-6add9dacf1870b4b.js +1 -0
  252. package/.next/static/chunks/app/apple-icon/route-6add9dacf1870b4b.js +1 -0
  253. package/.next/static/chunks/app/dev/terminal-test/page-d0132109f9d8524e.js +1 -0
  254. package/.next/static/chunks/app/error-d632d0714b987864.js +1 -0
  255. package/.next/static/chunks/app/global-error-f6bef179169bcdae.js +1 -0
  256. package/.next/static/chunks/app/icon/route-6add9dacf1870b4b.js +1 -0
  257. package/.next/static/chunks/app/icon-192/route-6add9dacf1870b4b.js +1 -0
  258. package/.next/static/chunks/app/icon-512/route-6add9dacf1870b4b.js +1 -0
  259. package/.next/static/chunks/app/layout-5cac6fe817194d7a.js +1 -0
  260. package/.next/static/chunks/app/loading-6add9dacf1870b4b.js +1 -0
  261. package/.next/static/chunks/app/manifest.webmanifest/route-6add9dacf1870b4b.js +1 -0
  262. package/.next/static/chunks/app/not-found-cba3f587e1f98dcb.js +1 -0
  263. package/.next/static/chunks/app/page-cf7bccb75990950d.js +1 -0
  264. package/.next/static/chunks/app/projects/[projectId]/layout-6add9dacf1870b4b.js +1 -0
  265. package/.next/static/chunks/app/projects/[projectId]/loading-6add9dacf1870b4b.js +1 -0
  266. package/.next/static/chunks/app/projects/[projectId]/page-039a93b16089ed57.js +1 -0
  267. package/.next/static/chunks/app/projects/[projectId]/sessions/[id]/page-043b525bedb8f0f7.js +1 -0
  268. package/.next/static/chunks/app/projects/[projectId]/settings/page-63572555892d7a61.js +1 -0
  269. package/.next/static/chunks/app/projects/layout-d43b2e38d46221bd.js +1 -0
  270. package/.next/static/chunks/app/prs/page-e447852fbe0c6ee4.js +1 -0
  271. package/.next/static/chunks/app/review/page-022b2d2c326ff413.js +1 -0
  272. package/.next/static/chunks/app/reviews/page-6add9dacf1870b4b.js +1 -0
  273. package/.next/static/chunks/app/sessions/[id]/error-67c0d27f977a1cc1.js +1 -0
  274. package/.next/static/chunks/app/sessions/[id]/loading-6add9dacf1870b4b.js +1 -0
  275. package/.next/static/chunks/app/sessions/[id]/not-found-cba3f587e1f98dcb.js +1 -0
  276. package/.next/static/chunks/app/sessions/[id]/page-863cf8dd2c76d06d.js +1 -0
  277. package/.next/static/chunks/app/test-direct/page-8b80ed180c0f2f42.js +1 -0
  278. package/.next/static/chunks/e12b4bb0.8742134e1ac0263f.js +58 -0
  279. package/.next/static/chunks/framework-7060e2ac4971c604.js +1 -0
  280. package/.next/static/chunks/main-app-162601c3f1c01b19.js +1 -0
  281. package/.next/static/chunks/main-ed1610689fbd6f0d.js +1 -0
  282. package/.next/static/chunks/pages/_app-f4baf4dbe88f6f54.js +1 -0
  283. package/.next/static/chunks/pages/_error-a7f6723f42093f29.js +1 -0
  284. package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  285. package/.next/static/chunks/webpack-f9566aaa604a1b07.js +1 -0
  286. package/.next/static/css/0c9b7451c2ce7c02.css +1 -0
  287. package/.next/static/css/7ca4e3753c1c7833.css +1 -0
  288. package/.next/static/css/b4a15f23f468892a.css +1 -0
  289. package/.next/static/css/d06ee45019116677.css +1 -0
  290. package/.next/static/media/91601dd83defba07-s.p.woff2 +0 -0
  291. package/.next/static/media/aa8291c31d4e9e54-s.p.woff2 +0 -0
  292. package/.next/static/pROr0laPuZIdA4NYNygMD/_buildManifest.js +1 -0
  293. package/.next/static/pROr0laPuZIdA4NYNygMD/_ssgManifest.js +1 -0
  294. package/LICENSE +22 -0
  295. package/dist-server/direct-terminal-ws.js +109 -0
  296. package/dist-server/mux-websocket.js +1162 -0
  297. package/dist-server/single-port-server.js +305 -0
  298. package/dist-server/start-all.js +150 -0
  299. package/dist-server/terminal-observability.js +16 -0
  300. package/dist-server/tmux-utils.js +301 -0
  301. package/next.config.js +71 -0
  302. package/package.json +97 -0
@@ -0,0 +1,942 @@
1
+ exports.id=4148,exports.ids=[4148],exports.modules={15407:(a,b,c)=>{"use strict";c.d(b,{Ag:()=>w,CK:()=>v,CM:()=>h,D8:()=>u,DD:()=>r,Fx:()=>t,Hk:()=>n,N_:()=>j,PE:()=>e,SB:()=>g,U1:()=>q,V1:()=>f,b8:()=>s,bz:()=>p,c5:()=>y,kw:()=>x,qX:()=>l,tT:()=>m,u3:()=>d,xn:()=>o,zi:()=>k});let d={ACTIVE:"active",READY:"ready",IDLE:"idle",WAITING_INPUT:"waiting_input",BLOCKED:"blocked",EXITED:"exited"},e=3e5,f=3e4,g={SPAWNING:"spawning",WORKING:"working",DETECTING:"detecting",PR_OPEN:"pr_open",CI_FAILED:"ci_failed",REVIEW_PENDING:"review_pending",CHANGES_REQUESTED:"changes_requested",APPROVED:"approved",MERGEABLE:"mergeable",MERGED:"merged",CLEANUP:"cleanup",NEEDS_INPUT:"needs_input",STUCK:"stuck",ERRORED:"errored",IDLE:"idle",KILLED:"killed",DONE:"done",TERMINATED:"terminated"},h=new Set(["killed","terminated","done","cleanup","errored","merged"]),i=new Set(["exited"]),j=new Set([]);function k(a){return a.lifecycle?"done"===a.lifecycle.session.state||"terminated"===a.lifecycle.session.state||"merged"===a.lifecycle.pr.state||"missing"===a.lifecycle.runtime.state||"exited"===a.lifecycle.runtime.state:h.has(a.status)||null!==a.activity&&i.has(a.activity)}function l(a){return a.lifecycle,k(a)&&!j.has(a.status)}function m(a,b,c){if(a.metadata?.role==="orchestrator")return!0;if(!b)return!1;let d=b.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");if(a.id===`${b}-orchestrator`)return!0;if(!RegExp(`^${d}-orchestrator-\\d+$`).test(a.id))return!1;if(c){for(let d of c)if(d!==b&&RegExp(`^${d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}-\\d+$`).test(a.id))return!1}return!0}let n="indeterminate";function o(a){return a===n}let p={OPEN:"open",MERGED:"merged",CLOSED:"closed"},q={PENDING:"pending",PASSING:"passing",FAILING:"failing",NONE:"none"};function r(a){if(a)return"permissionless"!==a&&"default"!==a&&"auto-edit"!==a&&"suggest"!==a?"skip"===a?"permissionless":void 0:a}function s(a){return"function"==typeof a.remap}function t(a){if(!a||"object"!=typeof a)return!1;let b=a.message?.toLowerCase()||"";return b.includes("issue")&&(b.includes("not found")||b.includes("does not exist"))||b.includes("no issue found")||b.includes("could not find issue")||b.includes("could not resolve to an issue")||b.includes("no issue with identifier")||b.includes("invalid issue format")}class u extends Error{constructor(a,b){super(`Session ${a} cannot be restored: ${b}`),this.sessionId=a,this.reason=b,this.name="SessionNotRestorableError"}}class v extends Error{constructor(a,b){super(`Workspace missing at ${a}${b?`: ${b}`:""}`),this.path=a,this.detail=b,this.name="WorkspaceMissingError"}}class w extends Error{constructor(a){super(`Session not found: ${a}`),this.sessionId=a,this.name="SessionNotFoundError"}}class x extends Error{constructor(a){super(a??"No agent-orchestrator.yaml found. Run `athene start` to create one."),this.name="ConfigNotFoundError"}}class y extends Error{constructor(a,b,c){super(b),this.projectId=a,this.reasonKind=c,this.name="ProjectResolveError"}}},26785:()=>{},43780:(a,b,c)=>{"use strict";c.d(b,{U10:()=>d.U1,xU:()=>b3,hae:()=>b4,Oo1:()=>b2,o3u:()=>b1,kw3:()=>d.kw,V1$:()=>d.V1,PES:()=>d.PE,mUH:()=>ab,HkR:()=>d.Hk,Agm:()=>d.Ag,D83:()=>d.D8,CMu:()=>d.CM,CK3:()=>d.CK,HrC:()=>cE,Bmx:()=>eb,nXN:()=>bY,Gfg:()=>dG,C1z:()=>d6,RaB:()=>aY,SkT:()=>dH,Qum:()=>dp,WVn:()=>cl,My0:()=>F,sa4:()=>cH,vQK:()=>ep,ipO:()=>cp,g9C:()=>T,yAg:()=>d7,Vo2:()=>ec,mKg:()=>cK,NoB:()=>U,zFo:()=>ew,RxI:()=>cI,XqS:()=>n,IXO:()=>o,ry1:()=>A,getWindowsPtyHosts:()=>eD,Gfo:()=>ef,b8Q:()=>d.b8,tTz:()=>d.tT,qX9:()=>d.qX,zi:()=>d.zi,VoP:()=>es,uFH:()=>w,g8K:()=>B,Z9L:()=>aP,G_c:()=>ac,rSb:()=>ae,_ZN:()=>ci,TF_:()=>dr,m5Y:()=>ap,DD3:()=>d.DD,DkI:()=>bJ,Ahw:()=>ea,XIc:()=>cV,giR:()=>dI,wxm:()=>ev,plx:()=>S,JyZ:()=>ed,t9S:()=>an,YEV:()=>eB,Vtt:()=>aj,fzr:()=>cW,qhr:()=>cq,J06:()=>c6,kct:()=>cT,vgx:()=>cn,cv0:()=>ex,unregisterWindowsPtyHost:()=>eC,D58:()=>bq,inW:()=>ag});var d=c(15407),e=c(73024),f=c(77598),g=c(76760),h=c(48161),i=c(34446),j=c(20642),k=c(67157);function l(a){if(a.length<=4)return a.toLowerCase();let b=a.match(/[A-Z]/g);if(b&&b.length>1)return b.join("").toLowerCase();if(a.includes("-")||a.includes("_")){let b=a.includes("-")?"-":"_";return a.split(b).map(a=>a[0]).join("").toLowerCase()}return a.slice(0,3).toLowerCase()}let m=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;function n(a){if(!a||"."===a||".."===a||a.length>128||!m.test(a))throw Error(`Unsafe project ID: "${a}"`);return(0,g.join)(s(),"projects",a)}function o(a){return(0,g.join)(n(a),"sessions")}function p(a){return(0,g.join)(n(a),"worktrees")}function q(a){return(0,g.join)(n(a),"code-reviews")}function r(a){return a.startsWith("~/")?(0,g.join)((0,h.homedir)(),a.slice(2)):a}function s(){return r("~/.agent-orchestrator")}var t=c(31421),u=c(57975);let v=(0,u.promisify)(t.execFile);function w(){return"win32"===process.platform}function x(){return w()?"process":"tmux"}let y=null;function z(a){let b=process.env.PATHEXT?.split(";").filter(Boolean)??[".COM",".EXE",".BAT",".CMD"];for(let c of(process.env.PATH??"").split(";").filter(Boolean)){let d=c.endsWith("\\")||c.endsWith("/")?c.slice(0,-1):c;for(let c of[...b,""]){let b=`${d}\\${a}${c}`;if((0,e.existsSync)(b))return b}}return null}function A(){return y||(y=w()?function(){let a=process.env.AO_SHELL;if(a)return{cmd:a,args:function(a){let b=a.replace(/\\/g,"/").split("/").pop().toLowerCase().replace(/\.exe$/,"");return"cmd"===b?a=>["/c",a]:"bash"===b||"sh"===b||"zsh"===b||"dash"===b?a=>["-c",a]:a=>["-Command",a]}(a)};let b=z("pwsh");if(b)return{cmd:b,args:a=>["-Command",a]};let c=process.env.SystemRoot||"C:\\Windows",d=`${c}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;if((0,e.existsSync)(d))return{cmd:d,args:a=>["-Command",a]};let f=z("powershell");return f?{cmd:f,args:a=>["-Command",a]}:{cmd:process.env.ComSpec||"cmd.exe",args:a=>["/c",a]}}():{cmd:"/bin/sh",args:a=>["-c",a]})}async function B(a,b="SIGTERM"){if(!(a<=0))if(w()){let b=["/T","/F","/PID",String(a)];try{await v("taskkill",b,{windowsHide:!0})}catch{}}else try{process.kill(-a,b)}catch{try{process.kill(a,b)}catch{}}}let C=10*!!w();function D(a,b){let c=`${a}.tmp.${process.pid}.${Date.now()}`;(0,e.writeFileSync)(c,b,"utf-8");try{!function(a,b){let c;for(let d=0;d<=C;d++)try{(0,e.renameSync)(a,b);return}catch(b){c=b;let a=b?.code;if("EPERM"!==a&&"EACCES"!==a&&"EBUSY"!==a)throw b;if(d===C)break}throw c}(c,a)}catch(a){try{(0,e.unlinkSync)(c)}catch{}throw a}}function E(a){let b=a.toLowerCase();return"github.com"===b||b.endsWith(".github.com")?"github":"gitlab.com"===b||b.endsWith(".gitlab.com")?"gitlab":"bitbucket.org"===b||b.endsWith(".bitbucket.org")||b.endsWith(".bitbucket.com")?"bitbucket":"unknown"}function F(a){let b=(0,g.join)(a,".git","HEAD");if((0,e.existsSync)(b)){let c=(0,e.readFileSync)(b,"utf-8").trim().match(/^ref: refs\/heads\/(.+)$/);if(c){for(let b of["main","master","next","develop"]){let c=(0,g.join)(a,".git","refs","remotes","origin",b),d=(0,g.join)(a,".git","packed-refs");if((0,e.existsSync)(c)||(0,e.existsSync)(d)&&(0,e.readFileSync)(d,"utf-8").includes(`refs/remotes/origin/${b}`))return b}return c[1]}}return"main"}function G(a,b,c={}){let d=c.timeoutMs??1e4,f=c.staleMs??6e4;(0,e.mkdirSync)((0,g.dirname)(a),{recursive:!0});let h=Date.now()+d,i=null,j=10;for(;null===i;)try{i=(0,e.openSync)(a,"wx")}catch(b){var k;if("EEXIST"!==b.code)throw Error(`Failed to acquire file lock: ${a}`,{cause:b});try{let b=(0,e.statSync)(a);if(Date.now()-b.mtimeMs>f){(0,e.rmSync)(a,{force:!0});continue}}catch{continue}if(Date.now()>h)throw Error(`Timed out waiting for file lock: ${a}`,{cause:b});k=j,Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,k),j=Math.min(2*j,250)}try{return b()}finally{try{(0,e.closeSync)(i)}catch{}try{(0,e.rmSync)(a,{force:!0})}catch{}}}function H(a){return a.replace(/\.git$/i,"")}function I(a){return"/"===a?"":a.replace(/\/+$/,"")}var J=c(98995);let K=(0,J.createRequire)("file:///home/slievr/proj/Athene/packages/core/dist/events-db.js"),L=null,M=!1,N=!1,O=0,P=0,Q=/token|password|secret|authorization|cookie|api[-_]?key/i,R=[[/\bBearer\s+[A-Za-z0-9._~+/=-]{12,}\b/gi,"Bearer [redacted]"],[/\bgh[pousr]_[A-Za-z0-9_]{20,}\b/g,"[redacted]"],[/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,"[redacted]"],[/\bsk-(?:ant-)?(?:proj-|svcacct-)?[A-Za-z0-9_-]{16,}\b/g,"[redacted]"],[/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g,"[redacted]"],[/\bAKIA[0-9A-Z]{16}\b/g,"[redacted]"],[/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,"[redacted]"],[/\b([A-Z][A-Z0-9_]*(?:TOKEN|PASSWORD|SECRET|AUTHORIZATION|COOKIE|API_KEY|APIKEY)[A-Z0-9_]*)=([^\s"'`]{6,})/g,"$1=[redacted]"]];function S(a){try{var b,c;let d=function(){if(M)return null;if(L)return L;try{return L=function(){let a=K("better-sqlite3");(0,e.mkdirSync)(s(),{recursive:!0});let b=new a((0,g.join)(s(),"activity-events.db"));b.pragma("journal_mode = WAL"),b.pragma("busy_timeout = 3000"),b.pragma("synchronous = NORMAL");let c=b.pragma("user_version",{simple:!0});b.exec(`
2
+ CREATE TABLE IF NOT EXISTS activity_events (
3
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
4
+ ts_epoch INTEGER NOT NULL,
5
+ ts TEXT NOT NULL,
6
+ project_id TEXT,
7
+ session_id TEXT,
8
+ source TEXT NOT NULL,
9
+ type TEXT NOT NULL,
10
+ log_level TEXT NOT NULL DEFAULT 'info',
11
+ summary TEXT NOT NULL,
12
+ data TEXT
13
+ );
14
+
15
+ CREATE INDEX IF NOT EXISTS idx_ae_ts ON activity_events(ts_epoch);
16
+ CREATE INDEX IF NOT EXISTS idx_ae_session ON activity_events(session_id);
17
+ CREATE INDEX IF NOT EXISTS idx_ae_project ON activity_events(project_id);
18
+ CREATE INDEX IF NOT EXISTS idx_ae_type ON activity_events(type);
19
+ CREATE INDEX IF NOT EXISTS idx_ae_source ON activity_events(source);
20
+ `),c<1&&b.pragma("user_version = 1");try{b.exec(`
21
+ CREATE VIRTUAL TABLE IF NOT EXISTS activity_events_fts USING fts5(
22
+ summary, data,
23
+ content='activity_events',
24
+ content_rowid='id'
25
+ );
26
+
27
+ CREATE TRIGGER IF NOT EXISTS activity_events_ai
28
+ AFTER INSERT ON activity_events
29
+ BEGIN
30
+ INSERT INTO activity_events_fts(rowid, summary, data)
31
+ VALUES (new.id, new.summary, new.data);
32
+ END;
33
+
34
+ CREATE TRIGGER IF NOT EXISTS activity_events_ad
35
+ AFTER DELETE ON activity_events
36
+ BEGIN
37
+ INSERT INTO activity_events_fts(activity_events_fts, rowid, summary, data)
38
+ VALUES ('delete', old.id, old.summary, old.data);
39
+ END;
40
+
41
+ CREATE TRIGGER IF NOT EXISTS activity_events_au
42
+ AFTER UPDATE ON activity_events
43
+ BEGIN
44
+ INSERT INTO activity_events_fts(activity_events_fts, rowid, summary, data)
45
+ VALUES ('delete', old.id, old.summary, old.data);
46
+ INSERT INTO activity_events_fts(rowid, summary, data)
47
+ VALUES (new.id, new.summary, new.data);
48
+ END;
49
+ `),b.exec("INSERT INTO activity_events_fts(activity_events_fts) VALUES('rebuild')")}catch(a){console.warn("[ao] activity-events FTS unavailable — writes will continue and search will use a bounded LIKE fallback:",a instanceof Error?a.message:String(a))}let d=Date.now()-6048e5;return b.prepare(`DELETE FROM activity_events
50
+ WHERE rowid IN (
51
+ SELECT rowid FROM activity_events WHERE ts_epoch < ? LIMIT ?
52
+ )`).run(d,1e3),b}()}catch(b){var a;return M=!0,a=b,!N&&("1"===process.env.AO_DEBUG||function(a=process.argv){return a.slice(2).includes("events")}())&&(N=!0,console.warn(function(a){return function(a){let b=a instanceof Error?a.message:String(a);return b.includes("Could not locate the bindings file")||b.includes("better_sqlite3.node")||b.includes("Cannot find module 'better-sqlite3'")}(a)?`[ao] activity-events disabled: better-sqlite3 not compiled for Node ${process.version} (ABI v${process.versions.modules}). Run \`pnpm rebuild better-sqlite3\` or use a supported Node version.`:`[ao] activity-events disabled: better-sqlite3 failed to load: ${(a instanceof Error?a.message:String(a)).split(/\r?\n/,1)[0]??"unknown error"}`}(a))),null}}();if(!d)return void O++;let f=Date.now(),h=new Date(f).toISOString(),i=(b=a.summary).length<=500?b:`${b.slice(0,497)}...`,j=a.data?function(a){let b,c=function a(b,c){if("bigint"==typeof b)return b.toString();if("string"==typeof b){let a=function(a){let b=a,c=0;for(;c<b.length;){let a=b.indexOf("://",c);if(-1===a)break;if(a<4){c=a+3;continue}let d=b.slice(Math.max(0,a-5),a).toLowerCase();if(!d.endsWith("http")&&!d.endsWith("https")){c=a+3;continue}let e=a+3;for(;e<b.length;){let d=b.charCodeAt(e);if(d<=32||47===d)break;if(64===d){b=b.slice(0,a+3).toLowerCase()+"[redacted]"+b.slice(e),c=a+3+10+1;break}e++}(e>=b.length||32>=b.charCodeAt(e)||47===b.charCodeAt(e))&&(c=a+3)}return b}(b);for(let[b,c]of R)a=a.replace(b,c);return a.length>500&&(a=`${a.slice(0,497)}...`),a}if(null===b||"object"!=typeof b)return b;if(c.has(b))return"[circular]";if(c.add(b),Array.isArray(b))return b.map(b=>a(b,c));let d={};for(let[e,f]of Object.entries(b))d[e]=Q.test(e)?"[redacted]":a(f,c);return d}(a,new WeakSet);try{b=JSON.stringify(c)}catch{return}if(!(b.length>16384))return b}(a.data):void 0;d.prepare(`INSERT INTO activity_events
53
+ (ts_epoch, ts, project_id, session_id, source, type, log_level, summary, data)
54
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(f,h,a.projectId??null,a.sessionId??null,a.source,a.kind,a.level??"info",i,j??null),f-P>=36e5&&(P=f,c=f-6048e5,d?.prepare(`DELETE FROM activity_events
55
+ WHERE rowid IN (
56
+ SELECT rowid FROM activity_events WHERE ts_epoch < ? LIMIT ?
57
+ )`).run(c,1e3))}catch{O++}}function T(a,b){let c=(0,g.resolve)(a),d=(0,g.basename)(c).toLowerCase().replace(/[^a-z0-9_-]/g,"-").replace(/^[^a-z0-9]/,"x").replace(/-+/g,"-").slice(0,30),e=`${c}:${b??""}`,h=(0,f.createHash)("sha256").update(e).digest("hex").slice(0,10);return`${d}_${h}`}function U(){if(process.env.AO_GLOBAL_CONFIG)return(0,g.resolve)(process.env.AO_GLOBAL_CONFIG);let a=process.env.XDG_CONFIG_HOME;return a?(0,g.join)(a,"agent-orchestrator","config.yaml"):(0,g.join)((0,h.homedir)(),".agent-orchestrator","config.yaml")}let V=k.Ik({owner:k.Yj(),name:k.Yj(),platform:k.k5(["github","gitlab","bitbucket"]),originUrl:k.Yj()}),W=new Set(["projectId","path","repo","defaultBranch","source","registeredAt","displayName","sessionPrefix","storageKey"]),X=["agent-orchestrator.yaml","agent-orchestrator.yml"],Y=new Set(["repo","defaultBranch","originUrl","projectId","path","storageKey"]),Z=k.Ik({projectId:k.Yj().optional(),path:k.Yj(),repo:V.optional(),defaultBranch:k.Yj().optional(),source:k.Yj().optional(),registeredAt:k.ai().optional(),displayName:k.Yj().optional(),sessionPrefix:k.Yj().optional(),storageKey:k.Yj().optional()}),$=k.k5(["stable","nightly","manual"]),_=k.k5(["git","npm-global","pnpm-global","bun-global","homebrew","unknown"]),aa=k.Ik({port:k.ai().default(3e3),terminalPort:k.ai().optional(),directTerminalPort:k.ai().optional(),readyThresholdMs:k.ai().nonnegative().default(3e5),updateChannel:$.optional().catch(void 0),installMethod:_.optional().catch(void 0),observability:k.Ik({logLevel:k.k5(["debug","info","warn","error"]).default("warn"),stderr:k.zM().default(!1)}).optional(),defaults:k.Ik({runtime:k.Yj().default(()=>x()),agent:k.Yj().default("claude-code"),workspace:k.Yj().default("worktree"),notifiers:k.YO(k.Yj()).default(["composio","desktop"]),orchestrator:k.Ik({agent:k.Yj().optional()}).optional(),worker:k.Ik({agent:k.Yj().optional()}).optional()}).default({}),projects:k.g1(Z).default({}),projectOrder:k.YO(k.Yj()).optional(),notifiers:k.g1(k.Ik({plugin:k.Yj()}).passthrough()).default({}),notificationRouting:k.g1(k.YO(k.Yj())).default({urgent:["desktop","composio"],action:["desktop","composio"],warning:["composio"],info:["composio"]}),reactions:k.g1(k.Ik({}).passthrough()).default({})}).passthrough(),ab=k.Ik({repo:k.Yj().optional(),defaultBranch:k.Yj().optional(),runtime:k.Yj().optional(),agent:k.Yj().optional(),workspace:k.Yj().optional(),tracker:k.Ik({plugin:k.Yj()}).passthrough().optional(),scm:k.Ik({plugin:k.Yj(),webhook:k.Ik({enabled:k.zM().optional(),path:k.Yj().optional(),secretEnvVar:k.Yj().optional(),signatureHeader:k.Yj().optional(),eventHeader:k.Yj().optional(),deliveryHeader:k.Yj().optional(),maxBodyBytes:k.ai().optional()}).optional()}).passthrough().optional(),symlinks:k.YO(k.Yj()).optional(),postCreate:k.YO(k.Yj()).optional(),agentConfig:k.Ik({permissions:k.k5(["permissionless","default","auto-edit","suggest","skip"]).optional(),model:k.Yj().optional(),orchestratorModel:k.Yj().optional()}).passthrough().optional(),orchestrator:k.Ik({agent:k.Yj().optional(),agentConfig:k.Ik({}).passthrough().optional()}).optional(),worker:k.Ik({agent:k.Yj().optional(),agentConfig:k.Ik({}).passthrough().optional()}).optional(),reactions:k.g1(k.Ik({}).passthrough()).optional(),agentRules:k.Yj().optional(),agentRulesFile:k.Yj().optional(),orchestratorRules:k.Yj().optional(),orchestratorSessionStrategy:k.k5(["reuse","delete","ignore","delete-new","ignore-new","kill-previous"]).optional(),opencodeIssueSessionStrategy:k.k5(["reuse","delete","ignore"]).optional(),decomposer:k.Ik({}).passthrough().optional()}).passthrough();function ac(a,b={}){let c=a??U();if(!(0,e.existsSync)(c))return null;let{parsed:f,migrationSummary:i}=function(a,b){let c=as(a);if(!c)return{parsed:null,migrationSummary:null};if(!ar(c).changed)return{parsed:c,migrationSummary:null};let d=null,e=()=>{let b=as(a);if(!b){c=null;return}let e=ar(b);c=b,e.changed&&(d=function(a){if(0===a.strippedProjects.length)return"[ao] migrated legacy project registry fields in global config";let b=a.strippedProjects.reduce((a,b)=>a+b.strippedFieldCount,0),c=a.strippedProjects.map(a=>`${a.projectId} (${a.strippedFieldCount})`).join(", ");return`[ao] stripped ${b} legacy project registry fields from ${a.strippedProjects.length} project${1===a.strippedProjects.length?"":"s"}: ${c}`}(e),ad(aa.parse(b),a))};if(b.alreadyLocked)e();else G(`${a}.lock`,e);return{parsed:c,migrationSummary:d}}(c,b);if(!f)return null;i&&(console.info(i),S({source:"config",kind:"config.migrated",summary:"global config migrated",data:{migrationSummary:i}}));let j=aa.parse(f);for(let[a,b]of Object.entries(j.projects))b.path=function(a,b){if("~"===b)return(0,h.homedir)();if(b.startsWith("~/")){let c=(0,h.homedir)(),e=(0,g.resolve)(c,b.slice(2));if(!function(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!c.startsWith(`..${g.sep}`)}(c,e))throw new d.c5(a,`Project path "${b}" escapes the home directory and cannot be loaded from the global registry.`);return e}return(0,g.resolve)(b)}(a,b.path);return j}function ad(a,b){let c=b??U(),d=(0,g.dirname)(c);(0,e.mkdirSync)(d,{recursive:!0}),D(c,(0,i.As)(a,{indent:2}))}function ae(a){for(let b of X.map(b=>(0,g.join)(a,b))){let a;if((0,e.existsSync)(b)){try{let c=(0,e.readFileSync)(b,"utf-8");a=(0,i.qg)(c)}catch(a){return{kind:"malformed",path:b,error:`Failed to parse local config at ${b}: ${a instanceof Error?a.message:String(a)}`}}if(!a||"object"!=typeof a)return{kind:"invalid",path:b,error:`Local config at ${b} must parse to an object`};if("projects"in a)return{kind:"old-format",path:b,error:`Local config at ${b} still uses a wrapped projects: format`};try{return{kind:"loaded",path:b,config:ab.parse(a)}}catch(a){return{kind:"invalid",path:b,error:`Local config at ${b} failed validation: ${a instanceof Error?a.message:String(a)}`}}}}return{kind:"missing"}}function af(a){let b={...a};for(let a of Y)Reflect.deleteProperty(b,a);return b}function ag(a,b,c=function(a){for(let b of X){let c=(0,g.join)(a,b);if((0,e.existsSync)(c))return c}return(0,g.join)(a,X[0])}(a)){(0,e.mkdirSync)((0,g.dirname)(c),{recursive:!0});let d=ab.parse(af(b));return D(c,(0,i.As)(d,{indent:2})),c}function ah(a){return null!=a&&"object"==typeof a&&!Array.isArray(a)}function ai(a,b,c){let d=ah(a[c])?a[c]:void 0,e=ah(b[c])?b[c]:void 0,f={...d??{},...e??{}};return Object.keys(f).length>0?f:void 0}function aj(a,b){let c=ae(b);if("old-format"!==c.kind||!c.path)throw Error(`No wrapped local config found for project "${a}" at ${b}`);let d=c.path,f=(0,e.readFileSync)(d,"utf-8"),g=(0,i.qg)(f);if(!g||"object"!=typeof g||!ao(g))throw Error(`Local config at ${d} is not a wrapped old-format config.`);let h=g.projects??{},j=h[a];if(!j||"object"!=typeof j){let a=Object.values(h).filter(a=>null!=a&&"object"==typeof a);j=1===a.length?a[0]:void 0}if(!j||"object"!=typeof j)throw Error(`Wrapped local config at ${d} does not contain project "${a}".`);ag(b,function(a,b){let c=ah(a.defaults)?a.defaults:{},d={};for(let a of["runtime","agent","workspace"])null!==c[a]&&void 0!==c[a]&&(d[a]=c[a]);let{name:e,path:f,sessionPrefix:g,projectId:h,source:i,registeredAt:j,displayName:k,orchestrator:l,worker:m,...n}=b,o={...d,...n},p=ai(c,b,"orchestrator"),q=ai(c,b,"worker");return p&&(o.orchestrator=p),q&&(o.worker=q),o}(g,j),d)}function ak(a){if(!a)return;let b=function(a){let b,c=a.trim(),d=c.match(/^git@([^:]+):(.+)$/);if(d){let a=d[1].toLowerCase(),b=H(I(d[2]));return`https://${a}/${b}`}let e=c.replace(/^[A-Za-z][A-Za-z0-9+.-]*:\/\//,a=>a.toLowerCase());try{b=new URL(e)}catch{throw Error(`Invalid origin URL: ${a}`)}let f=b.hostname.toLowerCase(),g=H(I(b.pathname));return`https://${f}${g}`}(a);if(b.startsWith("https://"))try{let a=new URL(b),c=a.pathname.split("/").filter(Boolean);if(c.length<2)return;let d=c[c.length-1],e=c.slice(0,-1).join("/"),f=E(a.host);if("unknown"===f)return;return{owner:e,name:d,platform:f,originUrl:b}}catch{return}}function al(a){if("string"!=typeof a)return;let b=a.trim();if(!b)return;if(b.startsWith("http://")||b.startsWith("https://")||b.startsWith("git@"))return ak(b);let c=b.split("/").filter(Boolean);if(2===c.length)return ak(`https://github.com/${c[0]}/${c[1]}`);if(c.length>=3&&c[0].includes(".")){let a=c[0];if("unknown"===E(a))return;let b=c.slice(1,-1).join("/"),d=c[c.length-1];return ak(`https://${a}/${b}/${d}`)}}function am(a,b,c){for(let[d,e]of Object.entries(a.projects))if(d!==c&&(e.sessionPrefix??l((0,g.basename)(e.path??d)))===b)return d;return null}function an(a,b,c,d,f,h){let i="string"==typeof f?f:h??U(),j=(0,g.resolve)(c),k=(0,e.realpathSync)((0,g.resolve)(c)),m=function(a){let b=function(a){let b=(0,g.join)(a,".git");if(!(0,e.existsSync)(b))return null;if((0,e.statSync)(b).isDirectory()){let a=(0,g.join)(b,"config");return(0,e.existsSync)(a)?a:null}let c=(0,e.readFileSync)(b,"utf-8").trim().match(/^gitdir:\s*(.+)$/i);if(!c)return null;let d=(0,g.resolve)(a,c[1]),f=(0,g.join)(d,"config");if((0,e.existsSync)(f))return f;let h=(0,g.join)(d,"commondir");if(!(0,e.existsSync)(h))return null;let i=(0,g.resolve)(d,(0,e.readFileSync)(h,"utf-8").trim()),j=(0,g.join)(i,"config");return(0,e.existsSync)(j)?j:null}(function(a){let b=(0,g.resolve)(a);for(;;){if((0,e.existsSync)((0,g.join)(b,".git")))return b;let c=(0,g.dirname)(b);if(c===b)return(0,g.resolve)(a);b=c}}(a));if(!b)return null;let c=(0,e.readFileSync)(b,"utf-8").split(/\r?\n/),d=!1;for(let a of c){let b=a.match(/^\s*\[(.+)\]\s*$/);if(b){d='remote "origin"'===b[1];continue}if(!d)continue;let c=a.match(/^\s*url\s*=\s*(.+)\s*$/);if(c?.[1])return c[1].trim()}return null}(k);return G(`${i}.lock`,()=>{let c=ac(i,{alreadyLocked:!0})??aq(),e=a,f=c.projects[a];if(!f){let a=T(k,m),b=c.projects[a];if(b?.path&&(0,g.resolve)(b.path)===k)e=a,f=b;else if(b)throw Error(`Project ID collision: "${a}" already registered at a different path (${b.path}). This is extremely unlikely — please file a bug.`);else e=a}if(f?.path&&(0,g.resolve)(f.path)!==k)throw Error(`Project id "${e}" is already registered for "${f.path}". Choose a different configProjectKey to add "${k}" as a separate project.`);for(let[a,b]of Object.entries(c.projects))if(a!==e&&(0,g.resolve)(b.path)===k)throw Error(`Project "${a}" is already registered at "${k}". Choose a different project ID or path.`);let h=f?.repo??ak(m)??(d?.repo?al(d.repo):void 0),n=f?.defaultBranch??d?.defaultBranch??"main",o=f?.sessionPrefix??d?.sessionPrefix??l((0,g.basename)(j)),p=f?.source??(h?"ao-project-add":"local"),q=f?.registeredAt??Math.floor(Date.now()/1e3),r=!f?.sessionPrefix&&!!d?.sessionPrefix,s=am(c,o,e);if(s&&r)throw Error(`Duplicate session prefix detected: "${o}"
58
+ Projects "${s}" and "${e}" would generate the same prefix.
59
+
60
+ Choose a different configProjectKey or add an explicit sessionPrefix before registering the project.`);let t=s?function(a,b,c){if(!am(b,a,c))return a;for(let d=1;d<1e4;d+=1){let e=`${a}-${d}`;if(!am(b,e,c))return e}throw Error(`Could not allocate a session prefix for "${a}" after 9999 attempts.`)}(o,c,e):o;return c.projects[e]={projectId:e,path:k,...h?{repo:h}:{},defaultBranch:n,source:p,registeredAt:q,displayName:b,sessionPrefix:t},ad(c,i),e})}function ao(a){return!!a&&"object"==typeof a&&"projects"in a&&"object"==typeof a.projects&&Object.values(a.projects).some(a=>null!=a&&"object"==typeof a&&"path"in a)}function ap(a,b){let c=b??U(),d=(0,e.readFileSync)(a,"utf-8"),f=(0,i.qg)(d);if(!ao(f))throw Error(`File at ${a} is not an old-format config.`);let j=f.projects??{},k=aq();for(let[a,b]of("number"==typeof f.port&&(k.port=f.port),null!==f.terminalPort&&void 0!==f.terminalPort&&(k.terminalPort=f.terminalPort),null!==f.directTerminalPort&&void 0!==f.directTerminalPort&&(k.directTerminalPort=f.directTerminalPort),null!==f.readyThresholdMs&&void 0!==f.readyThresholdMs&&(k.readyThresholdMs=f.readyThresholdMs),null!==f.observability&&void 0!==f.observability&&(k.observability=f.observability),null!==f.defaults&&void 0!==f.defaults&&(k.defaults=f.defaults),null!==f.notifiers&&void 0!==f.notifiers&&(k.notifiers=f.notifiers),null!==f.notificationRouting&&void 0!==f.notificationRouting&&(k.notificationRouting=f.notificationRouting),null!==f.reactions&&void 0!==f.reactions&&(k.reactions=f.reactions),Object.entries(j))){if(!b.path)continue;let c="string"==typeof b.path&&b.path.startsWith("~/")?(0,g.join)((0,h.homedir)(),b.path.slice(2)):b.path,d="string"==typeof b.originUrl?ak(b.originUrl):void 0;k.projects[a]={projectId:a,path:c,...d?{repo:d}:{},..."string"==typeof b.defaultBranch?{defaultBranch:b.defaultBranch}:{},source:"migrated",registeredAt:Math.floor(Date.now()/1e3),displayName:b.name??a,..."string"==typeof b.sessionPrefix?{sessionPrefix:b.sessionPrefix}:{}}}for(let[b,d]of(ad(k,c),Object.entries(j))){if(!d.path)continue;let b="string"==typeof d.path&&d.path.startsWith("~/")?(0,g.join)((0,h.homedir)(),d.path.slice(2)):d.path,{name:c,path:e,sessionPrefix:f,...j}=d;D((0,g.join)(b,(0,g.basename)(a)),(0,i.As)(j,{indent:2}))}return c}function aq(){return{port:3e3,readyThresholdMs:3e5,observability:{logLevel:"warn",stderr:!1},defaults:{runtime:x(),agent:"claude-code",workspace:"worktree",notifiers:["composio","desktop"]},projects:{},notifiers:{},notificationRouting:{urgent:["desktop","composio"],action:["desktop","composio"],warning:["composio"],info:["composio"]},reactions:{}}}function ar(a){let b=a.projects;if(!b||"object"!=typeof b)return{changed:!1,strippedProjects:[]};let c=!1,d=[];for(let[a,e]of Object.entries(b)){if(!e||"object"!=typeof e)continue;let b=e.projectId!==a||"string"==typeof e.name&&"string"!=typeof e.displayName||"string"==typeof e.repo||"string"==typeof e.originUrl&&void 0===e.repo,f=function(a,b){let c=0;if(b.projectId=a,"string"==typeof b.name&&"string"!=typeof b.displayName&&(b.displayName=b.name),"string"==typeof b.originUrl&&void 0===b.repo){let a=ak(b.originUrl);a&&(b.repo=a)}if("string"==typeof b.repo){let a=al(b.repo);a?b.repo=a:delete b.repo}for(let a of(delete b.name,delete b.originUrl,Object.keys(b)))W.has(a)||(Reflect.deleteProperty(b,a),c+=1);return{strippedFieldCount:c}}(a,e);f.strippedFieldCount>0&&d.push({projectId:a,strippedFieldCount:f.strippedFieldCount}),(f.strippedFieldCount>0||b)&&(c=!0)}return{changed:c,strippedProjects:d}}function as(a){let b=(0,e.readFileSync)(a,"utf-8"),c=(0,i.qg)(b);return c&&"object"==typeof c?c:null}function at(a,b,c){let e=function(a,b,c){let e=b.projects[a];if(!e||!e.path)return null;let f=e.path,h=e.displayName??a,i="string"==typeof e.sessionPrefix&&e.sessionPrefix.length>0?e.sessionPrefix:l((0,g.basename)(f)),j="string"==typeof e.defaultBranch&&e.defaultBranch.length>0?e.defaultBranch:"main",k=e.repo&&"string"==typeof e.repo.owner&&"string"==typeof e.repo.name?`${e.repo.owner}/${e.repo.name}`:void 0,m={name:h,path:f,...k?{repo:k}:{},sessionPrefix:i,defaultBranch:j},n=c=>{let e={...c},f=b.defaults??{};void 0===e.runtime&&(e.runtime=f.runtime),void 0===e.agent&&(e.agent=f.agent),void 0===e.workspace&&(e.workspace=f.workspace);let g={...f.orchestrator??{},...e.orchestrator??{}};Object.keys(g).length>0&&(e.orchestrator=g);let h={...f.worker??{},...e.worker??{}};Object.keys(h).length>0&&(e.worker=h);let i=["runtime","agent","workspace"].filter(a=>{let b=e[a];return"string"!=typeof b||0===b.length});if(i.length>0)throw new d.c5(a,`Project "${a}" is missing required behavior fields with no defaults: ${i.join(", ")}`);return e},o=ae(f);if("loaded"===o.kind&&o.config)return{...n(af(o.config)),...m};"malformed"===o.kind?S({projectId:a,source:"config",kind:"config.project_malformed",level:"error",summary:`local config for ${a} could not be parsed`,data:{path:o.path,error:o.error}}):"invalid"===o.kind&&S({projectId:a,source:"config",kind:"config.project_invalid",level:"error",summary:`local config for ${a} failed validation`,data:{path:o.path,error:o.error}});let p="missing"!==o.kind?o.error??"Failed to load local config":void 0,q="malformed"===o.kind||"invalid"===o.kind||"old-format"===o.kind?o.kind:void 0;return{...p?{}:n({}),...m,...p?{resolveError:p}:{},...q?{resolveErrorKind:q}:{}}}(a,b);if(!e)throw new d.c5(a,`Unknown project: ${a}`);if("string"==typeof e.resolveError&&e.resolveError.length>0)throw new d.c5(a,e.resolveError,e.resolveErrorKind);return e}function au(a,b,c){a.plugin||a.package||a.path||b.addIssue({code:j.eq.custom,message:`${c} config requires either 'plugin' (for built-ins) or 'package'/'path' (for external plugins)`}),a.package&&a.path&&b.addIssue({code:j.eq.custom,message:`${c} config cannot have both 'package' and 'path' - use one or the other`})}let av=k.Ik({auto:k.zM().default(!0),action:k.k5(["send-to-agent","notify","auto-merge"]).default("notify"),message:k.Yj().optional(),priority:k.k5(["urgent","action","warning","info"]).optional(),retries:k.ai().optional(),escalateAfter:k.KC([k.ai(),k.Yj()]).optional(),threshold:k.Yj().optional(),includeSummary:k.zM().optional()}),aw=k.Ik({plugin:k.Yj().optional(),package:k.Yj().optional(),path:k.Yj().optional()}).passthrough().superRefine((a,b)=>au(a,b,"Tracker")),ax=k.Ik({plugin:k.Yj().optional(),package:k.Yj().optional(),path:k.Yj().optional(),webhook:k.Ik({enabled:k.zM().default(!0),path:k.Yj().optional(),secretEnvVar:k.Yj().optional(),signatureHeader:k.Yj().optional(),eventHeader:k.Yj().optional(),deliveryHeader:k.Yj().optional(),maxBodyBytes:k.ai().int().positive().optional()}).optional()}).passthrough().superRefine((a,b)=>au(a,b,"SCM")),ay=k.Ik({plugin:k.Yj().optional(),package:k.Yj().optional(),path:k.Yj().optional()}).passthrough().superRefine((a,b)=>au(a,b,"Notifier")),az=k.Ik({logLevel:k.k5(["debug","info","warn","error"]).default("warn"),stderr:k.zM().default(!1)}).default({}),aA=k.k5(["permissionless","default","auto-edit","suggest","skip"]).default("permissionless").transform(a=>"skip"===a?"permissionless":a),aB=k.Ik({permissions:aA,model:k.Yj().optional(),orchestratorModel:k.Yj().optional(),opencodeSessionId:k.Yj().optional()}).passthrough(),aC=k.Ik({permissions:k.KC([k.k5(["permissionless","default","auto-edit","suggest"]),k.eu("skip")]).optional(),model:k.Yj().optional(),orchestratorModel:k.Yj().optional(),opencodeSessionId:k.Yj().optional()}).passthrough(),aD=k.Ik({agent:k.Yj().optional()}).optional(),aE=k.Ik({agent:k.Yj().optional(),agentConfig:aC.optional()}).optional(),aF=k.Ik({name:k.Yj().optional(),repo:k.Yj().optional(),path:k.Yj(),defaultBranch:k.Yj().default("main"),sessionPrefix:k.Yj().regex(/^[a-zA-Z0-9_-]+$/,"sessionPrefix must match [a-zA-Z0-9_-]+").optional(),resolveError:k.Yj().optional(),runtime:k.Yj().optional(),agent:k.Yj().optional(),workspace:k.Yj().optional(),env:k.g1(k.Yj(),k.Yj()).optional(),tracker:aw.optional(),scm:ax.optional(),symlinks:k.YO(k.Yj()).optional(),postCreate:k.YO(k.Yj()).optional(),agentConfig:aB.default({}),orchestrator:aE,worker:aE,reactions:k.g1(av.partial()).optional(),agentRules:k.Yj().optional(),agentRulesFile:k.Yj().optional(),orchestratorRules:k.Yj().optional(),orchestratorSessionStrategy:k.k5(["reuse","delete","ignore","delete-new","ignore-new","kill-previous"]).optional(),opencodeIssueSessionStrategy:k.k5(["reuse","delete","ignore"]).optional()}),aG=k.Ik({runtime:k.Yj().default(()=>x()),agent:k.Yj().default("claude-code"),workspace:k.Yj().default("worktree"),notifiers:k.YO(k.Yj()).default([]),orchestrator:aD,worker:aD}),aH=k.Ik({name:k.Yj(),source:k.k5(["registry","npm","local"]),package:k.Yj().optional(),version:k.Yj().optional(),path:k.Yj().optional(),enabled:k.zM().default(!0)}).superRefine((a,b)=>{"local"!==a.source||a.path||b.addIssue({code:j.eq.custom,path:["path"],message:"Local plugins require a path"}),"registry"!==a.source&&"npm"!==a.source||a.package||b.addIssue({code:j.eq.custom,path:["package"],message:"Registry and npm plugins require a package name"})}),aI=k.Ik({preventIdleSleep:k.zM().default("darwin"===process.platform)}).default({}),aJ=k.Ik({attentionZones:k.k5(["simple","detailed"]).default("simple")}),aK=k.Ik({autoCleanupOnMerge:k.zM().default(!0),mergeCleanupIdleGraceMs:k.ai().int().nonnegative().refine(a=>0===a||a>=1e4,{message:"mergeCleanupIdleGraceMs is in milliseconds; values between 1 and 9999 are likely a units mistake (use 0 to disable the gate, or e.g. 10000 for 10s, 300000 for 5min)"}).default(3e5)}).default({}),aL=k.Ik({$schema:k.Yj().optional(),port:k.ai().int().default(3e3),terminalPort:k.ai().int().optional(),directTerminalPort:k.ai().int().optional(),readyThresholdMs:k.ai().int().nonnegative().default(3e5),power:aI,lifecycle:aK,observability:az,defaults:aG.default({}),plugins:k.YO(aH).default([]),dashboard:aJ.optional(),projects:k.g1(k.Yj().regex(/^[a-zA-Z0-9_-]+$/,"Project ID must match [a-zA-Z0-9_-]+ (no dots, slashes, or special characters)"),aF),notifiers:k.g1(ay).default({}),notificationRouting:k.g1(k.YO(k.Yj())).default({}),reactions:k.g1(av).default({})});function aM(a){return a.startsWith("~/")?(0,g.join)((0,h.homedir)(),a.slice(2)):a}function aN(a,b){if(a){let b=a.split("/"),c=b[b.length-1]??a,d=c.match(/^(?:ao-)?plugin-(?:runtime|agent|workspace|tracker|scm|notifier|terminal)-(.+)$/);return d?.[1]?d[1]:c}if(b){let a=b.split("/").filter(a=>a&&"."!==a&&".."!==a);return a[a.length-1]??b}return"unknown"}function aO(a,b,c,d){if(!a.package&&!a.path)return null;a.path&&(a.path=aM(a.path));let e=a.plugin;return a.plugin||(a.plugin=aN(a.package,a.path)),{source:b,location:c,slot:d,package:a.package,path:a.path,expectedPluginName:e}}function aP(a){let b=a??function(a){if(process.env.AO_CONFIG_PATH){let a=(0,g.resolve)(process.env.AO_CONFIG_PATH);if((0,e.existsSync)(a))return a}let b=a=>{for(let b of["agent-orchestrator.yaml","agent-orchestrator.yml"]){let c=(0,g.resolve)(a,b);if((0,e.existsSync)(c))return c}let c=(0,g.resolve)(a,"..");return c===a?null:b(c)},c=b(process.cwd());if(c)return c;let d=U();if((0,e.existsSync)(d))return d;for(let a of[(0,g.resolve)((0,h.homedir)(),".agent-orchestrator.yaml"),(0,g.resolve)((0,h.homedir)(),".agent-orchestrator.yml"),(0,g.resolve)((0,h.homedir)(),".config","agent-orchestrator","config.yaml")])if((0,e.existsSync)(a))return a;return null}();if(!b)throw new d.kw;let c=(0,e.readFileSync)(b,"utf-8"),j=(0,i.qg)(c),k=function(a){if(!(0,e.existsSync)(a))return"missing";let b=(0,e.readFileSync)(a,"utf-8"),c=(0,i.qg)(b);return c&&"object"==typeof c&&"projects"in c?"wrapped":"flat-or-nonobject"}(b),l=!!b&&(0,g.resolve)(b)===(0,g.resolve)(U()),m=l||"wrapped"!==k?j:j&&"object"==typeof j&&"projects"in j&&j.projects&&"object"==typeof j.projects?{...j,projects:Object.fromEntries(Object.entries(j.projects).map(([a,c])=>c&&"object"==typeof c?"string"==typeof c.storageKey||"string"!=typeof c.path?[a,c]:[a,{...c,storageKey:function(a,b){let c=(0,e.realpathSync)(a),d=(0,g.dirname)(c),h=(0,f.createHash)("sha256").update(d).digest("hex").slice(0,12);return`${h}-${(0,g.basename)(b)}`}(b,c.path)}]:[a,c]))}:j,n=l?function(a){let b=ac(a);if(!b)return null;let c={},e={};for(let[f,g]of Object.entries(b.projects))try{c[f]=at(f,b,a)}catch(a){if(!(a instanceof d.c5))throw a;if(e[f]={projectId:f,path:g.path,resolveError:a.message},"malformed"===a.reasonKind||"invalid"===a.reasonKind)continue;S({projectId:f,source:"config",kind:"config.project_resolve_failed",level:"error",summary:`project ${f} failed to resolve`,data:{path:g.path,error:a.message}})}return{...aQ({port:b.port,terminalPort:b.terminalPort,directTerminalPort:b.directTerminalPort,readyThresholdMs:b.readyThresholdMs,observability:b.observability,defaults:b.defaults,notifiers:b.notifiers,notificationRouting:b.notificationRouting,reactions:b.reactions,projects:c}),degradedProjects:e}}(b)??aQ(m):"wrapped"===k?aQ(m):function(a,b){let c=ac(U());if(!c)return null;let d=(()=>{try{return(0,e.realpathSync)((0,g.resolve)((0,g.dirname)(a)))}catch{return(0,g.resolve)((0,g.dirname)(a))}})(),f=Object.entries(c.projects).find(([,a])=>{if("string"!=typeof a.path)return!1;try{return(0,e.realpathSync)((0,g.resolve)(a.path))===d}catch{return(0,g.resolve)(a.path)===d}});if(!f)return null;let[h]=f,i=at(h,c);return{...aQ({port:c.port,terminalPort:c.terminalPort,directTerminalPort:c.directTerminalPort,readyThresholdMs:c.readyThresholdMs,observability:c.observability,defaults:c.defaults,notifiers:c.notifiers,notificationRouting:c.notificationRouting,reactions:c.reactions,projects:{[h]:{...i}}}),degradedProjects:{}}}(b)??aQ(m);return n.configPath=b,"degradedProjects"in n||(n.degradedProjects={}),n}function aQ(a){var b;let c=aL.parse(a);(b=c=function(a){for(let[b,c]of Object.entries(a.projects)){c.name||(c.name=b),c.sessionPrefix||(c.sessionPrefix=l((0,g.basename)(c.path)));let a=function(a){if("gitlab"===a.scm?.plugin)return"gitlab";let b=a.scm?.host;if("string"==typeof b&&b.toLowerCase().includes("gitlab")||"gitlab"===a.tracker?.plugin)return"gitlab";let c=a.tracker?.host;return"string"==typeof c&&c.toLowerCase().includes("gitlab")?"gitlab":"github"}(c);!c.scm&&c.repo?.includes("/")&&(c.scm={plugin:a}),!c.tracker&&c.repo?.includes("/")&&(c.tracker={plugin:a})}return a}(c=function(a){for(let b of Object.values(a.projects))b.path=aM(b.path);for(let b of a.plugins??[])b.path&&(b.path=aM(b.path));return a}(c))).reactions={"pr-closed":{auto:!0,action:"notify",priority:"action",message:"A PR was closed without merging. Decide whether to learn from the closure, resume the work, or terminate the session."},"ci-failed":{auto:!0,action:"send-to-agent",retries:2,escalateAfter:2},"changes-requested":{auto:!0,action:"send-to-agent",message:"There are new review comments on your PR requesting changes.",escalateAfter:"30m"},"bugbot-comments":{auto:!0,action:"send-to-agent",message:"Automated review comments found on your PR. Details will follow shortly.",escalateAfter:"30m"},"merge-conflicts":{auto:!0,action:"send-to-agent",message:"Your branch has merge conflicts. Rebase on the default branch and resolve them.",escalateAfter:"15m"},"approved-and-green":{auto:!1,action:"notify",priority:"action",message:"PR is ready to merge"},"agent-idle":{auto:!0,action:"send-to-agent",message:"You appear to be idle. If your task is not complete, continue working — write the code, commit, push, and create a PR. If you are blocked, explain what is blocking you.",retries:2,escalateAfter:"15m"},"agent-stuck":{auto:!0,action:"notify",priority:"urgent",threshold:"10m"},"agent-needs-input":{auto:!0,action:"notify",priority:"urgent"},"agent-exited":{auto:!0,action:"notify",priority:"urgent"},"all-complete":{auto:!0,action:"notify",priority:"info",includeSummary:!0},...b.reactions};let d=function(a){let b=[];for(let[c,d]of Object.entries(a.projects)){if(d.tracker){let a=aO(d.tracker,`projects.${c}.tracker`,{kind:"project",projectId:c,configType:"tracker"},"tracker");a&&b.push(a)}if(d.scm){let a=aO(d.scm,`projects.${c}.scm`,{kind:"project",projectId:c,configType:"scm"},"scm");a&&b.push(a)}}for(let[c,d]of Object.entries(a.notifiers??{}))if(d){let a=aO(d,`notifiers.${c}`,{kind:"notifier",notifierId:c},"notifier");a&&b.push(a)}return b}(c=b);return d.length>0&&(c.plugins=function(a,b){let c=[...a??[]],d=new Set;for(let a of c)a.package&&d.add(`package:${a.package}`),a.path&&d.add(`path:${a.path}`);for(let a of b){let b=a.package?`package:${a.package}`:`path:${a.path}`;if(d.has(b)){let b=c.find(b=>a.package&&b.package===a.package||a.path&&b.path===a.path);b&&!1===b.enabled&&(b.enabled=!0);continue}d.add(b);let e=a.expectedPluginName??aN(a.package,a.path);c.push({name:e,source:a.package?"npm":"local",package:a.package,path:a.path,enabled:!0})}return c}(c.plugins,d),c._externalPluginEntries=d),!function(a){let b=new Set;for(let[c]of Object.entries(a.projects)){if(b.has(c))throw Error(`Duplicate project ID detected: "${c}"
61
+ Each project entry must use a unique registry key.`);b.add(c)}let c=new Set,d={};for(let[b,e]of Object.entries(a.projects)){let f=e.sessionPrefix||l(b);if(c.has(f)){let c=d[f];throw Error(`Duplicate session prefix detected: "${f}"
62
+ Projects "${c}" and "${b}" would generate the same prefix.
63
+
64
+ To fix this, add an explicit sessionPrefix to one of these projects:
65
+
66
+ projects:
67
+ ${c}:
68
+ path: ${a.projects[c]?.path}
69
+ sessionPrefix: ${f}1 # Add explicit prefix
70
+ ${b}:
71
+ path: ${e.path}
72
+ sessionPrefix: ${f}2 # Add explicit prefix
73
+ `)}c.add(f),d[f]=b}}(c),c}var aR=c(73136);let aS=["dist/index.js","index.js"],aT=[{slot:"runtime",name:"tmux",pkg:"@made-by-moonlight/athene-plugin-runtime-tmux"},{slot:"runtime",name:"process",pkg:"@made-by-moonlight/athene-plugin-runtime-process"},{slot:"agent",name:"claude-code",pkg:"@made-by-moonlight/athene-plugin-agent-claude-code"},{slot:"agent",name:"codex",pkg:"@made-by-moonlight/athene-plugin-agent-codex"},{slot:"agent",name:"aider",pkg:"@made-by-moonlight/athene-plugin-agent-aider"},{slot:"agent",name:"cursor",pkg:"@made-by-moonlight/athene-plugin-agent-cursor"},{slot:"agent",name:"kimicode",pkg:"@made-by-moonlight/athene-plugin-agent-kimicode"},{slot:"agent",name:"grok",pkg:"@made-by-moonlight/athene-plugin-agent-grok"},{slot:"agent",name:"opencode",pkg:"@made-by-moonlight/athene-plugin-agent-opencode"},{slot:"workspace",name:"worktree",pkg:"@made-by-moonlight/athene-plugin-workspace-worktree"},{slot:"workspace",name:"clone",pkg:"@made-by-moonlight/athene-plugin-workspace-clone"},{slot:"tracker",name:"github",pkg:"@made-by-moonlight/athene-plugin-tracker-github"},{slot:"tracker",name:"linear",pkg:"@made-by-moonlight/athene-plugin-tracker-linear"},{slot:"tracker",name:"gitlab",pkg:"@made-by-moonlight/athene-plugin-tracker-gitlab"},{slot:"scm",name:"github",pkg:"@made-by-moonlight/athene-plugin-scm-github"},{slot:"scm",name:"gitlab",pkg:"@made-by-moonlight/athene-plugin-scm-gitlab"},{slot:"notifier",name:"composio",pkg:"@made-by-moonlight/athene-plugin-notifier-composio"},{slot:"notifier",name:"dashboard",pkg:"@made-by-moonlight/athene-plugin-notifier-dashboard"},{slot:"notifier",name:"desktop",pkg:"@made-by-moonlight/athene-plugin-notifier-desktop"},{slot:"notifier",name:"discord",pkg:"@made-by-moonlight/athene-plugin-notifier-discord"},{slot:"notifier",name:"openclaw",pkg:"@made-by-moonlight/athene-plugin-notifier-openclaw"},{slot:"notifier",name:"slack",pkg:"@made-by-moonlight/athene-plugin-notifier-slack"},{slot:"notifier",name:"webhook",pkg:"@made-by-moonlight/athene-plugin-notifier-webhook"},{slot:"terminal",name:"iterm2",pkg:"@made-by-moonlight/athene-plugin-terminal-iterm2"},{slot:"terminal",name:"web",pkg:"@made-by-moonlight/athene-plugin-terminal-web"}];function aU(a,b,c){let d=c.plugin;return"string"==typeof d&&d.length>0?d===a:b===a}function aV(a,b){if(!Object.prototype.hasOwnProperty.call(b.notifiers??{},a))return!1;let c=b.notifiers?.[a];return!c||"object"!=typeof c||!aU(a,a,c)}function aW(a){return!!a&&"object"==typeof a&&!!(a.manifest&&"function"==typeof a.create)}function aX(a){if(aW(a))return a;if(a&&"object"==typeof a&&"default"in a){let b=a.default;if(aW(b))return b}return null}function aY(){let a=new Map;function b(b,c,d,e){a.set(`${b}:${c}`,{manifest:d,instance:e})}function c(a,d,e=!1){let{manifest:f}=a,g=function(a,b,c=!1){let d=new Map,e=Object.entries(b.notifiers??{}),f=Array.isArray(b.defaults?.notifiers)?b.defaults.notifiers:[],g=Object.values(b.notificationRouting??{}).flatMap(a=>Array.isArray(a)?a:[]),h=f.includes(a)||g.includes(a),i=b.notifiers?.[a];for(let[b,c]of(i&&"object"==typeof i&&aU(a,a,i)&&d.set(a,i),e))c&&"object"==typeof c&&aU(a,b,c)&&d.set(b,c);return 0===d.size&&h&&!aV(a,b)&&d.set(a,{}),[...d.entries()].map(([d,e])=>({registrationName:d,config:function(a,b,c,d,e,f=!1){if("package"in d&&"path"in d)throw Error(`In ${a} "${c}": both "package" and "path" are specified. Use "package" for npm plugins or "path" for local plugins, not both.`);let g=!f&&aT.some(c=>c.slot===a&&c.name===b);if((d.package||g)&&"path"in d){let e=d.package?`npm package "${d.package}"`:`built-in plugin "${b}"`;throw Error(`In ${a} "${c}": "path" field conflicts with reserved plugin loading field. You're loading via ${e}, but also have a "path" field which would be stripped. Rename your configuration field to something else (e.g., "apiPath", "webhookPath").`)}let{plugin:h,package:i,path:j,...k}=d;return e?{...k,configPath:e}:k}("notifier",a,d,e,b.configPath,c)}))}(f.name,d,e);if(0===g.length){if(aV(f.name,d))return;b(f.slot,f.name,f,a.create(void 0));return}for(let[c,d]of g.entries()){let e=a.create(d.config);b(f.slot,d.registrationName,f,e),0===c&&d.registrationName!==f.name&&b(f.slot,f.name,f,e)}}return{register(a,c){let{manifest:d}=a,e=a.create(c);b(d.slot,d.name,d,e)},get(b,c){let d=a.get(`${b}:${c}`);return d?d.instance:null},list(b){let c=new Map;for(let[d,e]of a)d.startsWith(`${b}:`)&&!c.has(e.manifest.name)&&c.set(e.manifest.name,e.manifest);return[...c.values()]},async loadBuiltins(a,b){let d=b??(a=>import(a));for(let b of aT){let e;try{e=aX(await d(b.pkg))}catch{continue}if(e)try{a&&"notifier"===e.manifest.slot?c(e,a):this.register(e)}catch(c){let a=c instanceof Error?c.message:String(c);process.stderr.write(`[plugin-registry] Failed to load built-in plugin "${b.name}": ${c}
74
+ `),S({source:"plugin-registry",kind:"plugin-registry.load_failed",level:"error",summary:`built-in plugin ${b.name} failed to load`,data:{plugin:b.name,slot:b.slot,pkg:b.pkg,builtin:!0,error:a}})}}},async loadFromConfig(a,b){await this.loadBuiltins(a,b);let d=b??(a=>import(a)),f=function(a){let b=new Map;if(!a)return b;for(let c of a){let a=c.package?`package:${c.package}`:`path:${c.path}`,d=b.get(a);d?d.push(c):b.set(a,[c])}return b}(a._externalPluginEntries);for(let b of a.plugins??[]){if(!1===b.enabled)continue;let i=function(a,b){switch(a.source){case"local":{if(!a.path)return null;let c=function(a){let b;if(!(0,e.existsSync)(a))return null;try{b=(0,e.statSync)(a)}catch{return null}if(b.isFile())return a;if(!b.isDirectory())return null;let c=(0,g.join)(a,"package.json");if((0,e.existsSync)(c))try{let b=(0,e.readFileSync)(c,"utf-8"),d=JSON.parse(b),f=function(a){if("string"==typeof a)return a;if(!a||"object"!=typeof a)return null;let b=a["."];if("string"==typeof b)return b;if(b&&"object"==typeof b){let a=b.import;if("string"==typeof a)return a;let c=b.default;if("string"==typeof c)return c}let c=a.import;if("string"==typeof c)return c;let d=a.default;return"string"==typeof d?d:null}(d.exports);if(f){let b=(0,g.resolve)(a,f);if((0,e.existsSync)(b))return b}if("string"==typeof d.module){let b=(0,g.resolve)(a,d.module);if((0,e.existsSync)(b))return b}if("string"==typeof d.main){let b=(0,g.resolve)(a,d.main);if((0,e.existsSync)(b))return b}}catch{}for(let b of aS){let c=(0,g.join)(a,b);if((0,e.existsSync)(c))return c}return null}(function(a,b){if((0,g.isAbsolute)(a))return a;let c=b?(0,g.dirname)(b):process.cwd();return(0,g.resolve)(c,a)}(a.path,b.configPath));return c?(0,aR.pathToFileURL)(c).href:null}case"registry":case"npm":var c;return a.package??(!(c=a.name)||c.startsWith(".")||c.startsWith("/")?null:c.startsWith("@")||c.includes("/")?c:null);default:return null}}(b,a);if(!i){process.stderr.write(`[plugin-registry] Could not resolve specifier for plugin "${b.name}" (source: ${b.source})
75
+ `),S({source:"plugin-registry",kind:"plugin-registry.specifier_failed",level:"error",summary:`could not resolve specifier for plugin ${b.name}`,data:{plugin:b.name,source:b.source??null}});continue}try{let e=aX(await d(i));if(!e)continue;for(let c of b.package?f.get(`package:${b.package}`)??[]:b.path?f.get(`path:${b.path}`)??[]:[])try{var h=e.manifest;if(c.expectedPluginName&&c.expectedPluginName!==h.name){let a=c.package?"package":"path";throw Error(`Plugin manifest.name mismatch at ${c.source}: expected "${c.expectedPluginName}" but ${a} "${i}" has manifest.name "${h.name}". Either update the 'plugin' field to match the actual manifest.name, or remove it to auto-infer.`)}!function(a,b,c){let{location:d,slot:e,source:f}=b;if("project"===d.kind){let{projectId:b,configType:e}=d,f=c.projects[b];f?.[e]&&(f[e].plugin=a.name)}else if("notifier"===d.kind){let{notifierId:b}=d,e=c.notifiers[b];e&&(e.plugin=a.name)}a.slot!==e&&process.stderr.write(`[plugin-registry] Plugin at ${f} has slot "${a.slot}" but was configured as "${e}". The plugin will be registered under its declared slot "${a.slot}".
76
+ `)}(e.manifest,c,a)}catch(d){let a=d instanceof Error?d.message:String(d);process.stderr.write(`[plugin-registry] Config validation failed for ${c.source}: ${d}
77
+ `),S({source:"plugin-registry",kind:"plugin-registry.validation_failed",level:"error",summary:`plugin manifest validation failed for ${b.name}`,data:{plugin:b.name,externalSource:c.source,specifier:i,manifestName:e.manifest.name,manifestSlot:e.manifest.slot,error:a}})}"notifier"===e.manifest.slot?c(e,a,!0):this.register(e)}catch(c){let a=c instanceof Error?c.message:String(c);process.stderr.write(`[plugin-registry] Failed to load plugin "${i}": ${c}
78
+ `),S({source:"plugin-registry",kind:"plugin-registry.load_failed",level:"error",summary:`external plugin ${b.name} failed to load`,data:{plugin:b.name,specifier:i,source:b.source??null,builtin:!1,error:a}})}}}}}let aZ=/\/(\d+)$/;function a$(a){let b=function(a){try{return new URL(a)}catch{return null}}(a),c=b?.pathname.split("/").filter(Boolean)??[],d=c.findIndex(a=>"pull"===a);if(d>=2&&d+1<c.length){let b=c[d-2],e=c[d-1],f=c[d+1];if(b&&e&&f&&/^\d+$/.test(f))return{owner:b,repo:e,number:Number.parseInt(f,10),url:a}}let e=c.findIndex((a,b)=>"-"===a&&"merge_requests"===c[b+1]&&b>=2&&b+2<c.length);if(e>=2){let b=c[e-2],d=c[e-1],f=c[e+2];if(b&&d&&f&&/^\d+$/.test(f))return{owner:b,repo:d,number:Number.parseInt(f,10),url:a}}let f=a.match(aZ);return f?{owner:"",repo:"",number:parseInt(f[1],10),url:a}:null}function a_(a){let b=new Set,c=[];for(let d of a){let a=function(a){let b=a$(a.url),c=a.owner||b?.owner||"",d=a.repo||b?.repo||"",e=a.number||b?.number||0;return c&&d&&e>0?`${c}/${d}#${e}`:`url:${a.url}`}(d);b.has(a)||(b.add(a),c.push(d))}return c}function a0(a){let b=new Set,c=[];for(let d of a){let a=d.trim();if(!a)continue;let e=a$(a),f=e&&e.owner&&e.repo&&e.number>0?`${e.owner}/${e.repo}#${e.number}`:`url:${a}`;b.has(f)||(b.add(f),c.push(a))}return c}let a1=new Set(["spawning","working","detecting","pr_open","ci_failed","review_pending","changes_requested","approved","mergeable","merged","cleanup","needs_input","stuck","errored","killed","idle","done","terminated"]);function a2(a){try{return JSON.parse(a)}catch{return null}}function a3(a){return"starting"===a?"working":a&&a1.has(a)?a:"spawning"}let a4=k.Yj().nullable(),a5=k.Ik({id:k.Yj(),runtimeName:k.Yj(),data:k.vk(a=>null===a||"object"!=typeof a||Array.isArray(a)?{}:a,k.g1(k.L5()))}),a6=k.Ik({version:k.eu(2),session:k.Ik({kind:k.k5(["worker","orchestrator"]),state:k.k5(["not_started","working","idle","needs_input","stuck","detecting","done","terminated"]),reason:k.k5(["spawn_requested","agent_acknowledged","task_in_progress","pr_created","pr_closed_waiting_decision","fixing_ci","resolving_review_comments","awaiting_user_input","awaiting_external_review","research_complete","merged_waiting_decision","manually_killed","runtime_lost","agent_process_exited","probe_failure","error_in_process","auto_cleanup","pr_merged"]),startedAt:a4,completedAt:a4,terminatedAt:a4,lastTransitionAt:k.Yj()}).partial().optional(),pr:k.Ik({state:k.k5(["none","open","merged","closed"]),reason:k.k5(["not_created","in_progress","ci_failing","review_pending","changes_requested","approved","merge_ready","merged","closed_unmerged","cleared_on_restore"]),number:k.ai().int().nullable(),url:k.Yj().nullable(),lastObservedAt:a4}).partial().optional(),runtime:k.Ik({state:k.k5(["unknown","alive","exited","missing","probe_failed"]),reason:k.k5(["spawn_incomplete","process_running","process_missing","tmux_missing","manual_kill_requested","probe_error","pr_merged_cleanup","auto_cleanup"]),lastObservedAt:a4,handle:a5.nullable(),tmuxName:k.Yj().nullable()}).partial().optional()}),a7=new Set(["done","terminated"]);function a8(a){a7.has(a.session.state)||(a.session.completedAt=null,a.session.terminatedAt=null)}function a9(a,b=null){if("string"!=typeof a)return b;let c=Date.parse(a);return Number.isNaN(c)?b:new Date(c).toISOString()}function ba(a,b=new Date){return{version:2,session:{kind:a,state:"not_started",reason:"spawn_requested",startedAt:null,completedAt:null,terminatedAt:null,lastTransitionAt:b.toISOString()},pr:{state:"none",reason:"not_created",number:null,url:null,lastObservedAt:null},runtime:{state:"unknown",reason:"spawn_incomplete",lastObservedAt:null,handle:null,tmuxName:null}}}function bb(a,b={}){let c=b.status??a3(a.status),d=b.sessionKind??("orchestrator"===a.role||b.sessionId?.endsWith("-orchestrator")?"orchestrator":"worker"),e=b.createdAt?.toISOString()??a9(a.createdAt,new Date().toISOString())??new Date().toISOString(),f=function(a){switch(a){case"spawning":return{state:"not_started",reason:"spawn_requested"};case"needs_input":return{state:"needs_input",reason:"awaiting_user_input"};case"stuck":return{state:"stuck",reason:"probe_failure"};case"errored":return{state:"terminated",reason:"error_in_process"};case"killed":case"terminated":case"cleanup":return{state:"terminated",reason:"manually_killed"};case"done":return{state:"done",reason:"research_complete"};case"merged":return{state:"idle",reason:"merged_waiting_decision"};case"idle":return{state:"idle",reason:"awaiting_external_review"};default:return{state:"working",reason:"task_in_progress"}}}(c),g=function(a,b){let c=a.pr??null;if(!c)return"merged"===b?{state:"merged",reason:"merged",number:null,url:null}:{state:"none",reason:"not_created",number:null,url:null};let d=a$(c);return{state:"merged"===b?"merged":"open",reason:"merged"===b?"merged":"in_progress",number:d?.number??null,url:c}}(a,c),h=function(a,b){let c=a.tmuxName?.trim()||null,d=b??(a.runtimeHandle?a2(a.runtimeHandle):null);return d||c?{state:"unknown",reason:"spawn_incomplete",handle:d??null,tmuxName:c}:{state:"unknown",reason:"spawn_incomplete",handle:null,tmuxName:null}}(a,b.runtimeHandle??null);return{version:2,session:{kind:d,state:f.state,reason:f.reason,startedAt:"spawning"===c?null:e,completedAt:"done"===c?e:null,terminatedAt:"killed"===c||"terminated"===c||"cleanup"===c?e:null,lastTransitionAt:e},pr:{state:g.state,reason:g.reason,number:g.number,url:g.url,lastObservedAt:g.url?e:null},runtime:{state:h.state,reason:h.reason,lastObservedAt:h.handle||h.tmuxName?e:null,handle:h.handle,tmuxName:h.tmuxName}}}function bc(a,b={}){let c=a.lifecycle?a2(a.lifecycle):a.statePayload&&"2"===a.stateVersion?a2(a.statePayload):null,d=a6.safeParse(c);return d.success?function(a,b,c={}){let d=bb(b,c),e=a.session,f=a.pr,g=a.runtime,h=Object.hasOwn(e??{},"kind"),i=Object.hasOwn(e??{},"state"),j=Object.hasOwn(e??{},"reason"),k=Object.hasOwn(e??{},"startedAt"),l=Object.hasOwn(e??{},"completedAt"),m=Object.hasOwn(e??{},"terminatedAt"),n=Object.hasOwn(e??{},"lastTransitionAt"),o=Object.hasOwn(f??{},"state"),p=Object.hasOwn(f??{},"reason"),q=Object.hasOwn(f??{},"number"),r=Object.hasOwn(f??{},"url"),s=Object.hasOwn(f??{},"lastObservedAt"),t=Object.hasOwn(g??{},"state"),u=Object.hasOwn(g??{},"reason"),v=Object.hasOwn(g??{},"lastObservedAt"),w=Object.hasOwn(g??{},"handle"),x=Object.hasOwn(g??{},"tmuxName");return{version:2,session:{kind:h?e?.kind==="orchestrator"?"orchestrator":"worker":d.session.kind,state:i?e?.state??d.session.state:d.session.state,reason:j?e?.reason??d.session.reason:d.session.reason,startedAt:k?a9(e?.startedAt):d.session.startedAt,completedAt:l?a9(e?.completedAt):d.session.completedAt,terminatedAt:m?a9(e?.terminatedAt):d.session.terminatedAt,lastTransitionAt:n?a9(e?.lastTransitionAt,d.session.lastTransitionAt)??d.session.lastTransitionAt:d.session.lastTransitionAt},pr:{state:o?f?.state??d.pr.state:d.pr.state,reason:p?f?.reason??d.pr.reason:d.pr.reason,number:q?"number"==typeof f?.number?f.number:null:d.pr.number,url:r?"string"==typeof f?.url?f.url:null:d.pr.url,lastObservedAt:s?a9(f?.lastObservedAt):d.pr.lastObservedAt},runtime:{state:t?g?.state??d.runtime.state:d.runtime.state,reason:u?g?.reason??d.runtime.reason:d.runtime.reason,lastObservedAt:v?a9(g?.lastObservedAt):d.runtime.lastObservedAt,handle:w?function(a){if(!a||"object"!=typeof a||"string"!=typeof a.id||"string"!=typeof a.runtimeName)return null;let b=a.data;return{id:a.id,runtimeName:a.runtimeName,data:b&&"object"==typeof b?b:{}}}(g?.handle):d.runtime.handle,tmuxName:x?"string"==typeof g?.tmuxName?g.tmuxName:null:d.runtime.tmuxName}}}(d.data,a,b):bb(a,b)}function bd(a){switch(a.session.state){case"not_started":return"spawning";case"needs_input":return"needs_input";case"stuck":return"stuck";case"done":return"done";case"terminated":switch(a.session.reason){case"manually_killed":case"runtime_lost":return"killed";case"auto_cleanup":case"pr_merged":return"cleanup";case"error_in_process":case"probe_failure":return"errored";default:return"terminated"}case"detecting":return"detecting"}return"merged"===a.pr.state?"merged":"open"===a.pr.state?"ci_failing"===a.pr.reason?"ci_failed":"changes_requested"===a.pr.reason?"changes_requested":"review_pending"===a.pr.reason?"review_pending":"approved"===a.pr.reason?"approved":"merge_ready"===a.pr.reason?"mergeable":"pr_open":"idle"===a.session.state?"idle":"working"}function be(a){return{lifecycle:JSON.stringify(a),pr:a.pr.url??"",runtimeHandle:a.runtime.handle?JSON.stringify(a.runtime.handle):"",tmuxName:a.runtime.tmuxName??"",role:"orchestrator"===a.session.kind?"orchestrator":""}}function bf(a){return{version:2,session:{...a.session},pr:{...a.pr},runtime:{...a.runtime,handle:a.runtime.handle?{id:a.runtime.handle.id,runtimeName:a.runtime.handle.runtimeName,data:structuredClone(a.runtime.handle.data)}:null}}}let bg=/^[a-zA-Z0-9_-]+$/;function bh(a,b="session ID"){if(!bg.test(a))throw Error(`Invalid ${b}: ${a}`)}function bi(a){let b={};for(let[c,d]of Object.entries(a))null!=d&&("object"==typeof d?b[c]=JSON.stringify(d):b[c]=String(d));return b}let bj=".json";function bk(a){return JSON.stringify(a,null,2)+"\n"}function bl(a){try{let b=JSON.parse(a);if("object"!=typeof b||null===b||Array.isArray(b))return null;return b}catch{return null}}function bm(a,b){return bh(b),(0,g.join)(a,`${b}${bj}`)}function bn(a,b){let c,d=bm(a,b);try{c=(0,e.readFileSync)(d,"utf-8").trim()}catch{return null}if(!c)return null;let f=bl(c);if(!f)return null;if(f.lifecycle||f.statePayload&&"2"===f.stateVersion){let a=function(a){if(a.lifecycle&&"object"==typeof a.lifecycle)return a.lifecycle;if(a.statePayload&&"2"===a.stateVersion){if("object"==typeof a.statePayload)return a.statePayload;if("string"==typeof a.statePayload)try{return JSON.parse(a.statePayload)}catch{}}}(f);a&&(f.status=bd(a))}return bi(f)}let bo=new Set(["runtimeHandle","lifecycle","statePayload","dashboard","agentReport","reportWatcher"]);function bp(a,b,c){let d=bm(a,b);(0,e.mkdirSync)((0,g.dirname)(d),{recursive:!0});let f={worktree:c.worktree,branch:c.branch,...c.lifecycle?{}:{status:c.status}};c.tmuxName&&(f.tmuxName=c.tmuxName),c.issue&&(f.issue=c.issue),c.issueTitle&&(f.issueTitle=c.issueTitle),c.pr&&(f.pr=c.pr),void 0!==c.prAutoDetect&&(f.prAutoDetect=c.prAutoDetect),c.summary&&(f.summary=c.summary),c.project&&(f.project=c.project),c.agent&&(f.agent=c.agent),c.createdAt&&(f.createdAt=c.createdAt),c.runtimeHandle&&(f.runtimeHandle=c.runtimeHandle),c.lifecycle&&(f.lifecycle=c.lifecycle),c.restoredAt&&(f.restoredAt=c.restoredAt),c.role&&(f.role=c.role),c.dashboard&&(f.dashboard=c.dashboard),c.opencodeSessionId&&(f.opencodeSessionId=c.opencodeSessionId),c.pinnedSummary&&(f.pinnedSummary=c.pinnedSummary),c.userPrompt&&(f.userPrompt=c.userPrompt),c.displayName&&(f.displayName=c.displayName),void 0!==c.displayNameUserSet&&(f.displayNameUserSet=c.displayNameUserSet),D(d,bk(f))}function bq(a,b,c){bs(a,b,a=>br(a,c),{createIfMissing:!0})}function br(a,b){let c={...a};for(let[a,d]of Object.entries(b))if(void 0!==d)if(""===d){let{[a]:b,...d}=c;c=d}else c[a]=d;return c}function bs(a,b,c,d={}){let f=bm(a,b);return G(`${f}.lock`,()=>{let h,i={};try{h=(0,e.readFileSync)(f,"utf-8").trim()}catch{}if(void 0!==h){if(h){let c=bl(h);if(c)i=bi(c);else{let c=`${f}.corrupt-${Date.now()}`,i=!1;try{(0,e.renameSync)(f,c),i=!0,console.warn(`[metadata] corrupt JSON at ${f}; preserved as ${c} before rewriting`)}catch{}let j=h.length>200?h.slice(0,200):h,k=(0,g.basename)((0,g.dirname)(a)),l=i?`Corrupt metadata for session ${b} renamed to ${(0,g.basename)(c)}`:`Corrupt metadata detected for session ${b}; failed to rename forensic copy before rewrite`;S({projectId:k||void 0,sessionId:b,source:d.activityEventSource??"session-manager",kind:"metadata.corrupt_detected",level:"error",summary:l,data:{path:f,renamedTo:i?c:null,renameSucceeded:i,contentSample:j,contentLength:h.length}})}}}else if(!d.createIfMissing)return null;let j=Object.fromEntries(Object.entries(c({...i})).filter(([,a])=>void 0!==a&&""!==a));return(0,e.mkdirSync)((0,g.dirname)(f),{recursive:!0}),D(f,bk(function(a){let b={},c=new Set(["dashboardPort","terminalWsPort","directTerminalWsPort"]),d=new Set(["prAutoDetect","displayNameUserSet"]);for(let[e,f]of Object.entries(a))if(void 0!==f&&""!==f)if(d.has(e))b[e]="on"===f||"true"===f||"off"!==f&&"false"!==f&&f;else if(c.has(e)){let a=Number(f);b[e]=Number.isFinite(a)?a:f}else if(bo.has(e)&&(f.startsWith("{")||f.startsWith("[")))try{b[e]=JSON.parse(f)}catch{b[e]=f}else b[e]=f;return b}(j))),j},{timeoutMs:5e3,staleMs:3e4})}function bt(a,b){let c=bm(a,b);if((0,e.existsSync)(c))try{(0,e.unlinkSync)(c)}catch{}}function bu(a){return(0,e.existsSync)(a)?(0,e.readdirSync)(a).filter(b=>{if(!b.endsWith(bj))return!1;let c=b.slice(0,-bj.length);if(!c||c.startsWith(".")||!bg.test(c))return!1;try{return(0,e.statSync)((0,g.join)(a,b)).isFile()}catch{return!1}}).map(a=>a.slice(0,-bj.length)):[]}function bv(a,b){let c=bm(a,b);(0,e.mkdirSync)((0,g.dirname)(c),{recursive:!0});try{let a=(0,e.openSync)(c,e.constants.O_WRONLY|e.constants.O_CREAT|e.constants.O_EXCL);return(0,e.closeSync)(a),!0}catch{return!1}}function bw(a,b,c,e){return(0,d.tT)({id:a,metadata:b},c,e)?"orchestrator":"worker"}function bx(a){let{role:b,project:c,defaults:e,persistedAgent:f,spawnAgentOverride:g}=a,h="orchestrator"===b?c.orchestrator:c.worker,i="orchestrator"===b?e.orchestrator:e.worker,j=c.agentConfig??{},k=h?.agentConfig??{},l=f||("worker"===b?g??h?.agent??c.agent??i?.agent??e.agent:h?.agent??c.agent??i?.agent??e.agent),m={...j};for(let[a,b]of Object.entries(k))void 0!==b&&(m[a]=b);let n="orchestrator"===b?k.orchestratorModel??k.model??j.orchestratorModel??j.model:k.model??j.model;void 0!==n&&(m.model=n);let o=(0,d.DD)("string"==typeof m.permissions?m.permissions:void 0);void 0!==o&&(m.permissions=o);let p="string"==typeof m.subagent?m.subagent:void 0;return{role:b,agentName:l,agentConfig:m,model:n,permissions:o,subagent:p}}let by=new Set(["active","ready","idle","blocked"]),bz=new Set(["active","ready"]),bA=new Set(["idle","blocked"]);function bB(a,b=new Date){if(!a)return"none";let c=Math.max(0,b.getTime()-a.getTime());return c<=6e4?"strong":c<=3e5?"weak":"stale"}function bC(a,b={}){return{state:a,activity:b.activity??null,timestamp:b.timestamp,source:b.source??"none",detail:b.detail}}function bD(a,b,c=new Date){return by.has(a.state)?!a.timestamp&&bA.has(a.state)?bC("stale",{activity:a.state,source:b,detail:"missing_timestamp"}):a.timestamp?bz.has(a.state)&&"stale"===bB(a.timestamp,c)?bC("stale",{activity:a.state,timestamp:a.timestamp,source:b,detail:"stale_timestamp"}):bC("valid",{activity:a.state,timestamp:a.timestamp,source:b}):bC("valid",{activity:a.state,source:b}):bC("valid",{activity:a.state,timestamp:a.timestamp,source:b})}function bE(a){return"valid"===a.state&&a.timestamp instanceof Date&&null!==a.activity&&bA.has(a.activity)}function bF(a){let b="none"===a.source?"":` via_${a.source}`,c=a.activity?` activity=${a.activity}`:"",d=a.timestamp?` at=${a.timestamp.toISOString()}`:"",e=a.detail?` detail=${a.detail}`:"";return`activity_signal=${a.state}${b}${c}${d}${e}`}var bG=c(51455);let bH=["started","working","waiting","needs_input","fixing_ci","addressing_reviews","pr_created","draft_pr_created","ready_for_review","completed"],bI={STATE:"agentReportedState",AT:"agentReportedAt",NOTE:"agentReportedNote",PR_NUMBER:"agentReportedPrNumber",PR_URL:"agentReportedPrUrl",PR_IS_DRAFT:"agentReportedPrIsDraft"};async function bJ(a,b){let c=function(a,b){return bh(b),(0,g.join)((0,g.join)(a,".agent-report-audit"),`${b}.ndjson`)}(a,b);return(0,e.existsSync)(c)?(await (0,bG.readFile)(c,"utf8")).split("\n").map(a=>a.trim()).filter(a=>a.length>0).flatMap(a=>{try{let b=JSON.parse(a);if("string"!=typeof b.timestamp||"string"!=typeof b.actor||"acknowledge"!==b.source&&"report"!==b.source||!bH.includes(b.reportState)||"boolean"!=typeof b.accepted||!b.before||!b.after)return[];return[b]}catch{return[]}}).reverse():[]}function bK(a){if(!a)return null;let b=a[bI.STATE],c=a[bI.AT];if(!b||!c||!bH.includes(b))return null;let d=Date.parse(c);if(Number.isNaN(d))return null;let e=a[bI.NOTE],f=a[bI.PR_NUMBER],g=f&&/^\d+$/.test(f)?Number.parseInt(f,10):void 0,h=a[bI.PR_URL]||void 0,i=a[bI.PR_IS_DRAFT];return{state:b,timestamp:new Date(d).toISOString(),note:e&&e.length>0?e:void 0,prNumber:g,prUrl:h,prIsDraft:"true"===i||"false"!==i&&void 0}}let bL=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;function bM(a,b){if(!a||"."===a||".."===a||!bL.test(a))throw Error(`Unsafe ${b}: "${a}"`)}function bN(a){if("string"!=typeof a)return;let b=Date.parse(a);return Number.isNaN(b)?void 0:new Date(b).toISOString()}function bO(a){return"object"==typeof a&&null!==a&&!Array.isArray(a)}function bP(a){return"number"==typeof a&&Number.isFinite(a)?a:void 0}function bQ(a){return"string"==typeof a&&a.trim().length>0?a:void 0}function bR(a){try{return JSON.parse((0,e.readFileSync)(a,"utf-8"))}catch{return null}}function bS(a,b){D(a,`${JSON.stringify(b,null,2)}
79
+ `)}function bT(a){return Object.fromEntries(Object.entries(a).filter(([,a])=>void 0!==a))}function bU(a,b){return Date.parse(b.updatedAt)-Date.parse(a.updatedAt)||Date.parse(b.createdAt)-Date.parse(a.createdAt)||a.id.localeCompare(b.id)}function bV(a,b){if(!bO(b))return null;let c=bQ(b.id),d=bQ(b.linkedSessionId),e=bQ(b.reviewerSessionId),f=bN(b.createdAt),g=bN(b.updatedAt)??f;return c&&d&&e&&f&&g?bT({id:c,projectId:bQ(b.projectId)??a,linkedSessionId:d,reviewerSessionId:e,status:function(a){switch(a){case"queued":case"preparing":case"running":case"needs_triage":case"sent_to_agent":case"waiting_update":case"clean":case"outdated":case"failed":case"cancelled":return a;default:return"queued"}}(b.status),createdAt:f,updatedAt:g,startedAt:bN(b.startedAt),completedAt:bN(b.completedAt),targetSha:bQ(b.targetSha),baseSha:bQ(b.baseSha),prNumber:bP(b.prNumber),prUrl:bQ(b.prUrl),reviewerWorkspacePath:bQ(b.reviewerWorkspacePath),summary:bQ(b.summary),terminationReason:bQ(b.terminationReason)}):null}function bW(a,b){if(!bO(b))return null;let c=bQ(b.id),d=bQ(b.runId),e=bQ(b.linkedSessionId),f=bQ(b.title),g=bQ(b.body),h=bN(b.createdAt),i=bN(b.updatedAt)??h;return c&&d&&e&&f&&g&&h&&i?bT({id:c,projectId:bQ(b.projectId)??a,runId:d,linkedSessionId:e,status:function(a){switch(a){case"dismissed":case"sent_to_agent":case"resolved":return a;default:return"open"}}(b.status),severity:function(a){switch(a){case"error":case"warning":case"info":return a;default:return"warning"}}(b.severity),title:f,body:g,filePath:bQ(b.filePath),startLine:bP(b.startLine),endLine:bP(b.endLine),category:bQ(b.category),confidence:bP(b.confidence),fingerprint:bQ(b.fingerprint),createdAt:h,updatedAt:i,dismissedAt:bN(b.dismissedAt),dismissedBy:bQ(b.dismissedBy),sentToAgentAt:bN(b.sentToAgentAt)}):null}class bX{constructor(a,b={}){this.projectId=a,this.storeDir=b.storeDir??q(a)}get runsDir(){return(0,g.join)(this.storeDir,"runs")}get findingsDir(){return(0,g.join)(this.storeDir,"findings")}ensure(){(0,e.mkdirSync)(this.runsDir,{recursive:!0}),(0,e.mkdirSync)(this.findingsDir,{recursive:!0})}listRuns(a={}){return this.readAllRuns().filter(b=>!a.linkedSessionId||b.linkedSessionId===a.linkedSessionId).filter(b=>!a.status||b.status===a.status).sort(bU)}listRunSummaries(a={}){let b=this.listFindings(),c=new Map;for(let a of b){let b=c.get(a.runId)??{findingCount:0,openFindingCount:0,dismissedFindingCount:0,sentFindingCount:0,resolvedFindingCount:0};b.findingCount++,"open"===a.status&&b.openFindingCount++,"dismissed"===a.status&&b.dismissedFindingCount++,"sent_to_agent"===a.status&&b.sentFindingCount++,"resolved"===a.status&&b.resolvedFindingCount++,c.set(a.runId,b)}return this.listRuns(a).map(a=>({...a,...c.get(a.id)??{findingCount:0,openFindingCount:0,dismissedFindingCount:0,sentFindingCount:0,resolvedFindingCount:0}}))}getRun(a){return bM(a,"review run id"),bV(this.projectId,bR(this.runPath(a)))}createRun(a,b=new Date){let c=`review-run-${(0,f.randomUUID)()}`,d=b.toISOString(),e=bT({id:c,projectId:this.projectId,linkedSessionId:a.linkedSessionId,reviewerSessionId:a.reviewerSessionId,status:a.status??"queued",createdAt:d,updatedAt:d,startedAt:"running"===a.status?d:void 0,targetSha:a.targetSha,baseSha:a.baseSha,prNumber:a.prNumber,prUrl:a.prUrl,reviewerWorkspacePath:a.reviewerWorkspacePath,summary:a.summary});return this.writeRun(e),e}updateRun(a,b,c=new Date){let d=this.getRun(a);if(!d)throw Error(`Code review run not found: ${a}`);let e=bT({...d,...b,id:d.id,projectId:d.projectId,createdAt:d.createdAt,updatedAt:c.toISOString()});return this.writeRun(e),e}listFindings(a={}){return this.readAllFindings().filter(b=>!a.runId||b.runId===a.runId).filter(b=>!a.linkedSessionId||b.linkedSessionId===a.linkedSessionId).filter(b=>!a.status||b.status===a.status).sort(bU)}getFinding(a){return bM(a,"review finding id"),bW(this.projectId,bR(this.findingPath(a)))}createFinding(a,b=new Date){if(!this.getRun(a.runId))throw Error(`Code review run not found: ${a.runId}`);let c=`review-finding-${(0,f.randomUUID)()}`,d=b.toISOString(),e=bT({id:c,projectId:this.projectId,runId:a.runId,linkedSessionId:a.linkedSessionId,status:a.status??"open",severity:a.severity,title:a.title,body:a.body,filePath:a.filePath,startLine:a.startLine,endLine:a.endLine,category:a.category,confidence:a.confidence,fingerprint:a.fingerprint,createdAt:d,updatedAt:d});return this.writeFinding(e),e}updateFinding(a,b,c=new Date){let d=this.getFinding(a);if(!d)throw Error(`Code review finding not found: ${a}`);let e=bT({...d,...b,id:d.id,projectId:d.projectId,runId:d.runId,linkedSessionId:d.linkedSessionId,createdAt:d.createdAt,updatedAt:c.toISOString()});return this.writeFinding(e),e}deleteAll(){(0,e.rmSync)(this.storeDir,{recursive:!0,force:!0})}runPath(a){return bM(a,"review run id"),(0,g.join)(this.runsDir,`${a}.json`)}findingPath(a){return bM(a,"review finding id"),(0,g.join)(this.findingsDir,`${a}.json`)}writeRun(a){this.ensure(),bS(this.runPath(a.id),a)}writeFinding(a){this.ensure(),bS(this.findingPath(a.id),a)}readAllRuns(){return this.readAllJsonFiles(this.runsDir).map(a=>bV(this.projectId,a)).filter(a=>null!==a)}readAllFindings(){return this.readAllJsonFiles(this.findingsDir).map(a=>bW(this.projectId,a)).filter(a=>null!==a)}readAllJsonFiles(a){return(0,e.existsSync)(a)?(0,e.readdirSync)(a,{withFileTypes:!0}).filter(a=>a.isFile()&&a.name.endsWith(".json")).map(b=>bR((0,g.join)(a,b.name))).filter(a=>null!==a):[]}}function bY(a,b={}){return new bX(a,b)}var bZ=c(58500);let b$=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;async function b_(a,b,d={}){let{execFile:e}=await Promise.resolve().then(c.t.bind(c,31421,19));return(0,u.promisify)(e)(a,b,{windowsHide:!0,...d})}async function b0(a,b,d={}){let{spawn:e}=await Promise.resolve().then(c.t.bind(c,31421,19));return new Promise((c,f)=>{let g=e(a,b,{cwd:d.cwd,env:d.env,shell:d.shell,windowsHide:d.windowsHide??!0,detached:!w(),stdio:["ignore","pipe","pipe"]}),h=d.maxBuffer??8388608,i="",j="",k=!1,l=a=>{k||(k=!0,o&&clearTimeout(o),a())},m=()=>void 0!==g.pid?B(g.pid).catch(()=>void 0):(g.kill("SIGTERM"),Promise.resolve()),n=(a,b,c)=>{let d=Error(a);d.code=b,d.signal=c,d.stdout=i,d.stderr=j,f(d)},o=d.timeout&&d.timeout>0?setTimeout(()=>{m().finally(()=>{l(()=>n(`Command timed out after ${d.timeout}ms`,null,"SIGTERM"))})},d.timeout):null,p=(a,b)=>{let c=b.toString();"stdout"===a?i+=c:j+=c,Buffer.byteLength(i)+Buffer.byteLength(j)<=h||(m(),l(()=>n(`Command output exceeded maxBuffer ${h}`)))};g.stdout?.on("data",a=>p("stdout",a)),g.stderr?.on("data",a=>p("stderr",a)),g.once("error",a=>l(()=>f(a))),g.once("close",(a,b)=>{l(()=>{if(0===a)return void c({stdout:i,stderr:j});n(`Command failed with code ${a??b??"unknown"}`,a,b)})})})}class b1 extends Error{constructor(a){super(`Code review run not found: ${a}`),this.name="CodeReviewRunNotFoundError"}}class b2 extends Error{constructor(a){super(`Code review run ${a.reviewerSessionId} is ${a.status}, not queued`),this.name="CodeReviewRunNotExecutableError",this.runId=a.id,this.reviewerSessionId=a.reviewerSessionId,this.status=a.status}}class b3 extends Error{constructor(a){super(a),this.name="CodeReviewInvalidSessionError"}}class b4 extends Error{constructor(a){super(`No open review findings to send for ${a.reviewerSessionId}.`),this.name="CodeReviewNoOpenFindingsError",this.runId=a.id,this.reviewerSessionId=a.reviewerSessionId}}function b5(a,b){return a.length>b?`${a.slice(0,b-1)}…`:a}function b6(a){return"number"==typeof a&&Number.isFinite(a)?a:void 0}function b7(a){return"object"!=typeof a||null===a||Array.isArray(a)?null:a}function b8(a,b){return"object"==typeof a&&null!==a&&"code"in a&&a.code===b}async function b9({store:a,lockFileName:b,label:c}){(0,e.mkdirSync)(a.storeDir,{recursive:!0});let d=(0,g.join)(a.storeDir,b),f=Date.now();for(;;)try{let a=(0,e.openSync)(d,"wx");(0,e.writeFileSync)(a,`${process.pid}
80
+ ${new Date().toISOString()}
81
+ `);let b=!1;return()=>{if(!b){b=!0;try{(0,e.closeSync)(a)}catch{}try{(0,e.unlinkSync)(d)}catch{}}}}catch(a){if(!b8(a,"EEXIST"))throw a;try{if(Date.now()-(0,e.statSync)(d).mtimeMs>3e4){(0,e.unlinkSync)(d);continue}}catch(a){if(b8(a,"ENOENT"))continue}if(Date.now()-f>5e3)throw Error(`Timed out waiting for ${c} lock`,{cause:a});await (0,bZ.setTimeout)(25)}}async function ca(a,b){let c=await b9({store:a,lockFileName:".create-run.lock",label:"code review run creation"});try{return await b()}finally{c()}}async function cb(a,b,c){if(!b||"."===b||".."===b||!b$.test(b))throw Error(`Unsafe review run id: "${b}"`);let d=await b9({store:a,lockFileName:`.execute-run-${b}.lock`,label:`code review run ${b} execution`});try{return await c()}finally{d()}}let cc=new Set(["queued","needs_triage","sent_to_agent","waiting_update","clean"]);function cd({store:a,existingRuns:b,linkedSessionId:c,targetSha:d,now:e}){if(!d)return 0;let f=0;for(let g of b)g.linkedSessionId===c&&g.targetSha&&g.targetSha!==d&&cc.has(g.status)&&(a.updateRun(g.id,{status:"outdated"},e),f++);return f}async function ce(a){let b=a.workspacePath;if(b)try{let{stdout:a}=await b_("git",["rev-parse","HEAD"],{cwd:b,timeout:5e3}),c=a.trim();return c.length>0?c:void 0}catch{return}}async function cf(a,b,c=3e4){let{stdout:d}=await b_("git",b,{cwd:a,timeout:c});return d.trim()}async function cg(a){if(a)try{return await cf(a,["rev-parse","HEAD"],5e3)}catch{return}}async function ch(a,b){if(!(0,e.existsSync)(b)){try{await cf(a,["worktree","prune"])}catch{}return}try{await cf(a,["worktree","remove","--force",b]);return}catch{try{await cf(a,["worktree","prune"])}catch{}(0,e.rmSync)(b,{recursive:!0,force:!0})}}async function ci({store:a,session:b,resolveTargetSha:c=ce,now:d=new Date}){let e=await c(b);return cd({store:a,existingRuns:a.listRuns({linkedSessionId:b.id}),linkedSessionId:b.id,targetSha:e,now:d})}async function cj({projectId:a,project:b,session:c,run:d}){let f=(0,g.join)(q(a),"workspaces"),h=(0,g.join)(f,d.reviewerSessionId);(0,e.mkdirSync)(f,{recursive:!0}),await ch(b.path,h);let i=d.targetSha??await cg(c.workspacePath)??"HEAD";return await cf(b.path,["worktree","add","--detach",h,i],6e4),h}async function ck(a){if(!(0,e.existsSync)(a))return null;try{return(0,e.readFileSync)(a,"utf-8")}catch{return null}}function cl(a){return async b=>{let c=A(),{stdout:d,stderr:e}=await b_(c.cmd,c.args(a),{cwd:b.workspacePath,timeout:6e5,maxBuffer:8388608,env:process.env});return{rawOutput:d.trim()||e.trim()}}}async function cm(a){let b=(0,g.join)(a.workspacePath,".ao-code-review-output.json"),c=`You are an AO reviewer agent. Review this repository snapshot for concrete bugs only.
82
+ Do not modify files. Do not publish comments anywhere.
83
+ Review the changes against base ref "${a.baseRef}". Start with: git diff --merge-base ${a.baseRef} HEAD -- .
84
+ If that diff command fails, inspect git status/log and compare this detached reviewer workspace to the base ref using read-only commands.
85
+ Linked coding worker: ${a.session.id}
86
+ Reviewer run: ${a.run.reviewerSessionId}
87
+ Base ref: ${a.baseRef}
88
+ Return only JSON using this schema:
89
+ {"findings":[{"severity":"warning|error|info","title":"short title","body":"specific issue and fix","filePath":"optional/path","startLine":1,"endLine":1,"confidence":0.8}]}
90
+ If there are no concrete bugs, return {"findings":[]}.`;try{let{stdout:d,stderr:e}=await b0("codex",["exec","--sandbox","read-only","--output-last-message",b,c],{cwd:a.workspacePath,timeout:6e5,maxBuffer:8388608,env:process.env,shell:w()});return{rawOutput:await ck(b)??(d.trim()||e.trim())}}catch(b){let a=b instanceof Error&&"stderr"in b&&"string"==typeof b.stderr?b.stderr.trim():b instanceof Error?b.message:String(b);throw Error(`Codex review failed: ${a}`,{cause:b})}}async function cn({config:a,sessionManager:b,storeFactory:c=bY,resolveTargetSha:e=ce,now:f=new Date},g){let h=await b.get(g.sessionId);if(!h)throw new d.Ag(g.sessionId);let i=a.projects[h.projectId];if(!i)throw new b3(`Unknown project for session ${h.id}: ${h.projectId}`);let j=i.sessionPrefix??h.projectId,k=Object.entries(a.projects).map(([a,b])=>b.sessionPrefix??a);if((0,d.tT)(h,j,k))throw new b3(`Cannot request code review for orchestrator session: ${h.id}`);let l=c(h.projectId),m=h.pr?.url??h.metadata.pr,n=h.pr?.number??function(a){if(!a)return;let b=a.match(/\/pull\/(\d+)(?:\D*$|$)/);if(!b)return;let c=Number.parseInt(b[1],10);return Number.isNaN(c)?void 0:c}(m),o=await e(h),p=g.requestedBy??"system";return ca(l,()=>{let a=l.listRuns(),b=function(a,b){let c=0,d=RegExp(`^${b.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}-rev-(\\d+)$`);for(let b of a){let a=b.reviewerSessionId.match(d);if(!a)continue;let e=Number.parseInt(a[1],10);!Number.isNaN(e)&&e>c&&(c=e)}return`${b}-rev-${c+1}`}(a,j);return cd({store:l,existingRuns:a,linkedSessionId:h.id,targetSha:o,now:f}),{...l.createRun({linkedSessionId:h.id,reviewerSessionId:b,status:g.status??"queued",targetSha:o,prNumber:n,prUrl:m,summary:g.summary??`Review requested from ${"cli"===p?"CLI":"web"===p?"dashboard":"automation"} for ${h.id}.`},f),findingCount:0,openFindingCount:0,dismissedFindingCount:0,sentFindingCount:0,resolvedFindingCount:0}})}function co(a,b){let c=a.listRunSummaries().find(a=>a.id===b);if(!c)throw new b1(b);return c}async function cp({config:a,sessionManager:b,storeFactory:c=bY,prepareWorkspace:e=cj,runReviewer:f=cm,now:g=()=>new Date,force:h=!1},{projectId:i,runId:j}){let k=a.projects[i];if(!k)throw Error(`Unknown project: ${i}`);let l=c(i),m=await cb(l,j,async()=>{let a=function(a,b,c){let d=a.getRun(b);if(!d)throw new b1(b);if("preparing"===d.status||"running"===d.status||!c&&!["queued","failed"].includes(d.status))throw new b2(d);return d}(l,j,h),c=await b.get(a.linkedSessionId);if(!c)throw new d.Ag(a.linkedSessionId);let e=g();return{run:l.updateRun(a.id,{status:"preparing",startedAt:a.startedAt??e.toISOString(),completedAt:void 0,terminationReason:void 0},e),session:c}}),n=m.run,o=m.session;try{let b=await e({projectId:i,project:k,session:o,run:n});n=l.updateRun(n.id,{status:"running",reviewerWorkspacePath:b},g());let c=o.pr?.baseBranch?.trim()||k.defaultBranch,d=await f({config:a,project:k,session:o,run:n,workspacePath:b,baseRef:c}),h=d.findings??function(a){let b=a.trim();if(!b)return[];let c=function(a){let b=[function(a){let b=a.trim(),c=b.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);return c?.[1]?.trim()??b}(a)],c=a.match(/```(?:json)?\s*([\s\S]*?)\s*```/i);for(let d of(c?.[1]&&b.push(c[1].trim()),a.split(/\r?\n/).map(a=>a.trim()).filter(Boolean).reverse()))(d.startsWith("{")||d.startsWith("["))&&b.push(d);for(let a of b)try{return JSON.parse(a)}catch{}return null}(b),d=b7(c),e=Array.isArray(c)?c:Array.isArray(d?.findings)?d.findings:null;return e?e.map((a,b)=>(function(a,b){let c=b7(a);if(!c)return null;let d="string"==typeof c.body?c.body.trim():"string"==typeof c.message?c.message.trim():"";if(!d)return null;let e="string"==typeof c.title&&c.title.trim()?c.title.trim():`Review finding ${b}`,f="string"==typeof c.filePath?c.filePath:"string"==typeof c.path?c.path:void 0;return{severity:function(a){switch(a){case"error":case"warning":case"info":return a;default:return"warning"}}(c.severity),title:b5(e,160),body:b5(d,12e3),filePath:f,startLine:b6(c.startLine??c.line),endLine:b6(c.endLine),category:"string"==typeof c.category?c.category:void 0,confidence:b6(c.confidence),fingerprint:"string"==typeof c.fingerprint?c.fingerprint:void 0}})(a,b+1)).filter(a=>null!==a):/^no findings?\.?$/i.test(b)?[]:[{severity:"warning",title:"Reviewer output",body:b5(b,12e3)}]}(d.rawOutput??"");for(let a of h)l.createFinding({runId:n.id,linkedSessionId:n.linkedSessionId,severity:a.severity??"warning",title:a.title?.trim()||"Review finding",body:a.body?.trim()||"Reviewer reported an issue without details.",filePath:a.filePath,startLine:a.startLine,endLine:a.endLine,category:a.category,confidence:a.confidence,fingerprint:a.fingerprint},g());let j=g();l.updateRun(n.id,{status:h.length>0?"needs_triage":"clean",completedAt:j.toISOString(),summary:d.summary??n.summary,terminationReason:void 0},j)}catch(b){let a=g();l.updateRun(n.id,{status:"failed",completedAt:a.toISOString(),terminationReason:b instanceof Error?b.message:String(b)},a)}return co(l,n.id)}async function cq({config:a,sessionManager:b,storeFactory:c=bY,now:e=()=>new Date},{projectId:f,runId:g}){if(!a.projects[f])throw Error(`Unknown project: ${f}`);let h=c(f),i=h.getRun(g);if(!i)throw new b1(g);let j=await b.get(i.linkedSessionId);if(!j)throw new d.Ag(i.linkedSessionId);let k=h.listFindings({runId:i.id,status:"open"});if(0===k.length)throw new b4(i);let l=function({run:a,findings:b,session:c}){let d=a.prNumber?`PR #${a.prNumber}${a.prUrl?` (${a.prUrl})`:""}`:a.prUrl?`PR ${a.prUrl}`:"the current PR",e=a.targetSha?`
91
+ Target SHA reviewed: ${a.targetSha}`:"";return[`AO reviewer ${a.reviewerSessionId} found ${b.length} open issue${1===b.length?"":"s"} for ${d}.`,`Linked coding worker: ${c.id}`,`Review run: ${a.id}${e}`,"\nPlease address each finding below. Verify each issue against the current source before editing, then update the PR branch and push your fixes.\nWhen you start working on these, report `athene report addressing-reviews`. When the fixes are ready for another review, report `athene report ready-for-review`.\n\nFindings:",b.map((a,b)=>(function(a,b){let c=[`${b}. [${a.severity}] ${a.title}`],d=a.filePath?void 0===a.startLine?a.filePath:void 0!==a.endLine&&a.endLine!==a.startLine?`${a.filePath}:${a.startLine}-${a.endLine}`:`${a.filePath}:${a.startLine}`:null;return d&&c.push(` Location: ${d}`),void 0!==a.confidence&&c.push(` Confidence: ${a.confidence}`),c.push(" Details:"),c.push(...a.body.split(/\r?\n/).map(a=>` ${a}`).filter((a,b,c)=>a.trim()||b<c.length-1)),c.join("\n")})(a,b+1)).join("\n\n")].join("\n")}({run:i,findings:k,session:j});await b.send(j.id,l);let m=e();for(let a of k)h.updateFinding(a.id,{status:"sent_to_agent",sentToAgentAt:m.toISOString()},m);return h.updateRun(i.id,{status:"waiting_update"},m),{run:co(h,i.id),sentFindingCount:k.length,message:l}}function cr(a,b=new Date){if(!a)return!1;let c=Date.parse(a);return!Number.isNaN(c)&&b.getTime()-c>3e5}function cs(a){var b;let c="now"in a&&a.now?a.now:new Date,e=c.toISOString(),g=(b=a.evidence,(0,f.createHash)("sha256").update(b.replace(/\sactivity=[^\s]+/g,"").replace(/\sat=[^\s]+/g,"").trim()).digest("hex").slice(0,12)),h="previousEvidenceHash"in a?a.previousEvidenceHash:void 0,i="detectingStartedAt"in a?a.detectingStartedAt:void 0,j=void 0!==h&&h!==g,k=j?e:i??e,l=j?1:a.currentAttempts+1,m=cr(k,c);return l>3||m?{status:d.SB.STUCK,evidence:a.evidence,detecting:{attempts:l,startedAt:k,evidenceHash:g},sessionState:"stuck",sessionReason:a.idleWasBlocked?"error_in_process":"probe_failure"}:{status:d.SB.DETECTING,evidence:a.evidence,detecting:{attempts:l,startedAt:k,evidenceHash:g},sessionState:"detecting",sessionReason:a.reason??"probe_failure"}}function ct(a){return a===d.bz.MERGED?{status:d.SB.MERGED,evidence:"pr_merged",detecting:{attempts:0},prState:"merged",prReason:"merged",sessionState:"idle",sessionReason:"merged_waiting_decision"}:a===d.bz.CLOSED?{status:d.SB.IDLE,evidence:"pr_closed",detecting:{attempts:0},prState:"closed",prReason:"closed_unmerged",sessionState:"idle",sessionReason:"pr_closed_waiting_decision"}:null}function cu(a){if(a.ciFailing)return{status:d.SB.CI_FAILED,evidence:"ci_failing",detecting:{attempts:0},prState:"open",prReason:"ci_failing",sessionState:"working",sessionReason:"fixing_ci"};if("changes_requested"===a.reviewDecision)return{status:d.SB.CHANGES_REQUESTED,evidence:"review_changes_requested",detecting:{attempts:0},prState:"open",prReason:"changes_requested",sessionState:"working",sessionReason:"resolving_review_comments"};if("approved"===a.reviewDecision||"none"===a.reviewDecision){if(a.mergeable)return{status:d.SB.MERGEABLE,evidence:"merge_ready",detecting:{attempts:0},prState:"open",prReason:"merge_ready",sessionState:"idle",sessionReason:"awaiting_external_review"};if("approved"===a.reviewDecision)return{status:d.SB.APPROVED,evidence:"review_approved",detecting:{attempts:0},prState:"open",prReason:"approved",sessionState:"idle",sessionReason:"awaiting_external_review"}}return"pending"===a.reviewDecision?{status:d.SB.REVIEW_PENDING,evidence:"review_pending",detecting:{attempts:0},prState:"open",prReason:"review_pending",sessionState:"idle",sessionReason:"awaiting_external_review"}:a.shouldEscalateIdleToStuck?{status:d.SB.STUCK,evidence:`idle_beyond_threshold ${a.activityEvidence}`,detecting:{attempts:0},prState:"open",prReason:"in_progress",sessionState:"stuck",sessionReason:a.idleWasBlocked?"error_in_process":"probe_failure"}:{status:d.SB.PR_OPEN,evidence:"pr_open",detecting:{attempts:0},prState:"open",prReason:"in_progress",sessionState:"idle",sessionReason:"pr_created"}}function cv(a){if(!a)return 0;let b=Number.parseInt(a,10);return Number.isFinite(b)&&b>0?b:0}function cw(a,b){let c=ct(a.state);return c||cu({reviewDecision:a.reviewDecision,ciFailing:a.ciStatus===d.U1.FAILING,mergeable:a.mergeable,shouldEscalateIdleToStuck:b.shouldEscalateIdleToStuck,idleWasBlocked:b.idleWasBlocked,activityEvidence:b.activityEvidence})}function cx(a){let b=ct(a.prState);return b||cu({reviewDecision:a.reviewDecision,ciFailing:a.ciStatus===d.U1.FAILING,mergeable:a.mergeable,shouldEscalateIdleToStuck:a.shouldEscalateIdleToStuck,idleWasBlocked:a.idleWasBlocked,activityEvidence:a.activityEvidence})}let cy={acknowledgeTimeoutMs:6e5,staleReportTimeoutMs:18e5,checkAcknowledge:!0,checkStale:!0,checkBlocked:!0},cz=new Set(["done","terminated","killed","cleanup","merged","errored"]),cA={LAST_AUDITED_AT:"reportWatcherLastAuditedAt",ACTIVE_TRIGGER:"reportWatcherActiveTrigger",TRIGGER_ACTIVATED_AT:"reportWatcherTriggerActivatedAt",TRIGGER_COUNT:"reportWatcherTriggerCount"},cB=`You are an AI coding agent managed by the Athene (ao).
92
+
93
+ ## Session Lifecycle
94
+ - You are running inside a managed session. Focus on the assigned task.
95
+ - When you finish your work, create a PR and push it. The orchestrator will handle CI monitoring and review routing.
96
+ - If you're told to take over or continue work on an existing PR, run \`athene session claim-pr <pr-number-or-url>\` from inside this session before making changes.
97
+ - If CI fails, the orchestrator will send you the failures — fix them and push again.
98
+ - If reviewers request changes, the orchestrator will forward their comments — address each one, push fixes, and reply to the comments.
99
+
100
+ ## Reporting Progress to AO
101
+ The orchestrator infers your status from runtime signals, but explicit reports are always preferred — they are accurate and fresh. Run these commands from the session shell (AO_SESSION_ID is pre-set for you):
102
+
103
+ - \`athene acknowledge\` — run once after reading the initial task so AO knows you picked it up.
104
+ - \`athene report working\` — declare you are actively making progress (useful after pauses or long thinking blocks).
105
+ - \`athene report waiting\` — you are blocked on something AO cannot unblock on its own (e.g. waiting for a human, external service).
106
+ - \`athene report needs-input\` — you need a decision or info from the human before proceeding.
107
+ - \`athene report fixing-ci\` — you are working specifically on making CI green again.
108
+ - \`athene report addressing-reviews\` — you are working on reviewer-requested changes.
109
+ - \`athene report pr-created --pr-url <url>\` / \`draft-pr-created\` / \`ready-for-review\` — declare PR workflow milestones as soon as you create or update the PR.
110
+ - \`athene report completed\` — you finished non-coding research or analysis work that doesn't produce a PR.
111
+
112
+ Rules:
113
+ - Do NOT self-report \`done\`, \`terminated\`, or terminal PR states like \`merged\`/\`closed\` — AO owns those transitions via SCM ground truth.
114
+ - A fresh report is trusted over weak inference but runtime death, activity-based waiting_input, and SCM events (merged/closed PR, CI failure, reviews) still take precedence.
115
+ - Use \`--note "<text>"\` to attach a short rationale when the state change is non-obvious.
116
+
117
+ ## Git Workflow
118
+ - Always create a feature branch from the default branch (never commit directly to it).
119
+ - Use conventional commit messages (feat:, fix:, chore:, etc.).
120
+ - Push your branch and create a PR when the implementation is ready.
121
+ - Keep PRs focused — one issue per PR.
122
+
123
+ ## PR Best Practices
124
+ - Write a clear PR title and description explaining what changed and why.
125
+ - Link the issue in the PR description so it auto-closes when merged.
126
+ - If the repo has CI checks, make sure they pass before requesting review.
127
+ - Respond to every review comment, even if just to acknowledge it.`,cC=`You are an AI coding agent managed by the Athene (ao).
128
+
129
+ ## Session Lifecycle
130
+ - You are running inside a managed session. Focus on the assigned task.
131
+ - No remote repository is configured — work locally. PR, CI, and review features are unavailable.
132
+
133
+ ## Reporting Progress to AO
134
+ Explicit reports help the orchestrator track your state accurately. Run these from the session shell (AO_SESSION_ID is pre-set):
135
+ - \`athene acknowledge\` — run once after reading the initial task.
136
+ - \`athene report working\` / \`waiting\` / \`needs-input\` — declare your current phase.
137
+ - \`athene report pr-created --pr-url <url>\` or \`draft-pr-created\` / \`ready-for-review\` — declare non-terminal PR workflow events when relevant.
138
+ - \`athene report completed\` — finish non-coding research or analysis work.
139
+ Do NOT self-report \`done\` or \`terminated\` — AO owns those transitions.
140
+
141
+ ## Git Workflow
142
+ - Always create a feature branch from the default branch (never commit directly to it).
143
+ - Use conventional commit messages (feat:, fix:, chore:, etc.).`,cD=/^ses_[A-Za-z0-9_-]+$/;function cE(a){if("string"!=typeof a)return;let b=a.trim();if(0!==b.length)return cD.test(b)?b:void 0}let cF=(0,u.promisify)(t.execFile),cG=null;function cH(){let a=cG||(cG=(0,g.join)(s(),".bun-tmp"));try{(0,e.mkdirSync)(a,{recursive:!0})}catch{}return a}function cI(a){let b=cH();return{...process.env,TMPDIR:b,TMP:b,TEMP:b,...a}}let cJ=null;async function cK(a){let b=a?.timeoutMs??3e4,c=a?.forceRefresh??!1,d=Date.now();if(cJ){if(cJ.promise)return cJ.promise;if(!c&&d-cJ.timestamp<500)return cJ.entries}let e=cF("opencode",["session","list","--format","json"],{timeout:b,env:cI(),..."win32"===process.platform?{shell:!0,windowsHide:!0}:{}}).then(({stdout:a})=>{let b=function(a){let b=a2(a);return Array.isArray(b)?b.flatMap(a=>{if(!a||"object"!=typeof a)return[];let b=cE(a.id);if(!b)return[];let c="string"==typeof a.title?a.title:"",d=a.updated,e="string"==typeof d||"number"==typeof d?d:void 0,f=function(a){if("number"==typeof a&&Number.isFinite(a))return a;if("string"!=typeof a)return;let b=a.trim();if(0===b.length)return;if(/^\d+$/.test(b)){let a=Number(b);return Number.isFinite(a)?a:void 0}let c=Date.parse(b);return Number.isNaN(c)?void 0:c}(d);return[{id:b,title:c,...void 0!==e?{updated:e}:{},...void 0!==f?{updatedAt:f}:{}}]}):[]}(a);return cJ?.promise===e&&(cJ={entries:b,timestamp:Date.now()}),b}).catch(()=>(cJ?.promise===e&&(cJ=null),[]));return cJ={entries:[],timestamp:d,promise:e},e}function cL(){if(cJ?.promise){cJ={...cJ,timestamp:0};return}cJ=null}let cM="\x3c!-- AO_ORCHESTRATOR_PROMPT_START --\x3e",cN="\x3c!-- AO_ORCHESTRATOR_PROMPT_END --\x3e";function cO(a,b){let c=(0,g.join)(a,"AGENTS.md");(0,e.mkdirSync)(a,{recursive:!0});let d=(function(a){let b=a.indexOf(cM),c=a.indexOf(cN);if(-1===b||-1===c||c<b)return a;let d=a.slice(0,b).trimEnd(),e=a.slice(c+cN.length).trimStart();return d&&e?`${d}
144
+
145
+ ${e}`:d||e})((0,e.existsSync)(c)?(0,e.readFileSync)(c,"utf-8"):"").trimEnd(),f=[cM,"## Athene\n",(0,e.readFileSync)(b,"utf-8").trim(),cN].join("\n"),h=d?`${d}
146
+
147
+ ${f}
148
+ `:`${f}
149
+ `;return(0,e.writeFileSync)(c,h,"utf-8"),c}function cP(a,b,c){(0,e.mkdirSync)(a,{recursive:!0});let d=(0,g.join)(a,`opencode-config-${b}.json`);return(0,e.writeFileSync)(d,JSON.stringify({instructions:c},null,2),"utf-8"),d}class cQ{push(a){this.dismissed||this.fns.push(a)}dismiss(){this.dismissed=!0}async runAll(a){if(!this.dismissed)for(this.dismissed=!0;this.fns.length>0;){let b=this.fns.pop();try{await b()}catch(b){a&&a(b)}}}constructor(){this.fns=[],this.dismissed=!1}}function cR(a){return`${a.sessionPrefix}-orchestrator`}function cS(a){return"kill-previous"===a||"delete-new"===a?"delete":"ignore-new"===a?"ignore":a??"reuse"}function cT(a){return w()?"'"+a.replace(/'/g,"''")+"'":"'"+a.replace(/'/g,"'\\''")+"'"}async function cU(a){let b=await (0,bG.open)(a,"r");try{let{size:a}=await b.stat();if(0===a)return null;let c=[],d=0,e=a;for(;e>0;){let a=Math.min(4096,e);e-=a;let f=Buffer.alloc(a);await b.read(f,0,a,e),c.unshift(f),d+=a;let g=Buffer.concat(c,d).toString("utf-8").split("\n");for(let a=g.length-1;a>=0;a--){let b=g[a].trim();if(b&&(a>0||0===e))return b}}return Buffer.concat(c,d).toString("utf-8").trim()||null}finally{await b.close()}}async function cV(a){try{let[b,c]=await Promise.all([cU(a),(0,bG.stat)(a)]);if(!b)return null;let d=JSON.parse(b);if("object"==typeof d&&null!==d&&!Array.isArray(d)){let a="string"==typeof d.type?d.type:null,b="string"==typeof d.subtype?d.subtype:null,e="string"==typeof d.level?d.level:null,f=null;if("object"==typeof d.payload&&null!==d.payload&&!Array.isArray(d.payload)){let a=d.payload;"string"==typeof a.type&&(f=a.type)}return{lastType:a,payloadType:f,lastSubtype:b,lastLevel:e,modifiedAt:c.mtime}}return{lastType:null,payloadType:null,lastSubtype:null,lastLevel:null,modifiedAt:c.mtime}}catch{return null}}function cW(a,b){for(let[c,d]of Object.entries(a.projects)){let a=d.sessionPrefix;if(b===a||b.startsWith(`${a}-`))return c}}let cX="/usr/local/bin",cY=`${cX}/gh`;function cZ(){return(0,g.join)((0,h.homedir)(),".ao","bin")}let c$="0.8.0";function c_(a){let b=w()?";":":",c=(a??(w()?"":"/usr/bin:/bin")).split(b).filter(Boolean),d=[],e=new Set,f=a=>{!a||e.has(a)||(d.push(a),e.add(a))};for(let a of(f(cZ()),w()||f(cX),c))f(a);return d.join(b)}let c0=`#!/usr/bin/env bash
150
+ # ao-metadata-helper — shared by gh/git wrappers
151
+ # Provides: update_ao_metadata, read_ao_metadata, ao_cache_*
152
+
153
+ # ── Shared validation ────────────────────────────────────────────────────────
154
+
155
+ _ao_validate_env() {
156
+ local ao_dir="\${AO_DATA_DIR:-}"
157
+ local ao_session="\${AO_SESSION:-}"
158
+ [[ -z "$ao_dir" || -z "$ao_session" ]] && return 1
159
+ case "$ao_session" in */* | *..*) return 1 ;; esac
160
+ case "$ao_dir" in
161
+ "$HOME"/.ao/* | "$HOME"/.agent-orchestrator/* | /tmp/*) ;;
162
+ *) return 1 ;;
163
+ esac
164
+ return 0
165
+ }
166
+
167
+ # ── Metadata write ───────────────────────────────────────────────────────────
168
+
169
+ update_ao_metadata() {
170
+ local key="$1" value="$2"
171
+ local ao_dir="\${AO_DATA_DIR:-}"
172
+ local ao_session="\${AO_SESSION:-}"
173
+
174
+ [[ -z "$ao_dir" || -z "$ao_session" ]] && return 0
175
+
176
+ # Validate: session name must not contain path separators or traversal
177
+ case "$ao_session" in
178
+ */* | *..*) return 0 ;;
179
+ esac
180
+
181
+ # Validate: ao_dir must be an absolute path under known ao directories or /tmp
182
+ case "$ao_dir" in
183
+ "$HOME"/.ao/* | "$HOME"/.agent-orchestrator/* | /tmp/*) ;;
184
+ *) return 0 ;;
185
+ esac
186
+
187
+ # V2 storage uses .json extension; fallback to bare filename for pre-migration layouts
188
+ local metadata_file="$ao_dir/\${ao_session}.json"
189
+ if [[ ! -f "$metadata_file" ]]; then
190
+ metadata_file="$ao_dir/$ao_session"
191
+ fi
192
+
193
+ # Resolve symlinks and verify canonicalized paths are still within trusted roots
194
+ local real_dir real_ao_dir
195
+ real_ao_dir="$(cd "$ao_dir" 2>/dev/null && pwd -P)" || return 0
196
+ real_dir="$(cd "$(dirname "$metadata_file")" 2>/dev/null && pwd -P)" || return 0
197
+
198
+ # Re-validate real_ao_dir against trusted roots after canonicalization
199
+ # (prevents /tmp/../../home/user from escaping the allowlist)
200
+ case "$real_ao_dir" in
201
+ "$HOME"/.ao/* | "$HOME"/.ao | "$HOME"/.agent-orchestrator/* | "$HOME"/.agent-orchestrator | /tmp/*) ;;
202
+ *) return 0 ;;
203
+ esac
204
+
205
+ [[ "$real_dir" == "$real_ao_dir"* ]] || return 0
206
+
207
+ [[ -f "$metadata_file" ]] || return 0
208
+
209
+ # Validate key — only allow alphanumeric, underscore, hyphen (prevents sed/jq injection)
210
+ [[ "$key" =~ ^[a-zA-Z0-9_-]+$ ]] || return 0
211
+
212
+ local temp_file="\${metadata_file}.tmp.$$"
213
+
214
+ # Strip newlines from value to prevent injection
215
+ local clean_value="$(printf '%s' "$value" | tr -d '\\n')"
216
+
217
+ # Detect JSON vs key=value format
218
+ local first_char
219
+ first_char="$(head -c1 "$metadata_file" 2>/dev/null)"
220
+
221
+ if [[ "$first_char" == "{" ]]; then
222
+ # JSON format
223
+ if command -v jq &>/dev/null; then
224
+ jq --arg k "$key" --arg v "$clean_value" '.[$k] = $v' "$metadata_file" > "$temp_file"
225
+ mv "$temp_file" "$metadata_file"
226
+ else
227
+ # jq unavailable — use node (hard dep) for safe nested JSON update
228
+ node -e "
229
+ const fs = require('fs');
230
+ const d = JSON.parse(fs.readFileSync(process.argv[1], 'utf8'));
231
+ d[process.argv[2]] = process.argv[3];
232
+ fs.writeFileSync(process.argv[4], JSON.stringify(d, null, 2));
233
+ " "$metadata_file" "$key" "$clean_value" "$temp_file"
234
+ mv "$temp_file" "$metadata_file"
235
+ fi
236
+ else
237
+ # Key=value format (legacy)
238
+ local escaped_value="$(printf '%s' "$clean_value" | sed 's/[&|\\\\]/\\\\&/g')"
239
+ if grep -q "^\${key}=" "$metadata_file" 2>/dev/null; then
240
+ sed "s|^\${key}=.*|\${key}=\${escaped_value}|" "$metadata_file" > "$temp_file"
241
+ else
242
+ cp "$metadata_file" "$temp_file"
243
+ printf '%s=%s\\n' "$key" "$clean_value" >> "$temp_file"
244
+ fi
245
+ mv "$temp_file" "$metadata_file"
246
+ fi
247
+ }
248
+
249
+ # ── Metadata read ────────────────────────────────────────────────────────────
250
+
251
+ read_ao_metadata() {
252
+ local key="$1"
253
+ _ao_validate_env || return 1
254
+ local metadata_file="\${AO_DATA_DIR}/\${AO_SESSION}"
255
+ [[ -f "$metadata_file" ]] || return 1
256
+ [[ "$key" =~ ^[a-zA-Z0-9_-]+$ ]] || return 1
257
+ local line
258
+ line=$(grep "^\${key}=" "$metadata_file" 2>/dev/null | head -1) || return 1
259
+ printf '%s' "\${line#*=}"
260
+ }
261
+
262
+ # ── Cache helpers ────────────────────────────────────────────────────────────
263
+
264
+ ao_cache_dir() {
265
+ _ao_validate_env || return 1
266
+ local d="\${AO_DATA_DIR}/.ghcache/\${AO_SESSION}"
267
+ mkdir -p "$d" 2>/dev/null || return 1
268
+ printf '%s' "$d"
269
+ }
270
+
271
+ ao_cache_fresh() {
272
+ local cache_key="$1" max_age="$2"
273
+ [[ "$cache_key" =~ ^[a-zA-Z0-9_.-]+$ ]] || return 1
274
+ local cache_dir
275
+ cache_dir="$(ao_cache_dir)" || return 1
276
+ local ts_file="$cache_dir/\${cache_key}.ts"
277
+ local stdout_file="$cache_dir/\${cache_key}.stdout"
278
+ [[ -f "$stdout_file" && -f "$ts_file" ]] || return 1
279
+ local cached_ts now
280
+ cached_ts=$(cat "$ts_file" 2>/dev/null) || return 1
281
+ # Sanity check: cached_ts must be a positive integer (epoch seconds)
282
+ [[ "$cached_ts" =~ ^[0-9]+$ && "$cached_ts" -gt 0 ]] || return 1
283
+ # max_age=0 means infinite TTL
284
+ [[ "$max_age" -eq 0 ]] 2>/dev/null && return 0
285
+ now=$(date +%s)
286
+ (( now - cached_ts < max_age ))
287
+ }
288
+
289
+ ao_cache_read() {
290
+ local cache_key="$1"
291
+ [[ "$cache_key" =~ ^[a-zA-Z0-9_.-]+$ ]] || return 1
292
+ local cache_dir
293
+ cache_dir="$(ao_cache_dir)" || return 1
294
+ cat "$cache_dir/\${cache_key}.stdout"
295
+ }
296
+
297
+ ao_cache_write() {
298
+ local cache_key="$1"
299
+ [[ "$cache_key" =~ ^[a-zA-Z0-9_.-]+$ ]] || return 1
300
+ local cache_dir
301
+ cache_dir="$(ao_cache_dir)" || return 1
302
+ local tmp="$cache_dir/\${cache_key}.stdout.tmp.$$"
303
+ cat > "$tmp" && mv "$tmp" "$cache_dir/\${cache_key}.stdout"
304
+ date +%s > "$cache_dir/\${cache_key}.ts"
305
+ }
306
+ `,c1=`#!/usr/bin/env bash
307
+ # ao gh wrapper — caches reads + auto-updates metadata on writes
308
+
309
+ # Find real gh by removing our wrapper directory from PATH
310
+ ao_bin_dir="$(cd "$(dirname "$0")" && pwd)"
311
+ clean_path="$(echo "$PATH" | tr ':' '\\n' | grep -Fxv "$ao_bin_dir" | grep . | tr '\\n' ':')"
312
+ clean_path="\${clean_path%:}"
313
+ real_gh=""
314
+
315
+ # Prefer explicit gh path when provided by AO environment.
316
+ # Guard against recursive self-reference to the wrapper in ~/.ao/bin.
317
+ if [[ -n "\${GH_PATH:-}" && -x "$GH_PATH" ]]; then
318
+ gh_dir="$(cd "$(dirname "$GH_PATH")" 2>/dev/null && pwd)"
319
+ if [[ "$gh_dir" != "$ao_bin_dir" ]]; then
320
+ real_gh="$GH_PATH"
321
+ fi
322
+ fi
323
+
324
+ if [[ -z "$real_gh" ]]; then
325
+ real_gh="$(PATH="$clean_path" command -v gh 2>/dev/null)"
326
+ fi
327
+
328
+ if [[ -z "$real_gh" ]]; then
329
+ echo "ao-wrapper: gh not found in PATH" >&2
330
+ exit 127
331
+ fi
332
+
333
+ # Source the metadata helper (provides update/read_ao_metadata, ao_cache_*)
334
+ source "$ao_bin_dir/ao-metadata-helper.sh" 2>/dev/null || true
335
+
336
+ # Redact sensitive values from args before tracing.
337
+ # Handles: -H "Authorization: ...", token=..., password=..., secret=...
338
+ _ao_redact_args() {
339
+ local prev=""
340
+ local out=()
341
+ for arg in "$@"; do
342
+ if [[ "$prev" == "-H" || "$prev" == "--header" ]] && [[ "$arg" =~ ^[Aa]uthorization: ]]; then
343
+ out+=("Authorization: [REDACTED]")
344
+ elif [[ "$arg" =~ ^-H[Aa]uthorization: ]]; then
345
+ out+=("-HAuthorization: [REDACTED]")
346
+ elif [[ "$arg" =~ ^[Tt]oken= ]]; then
347
+ out+=("token=[REDACTED]")
348
+ elif [[ "$arg" =~ ^[Pp]assword= ]]; then
349
+ out+=("password=[REDACTED]")
350
+ elif [[ "$arg" =~ ^[Ss]ecret= ]]; then
351
+ out+=("secret=[REDACTED]")
352
+ else
353
+ out+=("$arg")
354
+ fi
355
+ prev="$arg"
356
+ done
357
+ printf '%s
358
+ ' "\${out[@]}"
359
+ }
360
+
361
+ # Best-effort JSONL tracing for agent-side gh invocations.
362
+ log_gh_invocation() {
363
+ local trace_file="\${AO_AGENT_GH_TRACE:-}"
364
+ [[ -z "$trace_file" ]] && return 0
365
+ command -v jq >/dev/null 2>&1 || return 0
366
+
367
+ mkdir -p "$(dirname "$trace_file")" 2>/dev/null || return 0
368
+
369
+ local args_json
370
+ args_json="$(_ao_redact_args "$@" | jq -Rsc 'split("
371
+ ")[:-1]')" || return 0
372
+
373
+ # Compute operation: gh.{arg1}.{arg2} (mirrors AO-side extractOperation)
374
+ local _ao_op="gh"
375
+ [[ $# -ge 1 ]] && _ao_op="gh.$1"
376
+ [[ $# -ge 2 && "$2" != -* ]] && _ao_op="gh.$1.$2"
377
+
378
+ jq -nc \
379
+ --arg timestamp "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
380
+ --arg cwd "$PWD" \
381
+ --arg operation "$_ao_op" \
382
+ --arg aoSession "\${AO_SESSION:-}" \
383
+ --arg aoSessionName "\${AO_SESSION_NAME:-}" \
384
+ --arg aoProjectId "\${AO_PROJECT_ID:-}" \
385
+ --arg aoIssueId "\${AO_ISSUE_ID:-}" \
386
+ --arg aoCallerType "\${AO_CALLER_TYPE:-}" \
387
+ --arg pid "$$" \
388
+ --arg wrapperVersion "${c$}" \
389
+ --argjson args "$args_json" \
390
+ '{
391
+ timestamp: $timestamp,
392
+ cwd: $cwd,
393
+ args: $args,
394
+ operation: $operation,
395
+ aoSession: (if $aoSession == "" then null else $aoSession end),
396
+ aoSessionName: (if $aoSessionName == "" then null else $aoSessionName end),
397
+ aoProjectId: (if $aoProjectId == "" then null else $aoProjectId end),
398
+ aoIssueId: (if $aoIssueId == "" then null else $aoIssueId end),
399
+ aoCallerType: (if $aoCallerType == "" then null else $aoCallerType end),
400
+ pid: ($pid | tonumber),
401
+ wrapperVersion: $wrapperVersion
402
+ }' >> "$trace_file" 2>/dev/null || true
403
+ }
404
+
405
+ log_gh_invocation "$@"
406
+
407
+ # Best-effort cache-outcome tracing (appends to same JSONL trace file).
408
+ # result: hit | miss-stored | miss-write-failed | miss-negative | miss-error | passthrough
409
+ log_ao_cache() {
410
+ local result="$1" cache_key="$2" duration_ms="\${3:-0}" exit_code="\${4:-0}" ok="\${5:-true}"
411
+ local trace_file="\${AO_AGENT_GH_TRACE:-}"
412
+ [[ -z "$trace_file" ]] && return 0
413
+ printf '{"timestamp":"%s","cacheResult":"%s","cacheKey":"%s","pid":%s,"durationMs":%s,"exitCode":%s,"ok":%s}\\n' \
414
+ "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" "$result" "$cache_key" "$$" \
415
+ "$duration_ms" "$exit_code" "$ok" \
416
+ >> "$trace_file" 2>/dev/null || true
417
+ }
418
+
419
+ # =============================================================================
420
+ # Cacheable reads
421
+ # =============================================================================
422
+
423
+ # ── 1. PR discovery: gh pr list --head <B> --limit 1 ────────────────────────
424
+ # 120s TTL for positive results (non-empty array). Never caches [].
425
+ if [[ "$1" == "pr" && "$2" == "list" ]]; then
426
+ _ao_head="" _ao_limit="" _ao_json="" _ao_repo="" _ao_cacheable=true
427
+ _ao_saved_args=("$@")
428
+ shift 2
429
+ while [[ $# -gt 0 ]]; do
430
+ case "$1" in
431
+ --head) _ao_head="$2"; shift 2 ;;
432
+ --head=*) _ao_head="\${1#--head=}"; shift ;;
433
+ --limit) _ao_limit="$2"; shift 2 ;;
434
+ --limit=*) _ao_limit="\${1#--limit=}"; shift ;;
435
+ --json) _ao_json="$2"; shift 2 ;;
436
+ --json=*) _ao_json="\${1#--json=}"; shift ;;
437
+ --repo) _ao_repo="$2"; shift 2 ;;
438
+ --repo=*) _ao_repo="\${1#--repo=}"; shift ;;
439
+ --search|--state|--assignee|--label|--jq|--template)
440
+ _ao_cacheable=false; break ;;
441
+ --search=*|--state=*|--assignee=*|--label=*|--jq=*|--template=*)
442
+ _ao_cacheable=false; break ;;
443
+ -*) shift ;; # skip unknown flags
444
+ *) shift ;; # skip positional
445
+ esac
446
+ done
447
+ set -- "\${_ao_saved_args[@]}"
448
+
449
+ if [[ "$_ao_cacheable" == true && "$_ao_limit" == "1" && -n "$_ao_head" ]]; then
450
+ # Use sha256 hash suffix to avoid collisions from tr-based sanitization
451
+ # (e.g. feat/foo, feat-foo, feat_foo would otherwise map to the same key)
452
+ _ao_raw_key="pr-discovery-\${_ao_repo}-\${_ao_head}"
453
+ if [[ -n "$_ao_json" ]]; then
454
+ _ao_raw_key="\${_ao_raw_key}-j-\${_ao_json}"
455
+ fi
456
+ _ao_cache_key=$(printf '%s' "$_ao_raw_key" | shasum -a 256 | cut -c1-16)
457
+ _ao_cache_key="pr-disc-\${_ao_cache_key}"
458
+
459
+ if ao_cache_fresh "$_ao_cache_key" 120 2>/dev/null; then
460
+ log_ao_cache "hit" "$_ao_cache_key" 0 0 true
461
+ ao_cache_read "$_ao_cache_key"
462
+ exit 0
463
+ fi
464
+
465
+ # Cache miss — call real gh, cache positive results (stderr passes through)
466
+ _ao_tmpout="$(mktemp)"
467
+ trap 'rm -f "$_ao_tmpout"' EXIT
468
+ _ao_start_s=$(date +%s)
469
+ "$real_gh" "$@" > "$_ao_tmpout"
470
+ _ao_exit=$?
471
+ _ao_duration_ms=$(( ($(date +%s) - _ao_start_s) * 1000 ))
472
+ _ao_ok=true; [[ $_ao_exit -ne 0 ]] && _ao_ok=false
473
+ cat "$_ao_tmpout"
474
+ if [[ $_ao_exit -eq 0 ]]; then
475
+ _ao_trimmed=$(tr -d '[:space:]' < "$_ao_tmpout")
476
+ # Only cache non-empty positive results
477
+ if [[ -n "$_ao_trimmed" && "$_ao_trimmed" != "[]" ]]; then
478
+ if ao_cache_write "$_ao_cache_key" < "$_ao_tmpout" 2>/dev/null; then
479
+ log_ao_cache "miss-stored" "$_ao_cache_key" "$_ao_duration_ms" "$_ao_exit" "$_ao_ok"
480
+ else
481
+ log_ao_cache "miss-write-failed" "$_ao_cache_key" "$_ao_duration_ms" "$_ao_exit" "$_ao_ok"
482
+ fi
483
+ else
484
+ log_ao_cache "miss-negative" "$_ao_cache_key" "$_ao_duration_ms" "$_ao_exit" "$_ao_ok"
485
+ fi
486
+ else
487
+ log_ao_cache "miss-error" "$_ao_cache_key" "$_ao_duration_ms" "$_ao_exit" "$_ao_ok"
488
+ fi
489
+ exit $_ao_exit
490
+ fi
491
+ fi
492
+
493
+ # ── 2. Issue context: gh issue view <N> ─────────────────────────────────────
494
+ # 300-second TTL. Caches any successful response.
495
+ if [[ "$1" == "issue" && "$2" == "view" ]]; then
496
+ _ao_issue_id="" _ao_json="" _ao_repo="" _ao_cacheable=true
497
+ _ao_saved_args=("$@")
498
+ shift 2
499
+ # First non-flag arg is the issue identifier
500
+ while [[ $# -gt 0 ]]; do
501
+ case "$1" in
502
+ --web|--comments|--jq|--template)
503
+ _ao_cacheable=false; break ;;
504
+ --jq=*|--template=*)
505
+ _ao_cacheable=false; break ;;
506
+ --json) _ao_json="$2"; shift 2 ;;
507
+ --json=*) _ao_json="\${1#--json=}"; shift ;;
508
+ --repo) _ao_repo="$2"; shift 2 ;;
509
+ --repo=*) _ao_repo="\${1#--repo=}"; shift ;;
510
+ -*) shift ;;
511
+ *)
512
+ if [[ -z "$_ao_issue_id" && "$1" =~ ^[0-9]+$ ]]; then
513
+ _ao_issue_id="$1"
514
+ fi
515
+ shift ;;
516
+ esac
517
+ done
518
+ set -- "\${_ao_saved_args[@]}"
519
+
520
+ if [[ "$_ao_cacheable" == true && -n "$_ao_issue_id" ]]; then
521
+ _ao_raw_key="issue-ctx-\${_ao_repo}-\${_ao_issue_id}"
522
+ if [[ -n "$_ao_json" ]]; then
523
+ _ao_raw_key="\${_ao_raw_key}-j-\${_ao_json}"
524
+ fi
525
+ _ao_cache_key=$(printf '%s' "$_ao_raw_key" | shasum -a 256 | cut -c1-16)
526
+ _ao_cache_key="issue-\${_ao_cache_key}"
527
+
528
+ if ao_cache_fresh "$_ao_cache_key" 300 2>/dev/null; then
529
+ log_ao_cache "hit" "$_ao_cache_key" 0 0 true
530
+ ao_cache_read "$_ao_cache_key"
531
+ exit 0
532
+ fi
533
+
534
+ _ao_tmpout="$(mktemp)"
535
+ trap 'rm -f "$_ao_tmpout"' EXIT
536
+ _ao_start_s=$(date +%s)
537
+ "$real_gh" "$@" > "$_ao_tmpout"
538
+ _ao_exit=$?
539
+ _ao_duration_ms=$(( ($(date +%s) - _ao_start_s) * 1000 ))
540
+ _ao_ok=true; [[ $_ao_exit -ne 0 ]] && _ao_ok=false
541
+ cat "$_ao_tmpout"
542
+ if [[ $_ao_exit -eq 0 ]]; then
543
+ if ao_cache_write "$_ao_cache_key" < "$_ao_tmpout" 2>/dev/null; then
544
+ log_ao_cache "miss-stored" "$_ao_cache_key" "$_ao_duration_ms" "$_ao_exit" "$_ao_ok"
545
+ else
546
+ log_ao_cache "miss-write-failed" "$_ao_cache_key" "$_ao_duration_ms" "$_ao_exit" "$_ao_ok"
547
+ fi
548
+ else
549
+ log_ao_cache "miss-error" "$_ao_cache_key" "$_ao_duration_ms" "$_ao_exit" "$_ao_ok"
550
+ fi
551
+ exit $_ao_exit
552
+ fi
553
+ fi
554
+
555
+ # =============================================================================
556
+ # Write intercepts
557
+ # =============================================================================
558
+
559
+ case "$1/$2" in
560
+ pr/create)
561
+ tmpout="$(mktemp)"
562
+ trap 'rm -f "$tmpout"' EXIT
563
+
564
+ _ao_start_s=$(date +%s)
565
+ "$real_gh" "$@" 2>&1 | tee "$tmpout"
566
+ exit_code=\${PIPESTATUS[0]}
567
+ _ao_duration_ms=$(( ($(date +%s) - _ao_start_s) * 1000 ))
568
+ _ao_ok=true; [[ $exit_code -ne 0 ]] && _ao_ok=false
569
+
570
+ if [[ $exit_code -eq 0 ]]; then
571
+ output="$(cat "$tmpout")"
572
+ pr_url="$(echo "$output" | grep -Eo 'https?://[^/]+/[^/]+/[^/]+/pull/[0-9]+' | head -1)"
573
+ report_state="pr_created"
574
+ report_draft="false"
575
+ for arg in "$@"; do
576
+ if [[ "$arg" == "--draft" || "$arg" == "-d" ]]; then
577
+ report_state="draft_pr_created"
578
+ report_draft="true"
579
+ break
580
+ fi
581
+ done
582
+ if [[ -n "$pr_url" ]]; then
583
+ update_ao_metadata pr "$pr_url"
584
+ update_ao_metadata agentReportedPrUrl "$pr_url"
585
+ # Append to prs field (comma-separated list of all PR URLs for this session).
586
+ # Supports multiple PRs per session — same repo or different repos.
587
+ _ao_meta_f="\${AO_DATA_DIR}/\${AO_SESSION}.json"
588
+ [[ -f "$_ao_meta_f" ]] || _ao_meta_f="\${AO_DATA_DIR}/\${AO_SESSION}"
589
+ if head -c1 "$_ao_meta_f" 2>/dev/null | grep -q '{'; then
590
+ existing_prs="$(jq -r '.prs // empty' "$_ao_meta_f" 2>/dev/null || echo "")"
591
+ else
592
+ existing_prs="$(grep '^prs=' "$_ao_meta_f" 2>/dev/null | cut -d'=' -f2- || echo "")"
593
+ fi
594
+ if [[ -z "$existing_prs" ]]; then
595
+ new_prs="$pr_url"
596
+ else
597
+ if ! echo ",$existing_prs," | grep -qF ",$pr_url,"; then
598
+ new_prs="$existing_prs,$pr_url"
599
+ else
600
+ new_prs="$existing_prs"
601
+ fi
602
+ fi
603
+ update_ao_metadata prs "$new_prs"
604
+ fi
605
+ pr_number="$(printf '%s' "$pr_url" | grep -Eo '[0-9]+$' | head -1)"
606
+ if [[ -n "$pr_number" ]]; then
607
+ update_ao_metadata agentReportedPrNumber "$pr_number"
608
+ fi
609
+ update_ao_metadata agentReportedState "$report_state"
610
+ update_ao_metadata agentReportedAt "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
611
+ update_ao_metadata agentReportedPrIsDraft "$report_draft"
612
+ fi
613
+
614
+ log_ao_cache "passthrough" "" "$_ao_duration_ms" "$exit_code" "$_ao_ok"
615
+ exit $exit_code
616
+ ;;
617
+ *)
618
+ _ao_start_s=$(date +%s)
619
+ "$real_gh" "$@"
620
+ _ao_exit=$?
621
+ _ao_duration_ms=$(( ($(date +%s) - _ao_start_s) * 1000 ))
622
+ _ao_ok=true; [[ $_ao_exit -ne 0 ]] && _ao_ok=false
623
+ log_ao_cache "passthrough" "" "$_ao_duration_ms" "$_ao_exit" "$_ao_ok"
624
+ exit $_ao_exit
625
+ ;;
626
+ esac
627
+ `,c2=`#!/usr/bin/env bash
628
+ # ao git wrapper — auto-updates session metadata on branch operations
629
+
630
+ # Find real git by removing our wrapper directory from PATH
631
+ ao_bin_dir="$(cd "$(dirname "$0")" && pwd)"
632
+ clean_path="$(echo "$PATH" | tr ':' '\\n' | grep -Fxv "$ao_bin_dir" | grep . | tr '\\n' ':')"
633
+ clean_path="\${clean_path%:}"
634
+ real_git="$(PATH="$clean_path" command -v git 2>/dev/null)"
635
+
636
+ if [[ -z "$real_git" ]]; then
637
+ echo "ao-wrapper: git not found in PATH" >&2
638
+ exit 127
639
+ fi
640
+
641
+ # Source the metadata helper
642
+ source "$ao_bin_dir/ao-metadata-helper.sh" 2>/dev/null || true
643
+
644
+ # Run real git
645
+ "$real_git" "$@"
646
+ exit_code=$?
647
+
648
+ # Only update metadata on success
649
+ if [[ $exit_code -eq 0 ]]; then
650
+ case "$1/$2" in
651
+ checkout/-b)
652
+ update_ao_metadata branch "$3"
653
+ ;;
654
+ switch/-c)
655
+ update_ao_metadata branch "$3"
656
+ ;;
657
+ checkout/*|switch/*)
658
+ # Existing branch switch — only track feature-looking branches (contain / or -)
659
+ # Skip flags (e.g. -B), HEAD, tags, commit hashes, and simple names like "main"
660
+ branch="$2"
661
+ # If $2 is a flag, the actual branch name is in $3
662
+ if [[ "$branch" == -* ]]; then branch="$3"; fi
663
+ if [[ -n "$branch" && "$branch" != "HEAD" && "$branch" != -* && "$branch" == *[/-]* ]]; then
664
+ update_ao_metadata branch "$branch"
665
+ fi
666
+ ;;
667
+ esac
668
+ fi
669
+
670
+ exit $exit_code
671
+ `,c3=`\
672
+ // ---------------------------------------------------------------------------
673
+ // Metadata update (shared by gh/git wrappers)
674
+ // ---------------------------------------------------------------------------
675
+ function updateAoMetadata(key, value) {
676
+ const aoDir = process.env["AO_DATA_DIR"] || "";
677
+ const aoSession = process.env["AO_SESSION"] || "";
678
+ if (!aoDir || !aoSession) return;
679
+
680
+ // Validate session — no path separators or traversal
681
+ if (aoSession.includes("/") || aoSession.includes("\\\\") || aoSession.includes("..")) return;
682
+
683
+ // Validate key
684
+ if (!/^[a-zA-Z0-9_-]+$/.test(key)) return;
685
+
686
+ // Validate aoDir is under expected locations (mirrors bash ao-metadata-helper.sh)
687
+ const os = require("os");
688
+ const home = os.homedir();
689
+ const sep = path.sep;
690
+ let resolvedDir;
691
+ try { resolvedDir = fs.realpathSync(aoDir); } catch { resolvedDir = path.resolve(aoDir); }
692
+ const allowed = [path.join(home, ".ao"), path.join(home, ".agent-orchestrator"), os.tmpdir()];
693
+ if (!allowed.some(a => resolvedDir === a || resolvedDir.startsWith(a + sep))) return;
694
+
695
+ // Try V2 (.json) first, then fall back to V1 (bare) — mirrors bash ao-metadata-helper.sh
696
+ let metadataFile = path.join(resolvedDir, aoSession + ".json");
697
+ if (!fs.existsSync(metadataFile)) {
698
+ metadataFile = path.join(resolvedDir, aoSession);
699
+ }
700
+ if (!fs.existsSync(metadataFile)) return;
701
+
702
+ // Strip newlines from value
703
+ const cleanValue = String(value).replace(/[\\r\\n]/g, "");
704
+
705
+ let content;
706
+ try { content = fs.readFileSync(metadataFile, "utf8"); } catch { return; }
707
+
708
+ const tmpFile = metadataFile + ".tmp." + process.pid;
709
+ try {
710
+ if (metadataFile.endsWith(".json")) {
711
+ // V2 JSON format
712
+ let d;
713
+ try { d = JSON.parse(content); } catch { return; }
714
+ d[key] = cleanValue;
715
+ fs.writeFileSync(tmpFile, JSON.stringify(d, null, 2), "utf8");
716
+ } else {
717
+ // V1 key=value format
718
+ const lines = content.split("\\n");
719
+ const keyPrefix = key + "=";
720
+ const idx = lines.findIndex(l => l.startsWith(keyPrefix));
721
+ if (idx >= 0) {
722
+ lines[idx] = key + "=" + cleanValue;
723
+ } else {
724
+ lines.push(key + "=" + cleanValue);
725
+ }
726
+ fs.writeFileSync(tmpFile, lines.join("\\n"), "utf8");
727
+ }
728
+ fs.renameSync(tmpFile, metadataFile);
729
+ } catch {
730
+ try { fs.unlinkSync(tmpFile); } catch {}
731
+ }
732
+ }`,c4=`
733
+ ## Athene (ao) Session
734
+
735
+ You are running inside an Athene managed workspace.
736
+ Session metadata is updated automatically via shell wrappers.
737
+
738
+ If automatic updates fail, you can manually update metadata:
739
+ \`\`\`bash
740
+ ~/.ao/bin/ao-metadata-helper.sh # sourced automatically
741
+ # Then call: update_ao_metadata <key> <value>
742
+ \`\`\`
743
+ `;async function c5(a,b,c){let d=(0,f.randomBytes)(6).toString("hex"),e=`${a}.tmp.${d}`;await (0,bG.writeFile)(e,b,{encoding:"utf-8",mode:c}),await (0,bG.rename)(e,a)}async function c6(a){await (0,bG.mkdir)(cZ(),{recursive:!0});let b=(0,g.join)(cZ(),".ao-version"),c=!0;try{(await (0,bG.readFile)(b,"utf-8")).trim()===c$&&(c=!1)}catch{}if(c){if(w())for(let a of["gh","git"]){let b=(0,g.join)(cZ(),a),c="gh"===a?`#!/usr/bin/env node
744
+ // ao gh wrapper (Windows Node.js) — auto-updates session metadata on PR operations
745
+ "use strict";
746
+ const { spawnSync } = require("child_process");
747
+ const fs = require("fs");
748
+ const path = require("path");
749
+
750
+ // ---------------------------------------------------------------------------
751
+ // Real binary resolution
752
+ // ---------------------------------------------------------------------------
753
+ const AO_BIN_DIR = path.dirname(__filename);
754
+
755
+ function findRealGh() {
756
+ const explicit = process.env["GH_PATH"] || "";
757
+ if (explicit) {
758
+ try {
759
+ const resolved = path.resolve(explicit);
760
+ const dir = path.dirname(resolved);
761
+ if (dir !== AO_BIN_DIR && fs.existsSync(resolved)) return resolved;
762
+ } catch {}
763
+ }
764
+
765
+ // Walk PATH, skip wrapper directory
766
+ const pathDirs = (process.env["PATH"] || "").split(path.delimiter);
767
+ for (const dir of pathDirs) {
768
+ if (!dir || path.resolve(dir) === AO_BIN_DIR) continue;
769
+ // Windows executables always have an extension (.exe/.cmd). Skip the bare
770
+ // no-extension case — on Windows X_OK is identical to F_OK (execute bit
771
+ // doesn't exist), so a bare text file named "gh" would otherwise be
772
+ // selected before gh.exe.
773
+ for (const ext of [".exe", ".cmd"]) {
774
+ const candidate = path.join(dir, "gh" + ext);
775
+ try {
776
+ fs.accessSync(candidate, fs.constants.F_OK);
777
+ return candidate;
778
+ } catch {}
779
+ }
780
+ }
781
+ return null;
782
+ }
783
+
784
+ ${c3}
785
+
786
+ // ---------------------------------------------------------------------------
787
+ // Main
788
+ // ---------------------------------------------------------------------------
789
+ const realGh = findRealGh();
790
+ if (!realGh) {
791
+ process.stderr.write("ao-wrapper: gh not found in PATH\\n");
792
+ process.exit(127);
793
+ }
794
+
795
+ const args = process.argv.slice(2);
796
+ const sub1 = args[0] || "";
797
+ const sub2 = args[1] || "";
798
+ const key = sub1 + "/" + sub2;
799
+
800
+ if (key === "pr/create" || key === "pr/merge") {
801
+ const result = spawnSync(realGh, args, {
802
+ stdio: ["inherit", "pipe", "pipe"],
803
+ encoding: "utf8",
804
+ });
805
+
806
+ if (result.stdout) process.stdout.write(result.stdout);
807
+ if (result.stderr) process.stderr.write(result.stderr);
808
+
809
+ if (result.status === 0) {
810
+ const output = (result.stdout || "") + (result.stderr || "");
811
+ if (key === "pr/create") {
812
+ const match = output.match(/https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/pull\\/[0-9]+/);
813
+ if (match) {
814
+ const prUrl = match[0];
815
+ updateAoMetadata("pr", prUrl);
816
+ updateAoMetadata("status", "pr_open");
817
+ // Append to prs field — supports multiple PRs per session
818
+ let existingPrs = "";
819
+ try {
820
+ const aoDir = process.env["AO_DATA_DIR"] || "";
821
+ const aoSession = process.env["AO_SESSION"] || "";
822
+ if (aoDir && aoSession && /^[a-zA-Z0-9_-]+$/.test(aoSession)) {
823
+ let metaFile = path.join(aoDir, aoSession + ".json");
824
+ if (!fs.existsSync(metaFile)) metaFile = path.join(aoDir, aoSession);
825
+ if (fs.existsSync(metaFile)) {
826
+ const raw = fs.readFileSync(metaFile, "utf8");
827
+ if (metaFile.endsWith(".json")) {
828
+ existingPrs = JSON.parse(raw).prs || "";
829
+ } else {
830
+ const line = raw.split("\\n").find(l => l.startsWith("prs="));
831
+ existingPrs = line ? line.slice(4) : "";
832
+ }
833
+ }
834
+ }
835
+ } catch {}
836
+ const newPrs = existingPrs
837
+ ? existingPrs.split(",").map((u) => u.trim()).includes(prUrl)
838
+ ? existingPrs
839
+ : existingPrs + "," + prUrl
840
+ : prUrl;
841
+ updateAoMetadata("prs", newPrs);
842
+ }
843
+ } else if (key === "pr/merge") {
844
+ updateAoMetadata("status", "merged");
845
+ }
846
+ }
847
+
848
+ process.exit(result.status ?? 1);
849
+ } else {
850
+ const result = spawnSync(realGh, args, { stdio: "inherit" });
851
+ process.exit(result.status ?? 1);
852
+ }
853
+ `:`#!/usr/bin/env node
854
+ // ao git wrapper (Windows Node.js) — auto-updates session metadata on branch operations
855
+ "use strict";
856
+ const { spawnSync } = require("child_process");
857
+ const fs = require("fs");
858
+ const path = require("path");
859
+
860
+ // ---------------------------------------------------------------------------
861
+ // Real binary resolution
862
+ // ---------------------------------------------------------------------------
863
+ const AO_BIN_DIR = path.dirname(__filename);
864
+
865
+ function findRealGit() {
866
+ const pathDirs = (process.env["PATH"] || "").split(path.delimiter);
867
+ for (const dir of pathDirs) {
868
+ if (!dir || path.resolve(dir) === AO_BIN_DIR) continue;
869
+ // Windows executables always have an extension (.exe/.cmd). Skip the bare
870
+ // no-extension case — on Windows X_OK is identical to F_OK (execute bit
871
+ // doesn't exist), so a bare text file named "git" would otherwise be
872
+ // selected before git.exe.
873
+ for (const ext of [".exe", ".cmd"]) {
874
+ const candidate = path.join(dir, "git" + ext);
875
+ try {
876
+ fs.accessSync(candidate, fs.constants.F_OK);
877
+ return candidate;
878
+ } catch {}
879
+ }
880
+ }
881
+ return null;
882
+ }
883
+
884
+ ${c3}
885
+
886
+ // ---------------------------------------------------------------------------
887
+ // Main
888
+ // ---------------------------------------------------------------------------
889
+ const realGit = findRealGit();
890
+ if (!realGit) {
891
+ process.stderr.write("ao-wrapper: git not found in PATH\\n");
892
+ process.exit(127);
893
+ }
894
+
895
+ const args = process.argv.slice(2);
896
+ const result = spawnSync(realGit, args, { stdio: "inherit" });
897
+ const exitCode = result.status ?? 1;
898
+
899
+ if (exitCode === 0) {
900
+ const sub1 = args[0] || "";
901
+ const sub2 = args[1] || "";
902
+ const key = sub1 + "/" + sub2;
903
+
904
+ if (key === "checkout/-b" || key === "switch/-c") {
905
+ const branch = args[2];
906
+ if (branch) updateAoMetadata("branch", branch);
907
+ } else if (sub1 === "checkout" || sub1 === "switch") {
908
+ // Existing branch switch — only track feature-looking branches (contain / or -)
909
+ let branch = sub2;
910
+ // If sub2 is a flag, the actual branch name is in args[2]
911
+ if (branch && branch.startsWith("-")) branch = args[2] || "";
912
+ if (
913
+ branch &&
914
+ branch !== "HEAD" &&
915
+ !branch.startsWith("-") &&
916
+ (branch.includes("/") || branch.includes("-"))
917
+ ) {
918
+ updateAoMetadata("branch", branch);
919
+ }
920
+ }
921
+ }
922
+
923
+ process.exit(exitCode);
924
+ `;await c5(b+".cjs",c,420),await c5(b+".cmd",`@node "%~dp0${a}.cjs" %*\r
925
+ `,420)}else await c5((0,g.join)(cZ(),"ao-metadata-helper.sh"),c0,493),await c5((0,g.join)(cZ(),"gh"),c1,493),await c5((0,g.join)(cZ(),"git"),c2,493);await c5(b,c$,420)}let d=(0,g.join)(a,".ao","AGENTS.md");await (0,bG.mkdir)((0,g.join)(a,".ao"),{recursive:!0});let e=w()?`## Athene (ao) Session
926
+
927
+ You are running inside an Athene managed workspace.
928
+ Session metadata is updated automatically via shell wrappers.
929
+ `:c4.trimStart();await (0,bG.writeFile)(d,e,"utf-8")}let c7=(0,u.promisify)(t.execFile),c8=/^(prEnrichment|prReviewComments)_\d+$/,c9="win32"===process.platform?{shell:!0,windowsHide:!0}:{};async function da(a){let b,c=cE(a);if(c){for(let a of[0,200,600]){a>0&&await new Promise(b=>setTimeout(b,a));try{await c7("opencode",["session","delete",c],{timeout:3e4,...c9,env:cI()}),cL();return}catch(a){if(function(a){if(!(a instanceof Error))return!1;let b=[a.message,a.stderr,a.stdout].filter(Boolean).join("\n");return/session not found/i.test(b)}(a))return void cL();b=a}}throw b instanceof Error?b:Error(String(b))}}async function db(a=1e4){return cK({timeoutMs:a})}async function dc(a,b=1e4,c){let d=await (c??db(b)),e=`AO:${a}`;return d.filter(a=>a.title===e).sort((a,b)=>{let c=a.updatedAt??-1/0,d=b.updatedAt??-1/0;return c===d?0:d-c}).map(a=>a.id)}async function dd(a,b,c){return(await dc(a,b,c))[0]}function de(a){return a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}let df=new Set(["pr_open","ci_failed","review_pending","changes_requested","approved","mergeable"]),dg=new Set([...df,"merged"]);function dh(a){let b=a=>{let b=a.replace(/\s+/g," ").trim(),c=Array.from(b);return c.length<=80?b:`${c.slice(0,79).join("").trimEnd()}…`};if(a.issueTitle&&a.issueTitle.trim())return b(a.issueTitle);if(a.prompt&&a.prompt.trim()){let c=(a.prompt.split(/\r?\n/).map(a=>a.trim()).find(a=>a.length>0)??"").replace(/^#{1,6}\s+/,"");if(c)return b(c)}}function di(a){return new Promise(b=>setTimeout(b,a))}async function dj(a,b){try{return await a.isProcessRunning(b)!==!1}catch{return!0}}function dk(a,b){return a instanceof Error&&a.message.includes(`Orchestrator session "${b}" already exists`)}async function dl(a){try{let{stdout:b}=await c7("tmux",["display-message","-p","-t",a,"#{pane_current_command}"],{timeout:5e3,windowsHide:!0}),c=b.trim();return c.length>0?c:null}catch{return null}}function dm(a){let b=a.lifecycle??a.statePayload;if(b)try{return JSON.parse(b)}catch{return}}function dn(a,b,c){let d="orchestrator"===b.role||c.sessionPrefix&&RegExp(`^${de(c.sessionPrefix)}-orchestrator-\\d+$`).test(a)?"orchestrator":"worker";return function(a,b,c={}){let d=void 0!==c.runtimeHandle?c.runtimeHandle:b.runtimeHandle?a2(b.runtimeHandle):null,e=bc(b,{sessionId:a,status:c.status??a3(b.status),runtimeHandle:d,createdAt:c.createdAt,sessionKind:c.sessionKind}),f=c.status??bd(e),g=e.pr.url??b.pr,h="true"===b[bI.PR_IS_DRAFT],i=(a,c=!1,d)=>{let e=a$(a);return{number:e?.number||d||0,url:a,title:"",owner:e?.owner??"",repo:e?.repo??"",branch:b.branch??"",baseBranch:"",isDraft:c}},j=b.prs,k=e.pr.number??null,l=a_(j?j.split(",").map((a,b)=>i(a.trim(),0===b&&h,0===b?k:null)).filter(a=>!!a.url):g?[i(g,h,k)]:[]);return{id:a,projectId:b.project??c.projectId??"",status:f,activity:c.activity??null,activitySignal:c.activitySignal?c.activitySignal:void 0===c.activity||null===c.activity?bC("unavailable"):bC("valid",{activity:c.activity,timestamp:c.lastActivityAt,source:"exited"===c.activity?"runtime":"native"}),lifecycle:e,branch:b.branch||null,issueId:b.issue||null,pr:l[0]??null,prs:l,workspacePath:b.worktree||c.workspacePathFallback||null,runtimeHandle:e.runtime.handle??d,agentInfo:b.summary?{summary:b.summary,agentSessionId:null}:null,createdAt:b.createdAt?new Date(b.createdAt):c.createdAt??new Date,lastActivityAt:c.lastActivityAt??new Date,restoredAt:c.restoredAt??(b.restoredAt?new Date(b.restoredAt):void 0),metadata:b}}(a,b,{projectId:c.projectId,workspacePathFallback:c.workspacePathFallback,sessionKind:d,createdAt:c.createdAt,lastActivityAt:c.modifiedAt??new Date})}function dp(a){let{config:b,registry:c}=a;function f(a){return(0,g.resolve)(a).replace(/[/\\]$/,"")}function i(a,b,c){return!!a&&!!b&&f(c)!==f(a.path)&&(function(a,b){let c=[p(a)],d=new Set;for(let e of(d.add(a),d.add((0,g.basename)(b)),d))c.push((0,g.join)((0,h.homedir)(),".worktrees",e));return c})(b,a.path).some(a=>(function(a,b){let c=f(a),d=f(b),e="win32"===process.platform?"\\":"/";return c===d||c.startsWith(`${d}${e}`)})(c,a))}function j(a,b,c){return!!b&&("orchestrator"===b.role||!!c&&(a===`${c}-orchestrator`||RegExp(`^${de(c)}-orchestrator-\\d+$`).test(a)))}function k(a,b,c){return b===`${a.sessionPrefix}-orchestrator`||j(b,c??{},a.sessionPrefix)}function l(a,b){let c={...a};for(let[a,d]of Object.entries(b))if(void 0!==d){if(""===d){let{[a]:b,...d}=c;c=d;continue}c[a]=d}return c}function m(a,b,c){let d=bf(bc(b,{sessionId:a,status:a3(b.status)}));return c(d),a8(d),d}function q(a,b,c,d){let f=(0,g.join)(a,`${b}.json`),h=d;if(!h)try{h=(0,e.statSync)(f).mtime}catch{h=void 0}if(bq(a,b,c),h)try{(0,e.utimesSync)(f,h,h)}catch{}}let r=null,s=new Map,t=new Map;function u(){r=null}function v(a,b,c){if(b.raw.agent)return b;let d=D(c,b.sessionName,b.raw).agentName;return q(a,b.sessionName,{agent:d},b.modifiedAt),{...b,raw:l(b.raw,{agent:d})}}function w(a,b,c){let d={...b,raw:{...b.raw}};if(!j(d.sessionName,d.raw,c))return d;let e={};if("orchestrator"!==d.raw.role&&(e.role="orchestrator"),d.raw.pr&&(e.pr=""),"off"!==d.raw.prAutoDetect&&"false"!==d.raw.prAutoDetect&&(e.prAutoDetect="false"),dg.has(d.raw.status??"")&&(e.status="working"),Object.keys(e).length>0){let b=m(d.sessionName,d.raw,a=>{a.session.kind="orchestrator",a.pr.state="none",a.pr.reason="not_created",a.pr.number=null,a.pr.url=null,a.pr.lastObservedAt=null,"working"===e.status&&(a.session.state="working",a.session.reason="task_in_progress")});q(a,d.sessionName,{...e,...(d.raw,be(b))},d.modifiedAt),d.raw=l(d.raw,{...e,...(d.raw,be(b))})}return d}function x(a){let b=Date.parse(a.raw.restoredAt??a.raw.createdAt??"");return a.modifiedAt?a.modifiedAt.getTime():Number.isNaN(b)?0:b}function y(a,b){let c=o(a);if(!(0,e.existsSync)(c))return[];let d=bu(c).flatMap(a=>{let b,d=bn(c,a);if(!d)return[];try{b=(0,e.statSync)((0,g.join)(c,`${a}.json`)).mtime}catch{}return[{sessionName:a,raw:d,modifiedAt:b}]});return function(a,b,c){let d=b.map(a=>({...a,raw:{...a.raw}})),e=new Map;for(let b of d){if(!b.raw.lifecycle&&(!b.raw.statePayload||"2"!==b.raw.stateVersion)){let d=bf(bc(b.raw,{sessionId:b.sessionName,status:a3(b.raw.status),createdAt:b.raw.createdAt?new Date(b.raw.createdAt):void 0,sessionKind:j(b.sessionName,b.raw,c.sessionPrefix)?"orchestrator":"worker"})),e=(b.raw,be(d));q(a,b.sessionName,e,b.modifiedAt),b.raw=l(b.raw,e)}if(j(b.sessionName,b.raw,c.sessionPrefix)){b.raw=w(a,b,c.sessionPrefix).raw,b.raw=v(a,b,c).raw;continue}b.raw=v(a,b,c).raw;let d=b.raw.pr;if(!d)continue;let f=e.get(d)??[];f.push(b),e.set(d,f)}for(let b of e.values()){if(b.length<2)continue;let[c,...d]=[...b].sort((a,b)=>{let c=Number(df.has(b.raw.status??""))-Number(df.has(a.raw.status??""));if(0!==c)return c;let d=x(b)-x(a);return 0!==d?d:b.sessionName.localeCompare(a.sessionName)});for(let b of d){let c={pr:"",prAutoDetect:"false",...df.has(b.raw.status??"")?{status:"working"}:{}},d=m(b.sessionName,b.raw,a=>{a.pr.state="none",a.pr.reason="not_created",a.pr.number=null,a.pr.url=null,a.pr.lastObservedAt=null,"working"===c.status&&(a.session.state="working",a.session.reason="task_in_progress")}),e=(b.raw,be(d));q(a,b.sessionName,{...c,...e},b.modifiedAt),b.raw=l(b.raw,{...c,...e})}}return d}(c,d,b)}async function z(a){let{sessionsDir:b,criteria:c,strategy:d,includeTitleDiscoveryForSessionId:e=!1}=a;if("ignore"===d)return;let f=function(a,b){let c=[],d=(a,d)=>{if(!d||"opencode"!==d.agent||void 0!==b.issueId&&d.issue!==b.issueId||void 0!==b.sessionId&&a!==b.sessionId)return;let e=cE(d?.opencodeSessionId);e&&c.push(e)};for(let b of function(a){let b=a=>{let b=a.match(/-(\d+)$/);if(!b)return;let c=Number.parseInt(b[1],10);return Number.isNaN(c)?void 0:c};return[...a].sort((a,c)=>{let d=b(a),e=b(c);return void 0!==d&&void 0!==e&&d!==e?e-d:void 0!==d&&void 0===e?-1:void 0===d&&void 0!==e?1:c.localeCompare(a)})}(bu(a)))d(b,bn(a,b));return[...new Set(c)]}(b,c);if("delete"===d){for(let a of(e&&c.sessionId&&(f=[...f,...await dc(c.sessionId)]),[...new Set(f)]))await da(a);return}return 0===f.length&&c.sessionId&&(f=await dc(c.sessionId)),f[0]}async function A(a){try{let{stdout:b}=await c7("git",["ls-remote","--heads","origin",`session/${a.sessionPrefix}-*`],{cwd:a.path,timeout:5e3,...c9});return b.split("\n").flatMap(b=>{let c=b.trim();if(!c)return[];let d=(c.split(/\s+/)[1]??"").match(RegExp(`refs/heads/session/${de(a.sessionPrefix)}-(\\d+)$`));if(!d)return[];let e=Number.parseInt(d[1],10);return Number.isNaN(e)?[]:[e]}).filter((a,b,c)=>c.indexOf(a)===b)}catch{return[]}}async function B(a,b){let c=new Set;for(let d of bu(b)){let b=function(a,b){let c=a.match(RegExp(`^${de(b)}-(\\d+)$`));if(!c)return;let d=Number.parseInt(c[1],10);return Number.isNaN(d)?void 0:d}(d,a.sessionPrefix);void 0!==b&&c.add(b)}for(let b of(await A(a)))c.add(b);let d=function(a,b){let c=0,d=RegExp(`^${de(b)}-(\\d+)$`);for(let b of a){let a=b.match(d);if(a){let b=parseInt(a[1],10);b>c&&(c=b)}}return c+1}([...c].map(b=>`${a.sessionPrefix}-${b}`),a.sessionPrefix);for(let g=0;g<1e4;g++){var e,f;let g=`${a.sessionPrefix}-${d}`,h=a.path?(e=a.sessionPrefix,f=d,`${e}-${f}`):void 0;if(!c.has(d)&&bv(b,g))return{num:d,sessionId:g,tmuxName:h};c.add(d),d+=1}throw Error(`Failed to reserve session ID after 10000 attempts (prefix: ${a.sessionPrefix})`)}function C(a,d){let e=c.get("runtime",a.runtime??b.defaults.runtime),f=c.get("agent",d??a.agent??b.defaults.agent),g=c.get("workspace",a.workspace??b.defaults.workspace);return{runtime:e,agent:f,workspace:g,tracker:a.tracker?.plugin?c.get("tracker",a.tracker.plugin):null,scm:a.scm?.plugin?c.get("scm",a.scm.plugin):null}}function D(a,c,d){var e;return bx({role:bw((e={sessionId:c,metadata:d,project:a,defaults:b.defaults,allSessionPrefixes:Object.values(b.projects).map(a=>a.sessionPrefix)}).sessionId,e.metadata,e.project.sessionPrefix,e.allSessionPrefixes),project:e.project,defaults:e.defaults,persistedAgent:e.metadata?.agent})}async function E(a,b,c,d,e){if("opencode"!==d||cE(a.metadata.opencodeSessionId))return;let f=await dd(b,1e4,e);f&&(a.metadata.opencodeSessionId=f,bq(c,b,{opencodeSessionId:f}))}function F(a){for(let[c,d]of Object.entries(b.projects)){let b,f=o(c),h=bn(f,a);if(h){try{b=(0,e.statSync)((0,g.join)(f,`${a}.json`)).mtime}catch{b=void 0}return{raw:v(f,w(f,{sessionName:a,raw:h,modifiedAt:b},d.sessionPrefix),d).raw,sessionsDir:f,project:d,projectId:c}}}return null}function G(a){let b=F(a);if(!b)throw new d.Ag(a);return b}async function H(a,c,d,e,f,g,h){await E(a,c,d,f,h);let i=a.metadata.tmuxName?.trim(),j="string"==typeof i&&i.length>0,k=null!==a.runtimeHandle||j;k?!a.runtimeHandle&&j&&(a.runtimeHandle={id:i,runtimeName:e.runtime??b.defaults.runtime,data:{}}):a.runtimeHandle={id:c,runtimeName:e.runtime??b.defaults.runtime,data:{}},await J(a,g,k,d)}!function(){let a=!1;for(let[c]of Object.entries(b.projects)){let b=o(c);if((0,e.existsSync)(b))for(let d of bu(b)){let e=bn(b,d);if(!e)continue;let f=e.prs?e.prs.split(",").map(a=>a.trim()).filter(Boolean):[],g=a0(f),h={};f.length!==g.length&&(h.prs=g.join(","));let i=0;for(let a of Object.keys(e))c8.test(a)&&(h[a]="",i+=1);0!==Object.keys(h).length&&(bq(b,d,h),a=!0,S({projectId:c,sessionId:d,source:"session-manager",kind:"metadata.deduplicated",summary:`deduplicated PR metadata: ${d}`,data:{beforePrCount:f.length,afterPrCount:g.length,deletedIndexedKeyCount:i}}))}}a&&u()}();let I=new Set(["killed","done","merged","terminated","cleanup"]);async function J(a,c,d,e){async function f(b){let d;if(!c.agent||b?.skipIfNativeRestoreMetadataPresent&&function(a,b){let c=a.metadata??{};switch(b.name){case"claude-code":return"string"==typeof c.claudeSessionUuid&&c.claudeSessionUuid.trim().length>0;case"codex":return"string"==typeof c.codexThreadId&&c.codexThreadId.trim().length>0;case"opencode":return null!==cE(c.opencodeSessionId);default:return!1}}(a,c.agent))return;try{d=await c.agent.getSessionInfo(a)}catch{d=null}if(!d)return;a.agentInfo=d;let f=d.metadata??{};if(!Object.keys(f).every(b=>a.metadata?.[b]===f[b])&&Object.keys(f).length>0)try{bq(e,a.id,f),a.metadata=br(a.metadata,f),u()}catch{}}if(d&&a.runtimeHandle&&c.runtime&&"spawning"!==a.status)try{if(!await c.runtime.isAlive(a.runtimeHandle)){var g;a.lifecycle.runtime.state="missing",a.lifecycle.runtime.reason="tmux"===a.runtimeHandle.runtimeName?"tmux_missing":"process_missing",a.lifecycle.runtime.lastObservedAt=new Date().toISOString(),"done"!==a.lifecycle.session.state&&"terminated"!==a.lifecycle.session.state&&(a.lifecycle.session.state="detecting",a.lifecycle.session.reason="runtime_lost",a.lifecycle.session.lastTransitionAt=new Date().toISOString()),I.has(a.status)||(a.status="killed"),a.activity="exited",a.activitySignal=bC("valid",{activity:"exited",source:"runtime"}),c.agent&&(g=c.agent,"claude-code"===g.name||"codex"===g.name)&&await f({skipIfNativeRestoreMetadataPresent:!0});return}}catch{a.lifecycle.runtime.state="probe_failed",a.lifecycle.runtime.reason="probe_error",a.lifecycle.runtime.lastObservedAt=new Date().toISOString()}if(a.activitySignal=bC("unavailable"),c.agent){try{let d=await c.agent.getActivityState(a,b.readyThresholdMs);null!==d?(a.activitySignal=bD(d,"native"),a.activity=d.state,a.lifecycle.runtime.state="alive",a.lifecycle.runtime.reason="process_running",a.lifecycle.runtime.lastObservedAt=new Date().toISOString(),d.timestamp&&d.timestamp>a.lastActivityAt&&(a.lastActivityAt=d.timestamp)):a.activitySignal=bC("null",{source:"native"})}catch{a.activitySignal=bC("probe_failure",{source:"native"})}await f()}}async function K(a){let c,f,h=b.projects[a.projectId];if(!h)throw Error(`Unknown project: ${a.projectId}`);let j=bx({role:"worker",project:h,defaults:b.defaults,spawnAgentOverride:a.agent}),k=C(h,j.agentName);if(!k.runtime)throw Error(`Runtime plugin '${h.runtime??b.defaults.runtime}' not found`);if(!k.agent)throw Error(`Agent plugin '${j.agentName}' not found`);if(a.issueId&&k.tracker)try{c=await k.tracker.getIssue(a.issueId,h)}catch(b){if((0,d.Fx)(b));else throw S({projectId:a.projectId,source:"session-manager",kind:"tracker.issue_fetch_failed",level:"error",summary:`tracker getIssue failed for ${a.issueId}`,data:{issueId:a.issueId,tracker:k.tracker.name,reason:b instanceof Error?b.message:String(b)}}),Error(`Failed to fetch issue ${a.issueId}: ${b}`,{cause:b})}let l=o(a.projectId),m=new cQ;try{let d,o,q,r;({sessionId:f,tmuxName:d}=await B(h,l));let s=f;if(m.push(()=>bt(l,s)),a.branch)o=a.branch;else if(a.issueId&&k.tracker&&c){let b=c.branchName;o=b&&function(a){if(!a||"@"===a||a.startsWith(".")||a.endsWith(".")||a.endsWith("/")||a.endsWith(".lock")||a.includes("..")||a.includes("//")||a.includes("/.")||a.includes("@{")||a.startsWith("/"))return!1;for(let b=0;b<a.length;b++){let c=a.charCodeAt(b);if(c<=31||127===c)return!1}return!/[\s~^:?*[\\]/.test(a)}(b)?b:k.tracker.branchName(a.issueId,h)}else if(a.issueId){let b=a.issueId,c=/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(b)&&!b.includes("..")?b:b.toLowerCase().replace(/[^a-z0-9]+/g,"-").slice(0,60).replace(/^-+|-+$/g,"");o=`feat/${c||f}`}else o=`session/${f}`;let t=h.path;if(k.workspace){let b=await k.workspace.create({projectId:a.projectId,project:h,sessionId:f,branch:o,worktreeDir:p(a.projectId)});if(t=b.path,i(h,a.projectId,t)){let a=k.workspace;m.push(()=>a.destroy(t))}k.workspace.postCreate&&await k.workspace.postCreate(b,h)}if(a.issueId&&k.tracker&&c)try{q=await k.tracker.generatePrompt(a.issueId,h)}catch(b){S({projectId:a.projectId,sessionId:f,source:"session-manager",kind:"tracker.generate_prompt_failed",level:"warn",summary:`tracker generatePrompt failed for ${a.issueId}`,data:{issueId:a.issueId,tracker:k.tracker.name,reason:b instanceof Error?b.message:String(b)}})}let v=`${h.sessionPrefix}-orchestrator`,w=null!==bn(l,v),{systemPrompt:x,taskPrompt:y}=function(a){let b=function(a){let b=[];if(a.agentRules&&b.push(a.agentRules),a.agentRulesFile){let c=(0,g.resolve)(a.path,a.agentRulesFile);try{let a=(0,e.readFileSync)(c,"utf-8").trim();a&&b.push(a)}catch{}}return b.length>0?b.join("\n\n"):null}(a.project),c=[];return c.push(a.project.repo?cB:cC),a.orchestratorSessionId&&c.push(`## Talking to the Orchestrator
930
+ You can message the orchestrator session that spawned you with:
931
+
932
+ \`athene send ${a.orchestratorSessionId} "<your message>"\`
933
+
934
+ Only do this when you genuinely cannot proceed alone — cross-session coordination, a decision only the human-facing orchestrator can make, or a blocker outside your repo's scope. Do NOT ping for things you can resolve yourself (research, retries, normal CI/review fixes go through \`athene report\` and the existing flow). \`athene send\` automatically tags the message with your session ID, so the orchestrator always knows who's writing.`),c.push(function(a){let{project:b,projectId:c,issueId:d,issueContext:e}=a,f=[];if(f.push("## Project Context"),f.push(`- Project: ${b.name??c}`),b.repo&&f.push(`- Repository: ${b.repo}`),f.push(`- Default branch: ${b.defaultBranch}`),b.tracker&&f.push(`- Tracker: ${b.tracker.plugin}`),d){let a=d.replace(/^#/,"");f.push(`
935
+ ## Task`),f.push(`Work on issue #${a}`),f.push(`Create a branch named so that it auto-links to the issue tracker (e.g. feat/${a}).`)}if(e&&(f.push(`
936
+ ## Issue Details`),f.push(e)),b.reactions){let a=[];for(let[c,d]of Object.entries(b.reactions))d.auto&&"send-to-agent"===d.action&&a.push(`- ${c}: auto-handled (you'll receive instructions)`);a.length>0&&(f.push(`
937
+ ## Automated Reactions`),f.push("The orchestrator will automatically handle these events:"),f.push(...a))}return f.join("\n")}(a)),b&&c.push(`## Project Rules
938
+ ${b}`),{systemPrompt:c.join("\n\n"),taskPrompt:a.userPrompt?a.userPrompt:a.issueId?a.issueContext?`Work on issue #${a.issueId.replace(/^#/,"")}. The issue title, description, and labels are already in your system prompt — start implementing without re-fetching the issue. Fetch comments or linked issues only if you need additional context.`:`Work on issue #${a.issueId.replace(/^#/,"")}. Issue details were not pre-fetched — start by reading the issue (e.g. \`gh issue view ${a.issueId.replace(/^#/,"")}\`), then implement.`:void 0}}({project:h,projectId:a.projectId,issueId:a.issueId,issueContext:q,userPrompt:a.prompt,...w&&{orchestratorSessionId:v}}),A=n(a.projectId);(0,e.mkdirSync)(A,{recursive:!0});let C=(0,g.join)(A,`worker-prompt-${f}.md`);if((0,e.writeFileSync)(C,x,"utf-8"),m.push(()=>(0,e.unlinkSync)(C)),"opencode"===k.agent.name){let a=r=cP(A,f,[C]);m.push(()=>(0,e.unlinkSync)(a))}let D=h.opencodeIssueSessionStrategy??"reuse",E="opencode"===k.agent.name&&a.issueId?await z({sessionsDir:l,criteria:{issueId:a.issueId},strategy:D}):void 0,F={sessionId:f,projectConfig:{...h,agentConfig:{...j.agentConfig,...E?{opencodeSessionId:E}:{}}},workspacePath:t,issueId:a.issueId,prompt:y,systemPromptFile:C,permissions:j.permissions,model:j.model,subagent:a.subagent??j.subagent},G=k.agent.getLaunchCommand(F),H=k.agent.getEnvironment(F);k.agent.preLaunchSetup&&await k.agent.preLaunchSetup(t),k.agent.setupWorkspaceHooks&&await k.agent.setupWorkspaceHooks(t,{dataDir:l}),"claude-code"!==k.agent.name&&await c6(t);let I=await k.runtime.create({sessionId:d??f,workspacePath:t,launchCommand:G,environment:{...H,...r?{OPENCODE_CONFIG:r}:{},...h.env??{},PATH:c_(H.PATH??process.env.PATH),GH_PATH:cY,...process.env.AO_AGENT_GH_TRACE&&{AO_AGENT_GH_TRACE:process.env.AO_AGENT_GH_TRACE},AO_SESSION:f,AO_DATA_DIR:l,AO_SESSION_NAME:f,...d&&{AO_TMUX_NAME:d},AO_CALLER_TYPE:"agent",AO_PROJECT_ID:a.projectId,AO_CONFIG_PATH:b.configPath,...void 0!==b.port&&null!==b.port&&{AO_PORT:String(b.port)}}}),J=k.runtime;m.push(()=>J.destroy(I));let K=dh({issueTitle:c?.title,prompt:a.prompt}),L=new Date,M=ba("worker",L);M.runtime.handle=I,M.runtime.tmuxName=d??null;let N={id:f,projectId:a.projectId,status:bd(M),activity:"active",activitySignal:bC("valid",{activity:"active",timestamp:L,source:"runtime"}),lifecycle:M,branch:o,issueId:a.issueId??null,pr:null,prs:[],workspacePath:t,runtimeHandle:I,agentInfo:null,createdAt:L,lastActivityAt:L,metadata:{...E?{opencodeSessionId:E}:{},...a.prompt?{userPrompt:a.prompt}:{},...K?{displayName:K}:{}}};if(bp(l,f,{worktree:t,branch:o,status:bd(M),...be(M),lifecycle:M,tmuxName:d,issue:a.issueId,issueTitle:c?.title,project:a.projectId,agent:j.agentName,createdAt:L.toISOString(),runtimeHandle:I,opencodeSessionId:E,userPrompt:a.prompt,displayName:K}),k.agent.postLaunchSetup&&await k.agent.postLaunchSetup(N),"post-launch"===k.agent.promptDelivery&&F.prompt&&await k.runtime.sendMessage(I,F.prompt),"opencode"===k.agent.name&&"reuse"===D&&!N.metadata.opencodeSessionId){let a=await dd(f,1e4);a&&(N.metadata.opencodeSessionId=a)}return Object.keys(N.metadata||{}).length>0&&bq(l,f,N.metadata),u(),m.dismiss(),S({projectId:a.projectId,sessionId:f,source:"session-manager",kind:"session.spawned",summary:`spawned: ${f}`,data:{agent:k.agent.name,branch:N.branch??void 0}}),N}catch(b){throw S({projectId:a.projectId,sessionId:f,source:"session-manager",kind:"session.rollback_started",level:"warn",summary:"spawn rollback started",data:{reason:b instanceof Error?b.message:String(b)}}),await m.runAll(b=>{console.error("[session-manager] spawn rollback step failed:",b),S({projectId:a.projectId,sessionId:f,source:"session-manager",kind:"session.rollback_step_failed",level:"error",summary:"spawn rollback step failed",data:{reason:b instanceof Error?b.message:String(b)}})}),b}}function L(a,b,c){S({projectId:a.projectId,...c?{sessionId:c}:{},source:"session-manager",kind:"session.spawn_failed",level:"error",summary:"orchestrator spawn failed",data:{role:"orchestrator",reason:b instanceof Error?b.message:String(b)}})}async function M(a,c){S({projectId:a.projectId,source:"session-manager",kind:"session.spawn_started",summary:"orchestrator spawn started",data:{agent:a.agent??void 0,role:"orchestrator"}});try{return await N(a)}catch(f){let d=b.projects[a.projectId],e=d?cR(d):void 0;throw c?.suppressFixedReservationFailure===!0&&void 0!==e&&dk(f,e)||L(a,f,e),f}}async function N(a){let c,d,f,h,i=b.projects[a.projectId];if(!i)throw Error(`Unknown project: ${a.projectId}`);let j=bx({role:"orchestrator",project:i,defaults:b.defaults,spawnAgentOverride:a.agent}),k=C(i,j.agentName);if(!k.runtime)throw Error(`Runtime plugin '${i.runtime??b.defaults.runtime}' not found`);if(!k.agent)throw Error(`Agent plugin '${j.agentName}' not found`);let l=o(a.projectId),m=cS(i.orchestratorSessionStrategy),q=function(a,c){let d=cR(a);if(!bv(c,d))throw Error(`Orchestrator session "${d}" already exists. Use ensureOrchestrator() to reuse or restore it.`);return{sessionId:d,tmuxName:b.configPath?d:void 0}}(i,l),r=q.sessionId,s=q.tmuxName,t=`orchestrator/${r}`;if(!k.workspace){try{bt(l,r)}catch{}throw Error(`spawnOrchestrator requires a workspace plugin but none is configured for project '${a.projectId}'`)}let v={projectId:a.projectId,project:i,sessionId:r,branch:t,worktreeDir:p(a.projectId)},w=!1;try{let a=await k.workspace.findManagedWorkspace?.(v);c=(a??await k.workspace.create(v)).path,w=null!=a}catch(b){S({projectId:a.projectId,sessionId:r,source:"session-manager",kind:"session.spawn_step_failed",level:"error",summary:"orchestrator workspace.create failed",data:{role:"orchestrator",stage:"workspace_create",reason:b instanceof Error?b.message:String(b)}});try{bt(l,r)}catch{}throw b}let x=async a=>{if(!w)try{await k.workspace.destroy(c)}catch{}try{bt(l,r)}catch{}if(a)try{(0,e.unlinkSync)(a)}catch{}};try{k.agent.setupWorkspaceHooks&&await k.agent.setupWorkspaceHooks(c,{dataDir:l}),"claude-code"!==k.agent.name&&await c6(c)}catch(b){throw S({projectId:a.projectId,sessionId:r,source:"session-manager",kind:"session.workspace_hooks_failed",level:"error",summary:"orchestrator workspace hooks installation failed",data:{agent:k.agent.name,reason:b instanceof Error?b.message:String(b)}}),await x(),b}if(a.systemPrompt)try{let b=n(a.projectId);(0,e.mkdirSync)(b,{recursive:!0}),d=(0,g.join)(b,`orchestrator-prompt-${r}.md`),(0,e.writeFileSync)(d,a.systemPrompt,"utf-8")}catch(b){throw S({projectId:a.projectId,sessionId:r,source:"session-manager",kind:"session.spawn_step_failed",level:"error",summary:"orchestrator systemPrompt write failed",data:{role:"orchestrator",stage:"system_prompt_write",reason:b instanceof Error?b.message:String(b)}}),await x(d),b}if("opencode"===k.agent.name&&d)try{cO(c,d)}catch(b){throw S({projectId:a.projectId,sessionId:r,source:"session-manager",kind:"session.spawn_step_failed",level:"error",summary:"orchestrator AGENTS.md write failed",data:{role:"orchestrator",stage:"agents_md_write",reason:b instanceof Error?b.message:String(b)}}),await x(d),b}try{f="opencode"===k.agent.name&&"reuse"===m?await z({sessionsDir:l,criteria:{sessionId:r},strategy:"reuse"}):void 0,"opencode"===k.agent.name&&"delete"===m&&await z({sessionsDir:l,criteria:{sessionId:r},strategy:"delete",includeTitleDiscoveryForSessionId:!0})}catch(b){throw S({projectId:a.projectId,sessionId:r,source:"session-manager",kind:"session.spawn_step_failed",level:"error",summary:"orchestrator opencode session resolution failed",data:{role:"orchestrator",stage:"opencode_session_reuse",reason:b instanceof Error?b.message:String(b)}}),await x(d),b}let y={sessionId:r,projectConfig:{...i,agentConfig:{...j.agentConfig,permissions:"permissionless",...f?{opencodeSessionId:f}:{}}},workspacePath:c,permissions:"permissionless",model:j.model,systemPromptFile:d,subagent:j.subagent},A=k.agent.getLaunchCommand(y),B=k.agent.getEnvironment(y);k.agent.preLaunchSetup&&await k.agent.preLaunchSetup(c);try{h=await k.runtime.create({sessionId:s??r,workspacePath:c,launchCommand:A,environment:{...B,...i.env??{},PATH:c_(B.PATH??process.env.PATH),GH_PATH:cY,...process.env.AO_AGENT_GH_TRACE&&{AO_AGENT_GH_TRACE:process.env.AO_AGENT_GH_TRACE},AO_SESSION:r,AO_DATA_DIR:l,AO_SESSION_NAME:r,...s&&{AO_TMUX_NAME:s},AO_CALLER_TYPE:"orchestrator",AO_PROJECT_ID:a.projectId,AO_CONFIG_PATH:b.configPath,...void 0!==b.port&&null!==b.port&&{AO_PORT:String(b.port)}}})}catch(b){throw S({projectId:a.projectId,sessionId:r,source:"session-manager",kind:"session.spawn_step_failed",level:"error",summary:"orchestrator runtime.create failed",data:{role:"orchestrator",stage:"runtime_create",reason:b instanceof Error?b.message:String(b)}}),await x(d),b}let D=dh({prompt:a.systemPrompt}),E=new Date,F=ba("orchestrator",E);F.session.state="working",F.session.reason="task_in_progress",F.session.startedAt=E.toISOString(),F.session.lastTransitionAt=E.toISOString(),F.runtime.handle=h,F.runtime.tmuxName=s??null;let G={id:r,projectId:a.projectId,status:bd(F),activity:"active",activitySignal:bC("valid",{activity:"active",timestamp:E,source:"runtime"}),lifecycle:F,branch:t,issueId:null,pr:null,prs:[],workspacePath:c,runtimeHandle:h,agentInfo:null,createdAt:E,lastActivityAt:E,metadata:{...f?{opencodeSessionId:f}:{},...D?{displayName:D}:{}}};try{if(bp(l,r,{worktree:c,branch:t,status:bd(F),...be(F),lifecycle:F,role:"orchestrator",tmuxName:s,project:a.projectId,agent:j.agentName,createdAt:E.toISOString(),runtimeHandle:h,opencodeSessionId:f,displayName:D}),k.agent.postLaunchSetup&&await k.agent.postLaunchSetup(G),"post-launch"===k.agent.promptDelivery&&a.systemPrompt&&await k.runtime.sendMessage(h,"Begin."),"opencode"===k.agent.name&&"reuse"===m&&!G.metadata.opencodeSessionId){let a=await dd(r,1e4);a&&(G.metadata.opencodeSessionId=a)}Object.keys(G.metadata||{}).length>0&&bq(l,r,G.metadata),u()}catch(b){S({projectId:a.projectId,sessionId:r,source:"session-manager",kind:"session.spawn_step_failed",level:"error",summary:"orchestrator post-launch metadata write failed",data:{role:"orchestrator",stage:"post_launch_metadata",reason:b instanceof Error?b.message:String(b)}});try{await k.runtime.destroy(h)}catch{}throw await x(d),b}return S({projectId:a.projectId,sessionId:r,source:"session-manager",kind:"session.spawned",summary:`spawned: ${r}`,data:{agent:k.agent.name,branch:G.branch??void 0,role:"orchestrator"}}),G}async function O(a){let b=Date.now()+2e4;for(;Date.now()<b;){let b=await U(a);if(b?.metadata.role==="orchestrator")return b;await di(250)}return null}async function P(a){let c=b.projects[a.projectId];if(!c)throw Error(`Unknown project: ${a.projectId}`);let e=cR(c),f=t.get(e);f&&await f.catch(a=>{console.warn(`[ensureOrchestrator] in-flight relaunch for ${e} failed before ensure proceeded:`,a)});let g=await U(e);if(g){let b=cS(c.orchestratorSessionStrategy);if("delete"===b||"ignore"===b)return await V(e,{purgeOpenCode:"delete"===b}),bt(o(a.projectId),e),M(a);if("done"===g.lifecycle.session.state)throw new d.D8(e,`canonical orchestrator session is terminal with status "${g.status}". Remove or clean up this session before starting a new orchestrator.`);if((0,d.qX)(g))return Z(e);if(!(0,d.zi)(g))return g;throw new d.D8(e,`canonical orchestrator session is terminal with status "${g.status}". Remove or clean up this session before starting a new orchestrator.`)}try{return await M(a,{suppressFixedReservationFailure:!0})}catch(c){if(!dk(c,e))throw c;S({projectId:a.projectId,sessionId:e,source:"session-manager",kind:"session.orchestrator_conflict",level:"warn",summary:"concurrent orchestrator reservation conflict",data:{reason:c instanceof Error?c.message:String(c)}});let b=await O(e);if(b)return b;throw L(a,c,e),c}}async function Q(a){let c=b.projects[a.projectId];if(!c)throw Error(`Unknown project: ${a.projectId}`);let d=cR(c),e=o(a.projectId),f=s.get(d);if(f&&await f.catch(a=>{console.warn(`[relaunchOrchestrator] in-flight ensure for ${d} failed before relaunch proceeded:`,a)}),await U(d)){let a=D(c,d,bn(e,d)??{}).agentName;await V(d,{purgeOpenCode:"opencode"===a}),bt(e,d)}return M(a)}async function R(a){let c,d=Object.entries(b.projects).flatMap(([b,c])=>a&&b!==a?[]:y(b,c).map(a=>({sessionName:a.sessionName,projectId:b,raw:a.raw}))).map(async({sessionName:a,projectId:d,raw:f})=>{let h,i,j=b.projects[d];if(!j)return null;let k=o(d);try{let b=(0,g.join)(k,`${a}.json`),c=(0,e.statSync)(b);h=c.birthtime,i=c.mtime}catch{}let l=dn(a,f,{projectId:d,sessionPrefix:j.sessionPrefix,createdAt:h,modifiedAt:i,workspacePathFallback:j.path}),n=D(j,a,f).agentName,p=C(j,n),q="opencode"===n?c??=db():void 0,r=null,s=new Promise(a=>{r=setTimeout(a,12e3)}),t=H(l,a,k,j,n,p,q).catch(()=>{});try{await Promise.race([t,s])}finally{r&&clearTimeout(r)}let u=bc(f,{sessionId:a,status:a3(f.status)});if(l.lifecycle&&("missing"===l.lifecycle.runtime.state||"exited"===l.lifecycle.runtime.state)&&"terminated"!==u.session.state&&"done"!==u.session.state&&"detecting"!==u.session.state){let b=l.lifecycle.runtime.state,c=l.lifecycle.runtime.reason;try{let e=m(a,f,a=>{a.session.state="detecting",a.session.reason="runtime_lost",a.session.lastTransitionAt=new Date().toISOString(),a.runtime.state=b,a.runtime.reason=c,a.runtime.lastObservedAt=new Date().toISOString()});bq(k,a,be(e)),l.lifecycle=e,l.status=bd(e),S({projectId:d,sessionId:a,source:"session-manager",kind:"runtime.lost_detected",level:"warn",summary:`runtime lost reconciled: ${a}`,data:{runtimeState:b,runtimeReason:c}})}catch(b){S({projectId:d,sessionId:a,source:"session-manager",kind:"runtime.lost_persist_failed",level:"error",summary:`runtime_lost persist failed: ${a}`,data:{reason:b instanceof Error?b.message:String(b)}})}}return l});return(await Promise.all(d)).filter(a=>null!==a)}async function T(a){if(r&&Date.now()<r.expiresAt)return a?r.sessions.filter(b=>b.projectId===a):r.sessions;let b=await R();return r={sessions:b,expiresAt:Date.now()+35e3},a?b.filter(b=>b.projectId===a):b}async function U(a){for(let[c,d]of Object.entries(b.projects)){let b,f,h=o(c),i=bn(h,a);if(!i)continue;try{let c=(0,g.join)(h,`${a}.json`),d=(0,e.statSync)(c);b=d.birthtime,f=d.mtime}catch{}let j=v(h,w(h,{sessionName:a,raw:i,modifiedAt:f},d.sessionPrefix),d),k=dn(a,j.raw,{projectId:c,sessionPrefix:d.sessionPrefix,createdAt:b,modifiedAt:f,workspacePathFallback:d.path}),l=D(d,a,j.raw).agentName,m=C(d,l);return await H(k,a,h,d,l,m),k}return null}async function V(a,e){let f=F(a);if(!f){for(let[c]of Object.entries(b.projects)){let b=bn(o(c),a);if(b){let a=dm(b);if(a?.session.state==="terminated")return{cleaned:!1,alreadyTerminated:!0}}}throw new d.Ag(a)}let{raw:g,sessionsDir:h,project:j,projectId:k}=f,l=bc(g);if(l?.session.state==="terminated")return{cleaned:!1,alreadyTerminated:!0};let n=e?.reason??"manually_killed",p=D(j,a,g).agentName;if(S({projectId:k,sessionId:a,source:"session-manager",kind:"session.kill_started",summary:`kill started: ${a}`,data:{reason:n}}),g.runtimeHandle){let d=a2(g.runtimeHandle);if(d){let e=c.get("runtime",d.runtimeName??(j?j.runtime??b.defaults.runtime:b.defaults.runtime));if(e)try{await e.destroy(d)}catch(b){S({projectId:k,sessionId:a,source:"session-manager",kind:"runtime.destroy_failed",level:"warn",summary:`runtime.destroy failed during kill: ${a}`,data:{runtime:d.runtimeName??null,reason:b instanceof Error?b.message:String(b)}})}}}let q=g.worktree;if(q&&i(j,k,q)){let d=j?C(j).workspace:c.get("workspace",b.defaults.workspace);if(d)try{await d.destroy(q)}catch(b){S({projectId:k,sessionId:a,source:"session-manager",kind:"workspace.destroy_failed",level:"warn",summary:`workspace.destroy failed during kill: ${a}`,data:{workspace:d.name,reason:b instanceof Error?b.message:String(b)}})}}let r=!1;if(e?.purgeOpenCode===!0&&"opencode"===p){let b=cE(g.opencodeSessionId)??await dd(a,1e4);if(b)try{await da(b),r=!0}catch(c){S({projectId:k,sessionId:a,source:"session-manager",kind:"agent.opencode_purge_failed",level:"warn",summary:`opencode session purge failed: ${a}`,data:{opencodeSessionId:b,reason:c instanceof Error?c.message:String(c)}})}}let s="pr_merged"===n?"pr_merged_cleanup":"auto_cleanup"===n?"auto_cleanup":"manual_kill_requested",t=m(a,g,a=>{a.session.state="terminated",a.session.reason=n,a.session.terminatedAt=new Date().toISOString(),a.session.lastTransitionAt=a.session.terminatedAt,a.runtime.state=g.runtimeHandle||g.tmuxName?"missing":"exited",a.runtime.reason=s,a.runtime.lastObservedAt=new Date().toISOString()});return bq(h,a,{...be(t),...r&&{opencodeSessionId:"",opencodeCleanedAt:new Date().toISOString()}}),u(),S({projectId:k,sessionId:a,source:"session-manager",kind:"session.killed",summary:`killed: ${a}`,data:{reason:n}}),{cleaned:!0,alreadyTerminated:!1}}async function W(a,c){let e={killed:[],skipped:[],errors:[]},f=await R(a),g=new Set,h=new Set,i=(a,b)=>`${a}:${b}`,j=a=>{let b=a.indexOf(":");return -1===b?{projectId:"",id:a}:{projectId:a.slice(0,b),id:a.slice(b+1)}},l=(a,b)=>{let c=i(a,b);h.delete(c),g.add(c)},m=(a,b)=>{let c=i(a,b);g.has(c)||h.add(c)},n=c?.purgeOpenCode!==!1;for(let a of f)try{let e=b.projects[a.projectId];if(!e||k(e,a.id,a.metadata)){m(a.projectId,a.id);continue}let f=C(e),g=!1,h=a.prs.length>0?a.prs:a.pr?[a.pr]:[];if(h.length>0&&f.scm)try{(await Promise.all(h.map(a=>f.scm.getPRState(a)))).every(a=>a===d.bz.CLOSED)&&(g=!0)}catch{}if(!g&&a.issueId&&f.tracker)try{await f.tracker.isCompleted(a.issueId,e)&&(g=!0)}catch{}if(!g&&a.runtimeHandle&&f.runtime)try{await f.runtime.isAlive(a.runtimeHandle)||(g=!0)}catch{}g?(c?.dryRun||await V(a.id,{purgeOpenCode:n}),l(a.projectId,a.id)):m(a.projectId,a.id)}catch(c){let b=c instanceof Error?c.message:String(c);e.errors.push({sessionId:a.id,error:b}),S({projectId:a.projectId,sessionId:a.id,source:"session-manager",kind:"session.cleanup_error",level:"warn",summary:`cleanup error: ${a.id}`,data:{reason:b}})}for(let[d,f]of Object.entries(b.projects)){if(a&&d!==a)continue;let b=o(d);for(let a of bu(b)){let h=i(d,a);if(g.has(h))continue;let j=bn(b,a);if(!j)continue;let o=dm(j);if(o?.session.state!=="terminated")continue;if(k(f,a,j)){m(d,a);continue}let p=D(f,a,j).agentName,q=cE(j.opencodeSessionId);if("opencode"===p&&j.opencodeCleanedAt){m(d,a);continue}if("opencode"===p&&q&&n){if(!c?.dryRun)try{await da(q),bs(b,a,a=>({...a,opencodeSessionId:"",opencodeCleanedAt:new Date().toISOString()}),{activityEventSource:"session-manager"})}catch(c){let b=c instanceof Error?c.message:String(c);e.errors.push({sessionId:a,error:`Failed to delete OpenCode session ${q}: ${b}`}),S({projectId:d,sessionId:a,source:"session-manager",kind:"agent.opencode_purge_failed",level:"warn",summary:`opencode session purge failed during cleanup: ${a}`,data:{opencodeSessionId:q,reason:b}});continue}l(d,a)}else m(d,a)}}let p=[...g,...h],q=new Map;for(let a of p){let{id:b}=j(a);q.set(b,(q.get(b)??0)+1)}let r=a=>{let{projectId:b,id:c}=j(a);return(q.get(c)??0)>1?`${b}:${c}`:c};return e.killed=[...g].map(r),e.skipped=[...h].map(r),e}async function X(a,e){let{raw:f,sessionsDir:g,project:h,projectId:i}=G(a),j=D(h,a,f).agentName;if("opencode"===j&&!cE(f.opencodeSessionId)){let b=await dd(a,1e4);b&&(f.opencodeSessionId=b,bq(g,a,{opencodeSessionId:b}),u())}let k=f.runtimeHandle?a2(f.runtimeHandle):null,l=k?.runtimeName??h.runtime??b.defaults.runtime,m=c.get("runtime",l);if(!m)throw Error(`No runtime plugin for session ${a}`);let n=c.get("agent",j);if(!n)throw Error(`No agent plugin for session ${a}`);let o=async a=>{try{return await m.getOutput(a,20)??""}catch{return""}},p=a=>{if(!a)return null;try{return n.detectActivity(a)}catch{return null}},q=a=>a.includes("Press up to edit queued messages"),r=async()=>{let a=cE(f.opencodeSessionId);if("opencode"!==j||!a)return;let b=await db(1e4);return b.find(b=>b.id===a)?.updatedAt},s=async(a,b)=>{let c=a.runtimeHandle;if(!c)return;let d=Date.now()+b,e=null,f=0;for(;;){let[a,b,g,h]=await Promise.all([m.isAlive(c).catch(()=>!0),dj(n,c),o(c),"tmux"===c.runtimeName?dl(c.id):Promise.resolve(n.processName)]),i=g.trim().length>0,j=null===h||h===n.processName,k=i?g.trimEnd():null,l=null!==k&&k===e;if(a&&b&&j&&(q(g)||l)){if((f+=1)>=2)return}else f=0;if(e=k,Date.now()>=d)return;await di(500)}},t=async a=>{let b=a.runtimeHandle;if(!b)return!1;let c=Date.now()+5e3;for(;;){let[a,d,e,f]=await Promise.all([m.isAlive(b).catch(()=>!0),dj(n,b),o(b),"tmux"===b.runtimeName?dl(b.id):Promise.resolve(n.processName)]),g=null===f||f===n.processName;if(a&&g&&(d||e.trim().length>0))return!0;if(Date.now()>=c)return!1;await di(500)}},v=async(b,c)=>{let d;if("done"===c.lifecycle.session.state)throw Error(`Cannot send to session ${a}: ${b}`);try{d=await Z(a)}catch(d){let c=d instanceof Error?d.message:String(d);throw Error(`Cannot send to session ${a}: ${b} (${c})`,{cause:d})}if(!await t(d)){let c="restored session did not become ready for delivery";throw S({projectId:i,sessionId:a,source:"session-manager",kind:"session.restore_failed",level:"error",summary:`restore for delivery failed: ${a}`,data:{stage:"ready_timeout",reason:c,trigger:"send"}}),Error(`Cannot send to session ${a}: ${b} (${c})`)}return d},w=async(b=!1)=>{let c=await U(a);if(!c)throw new d.Ag(a);let e=c.runtimeHandle??{id:a,runtimeName:l,data:{}},f=c.runtimeHandle?c:{...c,runtimeHandle:e};if(b||(0,d.qX)(f))return v(b?"session needed to be restarted before delivery":"session is not running",f);let[g,h]=await Promise.all([m.isAlive(e).catch(()=>!0),dj(n,e)]);return("spawning"===f.status&&g&&(await s(f,2e4),[g,h]=await Promise.all([m.isAlive(e).catch(()=>!0),dj(n,e)])),g&&h)?f:v(g?"agent process is not running":"runtime is not alive",f)},x=async b=>{let c=b.runtimeHandle;if(!c)throw Error(`Session ${a} has no runtime handle`);let d=await o(c),f=p(d)??b.activity,g=await r();await m.sendMessage(c,e);for(let a=1;a<=6;a++){await di(500);let a=await o(c),e=p(a)??b.activity,h=await r();if(void 0!==g&&void 0!==h&&h>g||q(a)||a.length>0&&a!==d||"active"!==f&&"active"===e||"waiting_input"!==f&&"waiting_input"===e)break}},y="prepare";try{let a=await w();try{y="initial",await x(a)}catch(b){if(!(void 0===a.restoredAt&&(0,d.qX)(a))){if(b instanceof Error)throw b;throw Error(String(b),{cause:b})}y="restore_retry",a=await w(!0);try{await x(a)}catch(a){if(a instanceof Error)throw a;throw Error(String(a),{cause:a})}}}catch(b){throw S({projectId:i,sessionId:a,source:"session-manager",kind:"session.send_failed",level:"error",summary:`send failed: ${a}`,data:{stage:y,reason:b instanceof Error?b.message:String(b)}}),b}}async function Y(a,b,c){let e,f=b.trim();if(!f)throw Error("PR reference is required");let{raw:g,sessionsDir:h,project:i,projectId:k}=G(a);if(j(a,g,i.sessionPrefix))throw Error(`Session ${a} is an orchestrator session and cannot claim PRs`);let l=C(i,D(i,a,g).agentName).scm;if(!l?.resolvePR||!l.checkoutPR)throw Error(`SCM plugin ${i.scm?.plugin?`"${i.scm.plugin}" `:""}does not support claiming existing PRs`);let n=await l.resolvePR(f,i),o=await l.getPRState(n);if(o!==d.bz.OPEN)throw Error(`Cannot claim PR #${n.number} because it is ${o}`);let p=new Set;for(let{sessionName:b,raw:c}of y(k,i).filter(b=>b.sessionName!==a)){if(!c||j(b,c,i.sessionPrefix))continue;let a=new Set([c.pr,..."string"==typeof c.prs?c.prs.split(","):[]].map(a=>"string"==typeof a?a.trim():"").filter(Boolean)).has(n.url),d=c.branch===n.branch&&(c.prAutoDetect??"on")!=="off"&&"false"!==c.prAutoDetect;(a||d)&&p.add(b)}let q=[...p],r=g.worktree;if(!r)throw Error(`Session ${a} has no workspace to check out PR #${n.number}`);let s=await l.checkoutPR(n,r),t=m(a,g,a=>{a.pr.state="open",a.pr.reason="in_progress",a.pr.number=n.number,a.pr.url=n.url,a.pr.lastObservedAt=new Date().toISOString()}),v=a0((g.prs??g.pr??"").split(",").filter(a=>a.trim()!==n.url)).join(","),w=v?`${n.url},${v}`:n.url,x={prEnrichment:"",prReviewComments:""};for(let a of Object.keys(g))(/^prEnrichment_\d+$/.test(a)||/^prReviewComments_\d+$/.test(a))&&(x[a]="");for(let b of(bq(h,a,{pr:n.url,prs:w,status:bd(t),branch:n.branch,prAutoDetect:"",...x,...be(t)}),u(),q)){let a=bn(h,b);if(!a)continue;let c=m(b,a,b=>{b.pr.state="none",b.pr.reason="not_created",b.pr.number=null,b.pr.url=null,b.pr.lastObservedAt=null,df.has(a.status??"")&&(b.session.state="working",b.session.reason="task_in_progress")});bq(h,b,{pr:"",prs:"",prAutoDetect:"false",...df.has(a.status??"")?{status:"working"}:{},...be(c)}),u()}let z=!1;if(c?.assignOnGithub)if(l.assignPRToCurrentUser)try{await l.assignPRToCurrentUser(n),z=!0}catch(a){e=a instanceof Error?a.message:String(a)}else e=`SCM plugin "${l.name}" does not support assigning PRs`;return{sessionId:a,projectId:k,pr:n,branchChanged:s,githubAssigned:z,githubAssignmentError:e,takenOverFrom:q}}async function Z(a){let c,f,h=F(a);if(!h)throw new d.Ag(a);let i=h.raw,j=h.sessionsDir,k=h.project,l=h.projectId,m=D(k,a,i);if("opencode"===m.agentName&&!cE(i.opencodeSessionId)){let b=await dd(a,1e4);if(!b)throw new d.D8(a,"OpenCode session mapping is missing");i={...i,opencodeSessionId:b},bq(j,a,{opencodeSessionId:b})}let o=dn(a,i,{projectId:l,sessionPrefix:k.sessionPrefix,workspacePathFallback:k.path}),q=C(k,m.agentName);if(await J(o,q,!0,j),!(0,d.qX)(o)){let b=d.N_.has(o.status)?`status "${o.status}" is not restorable`:`session is not in a terminal state (status: "${o.status}", activity: "${o.activity}")`;throw S({projectId:l,sessionId:a,source:"session-manager",kind:"session.restore_failed",level:"error",summary:`restore not allowed: ${a}`,data:{stage:"validation",status:o.status,activity:o.activity,reason:b}}),new d.D8(a,b)}if(!q.runtime)throw Error(`Runtime plugin '${k.runtime??b.defaults.runtime}' not found`);if(!q.agent)throw Error(`Agent plugin '${m.agentName}' not found`);let r=i.worktree||k.path;if(!(q.workspace?.exists?await q.workspace.exists(r):(0,e.existsSync)(r))){if(!q.workspace?.restore)throw S({projectId:l,sessionId:a,source:"session-manager",kind:"session.restore_failed",level:"error",summary:`restore workspace failed: ${a}`,data:{stage:"workspace_restore",workspacePath:r,reason:"workspace plugin does not support restore"}}),new d.CK(r,"workspace plugin does not support restore");if(!o.branch)throw S({projectId:l,sessionId:a,source:"session-manager",kind:"session.restore_failed",level:"error",summary:`restore workspace failed: ${a}`,data:{stage:"workspace_restore",workspacePath:r,reason:"branch metadata is missing"}}),new d.CK(r,"branch metadata is missing");try{let b=await q.workspace.restore({projectId:l,project:k,sessionId:a,branch:o.branch,worktreeDir:p(l)},r);q.workspace.postCreate&&await q.workspace.postCreate(b,k)}catch(b){throw S({projectId:l,sessionId:a,source:"session-manager",kind:"session.restore_failed",level:"error",summary:`workspace restore failed: ${a}`,data:{stage:"workspace_restore",workspacePath:r,reason:b instanceof Error?b.message:String(b)}}),new d.CK(r,`restore failed: ${b instanceof Error?b.message:String(b)}`)}}if("opencode"===q.agent.name&&"orchestrator"===m.role){let b=n(l),c=(0,g.join)(b,`orchestrator-prompt-${a}.md`);if((0,e.existsSync)(c))try{cO(r,c)}catch(a){throw Error(`failed to restore OpenCode orchestrator AGENTS.md: ${a instanceof Error?a.message:String(a)}`,{cause:a})}}if("opencode"===q.agent.name&&"orchestrator"!==m.role){let b=n(l),d=(0,g.join)(b,`worker-prompt-${a}.md`);(0,e.existsSync)(d)&&(c=cP(b,a,[d]))}if(o.runtimeHandle)try{await q.runtime.destroy(o.runtimeHandle)}catch{}let s={...k,agentConfig:{...m.agentConfig,..."orchestrator"===m.role?{permissions:"permissionless"}:{},...o.metadata?.opencodeSessionId?{opencodeSessionId:o.metadata.opencodeSessionId}:{}}},t=(()=>{if("orchestrator"!==m.role)return;let b=n(l),c=(0,g.join)(b,`orchestrator-prompt-${a}.md`);return(0,e.existsSync)(c)?c:void 0})(),v={sessionId:a,projectConfig:s,workspacePath:r,issueId:o.issueId??void 0,permissions:"orchestrator"===m.role?"permissionless":m.permissions,model:m.model,subagent:m.subagent,...t&&{systemPromptFile:t}};if(q.agent.getRestoreCommand){let b=await q.agent.getRestoreCommand(o,s);if(b)f=b,bq(j,a,{restoreFallbackReason:""});else{let b=`${q.agent.name}.getRestoreCommand returned null`;bq(j,a,{restoreFallbackReason:b}),S({projectId:l,sessionId:a,source:"session-manager",kind:"session.restore_fallback",level:"warn",summary:`using fresh launch instead of native restore: ${a}`,data:{agent:q.agent.name,reason:b}}),f=q.agent.getLaunchCommand(v)}}else f=q.agent.getLaunchCommand(v),bq(j,a,{restoreFallbackReason:""});let w=q.agent.getEnvironment(v);q.agent.preLaunchSetup&&await q.agent.preLaunchSetup(r);let x=i.tmuxName,y=await q.runtime.create({sessionId:x??a,workspacePath:r,launchCommand:f,environment:{...w,...c?{OPENCODE_CONFIG:c}:{},...k.env??{},PATH:c_(w.PATH??process.env.PATH),GH_PATH:cY,...process.env.AO_AGENT_GH_TRACE&&{AO_AGENT_GH_TRACE:process.env.AO_AGENT_GH_TRACE},AO_SESSION:a,AO_DATA_DIR:j,AO_SESSION_NAME:a,...x&&{AO_TMUX_NAME:x},AO_CALLER_TYPE:"agent",...l&&{AO_PROJECT_ID:l},AO_CONFIG_PATH:b.configPath,...void 0!==b.port&&null!==b.port&&{AO_PORT:String(b.port)}}}),z=new Date().toISOString(),A=bf(o.lifecycle);A.session.state="working",A.session.reason="task_in_progress",A.session.lastTransitionAt=z,A.session.terminatedAt=null,A.session.completedAt=null,A.runtime.state="alive",A.runtime.reason="process_running",A.runtime.handle=y,A.runtime.lastObservedAt=z,("merged"===A.pr.state||"closed"===A.pr.state)&&(A.pr.state="none",A.pr.reason="cleared_on_restore",A.pr.number=null,A.pr.url=null,A.pr.lastObservedAt=null),bq(j,a,{...be(A),agent:m.agentName,restoredAt:z,mergedPendingCleanupSince:""}),u();let B=bd(A),E={...o,status:B,activity:"active",workspacePath:r,runtimeHandle:y,restoredAt:new Date(z)};if(q.agent.postLaunchSetup)try{let b={...E.metadata??{}};await q.agent.postLaunchSetup(E);let c=E.metadata??{},d=Object.fromEntries(Object.entries(c).filter(([a,c])=>b[a]!==c));Object.keys(d).length>0&&(bq(j,a,d),u())}catch{}return E}return{spawn:async function(a){S({projectId:a.projectId,source:"session-manager",kind:"session.spawn_started",summary:"spawn started",data:{agent:a.agent??void 0}});try{return await K(a)}catch(b){throw S({projectId:a.projectId,source:"session-manager",kind:"session.spawn_failed",level:"error",summary:"spawn failed",data:{reason:b instanceof Error?b.message:String(b)}}),b}},spawnOrchestrator:M,ensureOrchestrator:async function(a){let c=b.projects[a.projectId];if(!c)throw Error(`Unknown project: ${a.projectId}`);let d=cR(c),e=s.get(d);if(e)return e;let f=P(a).finally(()=>{s.delete(d)});return s.set(d,f),f},relaunchOrchestrator:async function(a){let c=b.projects[a.projectId];if(!c)throw Error(`Unknown project: ${a.projectId}`);let d=cR(c),e=t.get(d);if(e)return e;let f=Q(a).finally(()=>{t.delete(d)});return t.set(d,f),f},restore:Z,list:R,listCached:T,invalidateCache:u,get:U,kill:V,cleanup:W,send:X,claimPR:Y,remap:async function(a,b=!1){let{raw:c,sessionsDir:d,project:e}=G(a);if("opencode"!==D(e,a,c).agentName)throw Error(`Session ${a} is not using the opencode agent`);let f=cE(c.opencodeSessionId),g=b?await dd(a,1e4):f??await dd(a,1e4);if(!g)throw Error(`OpenCode session mapping is missing for ${a}`);return bq(d,a,{opencodeSessionId:g}),g}}}let dq=new Map;function dr(a,b){let c=dq.get(a);return c||(c=b(),dq.set(a,c)),c}let ds={debug:10,info:20,warn:30,error:40};function dt(){return new Date().toISOString()}function du(a){return a.replace(/[^a-zA-Z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")||"component"}function dv(a,b){return ds[a]>=ds[function(a){let b=a?.trim().toLowerCase();return"debug"===b||"info"===b||"warn"===b||"error"===b?b:null}(process.env.AO_LOG_LEVEL?.trim().toLowerCase())??b.observability?.logLevel??"warn"]}function dw(a,b,c){((function(a){let b=a?.trim().toLowerCase();return b?"1"===b||"true"===b||"yes"===b||"on"===b||"0"!==b&&"false"!==b&&"no"!==b&&"off"!==b&&null:null})(process.env.AO_OBSERVABILITY_STDERR)??a.observability?.stderr)&&dv(c,a)&&process.stderr.write(`${JSON.stringify({...b,level:c})}
939
+ `)}function dx(a){let b=(0,g.join)(function(a){let b=function(a){let b;try{b=(0,e.realpathSync)(a)}catch{b=(0,g.resolve)(a)}let c=(0,g.dirname)(b);return(0,f.createHash)("sha256").update(c).digest("hex").slice(0,12)}(a);return(0,g.join)(r("~/.agent-orchestrator"),`${b}-observability`)}(a.configPath),"processes");return(0,e.mkdirSync)(b,{recursive:!0}),b}function dy(a,b){return(0,g.join)(dx(a),`${du(b)}-${process.pid}.json`)}function dz(a){let b=a.replace(/\s+/g," ").trim();return b.length>256?`${b.slice(0,256)}…`:b}function dA(a){if(a)return function a(b,c=0){return null==b?b:"string"==typeof b?dz(b):"number"==typeof b||"boolean"==typeof b?b:c>=4?"[truncated]":Array.isArray(b)?b.slice(0,25).map(b=>a(b,c+1)):"object"==typeof b?Object.fromEntries(Object.entries(b).slice(0,25).map(([b,d])=>[b,/token|secret|password|cookie|authorization|api[-_]?key|prompt|message|note/i.test(b)?"[redacted]":a(d,c+1)])):String(b)}(a)}function dB(a){if(a)return dz(a)}function dC(a){if(a)return dz(a)}function dD(a,b,c){let d=`${a}.1`;(0,e.existsSync)(a)&&(0,e.statSync)(a).size>=c&&((0,e.existsSync)(d)&&(0,e.unlinkSync)(d),(0,e.renameSync)(a,d)),(0,e.appendFileSync)(a,`${JSON.stringify(b)}
940
+ `,"utf-8")}function dE(a,b){return b.localeCompare(a)}function dF(a){switch(a){case"error":return 3;case"warn":return 2;default:return 1}}function dG(a="ao"){return`${a}-${(0,f.randomUUID)()}`}function dH(a,b){let c=du(b);function d(b,d){try{var f,h;let i=dy(a,c),j=function(a,b){if(!(0,e.existsSync)(a))return{version:1,component:b,pid:process.pid,updatedAt:dt(),metrics:{},traces:[],sessions:{},health:{}};try{let c=JSON.parse((0,e.readFileSync)(a,"utf-8"));return{version:1,component:b,pid:process.pid,updatedAt:"string"==typeof c.updatedAt?c.updatedAt:dt(),metrics:c.metrics&&"object"==typeof c.metrics?c.metrics:{},traces:Array.isArray(c.traces)?c.traces:[],sessions:c.sessions&&"object"==typeof c.sessions?c.sessions:{},health:c.health&&"object"==typeof c.health?c.health:{}}}catch{return{version:1,component:b,pid:process.pid,updatedAt:dt(),metrics:{},traces:[],sessions:{},health:{}}}}(i,c);b(j);let k=dy(a,j.component);j.updatedAt=dt();let l=`${k}.tmp.${process.pid}.${Date.now()}`;(0,e.writeFileSync)(l,`${JSON.stringify(j,null,2)}
941
+ `,"utf-8"),(0,e.renameSync)(l,k),d&&dv(d.level,a)&&(f=d.payload,h=d.level,dD((0,g.join)(dx(a),`${du(c)}-${process.pid}.ndjson`),{...f,level:h},5242880),dw(a,d.payload,d.level))}catch(d){let b={source:"ao-observability",timestamp:dt(),component:c,outcome:"failure",operation:"observability.write",reason:d instanceof Error?d.message:String(d)};try{let c=(0,g.join)(dx(a),"observability-errors.ndjson");dD(c,b,524288)}catch{}dw(a,b,"error")}}return{component:c,recordOperation(a){let b=dt(),e=a.operation??a.metric,g=a.level??("failure"===a.outcome?"error":"info"),h={id:(0,f.randomUUID)(),timestamp:b,component:c,operation:e,outcome:a.outcome,correlationId:a.correlationId,projectId:a.projectId,sessionId:a.sessionId,path:dC(a.path),reason:dB(a.reason),durationMs:a.durationMs,data:dA(a.data)};d(c=>{var d,f;let g=(d=a.metric,f=a.projectId,`${f??"unknown"}::${d}`),i=c.metrics[g]??{total:0,success:0,failure:0};if(i.total+=1,i.lastAt=b,"success"===a.outcome?(i.success+=1,i.lastSuccessAt=b):(i.failure+=1,i.lastFailureAt=b,i.lastFailureReason=dB(a.reason)),c.metrics[g]=i,c.traces=[h,...c.traces].sort((a,b)=>dE(a.timestamp,b.timestamp)).slice(0,80),a.sessionId){c.sessions[a.sessionId]={sessionId:a.sessionId,projectId:a.projectId,correlationId:a.correlationId,operation:e,outcome:a.outcome,updatedAt:b,reason:dB(a.reason)};let d=Object.entries(c.sessions).sort(([,a],[,b])=>dE(a.updatedAt,b.updatedAt));c.sessions=Object.fromEntries(d.slice(0,200))}},{level:g,payload:{source:"ao-observability",timestamp:b,component:c,metric:a.metric,operation:e,outcome:a.outcome,correlationId:a.correlationId,projectId:a.projectId,sessionId:a.sessionId,reason:dB(a.reason),durationMs:a.durationMs,path:dC(a.path),data:dA(a.data)}})},recordDiagnostic(a){let b=dt(),e=a.level??"info",g={id:(0,f.randomUUID)(),timestamp:b,component:c,operation:a.operation,outcome:"success",correlationId:a.correlationId,projectId:a.projectId,sessionId:a.sessionId,path:dC(a.path),data:{message:dz(a.message),...dA(a.data)}};d(c=>{if(c.traces=[g,...c.traces].sort((a,b)=>dE(a.timestamp,b.timestamp)).slice(0,80),a.sessionId){c.sessions[a.sessionId]={sessionId:a.sessionId,projectId:a.projectId,correlationId:a.correlationId,operation:a.operation,outcome:"success",updatedAt:b};let d=Object.entries(c.sessions).sort(([,a],[,b])=>dE(a.updatedAt,b.updatedAt));c.sessions=Object.fromEntries(d.slice(0,200))}},{level:e,payload:{source:"ao-observability",timestamp:b,component:c,operation:a.operation,correlationId:a.correlationId,projectId:a.projectId,sessionId:a.sessionId,path:dC(a.path),data:{message:dz(a.message),...dA(a.data)}}})},setHealth(a){let b=dt();d(d=>{d.health[a.surface]={surface:a.surface,status:a.status,updatedAt:b,component:c,projectId:a.projectId,correlationId:a.correlationId,reason:dB(a.reason),details:dA(a.details)}},{level:"error"===a.status?"error":"warn"===a.status?"warn":"info",payload:{source:"ao-observability",timestamp:b,component:c,surface:a.surface,status:a.status,projectId:a.projectId,correlationId:a.correlationId,reason:dB(a.reason),details:dA(a.details)}})}}}function dI(a){let b=dx(a),c={};for(let a of(0,e.readdirSync)(b)){let d;if(!a.endsWith(".json"))continue;let f=(0,g.join)(b,a);try{d=JSON.parse((0,e.readFileSync)(f,"utf-8"))}catch{continue}if(d&&"object"==typeof d){for(let[a,b]of Object.entries(d.metrics??{})){let{projectId:e,metric:f}=function(a){let b=a.indexOf("::");if(-1===b)return{metric:a};let c=a.slice(0,b);return{projectId:"unknown"===c?void 0:c,metric:a.slice(b+2)}}(a);if(!e)continue;let g=c[e]??(c[e]={projectId:e,updatedAt:d.updatedAt,metrics:{},health:{},recentTraces:[],sessions:{}});g.metrics[f]=function(a,b){let c={total:(a?.total??0)+(b.total??0),success:(a?.success??0)+(b.success??0),failure:(a?.failure??0)+(b.failure??0),lastAt:a?.lastAt,lastSuccessAt:a?.lastSuccessAt,lastFailureAt:a?.lastFailureAt,lastFailureReason:a?.lastFailureReason};return b.lastAt&&(!c.lastAt||b.lastAt>c.lastAt)&&(c.lastAt=b.lastAt),b.lastSuccessAt&&(!c.lastSuccessAt||b.lastSuccessAt>c.lastSuccessAt)&&(c.lastSuccessAt=b.lastSuccessAt),b.lastFailureAt&&(!c.lastFailureAt||b.lastFailureAt>c.lastFailureAt)&&(c.lastFailureAt=b.lastFailureAt,c.lastFailureReason=b.lastFailureReason),c}(g.metrics[f],b),d.updatedAt>g.updatedAt&&(g.updatedAt=d.updatedAt)}for(let a of d.traces??[]){if(!a.projectId)continue;let b=c[a.projectId]??(c[a.projectId]={projectId:a.projectId,updatedAt:a.timestamp,metrics:{},health:{},recentTraces:[],sessions:{}});b.recentTraces.push(a),a.timestamp>b.updatedAt&&(b.updatedAt=a.timestamp)}for(let a of Object.values(d.health??{})){let b=a.projectId;if(!b)continue;let d=c[b]??(c[b]={projectId:b,updatedAt:a.updatedAt,metrics:{},health:{},recentTraces:[],sessions:{}}),e=d.health[a.surface];(!e||a.updatedAt>=e.updatedAt)&&(d.health[a.surface]=a),a.updatedAt>d.updatedAt&&(d.updatedAt=a.updatedAt)}for(let a of Object.values(d.sessions??{})){if(!a.projectId)continue;let b=c[a.projectId]??(c[a.projectId]={projectId:a.projectId,updatedAt:a.updatedAt,metrics:{},health:{},recentTraces:[],sessions:{}}),d=b.sessions[a.sessionId];(!d||a.updatedAt>=d.updatedAt)&&(b.sessions[a.sessionId]=a),a.updatedAt>b.updatedAt&&(b.updatedAt=a.updatedAt)}}}let d="ok";for(let a of Object.values(c))for(let b of(a.recentTraces=a.recentTraces.sort((a,b)=>dE(a.timestamp,b.timestamp)).slice(0,80),Object.values(a.health)))dF(b.status)>dF(d)&&(d=b.status);return{generatedAt:dt(),overallStatus:d,projects:c}}let dJ=[[/\bBearer\s+[A-Za-z0-9._~+/=-]{12,}\b/gi,"Bearer [redacted]"],[/\bgh[pousr]_[A-Za-z0-9_]{20,}\b/g,"[redacted]"],[/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,"[redacted]"],[/\bsk-(?:ant-)?(?:proj-|svcacct-)?[A-Za-z0-9_-]{16,}\b/g,"[redacted]"],[/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g,"[redacted]"],[/\bAKIA[0-9A-Z]{16}\b/g,"[redacted]"],[/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,"[redacted]"],[/\b([A-Z][A-Z0-9_]*(?:TOKEN|PASSWORD|SECRET|AUTHORIZATION|COOKIE|API_KEY|APIKEY)[A-Z0-9_]*)=([^\s"'`]{6,})/g,"$1=[redacted]"]];function dK(a){let b=a.reason?function(a){let b=function(a){let b=a,c=0;for(;c<b.length;){let a=b.indexOf("://",c);if(-1===a)break;if(a<4){c=a+3;continue}let d=b.slice(Math.max(0,a-5),a).toLowerCase();if(!d.endsWith("http")&&!d.endsWith("https")){c=a+3;continue}let e=a+3,f=!1;for(;e<b.length;){let d=b.charCodeAt(e);if(d<=32||47===d)break;if(64===d){b=b.slice(0,a+3).toLowerCase()+"[redacted]"+b.slice(e),c=a+3+10+1,f=!0;break}e++}f||(c=a+3)}return b}(a.replace(/\s+/g," ").trim());for(let[a,c]of dJ)b=b.replace(a,c);return b.length>300?`${b.slice(0,297)}...`:b}(a.reason):void 0,c={eventId:a.event.id,eventType:a.event.type,priority:a.event.priority,targetReference:a.target.reference,targetPlugin:a.target.pluginName,deliveryMethod:a.method??"notify"};a.observer.recordOperation({metric:"notification_delivery",operation:"notification.deliver",outcome:a.outcome,correlationId:dG("notification"),projectId:a.event.projectId,sessionId:a.event.sessionId,reason:b,data:c,level:"failure"===a.outcome?"warn":"info"}),a.observer.setHealth({surface:function(a){let b="",c=0,d=!1;for(let e of a){let a=e.charCodeAt(0);if(!(a>=48&&a<=57||a>=65&&a<=90||a>=97&&a<=122||"_"===e||"-"===e)){b.length>0&&!d&&(b+="-",d=!0);continue}("-"!==e||0!==b.length)&&(b+=e,d=!1,"-"!==e&&(c=b.length))}return b=b.slice(0,c),`notification.delivery.${b||"target"}`}(a.target.reference),status:"failure"===a.outcome?"warn":"ok",projectId:a.event.projectId,correlationId:dG("notification-health"),reason:b,details:c}),"failure"===a.outcome&&a.recordActivityEvent&&function(a,b){if(a.failureKind)try{var c;S({projectId:a.event.projectId,sessionId:a.event.sessionId,source:"notifier",kind:(c=a.failureKind,"target_missing"===c?"notification.target_missing":"notification.delivery_failed"),level:"warn",summary:"target_missing"===a.failureKind?`notification target missing: ${a.target.reference}`:`notification delivery failed: ${a.target.reference}`,data:{eventId:a.event.id,eventType:a.event.type,priority:a.event.priority,targetReference:a.target.reference,targetPlugin:a.target.pluginName,deliveryMethod:a.method??"notify",errorMessage:b}})}catch{}}(a,b??"notification delivery failed")}let dL={"pr-closed":"pr.closed","ci-failed":"ci.failing","changes-requested":"review.changes_requested","bugbot-comments":"automated_review.found","merge-conflicts":"merge.conflicts","approved-and-green":"merge.ready","agent-stuck":"session.stuck","agent-needs-input":"session.needs_input","agent-exited":"session.killed","all-complete":"summary.all_complete","report-no-acknowledge":"report.no_acknowledge","report-stale":"report.stale","report-needs-input":"report.needs_input"};function dM(a){return"string"==typeof a&&a.trim().length>0?a:void 0}function dN(a){let b=dM(a.conclusion),c=dM(a.url);return{name:a.name,status:a.status,...b?{conclusion:b}:{},...c?{url:c}:{}}}function dO(a){return{schemaVersion:3,...dM(a.semanticType)?{semanticType:a.semanticType}:{},subject:function(a){let{context:b,sessionId:c,projectId:d}=a,e={session:{id:c,projectId:d}};if(b.pr){let a=dM(b.pr.branch),c=dM(b.pr.title),d=dM(b.pr.baseBranch),f=dM(b.pr.owner),g=dM(b.pr.repo);e.pr={number:b.pr.number,url:b.pr.url,...a?{branch:a}:{},...c?{title:c}:{},...d?{baseBranch:d}:{},...f?{owner:f}:{},...g?{repo:g}:{},..."boolean"==typeof b.pr.isDraft?{isDraft:b.pr.isDraft}:{}}}let f=dM(b.issueId);if(f){let a=dM(b.issueTitle);e.issue={id:f,...a?{title:a}:{}}}let g=dM(b.summary);g&&(e.summary=g);let h=dM(b.branch);return h&&(e.branch=h),e}(a)}}function dP(a,b){b&&("none"!==b.ciStatus&&(a.ci={...a.ci??{},status:a.ci?.status??b.ciStatus}),"none"!==b.reviewDecision&&(a.review={...a.review??{},decision:a.review?.decision??b.reviewDecision}),(b.mergeable||"boolean"==typeof b.hasConflicts||"boolean"==typeof b.isBehind||(b.blockers?.length??0)>0)&&(a.merge={...a.merge??{},ready:a.merge?.ready??b.mergeable,..."boolean"==typeof b.hasConflicts?{conflicts:a.merge?.conflicts??b.hasConflicts}:{},..."boolean"==typeof b.isBehind?{isBehind:b.isBehind}:{},...b.blockers&&b.blockers.length>0?{blockers:b.blockers}:{}}))}function dQ(a,b,c){switch(b){case"ci.failing":a.ci={...a.ci??{},status:"failing"};break;case"review.pending":a.review={...a.review??{},decision:"pending"};break;case"review.approved":a.review={...a.review??{},decision:"approved"};break;case"review.changes_requested":a.review={...a.review??{},decision:"changes_requested"};break;case"merge.ready":a.merge={...a.merge??{},ready:!0,conflicts:c?.hasConflicts??!1,...a.subject.pr?.baseBranch?{baseBranch:a.subject.pr.baseBranch}:{}};break;case"merge.conflicts":a.merge={...a.merge??{},ready:!1,conflicts:!0,...a.subject.pr?.baseBranch?{baseBranch:a.subject.pr.baseBranch}:{}}}}function dR(a){var b,c;let d=(b=a.reactionKey,c=a.eventType,dL[b]??c),e=dO({...a,semanticType:d});return e.reaction={key:a.reactionKey,action:a.action},dP(e,a.enrichment),dQ(e,d,a.enrichment),e}function dS(a){let b=a.match(/^(\d+)(s|m|h)$/);if(!b)return 0;let c=parseInt(b[1],10);switch(b[2]){case"s":return 1e3*c;case"m":return 6e4*c;case"h":return 36e5*c;default:return 0}}let dT=new Set(["ci-failed"]),dU=["rebase-merge","rebase-apply","CHERRY_PICK_HEAD","BISECT_LOG"];async function dV(a){try{return await (0,bG.stat)(a),!0}catch(a){if("object"==typeof a&&null!==a&&"code"in a&&"ENOENT"===a.code)return!1;throw a}}async function dW(a){return(await Promise.all(dU.map(b=>dV((0,g.join)(a,b))))).some(Boolean)}async function dX(a){let b=(0,g.join)(a,".git");if((await (0,bG.stat)(b)).isDirectory())return b;let c=(await (0,bG.readFile)(b,"utf8")).trim().match(/^gitdir:\s*(.+)$/i);if(!c)throw Error(`Invalid .git pointer in workspace: ${a}`);return(0,g.resolve)((0,g.dirname)(b),c[1].trim())}async function dY(a){let b;try{b=await dX(a)}catch{return{kind:"unavailable"}}try{let a=(await (0,bG.readFile)((0,g.join)(b,"HEAD"),"utf8")).trim(),c="ref: refs/heads/";if(!a.startsWith(c))return await dW(b)?{kind:"unavailable"}:{kind:"detached"};let d=a.slice(c.length).trim();if(d.length>0)return{kind:"branch",branch:d};return await dW(b)?{kind:"unavailable"}:{kind:"detached"}}catch{return{kind:"unavailable"}}}function dZ(a){return a.includes("stuck")||a.includes("needs_input")||a.includes("errored")?"urgent":a.startsWith("summary.")?"info":a.includes("approved")||a.includes("ready")||a.includes("merged")||a.includes("completed")?"action":a.includes("fail")||a.includes("changes_requested")||a.includes("conflicts")?"warning":"info"}function d$(a,b){return{id:(0,f.randomUUID)(),type:a,priority:b.priority??dZ(a),sessionId:b.sessionId,projectId:b.projectId,timestamp:new Date,message:b.message,data:b.data??{}}}function d_(a,b){switch(b){case"working":return"session.working";case"pr_open":return"pr.created";case"ci_failed":return"ci.failing";case"review_pending":return"review.pending";case"changes_requested":return"review.changes_requested";case"approved":return"review.approved";case"mergeable":return"merge.ready";case"merged":return"merge.completed";case"needs_input":return"session.needs_input";case"stuck":return"session.stuck";case"errored":return"session.errored";case"killed":return"session.killed";default:return null}}function d0(a,b){let c=a_("prs"in a&&Array.isArray(a.prs)?a.prs:a.pr?[a.pr]:[]).map(a=>{let c=b.get(`${a.owner}/${a.repo}#${a.number}`);return{url:a.url,title:c?.title??null,number:a.number,branch:a.branch,baseBranch:a.baseBranch,owner:a.owner,repo:a.repo,isDraft:a.isDraft}});return{pr:c[0]??null,prs:c,issueId:a.issueId,issueTitle:a.metadata.issueTitle??null,summary:a.agentInfo?.summary??null,branch:a.branch}}function d1(a){switch(a){case"pr.closed":return"pr-closed";case"ci.failing":return"ci-failed";case"review.changes_requested":return"changes-requested";case"automated_review.found":return"bugbot-comments";case"merge.conflicts":return"merge-conflicts";case"merge.ready":return"approved-and-green";case"session.stuck":return"agent-stuck";case"session.needs_input":return"agent-needs-input";case"session.killed":return"agent-exited";case"summary.all_complete":return"all-complete";default:return null}}function d2(a){let b=d_(void 0,a);if(!b)return"info";let c=dZ(b);return"urgent"===c?"error":"warning"===c?"warn":"info"}function d3(a){return(0,d.xn)(a)?{state:"unknown",failed:!1,indeterminate:!0}:{state:a?"alive":"dead",failed:!1}}function d4(a){return"detecting"===a.session.state?a.session.reason:"not_created"!==a.pr.reason&&"in_progress"!==a.pr.reason?a.pr.reason:"process_running"!==a.runtime.reason?a.runtime.reason:a.session.reason}function d5(a,b,c,d,e,f,g,h){return{oldStatus:c,newStatus:d,statusTransition:g,previousSessionState:a.session.state,newSessionState:b.session.state,previousSessionReason:a.session.reason,newSessionReason:b.session.reason,previousPRState:a.pr.state,newPRState:b.pr.state,previousPRReason:a.pr.reason,newPRReason:b.pr.reason,previousRuntimeState:a.runtime.state,newRuntimeState:b.runtime.state,previousRuntimeReason:a.runtime.reason,newRuntimeReason:b.runtime.reason,primaryReason:d4(b),evidence:e,signalsConsulted:e.split(/\s+/).map(a=>a.trim()).filter(a=>a.length>0),detectingAttempts:f,recoveryAction:h?.result?.action??null,reactionKey:h?.key??null,reactionSuccess:h?.result?.success??null,escalated:h?.result?.escalated??null}}function d6(a){let{config:b,registry:c,sessionManager:e,projectId:f}=a,g=dH(b,"lifecycle-manager"),h=new Map,i=new Map,j=new Map,k=null,l=!1,m=!1,n=new Map,p=new Map;function q(a){let b=a_(a.prs.length>0?a.prs:a.pr?[a.pr]:[]);return(b.length!==a.prs.length||a.pr!==(b[0]??null))&&(a.prs=b,a.pr=b[0]??null),b}function r(a,b){let c={};for(let d of Object.keys(a.metadata)){let a=d.match(/^(prEnrichment|prReviewComments)_(\d+)$/);if(!a)continue;let e=Number.parseInt(a[2],10);(Number.isNaN(e)||e>=b)&&(c[d]="")}return c}function s(a){if(a.pr)return p.get(`${a.pr.owner}/${a.pr.repo}#${a.pr.number}`)}let t=new Set,u=new Map;async function v(a){p.clear(),t=new Set;let d=new Map,e=new Map,h=new Set;for(let c of a){let a=b.projects[c.projectId];if(!a?.scm?.plugin||!a.repo)continue;let f=a.scm.plugin;d.has(f)||d.set(f,[]),e.has(f)||e.set(f,new Set),e.get(f).add(a.repo);let g=q(c);if(0!==g.length)for(let b of g){let c=`${b.owner}/${b.repo}`;c!==a.repo&&e.get(f).add(c);let g=`${b.owner}/${b.repo}#${b.number}`;if(h.has(g))continue;h.add(g);let i=d.get(f);i&&i.push(b)}}for(let[a,b]of d){let d=c.get("scm",a);if(!d?.enrichSessionsPRBatch)continue;let h=[...e.get(a)??[]],i=Date.now();try{for(let[c,e]of(await d.enrichSessionsPRBatch(b,{recordSuccess(c){let d=Date.now()-i;g?.recordOperation({metric:"graphql_batch",operation:"batch_enrichment",correlationId:dG("graphql-batch"),outcome:"success",projectId:f,durationMs:d,data:{plugin:a,prCount:b.length,prKeys:b.map(a=>`${a.owner}/${a.repo}#${a.number}`)},level:"info"})},recordFailure(c){let d=Date.now()-i;g?.recordOperation({metric:"graphql_batch",operation:"batch_enrichment",correlationId:dG("graphql-batch"),outcome:"failure",reason:c.error,level:"warn",data:{plugin:a,prCount:b.length,error:c.error,durationMs:d}})},log(b,c){g?.recordDiagnostic?.({operation:"batch_enrichment.log",correlationId:dG("graphql-batch"),projectId:f,message:c,level:b,data:{plugin:a,source:"ao-graphql-batch"}})},reportPRListUnchangedRepos(a){for(let b of a)t.add(b)}},h)))p.set(c,e)}catch(e){let c=e instanceof Error?e.message:String(e),d=dG("batch-enrichment");g?.recordOperation?.({metric:"lifecycle_poll",operation:"batch_enrichment",correlationId:d,outcome:"failure",reason:c,level:"warn",data:{plugin:a,prCount:b.length}}),S({projectId:f,source:"scm",kind:"scm.batch_enrich_failed",level:"warn",summary:`batch_enrich failed for ${b.length} PR(s)`,data:{plugin:a,prCount:b.length,errorMessage:c}})}}for(let d of a){if(!d.branch||"off"===d.metadata.prAutoDetect||"false"===d.metadata.prAutoDetect||"orchestrator"===d.metadata.role||d.id.endsWith("-orchestrator"))continue;let a=q(d),e=new Set(a.map(a=>`${a.owner}/${a.repo}`)),f=b.projects[d.projectId]?.repo,h="closed"===d.lifecycle.pr.state;if(a.length>0&&f&&e.has(f)&&!h)continue;let i=b.projects[d.projectId];if(!i?.repo||!i.scm?.plugin||t.has(i.repo))continue;let j=c.get("scm",i.scm.plugin);if(j?.detectPR)try{let b=await j.detectPR(d,i);if(b){a.some(a=>a.owner===b.owner&&a.repo===b.repo&&a.number===b.number)||(d.prs=d.prs.filter(a=>a.owner!==b.owner||a.repo!==b.repo||a.number===b.number||p.get(`${a.owner}/${a.repo}#${a.number}`)?.state!=="closed").concat(b)),d.prs=a_(d.prs),d.pr=d.prs[0]??b;let c=o(d.projectId),e=[...new Set(d.prs.map(a=>a.url))].join(",");bq(c,d.id,{pr:d.pr.url,prs:e}),S({projectId:d.projectId,sessionId:d.id,source:"scm",kind:"scm.detect_pr_succeeded",summary:`PR #${b.number} detected`,data:{plugin:i.scm.plugin,prNumber:b.number,prUrl:b.url,prOwner:b.owner,prRepo:b.repo}})}}catch(b){let a=b instanceof Error?b.message:String(b);g?.recordOperation?.({metric:"lifecycle_poll",operation:"scm.detect_pr",outcome:"failure",correlationId:dG("detect-pr"),projectId:d.projectId,sessionId:d.id,reason:a,level:"warn"}),S({projectId:d.projectId,sessionId:d.id,source:"scm",kind:"scm.detect_pr_failed",level:"warn",summary:`detect_pr failed for ${d.id}`,data:{plugin:i.scm.plugin,errorMessage:a}})}}}function w(a,b){let c=B(a,"agent-stuck"),d=c?.threshold;if("string"!=typeof d)return!1;let e=dS(d);return!(e<=0)&&Date.now()-b.getTime()>e}async function x(a,c){var f,g;let h=b.projects[a.projectId];if(!h)return;let i=Object.values(b.projects).map(a=>a.sessionPrefix),j=bw(a.id,a.metadata,h.sessionPrefix,i),k=a.workspacePath;if(!("worker"===j&&null!==k&&(!a.pr||"closed"===a.lifecycle.pr.state)))return;let l=await dY(k);if("detached"===l.kind){null!==a.branch&&(a.branch=null,C(a,{branch:""}));return}if("branch"!==l.kind||l.branch===a.branch)return;let m=function(a,b){let c=`${a.projectId}:${b}`,d=n.get(c);return d&&d!==a.id?null:(n.set(c,a.id),c)}(a,l.branch);if(m)try{let g=c??await e.list(a.projectId);f=l.branch,g.some(c=>{if(c.id===a.id||c.projectId!==a.projectId||d.CM.has(c.status))return!1;let e=b.projects[c.projectId];return!!e&&"worker"===bw(c.id,c.metadata,e.sessionPrefix,i)&&c.branch===f})||(a.branch=l.branch,C(a,{branch:l.branch}))}finally{g=a.id,n.get(m)===g&&n.delete(m)}}async function y(a){let e=b.projects[a.projectId];if(!e)return{status:a.status,evidence:"project_missing",detectingAttempts:cv(a.metadata.detectingAttempts)};let f=bf(a.lifecycle),h=new Date().toISOString(),j=a.metadata.agent,k=j?c.get("agent",j):null,l=e.scm?.plugin?c.get("scm",e.scm.plugin):null,m=null,n=!1,o=a.status!==d.SB.SPAWNING,q=cv(a.metadata.detectingAttempts),r=a.metadata.detectingStartedAt||void 0,s=a.metadata.detectingEvidenceHash||void 0,t=(b={status:bd(f),evidence:"lifecycle_commit",detecting:{attempts:q}})=>(b.prState&&(f.pr.state=b.prState,f.pr.lastObservedAt=h),b.prReason&&(f.pr.reason=b.prReason),b.sessionState&&b.sessionReason&&(f.session.state=b.sessionState,f.session.reason=b.sessionReason,f.session.lastTransitionAt=h,"working"===b.sessionState&&null===f.session.startedAt&&(f.session.startedAt=h),"done"===b.sessionState&&null===f.session.completedAt&&(f.session.completedAt=h),"terminated"===b.sessionState&&null===f.session.terminatedAt&&(f.session.terminatedAt=h)),a8(f),a.lifecycle=f,a.status=b.status,a.activitySignal=v,{status:b.status,evidence:b.evidence,detectingAttempts:b.detecting.attempts,detectingStartedAt:b.detecting.startedAt,detectingEvidenceHash:b.detecting.evidenceHash}),u={state:"unknown",failed:!1};if(a.runtimeHandle&&o){let d=c.get("runtime",e.runtime??b.defaults.runtime);if(d)try{let b=await d.isAlive(a.runtimeHandle);f.runtime.lastObservedAt=h,u={state:b?"alive":"dead",failed:!1},b?(f.runtime.state="alive",f.runtime.reason="process_running"):(f.runtime.state="missing",f.runtime.reason="tmux"===a.runtimeHandle.runtimeName?"tmux_missing":"process_missing")}catch(b){f.runtime.state="probe_failed",f.runtime.reason="probe_error",f.runtime.lastObservedAt=h,u={state:"unknown",failed:!0},S({projectId:a.projectId,sessionId:a.id,source:"runtime",kind:"runtime.probe_failed",level:"warn",summary:`runtime.isAlive probe failed for ${a.id}`,data:{runtimeName:a.runtimeHandle.runtimeName,errorMessage:b instanceof Error?b.message:String(b)}})}}let v=bC("unavailable"),x={state:"unknown",failed:!1},y=bF(v);if(k&&(a.runtimeHandle||a.workspacePath))try{if(k.recordActivity&&a.workspacePath&&a.runtimeHandle&&o)try{let d=c.get("runtime",e.runtime??b.defaults.runtime),f=d?await d.getOutput(a.runtimeHandle,10):"";f&&await k.recordActivity(a,f)}catch(b){g?.recordOperation?.({metric:"lifecycle_poll",operation:"activity.record",outcome:"failure",correlationId:dG("lifecycle-poll"),projectId:a.projectId,sessionId:a.id,reason:b instanceof Error?b.message:String(b),level:"warn"})}let l=await k.getActivityState(a,b.readyThresholdMs);if(l){v=bD(l,"native"),y=bF(v),f.runtime.lastObservedAt=h;let b=i.get(a.id);if(i.set(a.id,l.state),void 0!==b&&b!==l.state&&S({projectId:a.projectId,sessionId:a.id,source:"lifecycle",kind:"activity.transition",summary:`${b} → ${l.state}`,data:{from:b,to:l.state}}),"missing"!==f.runtime.state&&"probe_failed"!==f.runtime.state&&(f.runtime.state="alive",f.runtime.reason="process_running"),"waiting_input"===l.state)return t({status:d.SB.NEEDS_INPUT,evidence:y,detecting:{attempts:0},sessionState:"needs_input",sessionReason:"awaiting_user_input"});"exited"===l.state&&o&&(x={state:"dead",failed:!1},f.runtime.state="exited",f.runtime.reason="process_missing"),bE(v)&&(m=v.timestamp,n="blocked"===v.activity)}else if(a.runtimeHandle&&o){v=bC("null",{source:"native"}),y=bF(v);let g=c.get("runtime",e.runtime??b.defaults.runtime),i=g?await g.getOutput(a.runtimeHandle,10):"";if(i){let b=k.detectActivity(i);if(v=bD({state:b},"terminal"),y=bF(v),"waiting_input"===b)return t({status:d.SB.NEEDS_INPUT,evidence:y,detecting:{attempts:0},sessionState:"needs_input",sessionReason:"awaiting_user_input"});try{let b=await k.isProcessRunning(a.runtimeHandle);x=d3(b),!1===b&&(f.runtime.state="exited",f.runtime.reason="process_missing",f.runtime.lastObservedAt=h)}catch(b){x={state:"unknown",failed:!0},S({projectId:a.projectId,sessionId:a.id,source:"agent",kind:"agent.process_probe_failed",level:"warn",summary:`agent.isProcessRunning failed for ${a.id}`,data:{agentName:j,where:"fallback",errorMessage:b instanceof Error?b.message:String(b)}})}}}else v=bC("null",{source:"native"}),y=bF(v)}catch(b){if(y=bF(v=bC("probe_failure",{source:"native"})),S({projectId:a.projectId,sessionId:a.id,source:"agent",kind:"agent.activity_probe_failed",level:"warn",summary:`activity probing failed for ${a.id}`,data:{agentName:j,errorMessage:b instanceof Error?b.message:String(b)}}),"stuck"===f.session.state||"needs_input"===f.session.state||"detecting"===f.session.state)return t({status:a.status,evidence:y,detecting:{attempts:q}});return t(cs({currentAttempts:q,idleWasBlocked:n,evidence:y,detectingStartedAt:r,previousEvidenceHash:s}))}if("unknown"===x.state&&!x.indeterminate&&a.runtimeHandle&&o&&k)try{let b=await k.isProcessRunning(a.runtimeHandle);x=d3(b),!1===b&&(f.runtime.state="exited",f.runtime.reason="process_missing",f.runtime.lastObservedAt=h)}catch(b){x={state:"unknown",failed:!0},S({projectId:a.projectId,sessionId:a.id,source:"agent",kind:"agent.process_probe_failed",level:"warn",summary:`agent.isProcessRunning failed for ${a.id}`,data:{agentName:j,where:"standalone",errorMessage:b instanceof Error?b.message:String(b)}})}if(x.indeterminate)return S({projectId:a.projectId,sessionId:a.id,source:"agent",kind:"agent.process_probe_failed",level:"warn",summary:`agent.isProcessRunning indeterminate for ${a.id}`,data:{agentName:j,reason:"probe_indeterminate"}}),{status:a.status,evidence:a.metadata.lifecycleEvidence??"process_probe_indeterminate",detectingAttempts:q,detectingStartedAt:r,detectingEvidenceHash:s,skipMetadataWrite:!0};let z=function(a){let b=function(a,b=new Date){return"valid"===a.state&&a.timestamp instanceof Date&&null!==a.activity&&bz.has(a.activity)&&"stale"!==bB(a.timestamp,b)}(a.activitySignal);return a.runtimeProbe.failed||a.processProbe.failed?cs({currentAttempts:a.currentAttempts,idleWasBlocked:a.idleWasBlocked,evidence:`probe_failed runtime=${a.runtimeProbe.state} process=${a.processProbe.state} ${a.activityEvidence}`,detectingStartedAt:a.detectingStartedAt,previousEvidenceHash:a.previousEvidenceHash}):"dead"===a.runtimeProbe.state&&"alive"===a.processProbe.state||"alive"===a.runtimeProbe.state&&"dead"===a.processProbe.state||"dead"===a.runtimeProbe.state&&b?cs({currentAttempts:a.currentAttempts,idleWasBlocked:a.idleWasBlocked,evidence:`signal_disagreement runtime=${a.runtimeProbe.state} process=${a.processProbe.state} ${a.activityEvidence}`,reason:"dead"===a.runtimeProbe.state?"runtime_lost":"agent_process_exited",detectingStartedAt:a.detectingStartedAt,previousEvidenceHash:a.previousEvidenceHash}):"dead"===a.runtimeProbe.state&&"unknown"===a.processProbe.state&&a.canProbeRuntimeIdentity?cs({currentAttempts:a.currentAttempts,idleWasBlocked:a.idleWasBlocked,evidence:`runtime_dead process_unknown ${a.activityEvidence}`,reason:"runtime_lost",detectingStartedAt:a.detectingStartedAt,previousEvidenceHash:a.previousEvidenceHash}):"dead"!==a.runtimeProbe.state||"dead"!==a.processProbe.state||b?null:{status:d.SB.KILLED,evidence:`runtime_dead process_dead ${a.activityEvidence}`,detecting:{attempts:0},sessionState:"terminated",sessionReason:"runtime_lost"}}({currentAttempts:q,runtimeProbe:u,processProbe:x,canProbeRuntimeIdentity:o,activitySignal:v,activityEvidence:y,idleWasBlocked:n,detectingStartedAt:r,previousEvidenceHash:s});if(z)return t(z);if(a.pr&&l)try{let b=`${a.pr.owner}/${a.pr.repo}#${a.pr.number}`,c=p.get(b);"none"===f.pr.state&&(f.pr.state="open"),"not_created"===f.pr.reason&&(f.pr.reason="in_progress"),f.pr.number=a.pr.number,f.pr.url=a.pr.url,f.pr.lastObservedAt=h;let d=!!(null!==m&&bE(v))&&w(a,m);if(c){if(a.prs.length>1){let b=a.prs.map(a=>p.get(`${a.owner}/${a.repo}#${a.number}`)).filter(a=>void 0!==a);if(b.length===a.prs.length){let a={ciStatus:b.some(a=>"failing"===a.ciStatus)?"failing":b.every(a=>"passing"===a.ciStatus||"none"===a.ciStatus)?"passing":"pending",reviewDecision:b.some(a=>"changes_requested"===a.reviewDecision)?"changes_requested":b.every(a=>"approved"===a.reviewDecision)?"approved":b.every(a=>"none"===a.reviewDecision)?"none":"pending",state:b.every(a=>"merged"===a.state)?"merged":b.some(a=>"open"===a.state)?"open":"closed",mergeable:b.every(a=>a.mergeable),blockers:[...new Set(b.flatMap(a=>a.blockers??[]))],title:c.title,additions:c.additions,deletions:c.deletions,isDraft:b.some(a=>a.isDraft),hasConflicts:b.some(a=>a.hasConflicts),isBehind:b.some(a=>a.isBehind)};return t(cw(a,{shouldEscalateIdleToStuck:d,idleWasBlocked:n,activityEvidence:y}))}}if(a.prs.length<=1)return t(cw(c,{shouldEscalateIdleToStuck:d,idleWasBlocked:n,activityEvidence:y}))}try{if(a.prs.length>1){let b=await Promise.all(a.prs.map(a=>l.getPRState(a)));if(b.every(a=>"merged"===a||"closed"===a)){let a=b.every(a=>"merged"===a)?"merged":"closed";return t(cx({prState:a,ciStatus:"none",reviewDecision:"none",mergeable:!1,shouldEscalateIdleToStuck:d,idleWasBlocked:n,activityEvidence:y}))}}else{let b=await l.getPRState(a.pr);if("merged"===b||"closed"===b)return t(cx({prState:b,ciStatus:"none",reviewDecision:"none",mergeable:!1,shouldEscalateIdleToStuck:d,idleWasBlocked:n,activityEvidence:y}))}}catch(b){S({projectId:a.projectId,sessionId:a.id,source:"scm",kind:"scm.poll_pr_failed",level:"warn",summary:`getPRState failed for PR #${a.pr.number}`,data:{plugin:e.scm?.plugin,prNumber:a.pr.number,prUrl:a.pr.url,errorMessage:b instanceof Error?b.message:String(b)}})}}catch(b){g?.recordOperation?.({metric:"lifecycle_poll",operation:"scm.poll_pr",outcome:"failure",correlationId:dG("lifecycle-poll"),projectId:a.projectId,sessionId:a.id,reason:b instanceof Error?b.message:String(b),level:"warn"})}let A=bK(a.metadata);if(A&&function(a,b=new Date,c=3e5,d=6e4){let e=Date.parse(a.timestamp);if(Number.isNaN(e))return!1;let f=b.getTime();return!(e>f+d)&&f-e<=c}(A)&&"orchestrator"!==f.session.kind&&"terminated"!==f.session.state&&"done"!==f.session.state){let a=function(a){switch(a){case"started":return{sessionState:"working",sessionReason:"agent_acknowledged"};case"working":case"draft_pr_created":return{sessionState:"working",sessionReason:"task_in_progress"};case"waiting":case"ready_for_review":return{sessionState:"idle",sessionReason:"awaiting_external_review"};case"needs_input":return{sessionState:"needs_input",sessionReason:"awaiting_user_input"};case"fixing_ci":return{sessionState:"working",sessionReason:"fixing_ci"};case"addressing_reviews":return{sessionState:"working",sessionReason:"resolving_review_comments"};case"pr_created":return{sessionState:"idle",sessionReason:"pr_created"};case"completed":return{sessionState:"idle",sessionReason:"research_complete"}}}(A.state);return t({status:bd({...f,session:{...f.session,state:a.sessionState,reason:a.sessionReason}}),evidence:`agent_report:${A.state}`,detecting:{attempts:0},sessionState:a.sessionState,sessionReason:a.sessionReason})}return m&&bE(v)&&w(a,m)?t({status:d.SB.STUCK,evidence:`idle_beyond_threshold ${y}`,detecting:{attempts:0},sessionState:"stuck",sessionReason:n?"error_in_process":"probe_failure"}):"valid"!==v.state&&(a.status===d.SB.DETECTING||a.status===d.SB.STUCK||a.status===d.SB.NEEDS_INPUT||"detecting"===f.session.state||"stuck"===f.session.state||"needs_input"===f.session.state)?t("unavailable"!==v.state||"stuck"!==f.session.state||"probe_failure"!==f.session.reason||"alive"!==u.state||u.failed?{status:bd(f),evidence:y,detecting:{attempts:0}}:{status:d.SB.DETECTING,evidence:y,detecting:{attempts:0},sessionState:"detecting",sessionReason:"probe_failure"}):t(a.status===d.SB.SPAWNING||a.status===d.SB.DETECTING||a.status===d.SB.STUCK||a.status===d.SB.NEEDS_INPUT?{status:d.SB.WORKING,evidence:y,detecting:{attempts:0},sessionState:"working",sessionReason:"task_in_progress"}:{status:a.status,evidence:y,detecting:{attempts:0}})}async function z(a,b,c){let{id:d,projectId:f}=a,g=`${d}:${b}`,h=j.get(g);if(h||(h={attempts:0,firstTriggered:new Date},j.set(g,h)),h.escalated)return{reactionType:b,success:!0,action:"escalated",escalated:!0};h.attempts++;let i=c.retries??1/0,k=c.escalateAfter,l=!1;if(h.attempts>i&&(l=!0),"string"==typeof k){let a=dS(k);a>0&&Date.now()-h.firstTriggered.getTime()>a&&(l=!0)}if("number"==typeof k&&h.attempts>k&&(l=!0),l){let e=h.attempts>i?"max_retries":"number"==typeof k&&h.attempts>k?"max_attempts":"max_duration",g=Date.now()-h.firstTriggered.getTime();S({projectId:f,sessionId:d,source:"reaction",kind:"reaction.escalated",level:"warn",summary:`reaction ${b} escalated after ${h.attempts} attempts`,data:{reactionKey:b,attempts:h.attempts,durationSinceFirstMs:g,escalationCause:e}});let j=d0(a,p),l=d$("reaction.escalated",{sessionId:d,projectId:f,message:`Reaction '${b}' escalated after ${h.attempts} attempts`,data:function(a){let b=dR(a);return b.escalation={attempts:a.attempts,cause:a.cause,..."number"==typeof a.durationMs?{durationMs:a.durationMs}:{}},b}({eventType:"reaction.escalated",sessionId:d,projectId:f,context:j,reactionKey:b,action:"escalated",attempts:h.attempts,cause:e,durationMs:g,enrichment:s(a)})});return await L(l,c.priority??"urgent"),h.escalated=!0,{reactionType:b,success:!0,action:"escalated",escalated:!0}}let m=c.action??"notify";switch(m){case"send-to-agent":if(c.message)try{return await e.send(d,c.message),S({projectId:f,sessionId:d,source:"reaction",kind:"reaction.action_succeeded",summary:`send-to-agent ${b}`,data:{reactionKey:b,action:"send-to-agent",attempts:h.attempts}}),{reactionType:b,success:!0,action:"send-to-agent",message:c.message,escalated:!1}}catch(a){return S({projectId:f,sessionId:d,source:"reaction",kind:"reaction.send_to_agent_failed",level:"warn",summary:`send-to-agent failed for ${d}`,data:{reactionKey:b,attempts:h.attempts,errorMessage:a instanceof Error?a.message:String(a)}}),{reactionType:b,success:!1,action:"send-to-agent",escalated:!1}}break;case"notify":{let e=d0(a,p),g=d$("reaction.triggered",{sessionId:d,projectId:f,message:c.message??`Reaction '${b}' triggered notification`,data:dR({eventType:"reaction.triggered",sessionId:d,projectId:f,context:e,reactionKey:b,action:"notify",enrichment:s(a)})});return await L(g,c.priority??"info"),S({projectId:f,sessionId:d,source:"reaction",kind:"reaction.action_succeeded",summary:`notify ${b}`,data:{reactionKey:b,action:"notify",attempts:h.attempts}}),{reactionType:b,success:!0,action:"notify",escalated:!1}}case"auto-merge":{let e=d0(a,p),g=d$("reaction.triggered",{sessionId:d,projectId:f,message:c.message??`Reaction '${b}' triggered auto-merge`,data:dR({eventType:"reaction.triggered",sessionId:d,projectId:f,context:e,reactionKey:b,action:"auto-merge",enrichment:s(a)})});return await L(g,"action"),S({projectId:f,sessionId:d,source:"reaction",kind:"reaction.action_succeeded",summary:`auto-merge ${b}`,data:{reactionKey:b,action:"auto-merge",attempts:h.attempts}}),{reactionType:b,success:!0,action:"auto-merge",escalated:!1}}}return{reactionType:b,success:!1,action:m,escalated:!1}}function A(a,b){j.delete(`${a}:${b}`)}function B(a,c){let d=b.projects[a.projectId],e=b.reactions[c],f=d?.reactions?.[c];return(f?{...e,...f}:e)||null}function C(a,c){if(!b.projects[a.projectId])return;let d=o(a.projectId),f=be(bf(a.lifecycle)),g={...c,...f};bq(d,a.id,g),e.invalidateCache();let h=Object.fromEntries(Object.entries(a.metadata).filter(([a])=>{let b=g[a];return void 0===b||""!==b}));for(let[a,b]of Object.entries(g))void 0!==b&&""!==b&&(h[a]=b);a.metadata=h,a.status=bd(a.lifecycle)}function D(a){return[...a].sort().join(",")}async function E(a,f,g,h){let i,j=b.projects[a.projectId];if(!j||!a.pr)return;let k=j.scm?.plugin?c.get("scm",j.scm.plugin):null;if(!k)return;let l="changes-requested",m="bugbot-comments";if(d.CM.has(g)||"open"!==a.lifecycle.pr.state){A(a.id,l),A(a.id,m),u.delete(a.id),C(a,{lastPendingReviewFingerprint:"",lastPendingReviewDispatchHash:"",lastPendingReviewDispatchAt:"",lastAutomatedReviewFingerprint:"",lastAutomatedReviewDispatchHash:"",lastAutomatedReviewDispatchAt:""});return}if(h?.key!==l&&h?.key!==m){let b=u.get(a.id)??0;if(Date.now()-b<12e4)return}let n=[];try{if(k.getReviewThreads){let b=await k.getReviewThreads(a.pr);i=b.threads,n=b.reviews}else i=await k.getPendingComments(a.pr)}catch(b){S({projectId:a.projectId,sessionId:a.id,source:"scm",kind:"scm.review_fetch_failed",level:"warn",summary:`review fetch failed for PR #${a.pr.number}`,data:{plugin:j.scm?.plugin,prNumber:a.pr.number,prUrl:a.pr.url,errorMessage:b instanceof Error?b.message:String(b)}});return}u.set(a.id,Date.now());{let b=i.filter(a=>!a.isBot),c=JSON.stringify({unresolvedThreads:b.length,unresolvedComments:b.map(a=>({url:a.url,path:a.path??"",author:a.author,body:a.body})),reviews:n.map(a=>({author:a.author,state:a.state,body:a.body})),commentsUpdatedAt:new Date().toISOString()});a.metadata.prReviewComments!==c&&C(a,{prReviewComments:c});let d=q(a),e=r(a,d.length);Object.keys(e).length>0&&C(a,e);for(let b=1;b<d.length;b++){let c,e,f=d[b];if(!f)continue;try{if(k.getReviewThreads){let a=await k.getReviewThreads(f);c=a.threads,e=a.reviews}else c=await k.getPendingComments(f),e=[]}catch{continue}let g=c.filter(a=>!a.isBot),h=JSON.stringify({unresolvedThreads:g.length,unresolvedComments:g.map(a=>({url:a.url,path:a.path??"",author:a.author,body:a.body})),reviews:e.map(a=>({author:a.author,state:a.state,body:a.body})),commentsUpdatedAt:new Date().toISOString()}),i=`prReviewComments_${b}`;a.metadata[i]!==h&&C(a,{[i]:h})}}let o=i.filter(a=>!a.isBot),p=i.filter(a=>a.isBot);{let b=D(o.map(a=>a.id)),c=a.metadata.lastPendingReviewFingerprint??"",d=a.metadata.lastPendingReviewDispatchHash??"";if(b!==c&&h?.key!==l&&A(a.id,l),b!==c&&C(a,{lastPendingReviewFingerprint:b}),b){if(b!==d){let c=B(a,l);if(c&&c.action&&(!1!==c.auto||"notify"===c.action)){let d=F(o,"reviewer",n),f=!1;if(h?.key===l&&"send-to-agent"===c.action)try{await e.send(a.id,d),f=!0}catch{}else{let b={...c,message:d};f=(await z(a,l,b)).success}f&&C(a,{lastPendingReviewDispatchHash:b,lastPendingReviewDispatchAt:new Date().toISOString()})}}}else A(a.id,l),C(a,{lastPendingReviewFingerprint:"",lastPendingReviewDispatchHash:"",lastPendingReviewDispatchAt:""})}{let b=D(p.map(a=>a.id)),c=a.metadata.lastAutomatedReviewFingerprint??"",d=a.metadata.lastAutomatedReviewDispatchHash??"";if(b!==c&&(A(a.id,m),C(a,{lastAutomatedReviewFingerprint:b})),b){if(b!==d){let c=B(a,m);if(c&&c.action&&(!1!==c.auto||"notify"===c.action)){let d=F(p,"bot"),f=!1;if(h?.key===m&&"send-to-agent"===c.action)try{await e.send(a.id,d),f=!0}catch{}else{let b={...c,message:d};f=(await z(a,m,b)).success}f&&C(a,{lastAutomatedReviewDispatchHash:b,lastAutomatedReviewDispatchAt:new Date().toISOString()})}}}else A(a.id,m),C(a,{lastAutomatedReviewFingerprint:"",lastAutomatedReviewDispatchHash:"",lastAutomatedReviewDispatchAt:""})}}function F(a,b,c=[]){let d=[],e=c.filter(a=>a.body&&a.body.trim().length>0);if(e.length>0)for(let a of e)d.push(`Review by @${a.author} (${a.state}):`),d.push(`"${a.body.trim()}"`,"");let f="reviewer"===b?`The following ${a.length} unresolved review comment(s) are on your PR (as of just now). You should not need to re-fetch this data unless you need additional context.`:`The following ${a.length} automated review comment(s) are on your PR (as of just now). You should not need to re-fetch this data unless you need additional context.`;d.push(f,"");for(let b=0;b<a.length;b++){let c=a[b],e=c.path?`${c.path}${c.line?`:${c.line}`:""}`:"(general)";d.push(`${b+1}. ${e} (@${c.author}): "${c.body}"`),c.url&&d.push(` ${c.url}`),c.threadId&&d.push(` Thread ID: ${c.threadId}`)}return d.push("","Address each comment, push fixes. Use the thread ID to resolve each thread directly after pushing. You should not need to re-fetch review data unless you need additional context beyond what is provided here."),d.join("\n")}function G(a){return"failed"===a.status||a.conclusion?.toUpperCase()==="FAILURE"}async function H(a,b,c){if(a.getCIFailureSummary)try{let d=await a.getCIFailureSummary(b,c);if(d?.failedJobs.length)return function(a){let b=["CI is failing on your PR.",""];for(let c of a.failedJobs){let a=c.failedStep?`${c.name} → ${c.failedStep}`:c.name;if(b.push(`Failed: ${a}`),b.push(`Failure URL: ${c.runUrl}`),c.logTail){let a=c.logTail.split(/\r?\n/).length,d=1===a?"line":"lines",e=c.logTail.split(/\r?\n/).map(a=>a.startsWith("```")?`\u200B${a}`:a).join("\n");b.push("",`Log tail (last ${a} ${d}):`,"```",e,"```")}b.push("")}return b.push("Fix the issues and push again."),b.join("\n")}(d)}catch{}let d=["CI checks are failing on your PR. Here are the failed checks:",""];for(let a of c){let b=a.conclusion??a.status,c=a.url?` — ${a.url}`:"";d.push(`- **${a.name}**: ${b}${c}`)}return d.push("","Investigate the failures, fix the issues, and push again."),d.join("\n")}async function I(a,b,c){let d=`${b.owner}/${b.repo}#${b.number}`,e=p.get(d),f=e?.ciChecks;if(void 0===f&&c.allowFetch)try{f=await a.getCIChecks(b)}catch{return null}let g=f?.filter(G)??[];return g.length>0?g:null}async function J(a,d,f,g){let h=b.projects[a.projectId];if(!h||!a.pr)return;let i=h.scm?.plugin?c.get("scm",h.scm.plugin):null;if(!i)return;let j="ci-failed";if("merged"===f||"killed"===f){A(a.id,j),C(a,{lastCIFailureFingerprint:"",lastCIFailureDispatchHash:"",lastCIFailureDispatchAt:""});return}if("ci_failed"!==f){a.metadata.lastCIFailureFingerprint&&(A(a.id,j),C(a,{lastCIFailureFingerprint:"",lastCIFailureDispatchHash:"",lastCIFailureDispatchAt:""}));return}let k=await I(i,a.pr,{allowFetch:!0});if(!k)return;let l=D(k.map(a=>`${a.name}:${a.status}:${a.conclusion??""}`)),m=a.metadata.lastCIFailureFingerprint??"",n=a.metadata.lastCIFailureDispatchHash??"";if(l!==m&&g?.key!==j&&A(a.id,j),l!==m&&C(a,{lastCIFailureFingerprint:l}),g?.key===j&&g.result?.success&&(!0===g.messageEnriched||"send-to-agent"!==g.result.action))return void C(a,{lastCIFailureDispatchHash:l,lastCIFailureDispatchAt:new Date().toISOString()});if(l===n)return;let o=B(a,j);if(o&&o.action&&(!1!==o.auto||"notify"===o.action)){let b=await H(i,a.pr,k);try{if("send-to-agent"===o.action)await e.send(a.id,b);else{let c=d0(a,p),d=d$("ci.failing",{sessionId:a.id,projectId:a.projectId,message:b,data:function(a){let b=dO({...a,semanticType:"ci.failing"});return b.ci={status:"failing",failedChecks:a.failedChecks.map(dN)},b}({sessionId:a.id,projectId:a.projectId,context:c,failedChecks:k})});await L(d,o.priority??"warning")}C(a,{lastCIFailureDispatchHash:l,lastCIFailureDispatchAt:new Date().toISOString()})}catch{}}}async function K(a,d){let e=b.projects[a.projectId];if(!e||!a.pr||!(e.scm?.plugin?c.get("scm",e.scm.plugin):null))return;let f="merge-conflicts";if("open"!==a.lifecycle.pr.state||"killed"===d){A(a.id,f),C(a,{lastMergeConflictDispatched:""});return}if("pr_open"!==d&&"ci_failed"!==d&&"review_pending"!==d&&"changes_requested"!==d&&"approved"!==d&&"mergeable"!==d)return;let g=`${a.pr.owner}/${a.pr.repo}#${a.pr.number}`,h=p.get(g);if(!h)return;let i=h.hasConflicts??!1,j=a.metadata.lastMergeConflictDispatched??"";if(i){if("true"===j)return;let b=B(a,f);if(b&&b.action&&(!1!==b.auto||"notify"===b.action))try{let c={...b,priority:b.priority??"warning"};if("send-to-agent"===b.action&&!b.message){let b=a.pr.baseBranch??"the default branch",d=h.isBehind?` is behind ${b} and`:"";c.message=`Your PR branch${d} has merge conflicts with ${b}. Rebase your branch on ${b}, resolve the conflicts, and push. You should not need to call gh for merge status unless you need additional context — this information is current.`}let d=await z(a,f,c);d.success&&"escalated"!==d.action&&C(a,{lastMergeConflictDispatched:"true"})}catch{}}else"true"===j&&(C(a,{lastMergeConflictDispatched:""}),A(a.id,f))}async function L(a,d){let e={...a,priority:d};for(let a of b.notificationRouting[d]??b.defaults.notifiers){let d=function(a,b){let c=a.notifiers?.[b];return c?.plugin?{reference:b,pluginName:c.plugin}:{reference:b,pluginName:b}}(b,a),f=c.get("notifier",d.reference)??c.get("notifier",d.pluginName);if(!f){dK({observer:g,event:e,target:d,outcome:"failure",method:"notify",reason:"notifier target not found",failureKind:"target_missing",recordActivityEvent:!0});continue}try{await f.notify(e),dK({observer:g,event:e,target:d,outcome:"success",method:"notify"})}catch(a){dK({observer:g,event:e,target:d,outcome:"failure",method:"notify",reason:a instanceof Error?a.message:String(a),failureKind:"delivery_failed",recordActivityEvent:!0})}}}async function M(a){if(a.status!==d.SB.MERGED)return;let{autoCleanupOnMerge:c=!0,mergeCleanupIdleGraceMs:f=3e5}=b.lifecycle??{};if(!c)return;let i=new Date().toISOString(),j=a.metadata.mergedPendingCleanupSince||i,k=Date.parse(j),l=!!Number.isFinite(k)&&Date.now()-k>=f,m=a.activity;if((m===d.u3.ACTIVE||m===d.u3.WAITING_INPUT||m===d.u3.BLOCKED)&&!l){a.metadata.mergedPendingCleanupSince||C(a,{mergedPendingCleanupSince:i}),g.recordOperation({metric:"lifecycle_poll",operation:"lifecycle.merge_cleanup.deferred",outcome:"success",correlationId:dG("lifecycle-merge-cleanup"),projectId:a.projectId,sessionId:a.id,reason:d4(a.lifecycle),data:{activity:m,pendingSince:j,graceMs:f},level:"info"}),S({projectId:a.projectId,sessionId:a.id,source:"lifecycle",kind:"session.auto_cleanup_deferred",summary:`auto-cleanup deferred for ${a.id}`,data:{activity:m,pendingElapsedMs:Number.isFinite(k)?Date.now()-k:null,graceMs:f}});return}let n=dG("lifecycle-merge-cleanup");try{let b=await e.kill(a.id,{purgeOpenCode:!0,reason:"pr_merged"});g.recordOperation({metric:"lifecycle_poll",operation:"lifecycle.merge_cleanup.completed",outcome:"success",correlationId:n,projectId:a.projectId,sessionId:a.id,reason:d4(a.lifecycle),data:{cleaned:b.cleaned,alreadyTerminated:b.alreadyTerminated,graceElapsed:l,activity:m},level:"info"}),S({projectId:a.projectId,sessionId:a.id,source:"lifecycle",kind:"session.auto_cleanup_completed",summary:`auto-cleanup completed for ${a.id}`,data:{cleaned:b.cleaned,alreadyTerminated:b.alreadyTerminated,graceElapsed:l,activity:m}}),h.delete(a.id)}catch(c){a.metadata.mergedPendingCleanupSince||C(a,{mergedPendingCleanupSince:i});let b=c instanceof Error?c.message:String(c);g.recordOperation({metric:"lifecycle_poll",operation:"lifecycle.merge_cleanup.failed",outcome:"failure",correlationId:n,projectId:a.projectId,sessionId:a.id,reason:b,level:"warn"}),S({projectId:a.projectId,sessionId:a.id,source:"lifecycle",kind:"session.auto_cleanup_failed",level:"error",summary:`auto-cleanup failed for ${a.id}`,data:{errorMessage:b}})}}async function N(a){var e;let f,i=h.get(a.id)??(a.metadata?.status||a.status),j=bf(a.lifecycle),k=a.lifecycle.pr.state,l=await y(a);if(l.skipMetadataWrite)return void h.set(a.id,i);let n=l.status,o=a.metadata.lifecycle!==JSON.stringify(a.lifecycle),q=l.evidence,r=l.detectingAttempts>0?String(l.detectingAttempts):"",t=l.detectingStartedAt??"",u=l.detectingEvidenceHash??"",v=n===d.SB.STUCK&&(l.detectingAttempts>3||cr(t)),w=v?a.metadata.detectingEscalatedAt||new Date().toISOString():"";if(v&&!a.metadata.detectingEscalatedAt){let b=l.detectingAttempts>3?"max_attempts":"max_duration";S({projectId:a.projectId,sessionId:a.id,source:"lifecycle",kind:"detecting.escalated",level:"warn",summary:`detecting → stuck via ${b}`,data:{attempts:l.detectingAttempts,cause:b,startedAt:t}})}let x={};if(a.metadata.lifecycleEvidence!==q&&(x.lifecycleEvidence=q),(a.metadata.detectingAttempts||"")!==r&&(x.detectingAttempts=r),(a.metadata.detectingStartedAt||"")!==t&&(x.detectingStartedAt=t),(a.metadata.detectingEvidenceHash||"")!==u&&(x.detectingEvidenceHash=u),(a.metadata.detectingEscalatedAt||"")!==w&&(x.detectingEscalatedAt=w),Object.keys(x).length>0&&C(a,x),a.pr){let b=`${a.pr.owner}/${a.pr.repo}#${a.pr.number}`,c=p.get(b);if(c)if("passing"===c.ciStatus){let b=Number(a.metadata.ciPassingStableCount??"0")+1;b>=2?(A(a.id,"ci-failed"),C(a,{ciPassingStableCount:""})):C(a,{ciPassingStableCount:String(b)})}else a.metadata.ciPassingStableCount&&C(a,{ciPassingStableCount:""})}if(n!==i){let e=dG("lifecycle-transition");h.set(a.id,n),C(a,{status:n}),S({projectId:a.projectId,sessionId:a.id,source:"lifecycle",kind:"lifecycle.transition",level:"ci_failed"===n?"warn":"info",summary:`${i} → ${n}`,data:{from:i,to:n}}),g.recordOperation({metric:"lifecycle_poll",operation:"lifecycle.transition",outcome:"success",correlationId:e,projectId:a.projectId,sessionId:a.id,reason:d4(a.lifecycle),data:d5(j,a.lifecycle,i,n,l.evidence,l.detectingAttempts,!0),level:d2(n)}),d.CM.has(n)||(m=!1);let k=d_(void 0,i);if(k){let b=d1(k);b&&!dT.has(b)&&A(a.id,b)}let o=d_(i,n);if(o){let d=!1,h=d1(o);if(h){let k=B(a,h),m=!1;if("ci-failed"===h&&a.pr&&k?.action==="send-to-agent"){let d=b.projects[a.projectId],e=d?.scm?.plugin?c.get("scm",d.scm.plugin):null;if(e){let b=await I(e,a.pr,{allowFetch:!1});b&&(k={...k,message:await H(e,a.pr,b)},m=!0)}}if(k&&k.action&&(!1!==k.auto||"notify"===k.action)){let b=await z(a,h,k);f={key:h,result:b,messageEnriched:m},g.recordOperation({metric:"lifecycle_poll",operation:"lifecycle.transition.reaction",outcome:b.success?"success":"failure",correlationId:e,projectId:a.projectId,sessionId:a.id,reason:d4(a.lifecycle),data:d5(j,a.lifecycle,i,n,l.evidence,l.detectingAttempts,!0,f),level:b.success?"info":"warn"}),d=!0}}if(!d){let b=dZ(o),c=d0(a,p),d=d$(o,{sessionId:a.id,projectId:a.projectId,message:`${a.id}: ${i} → ${n}`,data:function(a){let b=dO({...a,semanticType:a.eventType});return b.transition={kind:"session_status",from:a.oldStatus,to:a.newStatus},dP(b,a.enrichment),dQ(b,a.eventType,a.enrichment),b}({eventType:o,sessionId:a.id,projectId:a.projectId,context:c,oldStatus:i,newStatus:n,enrichment:s(a)})});await L(d,b)}}}else h.set(a.id,n),o&&(C(a,{status:n}),g.recordOperation({metric:"lifecycle_poll",operation:"lifecycle.sync",outcome:"success",correlationId:dG("lifecycle-sync"),projectId:a.projectId,sessionId:a.id,reason:d4(a.lifecycle),data:d5(j,a.lifecycle,i,n,l.evidence,l.detectingAttempts,!1),level:d2(n)}));let D=k===(e=a.lifecycle.pr.state)?null:"closed"===e?"pr.closed":null;if(D){let b=!1,c=d1(D);if(c){let d=B(a,c);d&&d.action&&(!1!==d.auto||"notify"===d.action)&&(await z(a,c,d),b=!0)}if(!b){let b=d0(a,p),c=d$(D,{sessionId:a.id,projectId:a.projectId,message:`${a.id}: PR ${k} → ${a.lifecycle.pr.state}`,data:function(a){let b=dO({...a,semanticType:a.eventType});return b.transition={kind:"pr_state",from:a.oldPRState,to:a.newPRState},dP(b,a.enrichment),dQ(b,a.eventType,a.enrichment),b}({eventType:D,sessionId:a.id,projectId:a.projectId,context:b,oldPRState:k,newPRState:a.lifecycle.pr.state,enrichment:s(a)})});await L(c,dZ(D))}}if(a.agentInfo?.summary&&!a.agentInfo.summaryIsFallback&&!a.metadata.pinnedSummary){let b=a.agentInfo.summary.replace(/[\n\r]/g," ").trim();if(b.length>=5)try{C(a,{pinnedSummary:b})}catch{}}await Promise.allSettled([E(a,i,n,f),K(a,n),J(a,i,n,f)]),await O(a),await M(a)}async function O(a){let b=function(a,b={},c=new Date){if(cz.has(a.status)||a.lifecycle?.session.kind==="orchestrator")return null;let d={...cy,...b},e=bK(a.metadata),f=function(a,b,c,d){if(!d.checkBlocked||!b)return null;if("needs_input"===b.state){let a=Date.parse(b.timestamp),d=Number.isNaN(a)?void 0:c.getTime()-a;return{trigger:"agent_needs_input",message:`Agent needs input: ${b.note??"waiting for user decision"}`,checkedAt:c.toISOString(),report:b,timeSinceReportMs:d}}return null}(0,e,c,d);if(f)return f;let g=function(a,b,c,d){if(!d.checkAcknowledge||b)return null;let e=a.createdAt??a.metadata.createdAt;if(!e)return null;let f="string"==typeof e?Date.parse(e):e.getTime();if(Number.isNaN(f))return null;let g=c.getTime()-f;return g<d.acknowledgeTimeoutMs?null:{trigger:"no_acknowledge",message:`Agent has not acknowledged task after ${Math.round(g/6e4)} minutes`,checkedAt:c.toISOString(),report:null,timeSinceSpawnMs:g}}(a,e,c,d);if(g)return g;let h=function(a,b,c,d){if(!d.checkStale||!b)return null;let e=Date.parse(b.timestamp);if(Number.isNaN(e))return null;let f=c.getTime()-e;return f<d.staleReportTimeoutMs||"waiting"===b.state||"needs_input"===b.state?null:{trigger:"stale_report",message:`Agent report is stale (${Math.round(f/6e4)} minutes since last report)`,checkedAt:c.toISOString(),report:b,timeSinceReportMs:f}}(0,e,c,d);return h||null}(a),c=new Date().toISOString();if(!b||!b.trigger){a.metadata[cA.ACTIVE_TRIGGER]&&C(a,{[cA.LAST_AUDITED_AT]:c,[cA.ACTIVE_TRIGGER]:"",[cA.TRIGGER_ACTIVATED_AT]:"",[cA.TRIGGER_COUNT]:""});return}let d=function(a){switch(a){case"no_acknowledge":return"report-no-acknowledge";case"stale_report":return"report-stale";case"agent_needs_input":return"report-needs-input"}}(b.trigger),e=B(a,d),f=parseInt(a.metadata[cA.TRIGGER_COUNT]??"0",10),h=a.metadata[cA.ACTIVE_TRIGGER]!==b.trigger;C(a,{[cA.LAST_AUDITED_AT]:c,[cA.ACTIVE_TRIGGER]:b.trigger,[cA.TRIGGER_ACTIVATED_AT]:h?c:a.metadata[cA.TRIGGER_ACTIVATED_AT]??c,[cA.TRIGGER_COUNT]:String(h?1:f+1)}),g.recordOperation({metric:"lifecycle_poll",operation:"report_watcher.audit",outcome:"success",correlationId:dG("report-watcher"),projectId:a.projectId,sessionId:a.id,reason:b.trigger,data:{trigger:b.trigger,message:b.message,timeSinceSpawnMs:b.timeSinceSpawnMs,timeSinceReportMs:b.timeSinceReportMs,reportState:b.report?.state},level:"warn"}),h&&S({projectId:a.projectId,sessionId:a.id,source:"report-watcher",kind:"report_watcher.triggered",level:"warn",summary:`${b.trigger} triggered`,data:{trigger:b.trigger,message:b.message,timeSinceSpawnMs:b.timeSinceSpawnMs,timeSinceReportMs:b.timeSinceReportMs,reportState:b.report?.state}}),h&&e&&!1!==e.auto&&await z(a,d,e)}async function P(){let a=dG("lifecycle-poll"),c=Date.now();if(!l){l=!0;try{let k=await e.list(f),l=k.filter(a=>{if(!d.CM.has(a.status))return!0;let b=h.get(a.id);return void 0!==b&&b!==a.status});await Promise.allSettled(l.map(a=>x(a,k))),await v(l),await Promise.allSettled(l.map(a=>N(a))),function(a){for(let c of a){let a=q(c);if(!c.pr||!b.projects[c.projectId])continue;let d=o(c.projectId),e=r(c,a.length);Object.keys(e).length>0&&(bq(d,c.id,e),c.metadata=Object.fromEntries(Object.entries(c.metadata).filter(([a])=>void 0===e[a])));let f=`${c.pr.owner}/${c.pr.repo}#${c.pr.number}`,g=p.get(f);if(g){let a=JSON.stringify({state:g.state,ciStatus:g.ciStatus,reviewDecision:g.reviewDecision,mergeable:g.mergeable,title:g.title,additions:g.additions,deletions:g.deletions,isDraft:g.isDraft,hasConflicts:g.hasConflicts,isBehind:g.isBehind,blockers:g.blockers,ciChecks:g.ciChecks?.map(a=>({name:a.name,status:a.status,url:a.url})),enrichedAt:new Date().toISOString()});c.metadata.prEnrichment!==a&&(bq(d,c.id,{prEnrichment:a}),c.metadata.prEnrichment=a),void 0!==g.isDraft&&c.pr&&(c.pr.isDraft=g.isDraft)}for(let b=1;b<a.length;b++){let e=a[b];if(!e)continue;let f=`${e.owner}/${e.repo}#${e.number}`,g=p.get(f);if(!g)continue;let h=JSON.stringify({state:g.state,ciStatus:g.ciStatus,reviewDecision:g.reviewDecision,mergeable:g.mergeable,title:g.title,additions:g.additions,deletions:g.deletions,isDraft:g.isDraft,hasConflicts:g.hasConflicts,isBehind:g.isBehind,blockers:g.blockers,ciChecks:g.ciChecks?.map(a=>({name:a.name,status:a.status,url:a.url})),enrichedAt:new Date().toISOString()}),i=`prEnrichment_${b}`;c.metadata[i]!==h&&(bq(d,c.id,{[i]:h}),c.metadata[i]=h),void 0!==g.isDraft&&(e.isDraft=g.isDraft)}}}(l);let n=new Set(k.map(a=>a.id));for(let a of h.keys())n.has(a)||h.delete(a);for(let a of i.keys())n.has(a)||i.delete(a);for(let a of j.keys()){let b=a.split(":")[0];b&&!n.has(b)&&j.delete(a)}for(let a of u.keys())n.has(a)||u.delete(a);let s=k.filter(a=>!d.CM.has(a.status));if(k.length>0&&0===s.length&&!m){m=!0;let a=d1("summary.all_complete");if(a){let c=b.reactions[a];c&&c.action&&(!1!==c.auto||"notify"===c.action)&&await z({id:"system",projectId:"all",pr:null,issueId:null,branch:null,metadata:{},agentInfo:null},a,c)}}f&&(g.recordOperation({metric:"lifecycle_poll",operation:"lifecycle.poll",outcome:"success",correlationId:a,projectId:f,durationMs:Date.now()-c,data:{sessionCount:k.length,activeSessionCount:s.length},level:"info"}),g.setHealth({surface:"lifecycle.worker",status:"ok",projectId:f,correlationId:a,details:{projectId:f,sessionCount:k.length,activeSessionCount:s.length}}))}catch(d){let b=d instanceof Error?d.message:String(d);g.recordOperation({metric:"lifecycle_poll",operation:"lifecycle.poll",outcome:"failure",correlationId:a,projectId:f,durationMs:Date.now()-c,reason:b,level:"error"}),S({projectId:f,source:"lifecycle",kind:"lifecycle.poll_failed",level:"error",summary:"poll cycle failed",data:{errorMessage:b,durationMs:Date.now()-c,projectScope:f??"all"}}),g.setHealth({surface:"lifecycle.worker",status:"error",projectId:f,correlationId:a,reason:b,details:f?{projectId:f}:{projectScope:"all"}})}finally{l=!1}}}return{start(a=3e4){k||(k=setInterval(()=>void P(),a),P())},stop(){k&&(clearInterval(k),k=null)},getStates:()=>new Map(h),async check(a){let b=await e.get(a);if(!b)throw Error(`Session ${a} not found`);await x(b),await v([b]),await N(b)}}}function d7(a){let b=function(a){let{config:b,projectId:c,project:d}=a,e=!!d.repo;return{projectId:c,projectName:d.name,projectRepo:d.repo??"not configured",projectDefaultBranch:d.defaultBranch,projectSessionPrefix:d.sessionPrefix,projectPath:d.path,dashboardPort:String(b.port??3e3),automatedReactionsSection:function(a){let b="*".repeat(2),c=a=>`${b}${a}${b}`,d=[];for(let[b,e]of Object.entries(a.reactions??{})){if(e.auto&&"send-to-agent"===e.action){d.push(`- ${c(b)}: Auto-sends instruction to agent (retries: ${e.retries??"none"}, escalates after: ${e.escalateAfter??"never"})`);continue}e.auto&&"notify"===e.action&&d.push(`- ${c(b)}: Notifies human (priority: ${e.priority??"info"})`)}return 0===d.length?"":d.join("\n")}(d),projectSpecificRulesSection:function(a){let b=a.orchestratorRules?.trim();return b||""}(d),repoConfiguredSection:e?"true":"",repoNotConfiguredSection:e?"":"true"}}(a);return(function(a,b){let c=a.replace(/\{\{([a-zA-Z0-9_]+)\}\}/g,"").match(/\{\{[^}]+\}\}/);if(c)throw Error(`Unresolved template placeholder: ${c[0]}`);return a.replace(/\{\{([a-zA-Z0-9_]+)\}\}/g,(a,c)=>{if(!Object.prototype.hasOwnProperty.call(b,c))throw Error(`Unresolved template placeholder: ${c}`);return b[c]})})(function(a,b){let c=[["REPO_CONFIGURED_SECTION_START","REPO_CONFIGURED_SECTION_END",b.repoConfiguredSection],["REPO_NOT_CONFIGURED_SECTION_START","REPO_NOT_CONFIGURED_SECTION_END",b.repoNotConfiguredSection],["AUTOMATED_REACTIONS_SECTION_START","AUTOMATED_REACTIONS_SECTION_END",b.automatedReactionsSection],["PROJECT_SPECIFIC_RULES_SECTION_START","PROJECT_SPECIFIC_RULES_SECTION_END",b.projectSpecificRulesSection]],d=a;for(let[a,b,e]of c){let c=`{{${a}}}`,f=`{{${b}}}`;for(;;){let a=d.indexOf(c),b=d.indexOf(f);if(-1===a&&-1===b)break;if(-1===a||-1===b||b<a)throw Error(`Malformed optional section block: expected ${c} before ${f}`);let g=b+f.length,h=d.slice(a+c.length,b);if(h.includes(c))throw Error(`Nested optional section blocks are not supported: ${c} before ${f}`);let i=e?h:"",j=d.slice(0,a),k=d.slice(g);d=i?j+i+k:function(a,b){let c=a.match(/\n*$/)?.[0]??"",d=b.match(/^\n*/)?.[0]??"",e=c.length+d.length>=2?"\n\n":c+d;return a.slice(0,a.length-c.length)+e+b.slice(d.length)}(j,k)}}return d}('# {{projectName}} Orchestrator\n\nYou are the **orchestrator agent** for the {{projectName}} project.\n\nYour role is to coordinate and manage worker agent sessions. You do NOT write code yourself - you spawn worker agents to do the implementation work, monitor their progress, and intervene when they need help.\n\n## Non-Negotiable Rules\n\n- Investigations from the orchestrator session are **read-only**. Inspect status, logs, metadata, PR state, and worker output, but do not edit repository files or implement fixes from the orchestrator session.\n- Any code change, test run tied to implementation, git branch work, or PR takeover must be delegated to a **worker session**.\n- The orchestrator session must never own a PR. Never claim a PR into the orchestrator session, and never treat the orchestrator as the worker responsible for implementation.\n- If an investigation discovers follow-up work, either spawn a worker session or direct an existing worker session with clear instructions.\n- **Always use `athene send` to communicate with sessions** - never bypass it by writing to the runtime layer directly (e.g. `tmux send-keys` / `tmux capture-pane` on Unix, or writing to the named pipe `\\\\.\\pipe\\ao-pty-<sessionId>` on Windows). Direct runtime access bypasses busy detection, retry logic, and input sanitization, and breaks multi-line input for some agents (e.g. Codex).\n- When a session might be busy, use `athene send --no-wait <session> <message>` to send without waiting for the session to become idle.\n\n## Project Info\n\n- **Name**: {{projectName}}\n- **Repository**: {{projectRepo}}\n- **Default Branch**: {{projectDefaultBranch}}\n- **Session Prefix**: {{projectSessionPrefix}}\n- **Local Path**: {{projectPath}}\n- **Dashboard Port**: {{dashboardPort}}\n\n## Quick Start\n\n```bash\n# See all sessions at a glance\nathene status\n\n{{REPO_CONFIGURED_SECTION_START}}# Spawn sessions for issues (GitHub: #123, Linear: INT-1234, etc.)\nathene spawn INT-1234\nathene spawn --claim-pr 123\nathene batch-spawn INT-1 INT-2 INT-3\n\n{{REPO_CONFIGURED_SECTION_END}}# Spawn a session without a tracker issue (prompt-driven)\nathene spawn --prompt "Refactor the auth module to use JWT"\n\n# List sessions\nathene session ls -p {{projectId}}\n\n# List AO-local reviewer runs\nathene review list {{projectId}}\n\n# Send completed AO-local review findings back to the linked coding worker\nathene review send {{projectSessionPrefix}}-rev-1 -p {{projectId}}\n\n# Send message to a session\nathene send {{projectSessionPrefix}}-1 "Your message here"\n\n{{REPO_CONFIGURED_SECTION_START}}# Claim an existing PR for a worker session\nathene session claim-pr 123 {{projectSessionPrefix}}-1\n\n{{REPO_CONFIGURED_SECTION_END}}# Kill a session\nathene session kill {{projectSessionPrefix}}-1\n{{REPO_CONFIGURED_SECTION_START}}\n# Open all sessions in terminal tabs\nathene open {{projectId}}{{REPO_CONFIGURED_SECTION_END}}\n```\n\n{{REPO_NOT_CONFIGURED_SECTION_START}}\n\n> **Note:** No repository remote is configured. Issue tracking, PR, and CI features are unavailable.\n> Add a `repo` field (owner/repo) to `agent-orchestrator.yaml` to enable them.\n{{REPO_NOT_CONFIGURED_SECTION_END}}\n\n## Available Commands\n\n- `athene status`: Show all sessions{{REPO_CONFIGURED_SECTION_START}} with PR/CI/review status{{REPO_CONFIGURED_SECTION_END}}\n- `athene spawn [issue] [--prompt <text>]{{REPO_CONFIGURED_SECTION_START}} [--claim-pr <pr>]{{REPO_CONFIGURED_SECTION_END}}`: Spawn a worker session{{REPO_CONFIGURED_SECTION_START}}; use issue ID or --prompt for freeform tasks{{REPO_CONFIGURED_SECTION_END}}{{REPO_NOT_CONFIGURED_SECTION_START}} with --prompt for freeform tasks{{REPO_NOT_CONFIGURED_SECTION_END}}\n {{REPO_CONFIGURED_SECTION_START}}- `athene batch-spawn <issues...>`: Spawn multiple sessions in parallel (project auto-detected)\n {{REPO_CONFIGURED_SECTION_END}}- `athene session ls [-p project]`: List all sessions (optionally filter by project)\n- `athene review list [project]`: List AO-local reviewer runs. These are review agents/runs, not coding worker sessions.\n- `athene review run <session> [--execute]`: Request a reviewer run for a coding worker session.\n- `athene review execute [project] [--run <run>]`: Execute a queued reviewer run.\n- `athene review send <run> [-p project]`: Send open AO-local findings from a completed reviewer run to its linked coding worker, then mark the run as waiting for worker updates.\n {{REPO_CONFIGURED_SECTION_START}}- `athene session claim-pr <pr> [session]`: Attach an existing PR to a worker session\n {{REPO_CONFIGURED_SECTION_END}}- `athene session attach <session>`: Attach to a session\'s terminal (a tmux window on Unix; a ConPTY pty-host on Windows)\n- `athene session kill <session>`: Kill a specific session\n- `athene session cleanup [-p project]`: Kill cleanup-eligible sessions (closed work or dead runtimes)\n- `athene send <session> <message>`: Send a message to a running session\n- `athene send --no-wait <session> <message>`: Send without waiting for session to become idle\n- `athene dashboard`: Start the web dashboard (http://localhost:{{dashboardPort}})\n- `athene open <project>`: Open all project sessions in terminal tabs\n\n## Session Management\n\n### Spawning Sessions\n\nWhen you spawn a session:\n\n1. A git worktree is created from `{{projectDefaultBranch}}`\n2. A feature branch is created (e.g., `feat/INT-1234` for issues, `session/<id>` for prompt-driven)\n3. A runtime session is started (e.g., `{{projectSessionPrefix}}-1`) — tmux session on Unix, ConPTY pty-host on Windows\n4. The agent is launched with context about the issue or prompt\n5. Metadata is written to the project-specific sessions directory\n\nA tracker issue is **not required**. Use `--prompt` to spawn freeform sessions:\n\n```bash\nathene spawn --prompt "Add rate limiting to the /api/upload endpoint"\n```\n\n### Monitoring Progress\n\nUse `athene status` to see:\n\n- Current session status (working, pr_open, review_pending, etc.)\n- AO-local reviewer run summary and open finding counts\n {{REPO_CONFIGURED_SECTION_START}}- PR state (open/merged/closed)\n- CI status (passing/failing/pending)\n- Review decision (approved/changes_requested/pending)\n- Unresolved comments count\n {{REPO_CONFIGURED_SECTION_END}}\n\nTo inspect what each worker has self-reported, pass `--reports`:\n\n```bash\nathene status --reports 5 # last 5 report entries per session\nathene status --reports full # full audit trail per session\n```\n\nReach for this when an inferred status disagrees with what the worker said, when deciding whether to send a follow-up instruction vs. wait, or when triaging a session that looks stuck.\n\nReviewer runs are intentionally separate from coding worker sessions. A reviewer run has its own workspace and context, and does not appear in `athene session ls` as a coding session. Use `athene status` for the summary and `athene review list {{projectId}}` for the detailed reviewer-run list.\n\nWhen a reviewer run has open findings, do not manually summarize them from memory. Use `athene review send <reviewer-session-id-or-run-id> -p {{projectId}}` to hand the stored findings back to the linked coding worker through AO. After sending, monitor the worker and request a new review once it reports the fixes are ready.\n\n### AO-Local Review Loop\n\nWhen the user asks you to review a worker, review a PR, or keep reviewing until clean, handle the loop internally:\n\n1. Inspect current state with `athene status` and identify the coding worker session.\n2. Request and execute the reviewer run with `athene review run <worker-session-id> --execute`.\n3. If the run is clean, report that the work is AO-review clean.\n4. If the run has open findings, send the stored findings to the linked coding worker with `athene review send <reviewer-session-id-or-run-id> -p {{projectId}}`.\n5. Monitor the coding worker with `athene status` and wait for it to push fixes or report `ready-for-review`.\n6. Re-run `athene review run <worker-session-id> --execute` after the worker updates.\n7. Continue until the review is clean, the worker is stuck, the user asks you to stop, or the configured review round limit is reached.\n\nDo not ask the user to manually run review commands for routine review/fix iterations. Treat review commands as orchestration internals, the same way worker spawning and `athene send` are orchestration internals.\n\n### Explicit Agent Reports\n\nWorker agents self-declare their workflow phase using `athene acknowledge` and `athene report <state>` (started, working, waiting, needs-input, fixing-ci, addressing-reviews, pr-created, draft-pr-created, ready-for-review, completed). These reports are persisted alongside the canonical lifecycle and may inform lifecycle inference, but do not replace runtime/activity/SCM-derived truth.\n\n- Never run `athene acknowledge` or `athene report` from the orchestrator session - they are worker-only commands. Read the audit trail with `athene status --reports` instead.\n- Fresh reports (<5 min) are useful hints when inference is weak, but runtime death, activity-based waiting_input, and SCM truth (merged/closed PR, CI failure, review decisions) still take precedence.\n- Use `--pr-url` / `--pr-number` on PR workflow reports when the agent knows them; merged/closed remain SCM-owned.\n- If an agent reports `waiting` but a PR actually merged, trust the PR state and follow up.\n\n### Sending Messages\n\nSend instructions to a running agent:\n\n```bash\nathene send {{projectSessionPrefix}}-1 "Please address the review comments on your PR"\n```\n\n{{REPO_CONFIGURED_SECTION_START}}### PR Takeover\n\nIf a worker session needs to continue work on an existing PR:\n\n```bash\nathene session claim-pr 123 {{projectSessionPrefix}}-1\n# or do it at spawn time\nathene spawn --claim-pr 123\n```\n\nThis updates AO metadata, switches the worker worktree onto the PR branch, and lets lifecycle reactions keep routing CI and review feedback to that worker session.\n\nNever claim a PR into `{{projectSessionPrefix}}-orchestrator`. If a PR needs implementation or takeover, delegate it to a worker session instead.\n{{REPO_CONFIGURED_SECTION_END}}\n\n### Investigation Workflow\n\nWhen debugging or triaging from the orchestrator session:\n\n1. Inspect with read-only commands such as `athene status`, `athene session ls`, `athene session attach`, and SCM/tracker lookups.\n2. Decide whether a worker already owns the work or a new worker is needed.\n3. Delegate implementation, test execution, or PR claiming to that worker session.\n4. Return to monitoring and coordination once the worker has the task.\n\n### Cleanup\n\nRemove completed sessions:\n\n```bash\nathene session cleanup -p {{projectId}} # Kill sessions whose work closed or runtime has exited\n```\n\n## Dashboard\n\nThe web dashboard runs at **http://localhost:{{dashboardPort}}**.\n\nFeatures:\n\n- Live session cards with activity status\n- PR table with CI checks and review state\n- Attention zones (merge ready, needs response, working, done)\n- One-click actions (send message, kill, merge PR)\n- Real-time updates via Server-Sent Events\n\n{{AUTOMATED_REACTIONS_SECTION_START}}\n\n## Automated Reactions\n\nThe system automatically handles these events:\n\n{{automatedReactionsSection}}\n{{AUTOMATED_REACTIONS_SECTION_END}}\n\n## Common Workflows\n\n{{REPO_CONFIGURED_SECTION_START}}### Bulk Issue Processing\n\n1. Get list of issues from tracker (GitHub/Linear/etc.)\n2. Use `athene batch-spawn` to spawn sessions for each issue\n3. Monitor with `athene status` or the dashboard\n4. Agents will fetch, implement, test, PR, and respond to reviews\n5. Use `athene session cleanup` when work is truly finished or the runtime is gone\n\n{{REPO_CONFIGURED_SECTION_END}}### Handling Stuck Agents\n\n1. Check `athene status` for sessions in "stuck" or "needs_input" state\n2. Attach with `athene session attach <session>` to see what they\'re doing\n3. Send clarification or instructions with `athene send <session> \'...\'`\n4. Or kill and respawn with fresh context if needed\n\n{{REPO_CONFIGURED_SECTION_START}}### PR Review Flow\n\n1. Agent creates PR and pushes\n2. CI runs automatically\n3. If CI fails: reaction auto-sends fix instructions to agent\n4. If reviewers request changes: reaction auto-sends comments to agent\n5. When approved + green: notify human to merge (unless auto-merge enabled)\n\n{{REPO_CONFIGURED_SECTION_END}}### Manual Intervention\n\nWhen an agent needs human judgment:\n\n1. You\'ll get a notification (desktop/slack/webhook)\n2. Check the dashboard or `athene status` for details\n3. Attach to the session if needed: `athene session attach <session>`\n4. Send instructions: `athene send <session> \'...\'`\n5. Or handle the human-only action yourself{{REPO_CONFIGURED_SECTION_START}} (merge PR, close issue, etc.){{REPO_CONFIGURED_SECTION_END}} while keeping implementation in worker sessions.\n\n## Tips\n\n1. **Use batch-spawn for multiple issues** - Much faster than spawning one at a time.\n\n2. **Check status before spawning** - Avoid creating duplicate sessions for issues already being worked on.\n\n3. **Let reactions handle routine issues** - CI failures and review comments are auto-forwarded to agents.\n\n4. **Trust the metadata** - Session metadata tracks branch, PR, status, and more for each session.\n\n5. **Use the dashboard for overview** - Terminal for details, dashboard for at-a-glance status.\n\n6. **Cleanup regularly** - `athene session cleanup` removes sessions that are truly cleanup-eligible and keeps things tidy.\n\n7. **Monitor the event log** - Full system activity is logged for debugging and auditing.\n\n8. **Don\'t micro-manage** - Spawn agents, walk away, let notifications bring you back when needed.\n\n{{PROJECT_SPECIFIC_RULES_SECTION_START}}\n\n## Project-Specific Rules\n\n{{projectSpecificRulesSection}}\n{{PROJECT_SPECIFIC_RULES_SECTION_END}}\n'.trim(),b),b).trim()}function d8(a){return(0,g.join)(a,".ao","activity.jsonl")}async function d9(a,b,c,d){let e=d8(a);await (0,bG.mkdir)((0,g.dirname)(e),{recursive:!0});let f={ts:new Date().toISOString(),state:b,source:c,...void 0!==d&&("waiting_input"===b||"blocked"===b)&&{trigger:d}};await (0,bG.appendFile)(e,JSON.stringify(f)+"\n","utf-8")}async function ea(a){let b=d8(a);try{let{open:a}=await Promise.resolve().then(c.t.bind(c,51455,19)),d=await a(b,"r");try{let a=await d.stat();if(0===a.size)return null;let b=Math.min(a.size,4096),c=Math.max(0,a.size-b),e=Buffer.alloc(b),{bytesRead:f}=await d.read(e,0,b,c);if(0===f)return null;let g=e.subarray(0,f).toString("utf-8").split("\n").filter(a=>a.trim());if(c>0&&g.length>1&&(g=g.slice(1)),0===g.length)return null;let h=null;for(let a=g.length-1;a>=0;a--)try{h=JSON.parse(g[a]);break}catch{continue}if(null===h||"object"!=typeof h||null===h||Array.isArray(h))return null;let i=h,j=new Set(["active","ready","idle","waiting_input","blocked","exited"]),k=new Set(["terminal","native","hook"]);if("string"!=typeof i.ts||"string"!=typeof i.state||"string"!=typeof i.source||!j.has(i.state)||!k.has(i.source))return null;return{entry:{ts:i.ts,state:i.state,source:i.source,..."string"==typeof i.trigger&&{trigger:i.trigger}},modifiedAt:a.mtime}}finally{await d.close()}}catch{return null}}function eb(a){if(!a)return null;let{entry:b}=a;if("waiting_input"===b.state||"blocked"===b.state){let a=new Date(b.ts);return Number.isNaN(a.getTime())?null:{state:b.state,timestamp:a}}return null}function ec(a,b,c){let d;if(!a)return null;let{entry:e}=a,f=new Date(e.ts);if(Number.isNaN(f.getTime()))return null;if("waiting_input"===e.state||"blocked"===e.state)return{state:e.state,timestamp:f};let g=Math.max(0,Date.now()-f.getTime());d=g<=b?"active":g<=c?"ready":"idle";let h={active:0,ready:1,idle:2},i=h[e.state]??2;return{state:(h[d]??2)>=i?d:e.state,timestamp:f}}async function ed(a,b,c){let{state:d,trigger:e}=function(a,b){let c=b(a),d="waiting_input"===c||"blocked"===c?a.trim().split("\n").slice(-3).join("\n"):void 0;return{state:c,trigger:d}}(b,c);if("waiting_input"!==d&&"blocked"!==d){let b=await ea(a);if(b&&b.entry.state===d&&Date.now()-b.modifiedAt.getTime()<2e4)return}await d9(a,d,"terminal",e)}let ee=(0,u.promisify)(t.execFile);async function ef(a,b=60){try{let{stdout:c}=await ee("git",["log",`--since=${b} seconds ago`,"--format=%H"],{cwd:a,timeout:5e3});return c.trim().length>0}catch{return!1}}let eg=(0,u.promisify)(t.execFile),eh=null;async function ei(){if(eh)return eh;let a=await ej();return eh=a,a}async function ej(){let a=(0,g.join)((0,h.homedir)(),".ao","bin"),b=(process.env.PATH??"").split(g.delimiter).filter(b=>b&&b!==a),c="win32"===process.platform?(process.env.PATHEXT?.split(";").filter(Boolean)??[".EXE",".CMD",".BAT"]).map(a=>a.toLowerCase()):[""];for(let a of b)for(let b of c){let c=(0,g.join)(a,`gh${b}`);try{return await (0,bG.access)(c,e.constants.X_OK),c}catch{}}throw Error("gh CLI not found outside ~/.ao/bin. Install gh or set GH_PATH to the real binary.")}function ek(a){if(!a)return;let b=a.trim();if(!b)return;let c=Number.parseInt(b,10);return Number.isFinite(c)?c:void 0}let el=new Set,em=new Set;async function en(a){let b=process.env.AO_GH_TRACE_FILE;if(!b)return;let c=(0,g.dirname)(b),d=`${JSON.stringify(a)}
942
+ `;try{el.has(c)||(await (0,bG.mkdir)(c,{recursive:!0}),el.add(c)),await (0,bG.appendFile)(b,d,"utf-8")}catch(a){if(!em.has(b)){em.add(b);let c=a instanceof Error?a.message:String(a);console.warn(`[gh-trace] Failed to write trace to ${b}: ${c}`)}}}function eo(a,b,c,d){let{statusLine:e,headers:f}=function(a){let b={},c=a.replace(/\r/g,"").split("\n"),d=-1;for(let a=c.length-1;a>=0;a--)if(c[a]?.startsWith("HTTP/")){d=a;break}if(-1===d)return{headers:b};let e=c[d];for(let a=d+1;a<c.length;a++){let d=c[a];if(!d)break;let e=d.indexOf(":");if(-1===e)continue;let f=d.slice(0,e).trim().toLowerCase(),g=d.slice(e+1).trim();b[f]=g}return{statusLine:e,headers:b}}(c.stdout??""),g=e?Number.parseInt(e.replace(/^HTTP\/[0-9.]+\s+/,"").split(" ")[0]??"",10):void 0;return{timestamp:new Date().toISOString(),component:b.component,operation:b.operation??function(a){if(0===a.length)return"gh";if(1===a.length)return`gh.${a[0]}`;for(let b=1;b<a.length;b++){let c=a[b];if(!c||c.startsWith("-")){("--method"===c||"-X"===c||"-H"===c||"--header"===c||"-f"===c||"--raw-field"===c||"-F"===c||"--field"===c||"--input"===c||"-t"===c||"--template"===c)&&b++;continue}let d=c.split("/")[0].split("?")[0];return`gh.${a[0]}.${d}`}return`gh.${a[0]}`}(a),projectId:b.projectId,sessionId:b.sessionId,cwd:b.cwd,args:function(a){let b=new Set(["-H","--header"]),c=["token=","password=","secret=","authorization="];return a.map((d,e)=>{let f=e>0?a[e-1]:void 0;if(f&&b.has(f)&&/^authorization:/i.test(d))return"Authorization: [REDACTED]";if(/^-H/i.test(d)&&/authorization:/i.test(d))return"-HAuthorization: [REDACTED]";for(let a of c)if(d.toLowerCase().startsWith(a))return`${d.slice(0,a.length)}[REDACTED]`;if(f&&("-f"===f||"--raw-field"===f||"-F"===f||"--field"===f)){for(let a of c)if(d.toLowerCase().startsWith(a))return`${d.slice(0,a.length)}[REDACTED]`}return d})}(a),endpoint:function(a){if("api"===a[0])for(let b=1;b<a.length;b++){let c=a[b];if(c){if("--method"===c||"-X"===c||"-H"===c||"--header"===c||"-f"===c||"--raw-field"===c||"-F"===c||"--field"===c||"--input"===c){b++;continue}if(!c.startsWith("-"))return c}}}(a),method:function(a){for(let b=0;b<a.length;b++)if("--method"===a[b]||"-X"===a[b])return a[b+1];return"api"===a[0]?"GET":void 0}(a),ok:c.ok,exitCode:c.exitCode,signal:c.signal,durationMs:d,stdoutBytes:Buffer.byteLength(c.stdout??"","utf-8"),stderrBytes:Buffer.byteLength(c.stderr??"","utf-8"),statusLine:e,httpStatus:Number.isFinite(g)?g:void 0,etag:f.etag,rateLimitLimit:ek(f["x-ratelimit-limit"]),rateLimitRemaining:ek(f["x-ratelimit-remaining"]),rateLimitReset:ek(f["x-ratelimit-reset"]),rateLimitResource:f["x-ratelimit-resource"],...function(a,b){if(!b.includes("graphql")||!a.includes('"rateLimit"'))return{};let c=a.match(/\r?\n\r?\n([\s\S]*)$/),d=c?c[1]:a;try{let a=JSON.parse(d.trim()),b=a?.data?.rateLimit;if(!b)return{};return{graphqlCost:"number"==typeof b.cost?b.cost:void 0,graphqlRemaining:"number"==typeof b.remaining?b.remaining:void 0,graphqlResetAt:"string"==typeof b.resetAt?b.resetAt:void 0}}catch{return{}}}(c.stdout??"",a)}}async function ep(a,b,c=3e4){let d=Date.now();try{let e=await ei(),{stdout:f,stderr:g}=await eg(e,a,{...b.cwd?{cwd:b.cwd}:{},maxBuffer:0xa00000,timeout:c}),h=eo(a,b,{ok:!0,stdout:f,stderr:g},Date.now()-d);return await en(h),f.trim()}catch(e){let c=eo(a,b,{ok:!1,stdout:"string"==typeof e.stdout?e.stdout:"",stderr:"string"==typeof e.stderr?e.stderr:"",exitCode:"number"==typeof e.exitCode?e.exitCode:"number"==typeof e.code?e.code:void 0,signal:"string"==typeof e.signal?e.signal:void 0},Date.now()-d);throw await en(c),e}}let eq={BUG_REPORT:"bug_report",IMPROVEMENT_SUGGESTION:"improvement_suggestion"},er=k.Yj().transform(a=>a.trim().replace(/\s+/g," ")).pipe(k.Yj().min(1));function es(a,b,c){if("nightly"===c){let c=eu(a),d=eu(b);if(et(c.prerelease)&&et(d.prerelease))return a!==b}return function(a,b){let c=eu(a),d=eu(b);for(let a=0;a<3;a++){let b=c.parts[a]??0,e=d.parts[a]??0;if(Number.isNaN(b)||Number.isNaN(e))return!1;if(b<e)return!0;if(b>e)return!1}return(!!c.prerelease||!!d.prerelease)&&(!!c.prerelease&&!d.prerelease||(!!c.prerelease||!d.prerelease)&&0>function(a,b){let c=a.split("."),d=b.split("."),e=Math.max(c.length,d.length);for(let a=0;a<e;a++){let b=c[a],e=d[a];if(void 0===b)return -1;if(void 0===e)return 1;let f=/^\d+$/.test(b),g=/^\d+$/.test(e);if(f&&g){let a=Number(b),c=Number(e);if(a!==c)return a<c?-1:1}else if(f!==g)return f?-1:1;else if(b!==e)return -1}return 0}(c.prerelease??"",d.prerelease??""))}(a,b)}function et(a){return"nightly"===a||a?.startsWith("nightly-")===!0||a?.startsWith("nightly.")===!0}function eu(a){let[b,...c]=a.split("-"),d=c.length>0?c.join("-"):void 0;return{parts:(b??"").split(".").map(Number),prerelease:d}}function ev(){let a=function(){let a=process.env.XDG_CACHE_HOME||(0,g.join)((0,h.homedir)(),".cache");return(0,g.join)(a,"ao","update-check.json")}();if(!(0,e.existsSync)(a))return null;try{let b=(0,e.readFileSync)(a,"utf-8");return JSON.parse(b)}catch{return null}}function ew(){let a=(0,J.createRequire)((0,aR.fileURLToPath)("file:///home/slievr/proj/Athene/packages/core/dist/update-cache.js"));for(let b of["@made-by-moonlight/athene/package.json","@made-by-moonlight/athene-cli/package.json","@made-by-moonlight/athene-web/package.json"])try{let c=a(b);if("string"==typeof c.version&&"0.0.0"!==c.version)return c.version}catch{}return"0.0.0"}function ex(a){let b=ac();if(!b?.projects[a])return;let{[a]:c,...d}=b.projects;if(b.projects=d,b.projectOrder){let c=b.projectOrder.filter(b=>b!==a);b.projectOrder=c.length>0?c:void 0}ad(b)}function ey(){return(0,g.join)((0,h.homedir)(),".agent-orchestrator","windows-pty-hosts.json")}function ez(){let a=ey();if(!(0,e.existsSync)(a))return[];try{let b=JSON.parse((0,e.readFileSync)(a,"utf-8"));if(!Array.isArray(b))return[];return b.filter(a=>"object"==typeof a&&null!==a&&"string"==typeof a.sessionId&&"number"==typeof a.ptyHostPid&&"string"==typeof a.pipePath)}catch{return[]}}function eA(a){let b=ey();if(0===a.length){try{(0,e.unlinkSync)(b)}catch{}return}D(b,JSON.stringify(a,null,2))}function eB(a){let b=ez().filter(b=>b.sessionId!==a.sessionId);b.push({...a,registeredAt:new Date().toISOString()}),eA(b)}function eC(a){let b=ez(),c=b.filter(b=>b.sessionId!==a);c.length!==b.length&&eA(c)}function eD(){let a=ez(),b=a.filter(a=>(function(a){try{return process.kill(a,0),!0}catch(a){return"EPERM"===a.code}})(a.ptyHostPid));return b.length!==a.length&&eA(b),b}k.Ik({title:er,body:er,evidence:k.YO(er).min(1),session:er,source:er,confidence:k.ai().finite().min(0).max(1)}).strict(),eq.BUG_REPORT,eq.IMPROVEMENT_SUGGESTION,k.Yj().regex(/^report_[A-Za-z0-9_-]+$/),k.Yj().datetime({offset:!0}),k.Yj().regex(/^[a-f0-9]{16}$/),(0,u.promisify)(t.execFile),new WeakSet},90337:()=>{}};