@evermore.work/server 2026.509.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1045) hide show
  1. package/dist/adapters/builtin-adapter-types.d.ts +5 -0
  2. package/dist/adapters/builtin-adapter-types.d.ts.map +1 -0
  3. package/dist/adapters/builtin-adapter-types.js +17 -0
  4. package/dist/adapters/builtin-adapter-types.js.map +1 -0
  5. package/dist/adapters/codex-models.d.ts +5 -0
  6. package/dist/adapters/codex-models.d.ts.map +1 -0
  7. package/dist/adapters/codex-models.js +105 -0
  8. package/dist/adapters/codex-models.js.map +1 -0
  9. package/dist/adapters/cursor-models.d.ts +13 -0
  10. package/dist/adapters/cursor-models.d.ts.map +1 -0
  11. package/dist/adapters/cursor-models.js +148 -0
  12. package/dist/adapters/cursor-models.js.map +1 -0
  13. package/dist/adapters/http/execute.d.ts +3 -0
  14. package/dist/adapters/http/execute.d.ts.map +1 -0
  15. package/dist/adapters/http/execute.js +51 -0
  16. package/dist/adapters/http/execute.js.map +1 -0
  17. package/dist/adapters/http/execute.test.d.ts +2 -0
  18. package/dist/adapters/http/execute.test.d.ts.map +1 -0
  19. package/dist/adapters/http/execute.test.js +40 -0
  20. package/dist/adapters/http/execute.test.js.map +1 -0
  21. package/dist/adapters/http/index.d.ts +3 -0
  22. package/dist/adapters/http/index.d.ts.map +1 -0
  23. package/dist/adapters/http/index.js +20 -0
  24. package/dist/adapters/http/index.js.map +1 -0
  25. package/dist/adapters/http/test.d.ts +3 -0
  26. package/dist/adapters/http/test.d.ts.map +1 -0
  27. package/dist/adapters/http/test.js +106 -0
  28. package/dist/adapters/http/test.js.map +1 -0
  29. package/dist/adapters/index.d.ts +4 -0
  30. package/dist/adapters/index.d.ts.map +1 -0
  31. package/dist/adapters/index.js +3 -0
  32. package/dist/adapters/index.js.map +1 -0
  33. package/dist/adapters/plugin-loader.d.ts +28 -0
  34. package/dist/adapters/plugin-loader.d.ts.map +1 -0
  35. package/dist/adapters/plugin-loader.js +196 -0
  36. package/dist/adapters/plugin-loader.js.map +1 -0
  37. package/dist/adapters/process/execute.d.ts +3 -0
  38. package/dist/adapters/process/execute.d.ts.map +1 -0
  39. package/dist/adapters/process/execute.js +70 -0
  40. package/dist/adapters/process/execute.js.map +1 -0
  41. package/dist/adapters/process/index.d.ts +3 -0
  42. package/dist/adapters/process/index.d.ts.map +1 -0
  43. package/dist/adapters/process/index.js +23 -0
  44. package/dist/adapters/process/index.js.map +1 -0
  45. package/dist/adapters/process/test.d.ts +3 -0
  46. package/dist/adapters/process/test.d.ts.map +1 -0
  47. package/dist/adapters/process/test.js +77 -0
  48. package/dist/adapters/process/test.js.map +1 -0
  49. package/dist/adapters/registry.d.ts +69 -0
  50. package/dist/adapters/registry.d.ts.map +1 -0
  51. package/dist/adapters/registry.js +566 -0
  52. package/dist/adapters/registry.js.map +1 -0
  53. package/dist/adapters/types.d.ts +2 -0
  54. package/dist/adapters/types.d.ts.map +1 -0
  55. package/dist/adapters/types.js +2 -0
  56. package/dist/adapters/types.js.map +1 -0
  57. package/dist/adapters/utils.d.ts +43 -0
  58. package/dist/adapters/utils.d.ts.map +1 -0
  59. package/dist/adapters/utils.js +52 -0
  60. package/dist/adapters/utils.js.map +1 -0
  61. package/dist/agent-auth-jwt.d.ts +14 -0
  62. package/dist/agent-auth-jwt.d.ts.map +1 -0
  63. package/dist/agent-auth-jwt.js +117 -0
  64. package/dist/agent-auth-jwt.js.map +1 -0
  65. package/dist/app.d.ts +43 -0
  66. package/dist/app.d.ts.map +1 -0
  67. package/dist/app.js +373 -0
  68. package/dist/app.js.map +1 -0
  69. package/dist/attachment-types.d.ts +23 -0
  70. package/dist/attachment-types.d.ts.map +1 -0
  71. package/dist/attachment-types.js +91 -0
  72. package/dist/attachment-types.js.map +1 -0
  73. package/dist/auth/better-auth.d.ts +33 -0
  74. package/dist/auth/better-auth.d.ts.map +1 -0
  75. package/dist/auth/better-auth.js +133 -0
  76. package/dist/auth/better-auth.js.map +1 -0
  77. package/dist/board-claim.d.ts +23 -0
  78. package/dist/board-claim.d.ts.map +1 -0
  79. package/dist/board-claim.js +115 -0
  80. package/dist/board-claim.js.map +1 -0
  81. package/dist/config-file.d.ts +3 -0
  82. package/dist/config-file.d.ts.map +1 -0
  83. package/dist/config-file.js +16 -0
  84. package/dist/config-file.js.map +1 -0
  85. package/dist/config.d.ts +44 -0
  86. package/dist/config.d.ts.map +1 -0
  87. package/dist/config.js +226 -0
  88. package/dist/config.js.map +1 -0
  89. package/dist/dev-runner-worktree.d.ts +15 -0
  90. package/dist/dev-runner-worktree.d.ts.map +1 -0
  91. package/dist/dev-runner-worktree.js +68 -0
  92. package/dist/dev-runner-worktree.js.map +1 -0
  93. package/dist/dev-server-status.d.ts +27 -0
  94. package/dist/dev-server-status.d.ts.map +1 -0
  95. package/dist/dev-server-status.js +74 -0
  96. package/dist/dev-server-status.js.map +1 -0
  97. package/dist/dev-watch-ignore.d.ts +2 -0
  98. package/dist/dev-watch-ignore.d.ts.map +1 -0
  99. package/dist/dev-watch-ignore.js +36 -0
  100. package/dist/dev-watch-ignore.js.map +1 -0
  101. package/dist/errors.d.ts +12 -0
  102. package/dist/errors.d.ts.map +1 -0
  103. package/dist/errors.js +28 -0
  104. package/dist/errors.js.map +1 -0
  105. package/dist/home-paths.d.ts +17 -0
  106. package/dist/home-paths.d.ts.map +1 -0
  107. package/dist/home-paths.js +75 -0
  108. package/dist/home-paths.js.map +1 -0
  109. package/dist/index.d.ts +10 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +753 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/lib/join-request-dedupe.d.ts +11 -0
  114. package/dist/lib/join-request-dedupe.d.ts.map +1 -0
  115. package/dist/lib/join-request-dedupe.js +49 -0
  116. package/dist/lib/join-request-dedupe.js.map +1 -0
  117. package/dist/log-redaction.d.ts +11 -0
  118. package/dist/log-redaction.d.ts.map +1 -0
  119. package/dist/log-redaction.js +122 -0
  120. package/dist/log-redaction.js.map +1 -0
  121. package/dist/middleware/auth.d.ts +12 -0
  122. package/dist/middleware/auth.d.ts.map +1 -0
  123. package/dist/middleware/auth.js +302 -0
  124. package/dist/middleware/auth.js.map +1 -0
  125. package/dist/middleware/board-mutation-guard.d.ts +3 -0
  126. package/dist/middleware/board-mutation-guard.d.ts.map +1 -0
  127. package/dist/middleware/board-mutation-guard.js +67 -0
  128. package/dist/middleware/board-mutation-guard.js.map +1 -0
  129. package/dist/middleware/error-handler.d.ts +17 -0
  130. package/dist/middleware/error-handler.d.ts.map +1 -0
  131. package/dist/middleware/error-handler.js +45 -0
  132. package/dist/middleware/error-handler.js.map +1 -0
  133. package/dist/middleware/http-log-policy.d.ts +2 -0
  134. package/dist/middleware/http-log-policy.d.ts.map +1 -0
  135. package/dist/middleware/http-log-policy.js +52 -0
  136. package/dist/middleware/http-log-policy.js.map +1 -0
  137. package/dist/middleware/index.d.ts +4 -0
  138. package/dist/middleware/index.d.ts.map +1 -0
  139. package/dist/middleware/index.js +4 -0
  140. package/dist/middleware/index.js.map +1 -0
  141. package/dist/middleware/logger.d.ts +4 -0
  142. package/dist/middleware/logger.d.ts.map +1 -0
  143. package/dist/middleware/logger.js +92 -0
  144. package/dist/middleware/logger.js.map +1 -0
  145. package/dist/middleware/private-hostname-guard.d.ts +11 -0
  146. package/dist/middleware/private-hostname-guard.d.ts.map +1 -0
  147. package/dist/middleware/private-hostname-guard.js +78 -0
  148. package/dist/middleware/private-hostname-guard.js.map +1 -0
  149. package/dist/middleware/validate.d.ts +4 -0
  150. package/dist/middleware/validate.d.ts.map +1 -0
  151. package/dist/middleware/validate.js +7 -0
  152. package/dist/middleware/validate.js.map +1 -0
  153. package/dist/onboarding-assets/ceo/AGENTS.md +59 -0
  154. package/dist/onboarding-assets/ceo/HEARTBEAT.md +85 -0
  155. package/dist/onboarding-assets/ceo/SOUL.md +33 -0
  156. package/dist/onboarding-assets/ceo/TOOLS.md +3 -0
  157. package/dist/onboarding-assets/default/AGENTS.md +17 -0
  158. package/dist/paths.d.ts +3 -0
  159. package/dist/paths.d.ts.map +1 -0
  160. package/dist/paths.js +31 -0
  161. package/dist/paths.js.map +1 -0
  162. package/dist/realtime/live-events-ws.d.ts +28 -0
  163. package/dist/realtime/live-events-ws.d.ts.map +1 -0
  164. package/dist/realtime/live-events-ws.js +187 -0
  165. package/dist/realtime/live-events-ws.js.map +1 -0
  166. package/dist/redaction.d.ts +5 -0
  167. package/dist/redaction.d.ts.map +1 -0
  168. package/dist/redaction.js +98 -0
  169. package/dist/redaction.js.map +1 -0
  170. package/dist/routes/access.d.ts +82 -0
  171. package/dist/routes/access.d.ts.map +1 -0
  172. package/dist/routes/access.js +3411 -0
  173. package/dist/routes/access.js.map +1 -0
  174. package/dist/routes/activity.d.ts +3 -0
  175. package/dist/routes/activity.d.ts.map +1 -0
  176. package/dist/routes/activity.js +90 -0
  177. package/dist/routes/activity.js.map +1 -0
  178. package/dist/routes/adapters.d.ts +16 -0
  179. package/dist/routes/adapters.d.ts.map +1 -0
  180. package/dist/routes/adapters.js +527 -0
  181. package/dist/routes/adapters.js.map +1 -0
  182. package/dist/routes/agents.d.ts +6 -0
  183. package/dist/routes/agents.d.ts.map +1 -0
  184. package/dist/routes/agents.js +2753 -0
  185. package/dist/routes/agents.js.map +1 -0
  186. package/dist/routes/approvals.d.ts +6 -0
  187. package/dist/routes/approvals.d.ts.map +1 -0
  188. package/dist/routes/approvals.js +300 -0
  189. package/dist/routes/approvals.js.map +1 -0
  190. package/dist/routes/assets.d.ts +4 -0
  191. package/dist/routes/assets.d.ts.map +1 -0
  192. package/dist/routes/assets.js +309 -0
  193. package/dist/routes/assets.js.map +1 -0
  194. package/dist/routes/auth.d.ts +3 -0
  195. package/dist/routes/auth.d.ts.map +1 -0
  196. package/dist/routes/auth.js +82 -0
  197. package/dist/routes/auth.js.map +1 -0
  198. package/dist/routes/authz.d.ts +19 -0
  199. package/dist/routes/authz.d.ts.map +1 -0
  200. package/dist/routes/authz.js +75 -0
  201. package/dist/routes/authz.js.map +1 -0
  202. package/dist/routes/companies.d.ts +4 -0
  203. package/dist/routes/companies.d.ts.map +1 -0
  204. package/dist/routes/companies.js +359 -0
  205. package/dist/routes/companies.js.map +1 -0
  206. package/dist/routes/company-skills.d.ts +3 -0
  207. package/dist/routes/company-skills.d.ts.map +1 -0
  208. package/dist/routes/company-skills.js +258 -0
  209. package/dist/routes/company-skills.js.map +1 -0
  210. package/dist/routes/costs.d.ts +11 -0
  211. package/dist/routes/costs.d.ts.map +1 -0
  212. package/dist/routes/costs.js +285 -0
  213. package/dist/routes/costs.js.map +1 -0
  214. package/dist/routes/dashboard.d.ts +3 -0
  215. package/dist/routes/dashboard.d.ts.map +1 -0
  216. package/dist/routes/dashboard.js +15 -0
  217. package/dist/routes/dashboard.js.map +1 -0
  218. package/dist/routes/environment-selection.d.ts +13 -0
  219. package/dist/routes/environment-selection.d.ts.map +1 -0
  220. package/dist/routes/environment-selection.js +30 -0
  221. package/dist/routes/environment-selection.js.map +1 -0
  222. package/dist/routes/environments.d.ts +6 -0
  223. package/dist/routes/environments.d.ts.map +1 -0
  224. package/dist/routes/environments.js +401 -0
  225. package/dist/routes/environments.js.map +1 -0
  226. package/dist/routes/execution-workspaces.d.ts +3 -0
  227. package/dist/routes/execution-workspaces.d.ts.map +1 -0
  228. package/dist/routes/execution-workspaces.js +536 -0
  229. package/dist/routes/execution-workspaces.js.map +1 -0
  230. package/dist/routes/goals.d.ts +3 -0
  231. package/dist/routes/goals.d.ts.map +1 -0
  232. package/dist/routes/goals.js +101 -0
  233. package/dist/routes/goals.js.map +1 -0
  234. package/dist/routes/health.d.ts +9 -0
  235. package/dist/routes/health.d.ts.map +1 -0
  236. package/dist/routes/health.js +114 -0
  237. package/dist/routes/health.js.map +1 -0
  238. package/dist/routes/inbox-dismissals.d.ts +3 -0
  239. package/dist/routes/inbox-dismissals.d.ts.map +1 -0
  240. package/dist/routes/inbox-dismissals.js +58 -0
  241. package/dist/routes/inbox-dismissals.js.map +1 -0
  242. package/dist/routes/index.d.ts +22 -0
  243. package/dist/routes/index.d.ts.map +1 -0
  244. package/dist/routes/index.js +22 -0
  245. package/dist/routes/index.js.map +1 -0
  246. package/dist/routes/instance-database-backups.d.ts +15 -0
  247. package/dist/routes/instance-database-backups.d.ts.map +1 -0
  248. package/dist/routes/instance-database-backups.js +12 -0
  249. package/dist/routes/instance-database-backups.js.map +1 -0
  250. package/dist/routes/instance-settings.d.ts +3 -0
  251. package/dist/routes/instance-settings.d.ts.map +1 -0
  252. package/dist/routes/instance-settings.js +110 -0
  253. package/dist/routes/instance-settings.js.map +1 -0
  254. package/dist/routes/issue-tree-control.d.ts +3 -0
  255. package/dist/routes/issue-tree-control.d.ts.map +1 -0
  256. package/dist/routes/issue-tree-control.js +363 -0
  257. package/dist/routes/issue-tree-control.js.map +1 -0
  258. package/dist/routes/issues-checkout-wakeup.d.ts +9 -0
  259. package/dist/routes/issues-checkout-wakeup.d.ts.map +1 -0
  260. package/dist/routes/issues-checkout-wakeup.js +12 -0
  261. package/dist/routes/issues-checkout-wakeup.js.map +1 -0
  262. package/dist/routes/issues.d.ts +23 -0
  263. package/dist/routes/issues.d.ts.map +1 -0
  264. package/dist/routes/issues.js +3886 -0
  265. package/dist/routes/issues.js.map +1 -0
  266. package/dist/routes/llms.d.ts +3 -0
  267. package/dist/routes/llms.d.ts.map +1 -0
  268. package/dist/routes/llms.js +80 -0
  269. package/dist/routes/llms.js.map +1 -0
  270. package/dist/routes/org-chart-svg.d.ts +25 -0
  271. package/dist/routes/org-chart-svg.d.ts.map +1 -0
  272. package/dist/routes/org-chart-svg.js +656 -0
  273. package/dist/routes/org-chart-svg.js.map +1 -0
  274. package/dist/routes/plugin-ui-static.d.ts +69 -0
  275. package/dist/routes/plugin-ui-static.d.ts.map +1 -0
  276. package/dist/routes/plugin-ui-static.js +411 -0
  277. package/dist/routes/plugin-ui-static.js.map +1 -0
  278. package/dist/routes/plugins.d.ts +121 -0
  279. package/dist/routes/plugins.d.ts.map +1 -0
  280. package/dist/routes/plugins.js +2192 -0
  281. package/dist/routes/plugins.js.map +1 -0
  282. package/dist/routes/projects.d.ts +3 -0
  283. package/dist/routes/projects.d.ts.map +1 -0
  284. package/dist/routes/projects.js +566 -0
  285. package/dist/routes/projects.js.map +1 -0
  286. package/dist/routes/routines.d.ts +6 -0
  287. package/dist/routes/routines.d.ts.map +1 -0
  288. package/dist/routes/routines.js +417 -0
  289. package/dist/routes/routines.js.map +1 -0
  290. package/dist/routes/secrets.d.ts +3 -0
  291. package/dist/routes/secrets.d.ts.map +1 -0
  292. package/dist/routes/secrets.js +128 -0
  293. package/dist/routes/secrets.js.map +1 -0
  294. package/dist/routes/sidebar-badges.d.ts +3 -0
  295. package/dist/routes/sidebar-badges.d.ts.map +1 -0
  296. package/dist/routes/sidebar-badges.js +68 -0
  297. package/dist/routes/sidebar-badges.js.map +1 -0
  298. package/dist/routes/sidebar-preferences.d.ts +3 -0
  299. package/dist/routes/sidebar-preferences.d.ts.map +1 -0
  300. package/dist/routes/sidebar-preferences.js +63 -0
  301. package/dist/routes/sidebar-preferences.js.map +1 -0
  302. package/dist/routes/user-profiles.d.ts +3 -0
  303. package/dist/routes/user-profiles.d.ts.map +1 -0
  304. package/dist/routes/user-profiles.js +337 -0
  305. package/dist/routes/user-profiles.js.map +1 -0
  306. package/dist/routes/workspace-command-authz.d.ts +14 -0
  307. package/dist/routes/workspace-command-authz.d.ts.map +1 -0
  308. package/dist/routes/workspace-command-authz.js +83 -0
  309. package/dist/routes/workspace-command-authz.js.map +1 -0
  310. package/dist/routes/workspace-runtime-service-authz.d.ts +12 -0
  311. package/dist/routes/workspace-runtime-service-authz.d.ts.map +1 -0
  312. package/dist/routes/workspace-runtime-service-authz.js +96 -0
  313. package/dist/routes/workspace-runtime-service-authz.js.map +1 -0
  314. package/dist/runtime-api.d.ts +19 -0
  315. package/dist/runtime-api.d.ts.map +1 -0
  316. package/dist/runtime-api.js +137 -0
  317. package/dist/runtime-api.js.map +1 -0
  318. package/dist/secrets/external-stub-providers.d.ts +5 -0
  319. package/dist/secrets/external-stub-providers.d.ts.map +1 -0
  320. package/dist/secrets/external-stub-providers.js +21 -0
  321. package/dist/secrets/external-stub-providers.js.map +1 -0
  322. package/dist/secrets/local-encrypted-provider.d.ts +3 -0
  323. package/dist/secrets/local-encrypted-provider.d.ts.map +1 -0
  324. package/dist/secrets/local-encrypted-provider.js +116 -0
  325. package/dist/secrets/local-encrypted-provider.js.map +1 -0
  326. package/dist/secrets/provider-registry.d.ts +5 -0
  327. package/dist/secrets/provider-registry.d.ts.map +1 -0
  328. package/dist/secrets/provider-registry.js +20 -0
  329. package/dist/secrets/provider-registry.js.map +1 -0
  330. package/dist/secrets/types.d.ts +21 -0
  331. package/dist/secrets/types.d.ts.map +1 -0
  332. package/dist/secrets/types.js +2 -0
  333. package/dist/secrets/types.js.map +1 -0
  334. package/dist/services/access.d.ts +171 -0
  335. package/dist/services/access.d.ts.map +1 -0
  336. package/dist/services/access.js +522 -0
  337. package/dist/services/access.js.map +1 -0
  338. package/dist/services/activity-log.d.ts +19 -0
  339. package/dist/services/activity-log.d.ts.map +1 -0
  340. package/dist/services/activity-log.js +99 -0
  341. package/dist/services/activity-log.js.map +1 -0
  342. package/dist/services/activity.d.ts +462 -0
  343. package/dist/services/activity.d.ts.map +1 -0
  344. package/dist/services/activity.js +443 -0
  345. package/dist/services/activity.js.map +1 -0
  346. package/dist/services/adapter-plugin-store.d.ts +36 -0
  347. package/dist/services/adapter-plugin-store.d.ts.map +1 -0
  348. package/dist/services/adapter-plugin-store.js +154 -0
  349. package/dist/services/adapter-plugin-store.js.map +1 -0
  350. package/dist/services/agent-instructions.d.ts +91 -0
  351. package/dist/services/agent-instructions.d.ts.map +1 -0
  352. package/dist/services/agent-instructions.js +580 -0
  353. package/dist/services/agent-instructions.js.map +1 -0
  354. package/dist/services/agent-permissions.d.ts +6 -0
  355. package/dist/services/agent-permissions.d.ts.map +1 -0
  356. package/dist/services/agent-permissions.js +18 -0
  357. package/dist/services/agent-permissions.js.map +1 -0
  358. package/dist/services/agent-start-lock.d.ts +2 -0
  359. package/dist/services/agent-start-lock.d.ts.map +1 -0
  360. package/dist/services/agent-start-lock.js +43 -0
  361. package/dist/services/agent-start-lock.js.map +1 -0
  362. package/dist/services/agents.d.ts +2253 -0
  363. package/dist/services/agents.d.ts.map +1 -0
  364. package/dist/services/agents.js +609 -0
  365. package/dist/services/agents.js.map +1 -0
  366. package/dist/services/approvals.d.ts +546 -0
  367. package/dist/services/approvals.d.ts.map +1 -0
  368. package/dist/services/approvals.js +212 -0
  369. package/dist/services/approvals.js.map +1 -0
  370. package/dist/services/assets.d.ts +33 -0
  371. package/dist/services/assets.d.ts.map +1 -0
  372. package/dist/services/assets.js +17 -0
  373. package/dist/services/assets.js.map +1 -0
  374. package/dist/services/board-auth.d.ts +239 -0
  375. package/dist/services/board-auth.d.ts.map +1 -0
  376. package/dist/services/board-auth.js +300 -0
  377. package/dist/services/board-auth.js.map +1 -0
  378. package/dist/services/budgets.d.ts +38 -0
  379. package/dist/services/budgets.d.ts.map +1 -0
  380. package/dist/services/budgets.js +784 -0
  381. package/dist/services/budgets.js.map +1 -0
  382. package/dist/services/companies.d.ts +154 -0
  383. package/dist/services/companies.d.ts.map +1 -0
  384. package/dist/services/companies.js +267 -0
  385. package/dist/services/companies.js.map +1 -0
  386. package/dist/services/company-export-readme.d.ts +17 -0
  387. package/dist/services/company-export-readme.d.ts.map +1 -0
  388. package/dist/services/company-export-readme.js +148 -0
  389. package/dist/services/company-export-readme.js.map +1 -0
  390. package/dist/services/company-member-roles.d.ts +9 -0
  391. package/dist/services/company-member-roles.d.ts.map +1 -0
  392. package/dist/services/company-member-roles.js +46 -0
  393. package/dist/services/company-member-roles.js.map +1 -0
  394. package/dist/services/company-portability.d.ts +24 -0
  395. package/dist/services/company-portability.d.ts.map +1 -0
  396. package/dist/services/company-portability.js +4076 -0
  397. package/dist/services/company-portability.js.map +1 -0
  398. package/dist/services/company-search-rate-limit.d.ts +22 -0
  399. package/dist/services/company-search-rate-limit.d.ts.map +1 -0
  400. package/dist/services/company-search-rate-limit.js +38 -0
  401. package/dist/services/company-search-rate-limit.js.map +1 -0
  402. package/dist/services/company-search.d.ts +8 -0
  403. package/dist/services/company-search.d.ts.map +1 -0
  404. package/dist/services/company-search.js +626 -0
  405. package/dist/services/company-search.js.map +1 -0
  406. package/dist/services/company-skills.d.ts +77 -0
  407. package/dist/services/company-skills.d.ts.map +1 -0
  408. package/dist/services/company-skills.js +2120 -0
  409. package/dist/services/company-skills.js.map +1 -0
  410. package/dist/services/costs.d.ts +127 -0
  411. package/dist/services/costs.d.ts.map +1 -0
  412. package/dist/services/costs.js +409 -0
  413. package/dist/services/costs.js.map +1 -0
  414. package/dist/services/cron.d.ts +80 -0
  415. package/dist/services/cron.d.ts.map +1 -0
  416. package/dist/services/cron.js +300 -0
  417. package/dist/services/cron.js.map +1 -0
  418. package/dist/services/dashboard.d.ts +34 -0
  419. package/dist/services/dashboard.d.ts.map +1 -0
  420. package/dist/services/dashboard.js +142 -0
  421. package/dist/services/dashboard.js.map +1 -0
  422. package/dist/services/default-agent-instructions.d.ts +9 -0
  423. package/dist/services/default-agent-instructions.d.ts.map +1 -0
  424. package/dist/services/default-agent-instructions.js +20 -0
  425. package/dist/services/default-agent-instructions.js.map +1 -0
  426. package/dist/services/documents.d.ts +199 -0
  427. package/dist/services/documents.d.ts.map +1 -0
  428. package/dist/services/documents.js +411 -0
  429. package/dist/services/documents.js.map +1 -0
  430. package/dist/services/environment-config.d.ts +43 -0
  431. package/dist/services/environment-config.d.ts.map +1 -0
  432. package/dist/services/environment-config.js +388 -0
  433. package/dist/services/environment-config.js.map +1 -0
  434. package/dist/services/environment-execution-target.d.ts +21 -0
  435. package/dist/services/environment-execution-target.d.ts.map +1 -0
  436. package/dist/services/environment-execution-target.js +119 -0
  437. package/dist/services/environment-execution-target.js.map +1 -0
  438. package/dist/services/environment-probe.d.ts +9 -0
  439. package/dist/services/environment-probe.d.ts.map +1 -0
  440. package/dist/services/environment-probe.js +106 -0
  441. package/dist/services/environment-probe.js.map +1 -0
  442. package/dist/services/environment-run-orchestrator.d.ts +124 -0
  443. package/dist/services/environment-run-orchestrator.d.ts.map +1 -0
  444. package/dist/services/environment-run-orchestrator.js +392 -0
  445. package/dist/services/environment-run-orchestrator.js.map +1 -0
  446. package/dist/services/environment-runtime.d.ts +90 -0
  447. package/dist/services/environment-runtime.d.ts.map +1 -0
  448. package/dist/services/environment-runtime.js +934 -0
  449. package/dist/services/environment-runtime.js.map +1 -0
  450. package/dist/services/environments.d.ts +36 -0
  451. package/dist/services/environments.d.ts.map +1 -0
  452. package/dist/services/environments.js +260 -0
  453. package/dist/services/environments.js.map +1 -0
  454. package/dist/services/execution-workspace-policy.d.ts +30 -0
  455. package/dist/services/execution-workspace-policy.d.ts.map +1 -0
  456. package/dist/services/execution-workspace-policy.js +195 -0
  457. package/dist/services/execution-workspace-policy.js.map +1 -0
  458. package/dist/services/execution-workspaces.d.ts +30 -0
  459. package/dist/services/execution-workspaces.d.ts.map +1 -0
  460. package/dist/services/execution-workspaces.js +635 -0
  461. package/dist/services/execution-workspaces.js.map +1 -0
  462. package/dist/services/feedback-redaction.d.ts +23 -0
  463. package/dist/services/feedback-redaction.d.ts.map +1 -0
  464. package/dist/services/feedback-redaction.js +150 -0
  465. package/dist/services/feedback-redaction.js.map +1 -0
  466. package/dist/services/feedback-share-client.d.ts +9 -0
  467. package/dist/services/feedback-share-client.d.ts.map +1 -0
  468. package/dist/services/feedback-share-client.js +46 -0
  469. package/dist/services/feedback-share-client.js.map +1 -0
  470. package/dist/services/feedback.d.ts +93 -0
  471. package/dist/services/feedback.d.ts.map +1 -0
  472. package/dist/services/feedback.js +1717 -0
  473. package/dist/services/feedback.js.map +1 -0
  474. package/dist/services/finance.d.ts +93 -0
  475. package/dist/services/finance.d.ts.map +1 -0
  476. package/dist/services/finance.js +120 -0
  477. package/dist/services/finance.js.map +1 -0
  478. package/dist/services/github-fetch.d.ts +4 -0
  479. package/dist/services/github-fetch.d.ts.map +1 -0
  480. package/dist/services/github-fetch.js +23 -0
  481. package/dist/services/github-fetch.js.map +1 -0
  482. package/dist/services/goals.d.ts +433 -0
  483. package/dist/services/goals.d.ts.map +1 -0
  484. package/dist/services/goals.js +54 -0
  485. package/dist/services/goals.js.map +1 -0
  486. package/dist/services/heartbeat-run-summary.d.ts +7 -0
  487. package/dist/services/heartbeat-run-summary.d.ts.map +1 -0
  488. package/dist/services/heartbeat-run-summary.js +84 -0
  489. package/dist/services/heartbeat-run-summary.js.map +1 -0
  490. package/dist/services/heartbeat-stop-metadata.d.ts +28 -0
  491. package/dist/services/heartbeat-stop-metadata.d.ts.map +1 -0
  492. package/dist/services/heartbeat-stop-metadata.js +86 -0
  493. package/dist/services/heartbeat-stop-metadata.js.map +1 -0
  494. package/dist/services/heartbeat-stop-metadata.test.d.ts +2 -0
  495. package/dist/services/heartbeat-stop-metadata.test.d.ts.map +1 -0
  496. package/dist/services/heartbeat-stop-metadata.test.js +93 -0
  497. package/dist/services/heartbeat-stop-metadata.test.js.map +1 -0
  498. package/dist/services/heartbeat.d.ts +1484 -0
  499. package/dist/services/heartbeat.d.ts.map +1 -0
  500. package/dist/services/heartbeat.js +7557 -0
  501. package/dist/services/heartbeat.js.map +1 -0
  502. package/dist/services/hire-hook.d.ts +14 -0
  503. package/dist/services/hire-hook.d.ts.map +1 -0
  504. package/dist/services/hire-hook.js +85 -0
  505. package/dist/services/hire-hook.js.map +1 -0
  506. package/dist/services/inbox-dismissals.d.ts +22 -0
  507. package/dist/services/inbox-dismissals.d.ts.map +1 -0
  508. package/dist/services/inbox-dismissals.js +33 -0
  509. package/dist/services/inbox-dismissals.js.map +1 -0
  510. package/dist/services/index.d.ts +44 -0
  511. package/dist/services/index.d.ts.map +1 -0
  512. package/dist/services/index.js +44 -0
  513. package/dist/services/index.js.map +1 -0
  514. package/dist/services/instance-settings.d.ts +11 -0
  515. package/dist/services/instance-settings.d.ts.map +1 -0
  516. package/dist/services/instance-settings.js +138 -0
  517. package/dist/services/instance-settings.js.map +1 -0
  518. package/dist/services/invite-grants.d.ts +15 -0
  519. package/dist/services/invite-grants.d.ts.map +1 -0
  520. package/dist/services/invite-grants.js +50 -0
  521. package/dist/services/invite-grants.js.map +1 -0
  522. package/dist/services/issue-approvals.d.ts +56 -0
  523. package/dist/services/issue-approvals.d.ts.map +1 -0
  524. package/dist/services/issue-approvals.js +153 -0
  525. package/dist/services/issue-approvals.js.map +1 -0
  526. package/dist/services/issue-assignment-wakeup.d.ts +29 -0
  527. package/dist/services/issue-assignment-wakeup.d.ts.map +1 -0
  528. package/dist/services/issue-assignment-wakeup.js +22 -0
  529. package/dist/services/issue-assignment-wakeup.js.map +1 -0
  530. package/dist/services/issue-continuation-summary.d.ts +66 -0
  531. package/dist/services/issue-continuation-summary.d.ts.map +1 -0
  532. package/dist/services/issue-continuation-summary.js +212 -0
  533. package/dist/services/issue-continuation-summary.js.map +1 -0
  534. package/dist/services/issue-execution-policy.d.ts +93 -0
  535. package/dist/services/issue-execution-policy.d.ts.map +1 -0
  536. package/dist/services/issue-execution-policy.js +838 -0
  537. package/dist/services/issue-execution-policy.js.map +1 -0
  538. package/dist/services/issue-goal-fallback.d.ts +18 -0
  539. package/dist/services/issue-goal-fallback.d.ts.map +1 -0
  540. package/dist/services/issue-goal-fallback.js +33 -0
  541. package/dist/services/issue-goal-fallback.js.map +1 -0
  542. package/dist/services/issue-liveness.d.ts +3 -0
  543. package/dist/services/issue-liveness.d.ts.map +1 -0
  544. package/dist/services/issue-liveness.js +2 -0
  545. package/dist/services/issue-liveness.js.map +1 -0
  546. package/dist/services/issue-references.d.ts +21 -0
  547. package/dist/services/issue-references.d.ts.map +1 -0
  548. package/dist/services/issue-references.js +318 -0
  549. package/dist/services/issue-references.js.map +1 -0
  550. package/dist/services/issue-thread-interactions.d.ts +76 -0
  551. package/dist/services/issue-thread-interactions.d.ts.map +1 -0
  552. package/dist/services/issue-thread-interactions.js +923 -0
  553. package/dist/services/issue-thread-interactions.js.map +1 -0
  554. package/dist/services/issue-thread-interactions.test.d.ts +2 -0
  555. package/dist/services/issue-thread-interactions.test.d.ts.map +1 -0
  556. package/dist/services/issue-thread-interactions.test.js +195 -0
  557. package/dist/services/issue-thread-interactions.test.js.map +1 -0
  558. package/dist/services/issue-tree-control.d.ts +89 -0
  559. package/dist/services/issue-tree-control.d.ts.map +1 -0
  560. package/dist/services/issue-tree-control.js +933 -0
  561. package/dist/services/issue-tree-control.js.map +1 -0
  562. package/dist/services/issues.d.ts +710 -0
  563. package/dist/services/issues.d.ts.map +1 -0
  564. package/dist/services/issues.js +3199 -0
  565. package/dist/services/issues.js.map +1 -0
  566. package/dist/services/json-schema-secret-refs.d.ts +5 -0
  567. package/dist/services/json-schema-secret-refs.d.ts.map +1 -0
  568. package/dist/services/json-schema-secret-refs.js +67 -0
  569. package/dist/services/json-schema-secret-refs.js.map +1 -0
  570. package/dist/services/live-events.d.ts +17 -0
  571. package/dist/services/live-events.d.ts.map +1 -0
  572. package/dist/services/live-events.js +33 -0
  573. package/dist/services/live-events.js.map +1 -0
  574. package/dist/services/local-service-supervisor.d.ts +56 -0
  575. package/dist/services/local-service-supervisor.d.ts.map +1 -0
  576. package/dist/services/local-service-supervisor.js +284 -0
  577. package/dist/services/local-service-supervisor.js.map +1 -0
  578. package/dist/services/plugin-capability-validator.d.ts +108 -0
  579. package/dist/services/plugin-capability-validator.d.ts.map +1 -0
  580. package/dist/services/plugin-capability-validator.js +313 -0
  581. package/dist/services/plugin-capability-validator.js.map +1 -0
  582. package/dist/services/plugin-config-validator.d.ts +26 -0
  583. package/dist/services/plugin-config-validator.d.ts.map +1 -0
  584. package/dist/services/plugin-config-validator.js +41 -0
  585. package/dist/services/plugin-config-validator.js.map +1 -0
  586. package/dist/services/plugin-database.d.ts +49 -0
  587. package/dist/services/plugin-database.d.ts.map +1 -0
  588. package/dist/services/plugin-database.js +440 -0
  589. package/dist/services/plugin-database.js.map +1 -0
  590. package/dist/services/plugin-dev-watcher.d.ts +30 -0
  591. package/dist/services/plugin-dev-watcher.d.ts.map +1 -0
  592. package/dist/services/plugin-dev-watcher.js +241 -0
  593. package/dist/services/plugin-dev-watcher.js.map +1 -0
  594. package/dist/services/plugin-environment-driver.d.ts +124 -0
  595. package/dist/services/plugin-environment-driver.d.ts.map +1 -0
  596. package/dist/services/plugin-environment-driver.js +224 -0
  597. package/dist/services/plugin-environment-driver.js.map +1 -0
  598. package/dist/services/plugin-event-bus.d.ts +149 -0
  599. package/dist/services/plugin-event-bus.d.ts.map +1 -0
  600. package/dist/services/plugin-event-bus.js +258 -0
  601. package/dist/services/plugin-event-bus.js.map +1 -0
  602. package/dist/services/plugin-host-service-cleanup.d.ts +14 -0
  603. package/dist/services/plugin-host-service-cleanup.d.ts.map +1 -0
  604. package/dist/services/plugin-host-service-cleanup.js +37 -0
  605. package/dist/services/plugin-host-service-cleanup.js.map +1 -0
  606. package/dist/services/plugin-host-services.d.ts +17 -0
  607. package/dist/services/plugin-host-services.d.ts.map +1 -0
  608. package/dist/services/plugin-host-services.js +1861 -0
  609. package/dist/services/plugin-host-services.js.map +1 -0
  610. package/dist/services/plugin-job-coordinator.d.ts +81 -0
  611. package/dist/services/plugin-job-coordinator.d.ts.map +1 -0
  612. package/dist/services/plugin-job-coordinator.js +172 -0
  613. package/dist/services/plugin-job-coordinator.js.map +1 -0
  614. package/dist/services/plugin-job-scheduler.d.ts +163 -0
  615. package/dist/services/plugin-job-scheduler.d.ts.map +1 -0
  616. package/dist/services/plugin-job-scheduler.js +454 -0
  617. package/dist/services/plugin-job-scheduler.js.map +1 -0
  618. package/dist/services/plugin-job-store.d.ts +208 -0
  619. package/dist/services/plugin-job-store.d.ts.map +1 -0
  620. package/dist/services/plugin-job-store.js +350 -0
  621. package/dist/services/plugin-job-store.js.map +1 -0
  622. package/dist/services/plugin-lifecycle.d.ts +203 -0
  623. package/dist/services/plugin-lifecycle.d.ts.map +1 -0
  624. package/dist/services/plugin-lifecycle.js +476 -0
  625. package/dist/services/plugin-lifecycle.js.map +1 -0
  626. package/dist/services/plugin-loader.d.ts +445 -0
  627. package/dist/services/plugin-loader.d.ts.map +1 -0
  628. package/dist/services/plugin-loader.js +1273 -0
  629. package/dist/services/plugin-loader.js.map +1 -0
  630. package/dist/services/plugin-local-folders.d.ts +48 -0
  631. package/dist/services/plugin-local-folders.d.ts.map +1 -0
  632. package/dist/services/plugin-local-folders.js +461 -0
  633. package/dist/services/plugin-local-folders.js.map +1 -0
  634. package/dist/services/plugin-log-retention.d.ts +20 -0
  635. package/dist/services/plugin-log-retention.d.ts.map +1 -0
  636. package/dist/services/plugin-log-retention.js +63 -0
  637. package/dist/services/plugin-log-retention.js.map +1 -0
  638. package/dist/services/plugin-managed-agents.d.ts +15 -0
  639. package/dist/services/plugin-managed-agents.d.ts.map +1 -0
  640. package/dist/services/plugin-managed-agents.js +414 -0
  641. package/dist/services/plugin-managed-agents.js.map +1 -0
  642. package/dist/services/plugin-managed-routines.d.ts +41 -0
  643. package/dist/services/plugin-managed-routines.d.ts.map +1 -0
  644. package/dist/services/plugin-managed-routines.js +416 -0
  645. package/dist/services/plugin-managed-routines.js.map +1 -0
  646. package/dist/services/plugin-manifest-validator.d.ts +79 -0
  647. package/dist/services/plugin-manifest-validator.d.ts.map +1 -0
  648. package/dist/services/plugin-manifest-validator.js +84 -0
  649. package/dist/services/plugin-manifest-validator.js.map +1 -0
  650. package/dist/services/plugin-registry.d.ts +2550 -0
  651. package/dist/services/plugin-registry.d.ts.map +1 -0
  652. package/dist/services/plugin-registry.js +581 -0
  653. package/dist/services/plugin-registry.js.map +1 -0
  654. package/dist/services/plugin-runtime-sandbox.d.ts +40 -0
  655. package/dist/services/plugin-runtime-sandbox.d.ts.map +1 -0
  656. package/dist/services/plugin-runtime-sandbox.js +154 -0
  657. package/dist/services/plugin-runtime-sandbox.js.map +1 -0
  658. package/dist/services/plugin-secrets-handler.d.ts +81 -0
  659. package/dist/services/plugin-secrets-handler.d.ts.map +1 -0
  660. package/dist/services/plugin-secrets-handler.js +231 -0
  661. package/dist/services/plugin-secrets-handler.js.map +1 -0
  662. package/dist/services/plugin-state-store.d.ts +92 -0
  663. package/dist/services/plugin-state-store.d.ts.map +1 -0
  664. package/dist/services/plugin-state-store.js +190 -0
  665. package/dist/services/plugin-state-store.js.map +1 -0
  666. package/dist/services/plugin-stream-bus.d.ts +29 -0
  667. package/dist/services/plugin-stream-bus.d.ts.map +1 -0
  668. package/dist/services/plugin-stream-bus.js +48 -0
  669. package/dist/services/plugin-stream-bus.js.map +1 -0
  670. package/dist/services/plugin-tool-dispatcher.d.ts +180 -0
  671. package/dist/services/plugin-tool-dispatcher.d.ts.map +1 -0
  672. package/dist/services/plugin-tool-dispatcher.js +224 -0
  673. package/dist/services/plugin-tool-dispatcher.js.map +1 -0
  674. package/dist/services/plugin-tool-registry.d.ts +192 -0
  675. package/dist/services/plugin-tool-registry.d.ts.map +1 -0
  676. package/dist/services/plugin-tool-registry.js +224 -0
  677. package/dist/services/plugin-tool-registry.js.map +1 -0
  678. package/dist/services/plugin-worker-manager.d.ts +262 -0
  679. package/dist/services/plugin-worker-manager.d.ts.map +1 -0
  680. package/dist/services/plugin-worker-manager.js +836 -0
  681. package/dist/services/plugin-worker-manager.js.map +1 -0
  682. package/dist/services/productivity-review.d.ts +83 -0
  683. package/dist/services/productivity-review.d.ts.map +1 -0
  684. package/dist/services/productivity-review.js +652 -0
  685. package/dist/services/productivity-review.js.map +1 -0
  686. package/dist/services/project-workspace-runtime-config.d.ts +4 -0
  687. package/dist/services/project-workspace-runtime-config.d.ts.map +1 -0
  688. package/dist/services/project-workspace-runtime-config.js +54 -0
  689. package/dist/services/project-workspace-runtime-config.js.map +1 -0
  690. package/dist/services/projects.d.ts +99 -0
  691. package/dist/services/projects.d.ts.map +1 -0
  692. package/dist/services/projects.js +879 -0
  693. package/dist/services/projects.js.map +1 -0
  694. package/dist/services/quota-windows.d.ts +9 -0
  695. package/dist/services/quota-windows.d.ts.map +1 -0
  696. package/dist/services/quota-windows.js +56 -0
  697. package/dist/services/quota-windows.js.map +1 -0
  698. package/dist/services/recovery/index.d.ts +10 -0
  699. package/dist/services/recovery/index.d.ts.map +1 -0
  700. package/dist/services/recovery/index.js +6 -0
  701. package/dist/services/recovery/index.js.map +1 -0
  702. package/dist/services/recovery/issue-graph-liveness.d.ts +85 -0
  703. package/dist/services/recovery/issue-graph-liveness.d.ts.map +1 -0
  704. package/dist/services/recovery/issue-graph-liveness.js +343 -0
  705. package/dist/services/recovery/issue-graph-liveness.js.map +1 -0
  706. package/dist/services/recovery/model-profile-hint.d.ts +8 -0
  707. package/dist/services/recovery/model-profile-hint.d.ts.map +1 -0
  708. package/dist/services/recovery/model-profile-hint.js +11 -0
  709. package/dist/services/recovery/model-profile-hint.js.map +1 -0
  710. package/dist/services/recovery/origins.d.ts +36 -0
  711. package/dist/services/recovery/origins.d.ts.map +1 -0
  712. package/dist/services/recovery/origins.js +45 -0
  713. package/dist/services/recovery/origins.js.map +1 -0
  714. package/dist/services/recovery/pause-hold-guard.d.ts +6 -0
  715. package/dist/services/recovery/pause-hold-guard.d.ts.map +1 -0
  716. package/dist/services/recovery/pause-hold-guard.js +6 -0
  717. package/dist/services/recovery/pause-hold-guard.js.map +1 -0
  718. package/dist/services/recovery/run-liveness-continuations.d.ts +50 -0
  719. package/dist/services/recovery/run-liveness-continuations.d.ts.map +1 -0
  720. package/dist/services/recovery/run-liveness-continuations.js +117 -0
  721. package/dist/services/recovery/run-liveness-continuations.js.map +1 -0
  722. package/dist/services/recovery/service.d.ts +195 -0
  723. package/dist/services/recovery/service.d.ts.map +1 -0
  724. package/dist/services/recovery/service.js +2210 -0
  725. package/dist/services/recovery/service.js.map +1 -0
  726. package/dist/services/recovery/successful-run-handoff.d.ts +87 -0
  727. package/dist/services/recovery/successful-run-handoff.d.ts.map +1 -0
  728. package/dist/services/recovery/successful-run-handoff.js +297 -0
  729. package/dist/services/recovery/successful-run-handoff.js.map +1 -0
  730. package/dist/services/recovery/successful-run-handoff.test.d.ts +2 -0
  731. package/dist/services/recovery/successful-run-handoff.test.d.ts.map +1 -0
  732. package/dist/services/recovery/successful-run-handoff.test.js +267 -0
  733. package/dist/services/recovery/successful-run-handoff.test.js.map +1 -0
  734. package/dist/services/routines.d.ts +166 -0
  735. package/dist/services/routines.d.ts.map +1 -0
  736. package/dist/services/routines.js +1937 -0
  737. package/dist/services/routines.js.map +1 -0
  738. package/dist/services/run-continuations.d.ts +3 -0
  739. package/dist/services/run-continuations.d.ts.map +1 -0
  740. package/dist/services/run-continuations.js +2 -0
  741. package/dist/services/run-continuations.js.map +1 -0
  742. package/dist/services/run-liveness.d.ts +46 -0
  743. package/dist/services/run-liveness.d.ts.map +1 -0
  744. package/dist/services/run-liveness.js +275 -0
  745. package/dist/services/run-liveness.js.map +1 -0
  746. package/dist/services/run-log-store.d.ts +34 -0
  747. package/dist/services/run-log-store.d.ts.map +1 -0
  748. package/dist/services/run-log-store.js +111 -0
  749. package/dist/services/run-log-store.js.map +1 -0
  750. package/dist/services/sandbox-provider-runtime.d.ts +132 -0
  751. package/dist/services/sandbox-provider-runtime.d.ts.map +1 -0
  752. package/dist/services/sandbox-provider-runtime.js +216 -0
  753. package/dist/services/sandbox-provider-runtime.js.map +1 -0
  754. package/dist/services/secrets.d.ts +515 -0
  755. package/dist/services/secrets.d.ts.map +1 -0
  756. package/dist/services/secrets.js +290 -0
  757. package/dist/services/secrets.js.map +1 -0
  758. package/dist/services/sidebar-badges.d.ts +14 -0
  759. package/dist/services/sidebar-badges.d.ts.map +1 -0
  760. package/dist/services/sidebar-badges.js +48 -0
  761. package/dist/services/sidebar-badges.js.map +1 -0
  762. package/dist/services/sidebar-preferences.d.ts +9 -0
  763. package/dist/services/sidebar-preferences.d.ts.map +1 -0
  764. package/dist/services/sidebar-preferences.js +82 -0
  765. package/dist/services/sidebar-preferences.js.map +1 -0
  766. package/dist/services/work-products.d.ts +14 -0
  767. package/dist/services/work-products.d.ts.map +1 -0
  768. package/dist/services/work-products.js +100 -0
  769. package/dist/services/work-products.js.map +1 -0
  770. package/dist/services/workspace-operation-log-store.d.ts +33 -0
  771. package/dist/services/workspace-operation-log-store.d.ts.map +1 -0
  772. package/dist/services/workspace-operation-log-store.js +110 -0
  773. package/dist/services/workspace-operation-log-store.js.map +1 -0
  774. package/dist/services/workspace-operations.d.ts +44 -0
  775. package/dist/services/workspace-operations.d.ts.map +1 -0
  776. package/dist/services/workspace-operations.js +211 -0
  777. package/dist/services/workspace-operations.js.map +1 -0
  778. package/dist/services/workspace-realization.d.ts +33 -0
  779. package/dist/services/workspace-realization.d.ts.map +1 -0
  780. package/dist/services/workspace-realization.js +221 -0
  781. package/dist/services/workspace-realization.js.map +1 -0
  782. package/dist/services/workspace-runtime-read-model.d.ts +92 -0
  783. package/dist/services/workspace-runtime-read-model.d.ts.map +1 -0
  784. package/dist/services/workspace-runtime-read-model.js +67 -0
  785. package/dist/services/workspace-runtime-read-model.js.map +1 -0
  786. package/dist/services/workspace-runtime.d.ts +238 -0
  787. package/dist/services/workspace-runtime.d.ts.map +1 -0
  788. package/dist/services/workspace-runtime.js +2388 -0
  789. package/dist/services/workspace-runtime.js.map +1 -0
  790. package/dist/startup-banner.d.ts +32 -0
  791. package/dist/startup-banner.d.ts.map +1 -0
  792. package/dist/startup-banner.js +118 -0
  793. package/dist/startup-banner.js.map +1 -0
  794. package/dist/storage/index.d.ts +6 -0
  795. package/dist/storage/index.d.ts.map +1 -0
  796. package/dist/storage/index.js +29 -0
  797. package/dist/storage/index.js.map +1 -0
  798. package/dist/storage/local-disk-provider.d.ts +3 -0
  799. package/dist/storage/local-disk-provider.d.ts.map +1 -0
  800. package/dist/storage/local-disk-provider.js +79 -0
  801. package/dist/storage/local-disk-provider.js.map +1 -0
  802. package/dist/storage/provider-registry.d.ts +4 -0
  803. package/dist/storage/provider-registry.d.ts.map +1 -0
  804. package/dist/storage/provider-registry.js +15 -0
  805. package/dist/storage/provider-registry.js.map +1 -0
  806. package/dist/storage/s3-provider.d.ts +11 -0
  807. package/dist/storage/s3-provider.d.ts.map +1 -0
  808. package/dist/storage/s3-provider.js +123 -0
  809. package/dist/storage/s3-provider.js.map +1 -0
  810. package/dist/storage/service.d.ts +3 -0
  811. package/dist/storage/service.d.ts.map +1 -0
  812. package/dist/storage/service.js +120 -0
  813. package/dist/storage/service.js.map +1 -0
  814. package/dist/storage/types.d.ts +55 -0
  815. package/dist/storage/types.d.ts.map +1 -0
  816. package/dist/storage/types.js +2 -0
  817. package/dist/storage/types.js.map +1 -0
  818. package/dist/telemetry.d.ts +6 -0
  819. package/dist/telemetry.d.ts.map +1 -0
  820. package/dist/telemetry.js +20 -0
  821. package/dist/telemetry.js.map +1 -0
  822. package/dist/ui-branding.d.ts +13 -0
  823. package/dist/ui-branding.d.ts.map +1 -0
  824. package/dist/ui-branding.js +187 -0
  825. package/dist/ui-branding.js.map +1 -0
  826. package/dist/version.d.ts +2 -0
  827. package/dist/version.d.ts.map +1 -0
  828. package/dist/version.js +5 -0
  829. package/dist/version.js.map +1 -0
  830. package/dist/vite-html-renderer.d.ts +18 -0
  831. package/dist/vite-html-renderer.d.ts.map +1 -0
  832. package/dist/vite-html-renderer.js +61 -0
  833. package/dist/vite-html-renderer.js.map +1 -0
  834. package/dist/worktree-config.d.ts +19 -0
  835. package/dist/worktree-config.d.ts.map +1 -0
  836. package/dist/worktree-config.js +368 -0
  837. package/dist/worktree-config.js.map +1 -0
  838. package/package.json +90 -0
  839. package/skills/diagnose-why-work-stopped/SKILL.md +161 -0
  840. package/skills/evermore/SKILL.md +366 -0
  841. package/skills/evermore/references/api-reference.md +899 -0
  842. package/skills/evermore/references/company-skills.md +193 -0
  843. package/skills/evermore/references/issue-workspaces.md +80 -0
  844. package/skills/evermore/references/routines.md +187 -0
  845. package/skills/evermore/references/workflows.md +141 -0
  846. package/skills/evermore-converting-plans-to-tasks/SKILL.md +42 -0
  847. package/skills/evermore-create-agent/SKILL.md +163 -0
  848. package/skills/evermore-create-agent/references/agent-instruction-templates.md +123 -0
  849. package/skills/evermore-create-agent/references/agents/coder.md +64 -0
  850. package/skills/evermore-create-agent/references/agents/qa.md +88 -0
  851. package/skills/evermore-create-agent/references/agents/securityengineer.md +135 -0
  852. package/skills/evermore-create-agent/references/agents/uxdesigner.md +115 -0
  853. package/skills/evermore-create-agent/references/api-reference.md +110 -0
  854. package/skills/evermore-create-agent/references/baseline-role-guide.md +168 -0
  855. package/skills/evermore-create-agent/references/draft-review-checklist.md +95 -0
  856. package/skills/evermore-create-plugin/SKILL.md +101 -0
  857. package/skills/evermore-dev/SKILL.md +267 -0
  858. package/skills/para-memory-files/SKILL.md +104 -0
  859. package/skills/para-memory-files/references/schemas.md +35 -0
  860. package/skills/terminal-bench-loop/SKILL.md +236 -0
  861. package/ui-dist/android-chrome-192x192.png +0 -0
  862. package/ui-dist/android-chrome-512x512.png +0 -0
  863. package/ui-dist/apple-touch-icon.png +0 -0
  864. package/ui-dist/assets/_basePickBy-Ds9oHp1_.js +1 -0
  865. package/ui-dist/assets/_baseUniq-CHYwQyJ_.js +1 -0
  866. package/ui-dist/assets/apl-B4CMkyY2.js +1 -0
  867. package/ui-dist/assets/arc-CiUKtBzk.js +1 -0
  868. package/ui-dist/assets/architectureDiagram-VXUJARFQ-CAW2b6pT.js +36 -0
  869. package/ui-dist/assets/asciiarmor-Df11BRmG.js +1 -0
  870. package/ui-dist/assets/asn1-EdZsLKOL.js +1 -0
  871. package/ui-dist/assets/asterisk-B-8jnY81.js +1 -0
  872. package/ui-dist/assets/blockDiagram-VD42YOAC-1Rk6YCcn.js +122 -0
  873. package/ui-dist/assets/brainfuck-C4LP7Hcl.js +1 -0
  874. package/ui-dist/assets/c4Diagram-YG6GDRKO-DF5RJtyZ.js +10 -0
  875. package/ui-dist/assets/channel-D7SqxhNi.js +1 -0
  876. package/ui-dist/assets/chunk-4BX2VUAB-BSZDJAxk.js +1 -0
  877. package/ui-dist/assets/chunk-55IACEB6-DgVOW-V3.js +1 -0
  878. package/ui-dist/assets/chunk-B4BG7PRW-C1sGAq6t.js +165 -0
  879. package/ui-dist/assets/chunk-DI55MBZ5-DZyfq3VK.js +220 -0
  880. package/ui-dist/assets/chunk-FMBD7UC4-D6K9nYXi.js +15 -0
  881. package/ui-dist/assets/chunk-QN33PNHL-BJ0Ni2l9.js +1 -0
  882. package/ui-dist/assets/chunk-QZHKN3VN-Cwjr0vxG.js +1 -0
  883. package/ui-dist/assets/chunk-TZMSLE5B-C2RGCkyV.js +1 -0
  884. package/ui-dist/assets/classDiagram-2ON5EDUG-Cx1PlXXb.js +1 -0
  885. package/ui-dist/assets/classDiagram-v2-WZHVMYZB-Cx1PlXXb.js +1 -0
  886. package/ui-dist/assets/clike-B9uivgTg.js +1 -0
  887. package/ui-dist/assets/clojure-BMjYHr_A.js +1 -0
  888. package/ui-dist/assets/clone-5ZE-SRxk.js +1 -0
  889. package/ui-dist/assets/cmake-BQqOBYOt.js +1 -0
  890. package/ui-dist/assets/cobol-CWcv1MsR.js +1 -0
  891. package/ui-dist/assets/coffeescript-S37ZYGWr.js +1 -0
  892. package/ui-dist/assets/commonlisp-DBKNyK5s.js +1 -0
  893. package/ui-dist/assets/cose-bilkent-S5V4N54A-CW0Mh3DC.js +1 -0
  894. package/ui-dist/assets/crystal-SjHAIU92.js +1 -0
  895. package/ui-dist/assets/css-BnMrqG3P.js +1 -0
  896. package/ui-dist/assets/cypher-C_CwsFkJ.js +1 -0
  897. package/ui-dist/assets/cytoscape.esm-jbPEKk2Y.js +321 -0
  898. package/ui-dist/assets/d-pRatUO7H.js +1 -0
  899. package/ui-dist/assets/dagre-6UL2VRFP-BXDbyGyw.js +4 -0
  900. package/ui-dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  901. package/ui-dist/assets/diagram-PSM6KHXK-BHW-b3P9.js +24 -0
  902. package/ui-dist/assets/diagram-QEK2KX5R-vjGsaMmX.js +43 -0
  903. package/ui-dist/assets/diagram-S2PKOQOG-BHVhRqBj.js +24 -0
  904. package/ui-dist/assets/diff-DbItnlRl.js +1 -0
  905. package/ui-dist/assets/dockerfile-BKs6k2Af.js +1 -0
  906. package/ui-dist/assets/dtd-DF_7sFjM.js +1 -0
  907. package/ui-dist/assets/dylan-DwRh75JA.js +1 -0
  908. package/ui-dist/assets/ebnf-CDyGwa7X.js +1 -0
  909. package/ui-dist/assets/ecl-Cabwm37j.js +1 -0
  910. package/ui-dist/assets/eiffel-CnydiIhH.js +1 -0
  911. package/ui-dist/assets/elm-vLlmbW-K.js +1 -0
  912. package/ui-dist/assets/erDiagram-Q2GNP2WA-DwsdEDB2.js +60 -0
  913. package/ui-dist/assets/erlang-BNw1qcRV.js +1 -0
  914. package/ui-dist/assets/factor-kuTfRLto.js +1 -0
  915. package/ui-dist/assets/fcl-Kvtd6kyn.js +1 -0
  916. package/ui-dist/assets/flowDiagram-NV44I4VS-Bv7drkZu.js +162 -0
  917. package/ui-dist/assets/forth-Ffai-XNe.js +1 -0
  918. package/ui-dist/assets/fortran-DYz_wnZ1.js +1 -0
  919. package/ui-dist/assets/ganttDiagram-JELNMOA3-DyYAGyjV.js +267 -0
  920. package/ui-dist/assets/gas-Bneqetm1.js +1 -0
  921. package/ui-dist/assets/gherkin-heZmZLOM.js +1 -0
  922. package/ui-dist/assets/gitGraphDiagram-V2S2FVAM-DmKJJ2X0.js +65 -0
  923. package/ui-dist/assets/graph-BI12oqz9.js +1 -0
  924. package/ui-dist/assets/groovy-D9Dt4D0W.js +1 -0
  925. package/ui-dist/assets/haskell-Cw1EW3IL.js +1 -0
  926. package/ui-dist/assets/haxe-H-WmDvRZ.js +1 -0
  927. package/ui-dist/assets/http-DBlCnlav.js +1 -0
  928. package/ui-dist/assets/idl-BEugSyMb.js +1 -0
  929. package/ui-dist/assets/index-B1YmgKZD.js +1 -0
  930. package/ui-dist/assets/index-B5EG1mbW.js +1 -0
  931. package/ui-dist/assets/index-B63DPkk7.js +2 -0
  932. package/ui-dist/assets/index-BAalUM2u.js +1 -0
  933. package/ui-dist/assets/index-BCyQqUEQ.js +1 -0
  934. package/ui-dist/assets/index-BSRsyahM.js +1 -0
  935. package/ui-dist/assets/index-B_Iu4zUd.js +1 -0
  936. package/ui-dist/assets/index-C-BdZUIH.js +1 -0
  937. package/ui-dist/assets/index-CGgUnSQj.js +6 -0
  938. package/ui-dist/assets/index-COTIEysQ.js +1 -0
  939. package/ui-dist/assets/index-ChSqseHR.js +1 -0
  940. package/ui-dist/assets/index-Ckf1hADU.js +534 -0
  941. package/ui-dist/assets/index-D4M1TSCO.js +3 -0
  942. package/ui-dist/assets/index-DCTk2CN-.js +7 -0
  943. package/ui-dist/assets/index-DI-wyUUr.js +1 -0
  944. package/ui-dist/assets/index-DNtLqZ-D.js +1 -0
  945. package/ui-dist/assets/index-DSRR_614.css +1 -0
  946. package/ui-dist/assets/index-DarmgkJv.js +1 -0
  947. package/ui-dist/assets/index-DdcxF71a.js +1 -0
  948. package/ui-dist/assets/index-DfwWaMga.js +1 -0
  949. package/ui-dist/assets/index-SzUviW57.js +13 -0
  950. package/ui-dist/assets/index-VjZhELb6.js +1 -0
  951. package/ui-dist/assets/index-mEcmy8wG.js +1 -0
  952. package/ui-dist/assets/index-q7ldlDv6.js +1 -0
  953. package/ui-dist/assets/infoDiagram-HS3SLOUP-CqAxMRbC.js +2 -0
  954. package/ui-dist/assets/init-Gi6I4Gst.js +1 -0
  955. package/ui-dist/assets/javascript-iXu5QeM3.js +1 -0
  956. package/ui-dist/assets/journeyDiagram-XKPGCS4Q-DUJiudtY.js +139 -0
  957. package/ui-dist/assets/julia-DuME0IfC.js +1 -0
  958. package/ui-dist/assets/kanban-definition-3W4ZIXB7-CiRgJ4X2.js +89 -0
  959. package/ui-dist/assets/katex-B95LWT_Q.js +261 -0
  960. package/ui-dist/assets/layout-DJ8V2pqt.js +1 -0
  961. package/ui-dist/assets/linear-BwnNUuyZ.js +1 -0
  962. package/ui-dist/assets/livescript-BwQOo05w.js +1 -0
  963. package/ui-dist/assets/lua-BgMRiT3U.js +1 -0
  964. package/ui-dist/assets/mathematica-DTrFuWx2.js +1 -0
  965. package/ui-dist/assets/mbox-CNhZ1qSd.js +1 -0
  966. package/ui-dist/assets/mermaid.core-DLCiCWj4.js +250 -0
  967. package/ui-dist/assets/mindmap-definition-VGOIOE7T-epIiGA01.js +68 -0
  968. package/ui-dist/assets/mirc-CjQqDB4T.js +1 -0
  969. package/ui-dist/assets/mllike-CXdrOF99.js +1 -0
  970. package/ui-dist/assets/modelica-Dc1JOy9r.js +1 -0
  971. package/ui-dist/assets/mscgen-BA5vi2Kp.js +1 -0
  972. package/ui-dist/assets/mumps-BT43cFF4.js +1 -0
  973. package/ui-dist/assets/nginx-DdIZxoE0.js +1 -0
  974. package/ui-dist/assets/nsis-LdVXkNf5.js +1 -0
  975. package/ui-dist/assets/ntriples-BfvgReVJ.js +1 -0
  976. package/ui-dist/assets/octave-Ck1zUtKM.js +1 -0
  977. package/ui-dist/assets/ordinal-Cboi1Yqb.js +1 -0
  978. package/ui-dist/assets/oz-BzwKVEFT.js +1 -0
  979. package/ui-dist/assets/pascal--L3eBynH.js +1 -0
  980. package/ui-dist/assets/perl-CdXCOZ3F.js +1 -0
  981. package/ui-dist/assets/pieDiagram-ADFJNKIX-CHx4pJ9Y.js +30 -0
  982. package/ui-dist/assets/pig-CevX1Tat.js +1 -0
  983. package/ui-dist/assets/powershell-CFHJl5sT.js +1 -0
  984. package/ui-dist/assets/properties-C78fOPTZ.js +1 -0
  985. package/ui-dist/assets/protobuf-ChK-085T.js +1 -0
  986. package/ui-dist/assets/pug-DeIclll2.js +1 -0
  987. package/ui-dist/assets/puppet-DMA9R1ak.js +1 -0
  988. package/ui-dist/assets/python-BuPzkPfP.js +1 -0
  989. package/ui-dist/assets/q-pXgVlZs6.js +1 -0
  990. package/ui-dist/assets/quadrantDiagram-AYHSOK5B-D0tXmGxE.js +7 -0
  991. package/ui-dist/assets/r-B6wPVr8A.js +1 -0
  992. package/ui-dist/assets/requirementDiagram-UZGBJVZJ-BgFc9Xc4.js +64 -0
  993. package/ui-dist/assets/rpm-CTu-6PCP.js +1 -0
  994. package/ui-dist/assets/ruby-B2Rjki9n.js +1 -0
  995. package/ui-dist/assets/sankeyDiagram-TZEHDZUN-DqntX5wV.js +10 -0
  996. package/ui-dist/assets/sas-B4kiWyti.js +1 -0
  997. package/ui-dist/assets/scheme-C41bIUwD.js +1 -0
  998. package/ui-dist/assets/sequenceDiagram-WL72ISMW-BfIJeGAT.js +145 -0
  999. package/ui-dist/assets/shell-CjFT_Tl9.js +1 -0
  1000. package/ui-dist/assets/sieve-C3Gn_uJK.js +1 -0
  1001. package/ui-dist/assets/simple-mode-GW_nhZxv.js +1 -0
  1002. package/ui-dist/assets/smalltalk-CnHTOXQT.js +1 -0
  1003. package/ui-dist/assets/solr-DehyRSwq.js +1 -0
  1004. package/ui-dist/assets/sparql-DkYu6x3z.js +1 -0
  1005. package/ui-dist/assets/spreadsheet-BCZA_wO0.js +1 -0
  1006. package/ui-dist/assets/sql-D0XecflT.js +1 -0
  1007. package/ui-dist/assets/stateDiagram-FKZM4ZOC-CBlsmcoW.js +1 -0
  1008. package/ui-dist/assets/stateDiagram-v2-4FDKWEC3-DJtH2tCS.js +1 -0
  1009. package/ui-dist/assets/stex-C3f8Ysf7.js +1 -0
  1010. package/ui-dist/assets/stylus-B533Al4x.js +1 -0
  1011. package/ui-dist/assets/swift-BzpIVaGY.js +1 -0
  1012. package/ui-dist/assets/tcl-DVfN8rqt.js +1 -0
  1013. package/ui-dist/assets/textile-CnDTJFAw.js +1 -0
  1014. package/ui-dist/assets/tiddlywiki-DO-Gjzrf.js +1 -0
  1015. package/ui-dist/assets/tiki-DGYXhP31.js +1 -0
  1016. package/ui-dist/assets/timeline-definition-IT6M3QCI-C2XyT4Lo.js +61 -0
  1017. package/ui-dist/assets/toml-Bm5Em-hy.js +1 -0
  1018. package/ui-dist/assets/treemap-GDKQZRPO-DvTrxs0e.js +154 -0
  1019. package/ui-dist/assets/troff-wAsdV37c.js +1 -0
  1020. package/ui-dist/assets/ttcn-CfJYG6tj.js +1 -0
  1021. package/ui-dist/assets/ttcn-cfg-B9xdYoR4.js +1 -0
  1022. package/ui-dist/assets/turtle-B1tBg_DP.js +1 -0
  1023. package/ui-dist/assets/vb-CmGdzxic.js +1 -0
  1024. package/ui-dist/assets/vbscript-BuJXcnF6.js +1 -0
  1025. package/ui-dist/assets/velocity-D8B20fx6.js +1 -0
  1026. package/ui-dist/assets/verilog-C6RDOZhf.js +1 -0
  1027. package/ui-dist/assets/vhdl-lSbBsy5d.js +1 -0
  1028. package/ui-dist/assets/webidl-ZXfAyPTL.js +1 -0
  1029. package/ui-dist/assets/xquery-DzFWVndE.js +1 -0
  1030. package/ui-dist/assets/xychartDiagram-PRI3JC2R-pTizTbG0.js +7 -0
  1031. package/ui-dist/assets/yacas-BJ4BC0dw.js +1 -0
  1032. package/ui-dist/assets/z80-Hz9HOZM7.js +1 -0
  1033. package/ui-dist/brands/opencode-logo-dark-square.svg +18 -0
  1034. package/ui-dist/brands/opencode-logo-light-square.svg +18 -0
  1035. package/ui-dist/favicon-16x16.png +0 -0
  1036. package/ui-dist/favicon-32x32.png +0 -0
  1037. package/ui-dist/favicon.ico +0 -0
  1038. package/ui-dist/favicon.svg +9 -0
  1039. package/ui-dist/index.html +49 -0
  1040. package/ui-dist/site.webmanifest +30 -0
  1041. package/ui-dist/sw.js +42 -0
  1042. package/ui-dist/worktree-favicon-16x16.png +0 -0
  1043. package/ui-dist/worktree-favicon-32x32.png +0 -0
  1044. package/ui-dist/worktree-favicon.ico +0 -0
  1045. package/ui-dist/worktree-favicon.svg +9 -0
@@ -0,0 +1,2388 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync } from "node:fs";
3
+ import fs from "node:fs/promises";
4
+ import net from "node:net";
5
+ import { createHash, randomUUID } from "node:crypto";
6
+ import path from "node:path";
7
+ import { setTimeout as delay } from "node:timers/promises";
8
+ import { executionWorkspaces, projectWorkspaces, workspaceRuntimeServices } from "@evermore.work/db";
9
+ import { listWorkspaceServiceCommandDefinitions, } from "@evermore.work/shared";
10
+ import { and, desc, eq, inArray } from "drizzle-orm";
11
+ import { asNumber, asString, parseObject, renderTemplate } from "../adapters/utils.js";
12
+ import { resolveHomeAwarePath } from "../home-paths.js";
13
+ import { createLocalServiceKey, findLocalServiceRegistryRecordByRuntimeServiceId, findAdoptableLocalService, readLocalServicePortOwner, removeLocalServiceRegistryRecord, terminateLocalService, touchLocalServiceRegistryRecord, writeLocalServiceRegistryRecord, } from "./local-service-supervisor.js";
14
+ import { readExecutionWorkspaceConfig } from "./execution-workspaces.js";
15
+ import { readProjectWorkspaceRuntimeConfig } from "./project-workspace-runtime-config.js";
16
+ export function resolveShell() {
17
+ const fallback = process.platform === "win32" ? "sh" : "/bin/sh";
18
+ const shell = process.env.SHELL?.trim();
19
+ if (!shell)
20
+ return fallback;
21
+ if (path.isAbsolute(shell) && !existsSync(shell))
22
+ return fallback;
23
+ return shell;
24
+ }
25
+ const runtimeServicesById = new Map();
26
+ const runtimeServicesByReuseKey = new Map();
27
+ const runtimeServiceLeasesByRun = new Map();
28
+ const DEFAULT_EXECUTE_PROCESS_OUTPUT_BYTES = 256 * 1024;
29
+ export async function resetRuntimeServicesForTests() {
30
+ for (const record of runtimeServicesById.values()) {
31
+ clearIdleTimer(record);
32
+ }
33
+ runtimeServicesById.clear();
34
+ runtimeServicesByReuseKey.clear();
35
+ runtimeServiceLeasesByRun.clear();
36
+ }
37
+ function stableStringify(value) {
38
+ if (Array.isArray(value)) {
39
+ return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
40
+ }
41
+ if (value && typeof value === "object") {
42
+ const rec = value;
43
+ return `{${Object.keys(rec).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(rec[key])}`).join(",")}}`;
44
+ }
45
+ return JSON.stringify(value);
46
+ }
47
+ function readJsonFile(filePath) {
48
+ return JSON.parse(readFileSync(filePath, "utf8"));
49
+ }
50
+ function findWorkspaceRoot(startCwd) {
51
+ let current = path.resolve(startCwd);
52
+ while (true) {
53
+ if (existsSync(path.join(current, "pnpm-workspace.yaml"))) {
54
+ return current;
55
+ }
56
+ const parent = path.dirname(current);
57
+ if (parent === current)
58
+ return null;
59
+ current = parent;
60
+ }
61
+ }
62
+ function isLinkedGitWorktreeCheckout(rootDir) {
63
+ const gitMetadataPath = path.join(rootDir, ".git");
64
+ if (!existsSync(gitMetadataPath))
65
+ return false;
66
+ const stat = lstatSync(gitMetadataPath);
67
+ if (!stat.isFile())
68
+ return false;
69
+ return readFileSync(gitMetadataPath, "utf8").trimStart().startsWith("gitdir:");
70
+ }
71
+ function discoverWorkspacePackagePaths(rootDir) {
72
+ const packagePaths = new Map();
73
+ const ignoredDirNames = new Set([".git", ".evermore", "dist", "node_modules"]);
74
+ function visit(dirPath) {
75
+ if (!existsSync(dirPath))
76
+ return;
77
+ const packageJsonPath = path.join(dirPath, "package.json");
78
+ if (existsSync(packageJsonPath)) {
79
+ const packageJson = readJsonFile(packageJsonPath);
80
+ if (typeof packageJson.name === "string" && packageJson.name.length > 0) {
81
+ packagePaths.set(packageJson.name, dirPath);
82
+ }
83
+ }
84
+ for (const entry of readdirSync(dirPath, { withFileTypes: true })) {
85
+ if (!entry.isDirectory())
86
+ continue;
87
+ if (ignoredDirNames.has(entry.name))
88
+ continue;
89
+ visit(path.join(dirPath, entry.name));
90
+ }
91
+ }
92
+ visit(path.join(rootDir, "packages"));
93
+ visit(path.join(rootDir, "server"));
94
+ visit(path.join(rootDir, "ui"));
95
+ visit(path.join(rootDir, "cli"));
96
+ return packagePaths;
97
+ }
98
+ function findServerWorkspaceLinkMismatches(rootDir) {
99
+ const serverPackageJsonPath = path.join(rootDir, "server", "package.json");
100
+ if (!existsSync(serverPackageJsonPath))
101
+ return [];
102
+ const serverPackageJson = readJsonFile(serverPackageJsonPath);
103
+ const dependencies = {
104
+ ...serverPackageJson.dependencies,
105
+ ...serverPackageJson.devDependencies,
106
+ };
107
+ const workspacePackagePaths = discoverWorkspacePackagePaths(rootDir);
108
+ const mismatches = [];
109
+ for (const [packageName, version] of Object.entries(dependencies)) {
110
+ if (typeof version !== "string" || !version.startsWith("workspace:"))
111
+ continue;
112
+ const expectedPath = workspacePackagePaths.get(packageName);
113
+ if (!expectedPath)
114
+ continue;
115
+ const normalizedExpectedPath = existsSync(expectedPath) ? path.resolve(realpathSync(expectedPath)) : path.resolve(expectedPath);
116
+ const linkPath = path.join(rootDir, "server", "node_modules", ...packageName.split("/"));
117
+ const actualPath = existsSync(linkPath) ? path.resolve(realpathSync(linkPath)) : null;
118
+ if (actualPath === normalizedExpectedPath)
119
+ continue;
120
+ mismatches.push({
121
+ packageName,
122
+ expectedPath: normalizedExpectedPath,
123
+ actualPath,
124
+ });
125
+ }
126
+ return mismatches;
127
+ }
128
+ export async function ensureServerWorkspaceLinksCurrent(startCwd, opts) {
129
+ const workspaceRoot = findWorkspaceRoot(startCwd);
130
+ if (!workspaceRoot)
131
+ return;
132
+ if (!isLinkedGitWorktreeCheckout(workspaceRoot))
133
+ return;
134
+ const mismatches = findServerWorkspaceLinkMismatches(workspaceRoot);
135
+ if (mismatches.length === 0)
136
+ return;
137
+ if (opts?.onLog) {
138
+ await opts.onLog("stdout", "[runtime] detected stale workspace package links for server; relinking dependencies...\n");
139
+ for (const mismatch of mismatches) {
140
+ await opts.onLog("stdout", `[runtime] ${mismatch.packageName}: ${mismatch.actualPath ?? "missing"} -> ${mismatch.expectedPath}\n`);
141
+ }
142
+ }
143
+ for (const mismatch of mismatches) {
144
+ const linkPath = path.join(workspaceRoot, "server", "node_modules", ...mismatch.packageName.split("/"));
145
+ await fs.mkdir(path.dirname(linkPath), { recursive: true });
146
+ await fs.rm(linkPath, { recursive: true, force: true });
147
+ await fs.symlink(mismatch.expectedPath, linkPath);
148
+ }
149
+ const remainingMismatches = findServerWorkspaceLinkMismatches(workspaceRoot);
150
+ if (remainingMismatches.length === 0)
151
+ return;
152
+ throw new Error(`Workspace relink did not repair all server package links: ${remainingMismatches.map((item) => item.packageName).join(", ")}`);
153
+ }
154
+ export function sanitizeRuntimeServiceBaseEnv(baseEnv) {
155
+ const env = { ...baseEnv };
156
+ for (const key of Object.keys(env)) {
157
+ if (key.startsWith("EVERMORE_")) {
158
+ delete env[key];
159
+ }
160
+ }
161
+ delete env.DATABASE_URL;
162
+ delete env.npm_config_tailscale_auth;
163
+ delete env.npm_config_authenticated_private;
164
+ return env;
165
+ }
166
+ function stableRuntimeServiceId(input) {
167
+ if (input.reportId)
168
+ return input.reportId;
169
+ const digest = createHash("sha256")
170
+ .update(stableStringify({
171
+ adapterType: input.adapterType,
172
+ runId: input.runId,
173
+ scopeType: input.scopeType,
174
+ scopeId: input.scopeId,
175
+ serviceName: input.serviceName,
176
+ providerRef: input.providerRef,
177
+ reuseKey: input.reuseKey,
178
+ }))
179
+ .digest("hex")
180
+ .slice(0, 32);
181
+ return `${input.adapterType}-${digest}`;
182
+ }
183
+ function toRuntimeServiceRef(record, overrides) {
184
+ return {
185
+ id: record.id,
186
+ companyId: record.companyId,
187
+ projectId: record.projectId,
188
+ projectWorkspaceId: record.projectWorkspaceId,
189
+ executionWorkspaceId: record.executionWorkspaceId,
190
+ issueId: record.issueId,
191
+ serviceName: record.serviceName,
192
+ status: record.status,
193
+ lifecycle: record.lifecycle,
194
+ scopeType: record.scopeType,
195
+ scopeId: record.scopeId,
196
+ reuseKey: record.reuseKey,
197
+ command: record.command,
198
+ cwd: record.cwd,
199
+ port: record.port,
200
+ url: record.url,
201
+ provider: record.provider,
202
+ providerRef: record.providerRef,
203
+ ownerAgentId: record.ownerAgentId,
204
+ startedByRunId: record.startedByRunId,
205
+ lastUsedAt: record.lastUsedAt,
206
+ startedAt: record.startedAt,
207
+ stoppedAt: record.stoppedAt,
208
+ stopPolicy: record.stopPolicy,
209
+ healthStatus: record.healthStatus,
210
+ reused: record.reused,
211
+ ...overrides,
212
+ };
213
+ }
214
+ function sanitizeSlugPart(value, fallback) {
215
+ const raw = (value ?? "").trim().toLowerCase();
216
+ const normalized = raw
217
+ .replace(/[^a-z0-9_-]+/g, "-")
218
+ .replace(/-+/g, "-")
219
+ .replace(/^[-_]+|[-_]+$/g, "");
220
+ return normalized.length > 0 ? normalized : fallback;
221
+ }
222
+ function renderWorkspaceTemplate(template, input) {
223
+ const issueIdentifier = input.issue?.identifier ?? input.issue?.id ?? "issue";
224
+ const slug = sanitizeSlugPart(input.issue?.title, sanitizeSlugPart(issueIdentifier, "issue"));
225
+ return renderTemplate(template, {
226
+ issue: {
227
+ id: input.issue?.id ?? "",
228
+ identifier: input.issue?.identifier ?? "",
229
+ title: input.issue?.title ?? "",
230
+ },
231
+ agent: {
232
+ id: input.agent.id ?? "",
233
+ name: input.agent.name,
234
+ },
235
+ project: {
236
+ id: input.projectId ?? "",
237
+ },
238
+ workspace: {
239
+ repoRef: input.repoRef ?? "",
240
+ },
241
+ slug,
242
+ });
243
+ }
244
+ function sanitizeBranchName(value) {
245
+ return value
246
+ .trim()
247
+ .replace(/[^A-Za-z0-9._/-]+/g, "-")
248
+ .replace(/-+/g, "-")
249
+ .replace(/^[-/.]+|[-/.]+$/g, "")
250
+ .slice(0, 120) || "evermore-work";
251
+ }
252
+ function isAbsolutePath(value) {
253
+ return path.isAbsolute(value) || value.startsWith("~");
254
+ }
255
+ function resolveConfiguredPath(value, baseDir) {
256
+ if (isAbsolutePath(value)) {
257
+ return resolveHomeAwarePath(value);
258
+ }
259
+ return path.resolve(baseDir, value);
260
+ }
261
+ function formatCommandForDisplay(command, args) {
262
+ return [command, ...args]
263
+ .map((part) => (/^[A-Za-z0-9_./:-]+$/.test(part) ? part : JSON.stringify(part)))
264
+ .join(" ");
265
+ }
266
+ function trimToLastBytes(value, limit) {
267
+ const byteLength = Buffer.byteLength(value, "utf8");
268
+ if (byteLength <= limit)
269
+ return value;
270
+ return Buffer.from(value, "utf8").subarray(byteLength - limit).toString("utf8");
271
+ }
272
+ function createProcessOutputCapture(maxBytes) {
273
+ const limit = Math.max(1, Math.trunc(maxBytes));
274
+ let text = "";
275
+ let truncated = false;
276
+ let totalBytes = 0;
277
+ return {
278
+ append(chunk) {
279
+ if (!chunk)
280
+ return;
281
+ totalBytes += Buffer.byteLength(chunk, "utf8");
282
+ const combined = text + chunk;
283
+ if (Buffer.byteLength(combined, "utf8") <= limit) {
284
+ text = combined;
285
+ return;
286
+ }
287
+ text = trimToLastBytes(combined, limit);
288
+ truncated = true;
289
+ },
290
+ finish() {
291
+ if (!truncated) {
292
+ return {
293
+ text,
294
+ truncated: false,
295
+ totalBytes,
296
+ };
297
+ }
298
+ return {
299
+ text: `[output truncated to last ${limit} bytes; total ${totalBytes} bytes]\n${text}`,
300
+ truncated: true,
301
+ totalBytes,
302
+ };
303
+ },
304
+ };
305
+ }
306
+ async function executeProcess(input) {
307
+ const proc = await new Promise((resolve, reject) => {
308
+ const child = spawn(input.command, input.args, {
309
+ cwd: input.cwd,
310
+ stdio: ["ignore", "pipe", "pipe"],
311
+ env: input.env ?? process.env,
312
+ });
313
+ const stdout = createProcessOutputCapture(input.maxStdoutBytes ?? DEFAULT_EXECUTE_PROCESS_OUTPUT_BYTES);
314
+ const stderr = createProcessOutputCapture(input.maxStderrBytes ?? DEFAULT_EXECUTE_PROCESS_OUTPUT_BYTES);
315
+ child.stdout?.on("data", (chunk) => {
316
+ stdout.append(String(chunk));
317
+ });
318
+ child.stderr?.on("data", (chunk) => {
319
+ stderr.append(String(chunk));
320
+ });
321
+ child.on("error", reject);
322
+ child.on("close", (code) => resolve({ stdout, stderr, code }));
323
+ });
324
+ const stdout = proc.stdout.finish();
325
+ const stderr = proc.stderr.finish();
326
+ return {
327
+ stdout: stdout.text,
328
+ stderr: stderr.text,
329
+ code: proc.code,
330
+ stdoutTruncated: stdout.truncated,
331
+ stderrTruncated: stderr.truncated,
332
+ stdoutBytes: stdout.totalBytes,
333
+ stderrBytes: stderr.totalBytes,
334
+ };
335
+ }
336
+ async function runGit(args, cwd) {
337
+ const proc = await executeProcess({
338
+ command: "git",
339
+ args,
340
+ cwd,
341
+ });
342
+ if (proc.code !== 0) {
343
+ throw new Error(proc.stderr.trim() || proc.stdout.trim() || `git ${args.join(" ")} failed`);
344
+ }
345
+ return proc.stdout.trim();
346
+ }
347
+ function gitErrorIncludes(error, needle) {
348
+ const message = error instanceof Error ? error.message : String(error);
349
+ return message.toLowerCase().includes(needle.toLowerCase());
350
+ }
351
+ function parseGitWorktreeListPorcelain(raw) {
352
+ const entries = [];
353
+ let current = {};
354
+ for (const line of raw.split(/\r?\n/)) {
355
+ if (line.startsWith("worktree ")) {
356
+ current = { worktree: line.slice("worktree ".length) };
357
+ continue;
358
+ }
359
+ if (line.startsWith("branch ")) {
360
+ current.branch = line.slice("branch ".length);
361
+ continue;
362
+ }
363
+ if (line === "" && current.worktree) {
364
+ entries.push({
365
+ worktree: current.worktree,
366
+ branch: current.branch ?? null,
367
+ });
368
+ current = {};
369
+ }
370
+ }
371
+ if (current.worktree) {
372
+ entries.push({
373
+ worktree: current.worktree,
374
+ branch: current.branch ?? null,
375
+ });
376
+ }
377
+ return entries;
378
+ }
379
+ async function resolveGitOwnerRepoRoot(cwd) {
380
+ const checkoutRoot = path.resolve(await runGit(["rev-parse", "--show-toplevel"], cwd));
381
+ const commonDir = await runGit(["rev-parse", "--git-common-dir"], checkoutRoot).catch(() => null);
382
+ if (!commonDir)
383
+ return checkoutRoot;
384
+ return path.dirname(path.resolve(checkoutRoot, commonDir));
385
+ }
386
+ async function findRegisteredGitWorktreeByBranch(repoRoot, branchName) {
387
+ const raw = await runGit(["worktree", "list", "--porcelain"], repoRoot).catch(() => null);
388
+ if (!raw)
389
+ return null;
390
+ const expectedBranchRef = `refs/heads/${branchName}`;
391
+ for (const entry of parseGitWorktreeListPorcelain(raw)) {
392
+ if (entry.branch !== expectedBranchRef)
393
+ continue;
394
+ return path.resolve(entry.worktree);
395
+ }
396
+ return null;
397
+ }
398
+ async function isGitCheckout(cwd) {
399
+ return Boolean(await runGit(["rev-parse", "--git-dir"], cwd).catch(() => null));
400
+ }
401
+ async function detectDefaultBranch(repoRoot) {
402
+ // Try the explicit remote HEAD first (set by git clone or git remote set-head)
403
+ try {
404
+ const remoteHead = await runGit(["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"], repoRoot);
405
+ const branch = remoteHead?.startsWith("origin/") ? remoteHead.slice("origin/".length) : remoteHead;
406
+ if (branch)
407
+ return branch;
408
+ }
409
+ catch {
410
+ // Not set — fall through to heuristic
411
+ }
412
+ // Fallback: check for common default branch names on the remote
413
+ for (const candidate of ["main", "master"]) {
414
+ try {
415
+ await runGit(["rev-parse", "--verify", `refs/remotes/origin/${candidate}`], repoRoot);
416
+ return candidate;
417
+ }
418
+ catch {
419
+ // Not found — try next
420
+ }
421
+ }
422
+ return null;
423
+ }
424
+ async function directoryExists(value) {
425
+ return fs.stat(value).then((stats) => stats.isDirectory()).catch(() => false);
426
+ }
427
+ async function listLinkedGitWorktreePaths(repoRoot) {
428
+ const output = await runGit(["worktree", "list", "--porcelain"], repoRoot);
429
+ const paths = new Set();
430
+ for (const line of output.split("\n")) {
431
+ if (!line.startsWith("worktree "))
432
+ continue;
433
+ const worktree = line.slice("worktree ".length).trim();
434
+ if (!worktree)
435
+ continue;
436
+ paths.add(path.resolve(worktree));
437
+ }
438
+ return paths;
439
+ }
440
+ async function validateLinkedGitWorktree(input) {
441
+ const resolvedWorktreePath = path.resolve(input.worktreePath);
442
+ const listedWorktrees = await listLinkedGitWorktreePaths(input.repoRoot);
443
+ if (!listedWorktrees.has(resolvedWorktreePath)) {
444
+ return {
445
+ valid: false,
446
+ reason: "path is not registered in `git worktree list`",
447
+ };
448
+ }
449
+ const worktreeTopLevel = await runGit(["rev-parse", "--show-toplevel"], resolvedWorktreePath).catch(() => null);
450
+ if (!worktreeTopLevel || path.resolve(worktreeTopLevel) !== resolvedWorktreePath) {
451
+ return {
452
+ valid: false,
453
+ reason: "git resolves this path to a different repository root",
454
+ };
455
+ }
456
+ if (input.expectedBranchName) {
457
+ const currentBranch = await runGit(["symbolic-ref", "--quiet", "--short", "HEAD"], resolvedWorktreePath).catch(() => null);
458
+ if (currentBranch !== input.expectedBranchName) {
459
+ return {
460
+ valid: false,
461
+ reason: `worktree HEAD is on "${currentBranch ?? "<detached>"}" instead of "${input.expectedBranchName}"`,
462
+ };
463
+ }
464
+ }
465
+ return { valid: true };
466
+ }
467
+ function terminateChildProcess(child) {
468
+ if (!child.pid)
469
+ return;
470
+ if (process.platform !== "win32") {
471
+ try {
472
+ process.kill(-child.pid, "SIGTERM");
473
+ return;
474
+ }
475
+ catch {
476
+ // Fall through to the direct child kill.
477
+ }
478
+ }
479
+ if (!child.killed) {
480
+ child.kill("SIGTERM");
481
+ }
482
+ }
483
+ function buildWorkspaceCommandEnv(input) {
484
+ const env = { ...process.env };
485
+ env.EVERMORE_WORKSPACE_CWD = input.worktreePath;
486
+ env.EVERMORE_WORKSPACE_PATH = input.worktreePath;
487
+ env.EVERMORE_WORKSPACE_WORKTREE_PATH = input.worktreePath;
488
+ env.EVERMORE_WORKSPACE_BRANCH = input.branchName;
489
+ env.EVERMORE_WORKSPACE_BASE_CWD = input.base.baseCwd;
490
+ env.EVERMORE_WORKSPACE_REPO_ROOT = input.repoRoot;
491
+ env.EVERMORE_WORKSPACE_SOURCE = input.base.source;
492
+ env.EVERMORE_WORKSPACE_REPO_REF = input.base.repoRef ?? "";
493
+ env.EVERMORE_WORKSPACE_REPO_URL = input.base.repoUrl ?? "";
494
+ env.EVERMORE_WORKSPACE_CREATED = input.created ? "true" : "false";
495
+ env.EVERMORE_PROJECT_ID = input.base.projectId ?? "";
496
+ env.EVERMORE_PROJECT_WORKSPACE_ID = input.base.workspaceId ?? "";
497
+ env.EVERMORE_AGENT_ID = input.agent.id ?? "";
498
+ env.EVERMORE_AGENT_NAME = input.agent.name;
499
+ env.EVERMORE_COMPANY_ID = input.agent.companyId;
500
+ env.EVERMORE_ISSUE_ID = input.issue?.id ?? "";
501
+ env.EVERMORE_ISSUE_IDENTIFIER = input.issue?.identifier ?? "";
502
+ env.EVERMORE_ISSUE_TITLE = input.issue?.title ?? "";
503
+ env.EVERMORE_ISSUE_WORK_MODE = input.issue?.workMode ?? "";
504
+ return env;
505
+ }
506
+ function quoteShellArg(value) {
507
+ return `'${value.replace(/'/g, `'\\''`)}'`;
508
+ }
509
+ function resolveRepoManagedWorkspaceCommand(command, repoRoot) {
510
+ const patterns = [
511
+ /^(?<prefix>(?:bash|sh|zsh)\s+)(?<quote>["']?)(?<relative>\.\/[^"'\s]+)\k<quote>(?<suffix>(?:\s.*)?)$/s,
512
+ /^(?<quote>["']?)(?<relative>\.\/[^"'\s]+)\k<quote>(?<suffix>(?:\s.*)?)$/s,
513
+ ];
514
+ for (const pattern of patterns) {
515
+ const match = command.match(pattern);
516
+ if (!match?.groups)
517
+ continue;
518
+ const relativePath = match.groups.relative;
519
+ const repoManagedPath = path.join(repoRoot, relativePath.slice(2));
520
+ if (!existsSync(repoManagedPath))
521
+ continue;
522
+ const prefix = match.groups.prefix ?? "";
523
+ const suffix = match.groups.suffix ?? "";
524
+ return `${prefix}${quoteShellArg(repoManagedPath)}${suffix}`;
525
+ }
526
+ return command;
527
+ }
528
+ async function runWorkspaceCommand(input) {
529
+ const shell = resolveShell();
530
+ const proc = await executeProcess({
531
+ command: shell,
532
+ args: ["-c", input.resolvedCommand ?? input.command],
533
+ cwd: input.cwd,
534
+ env: input.env,
535
+ });
536
+ if (proc.code === 0)
537
+ return;
538
+ const details = [proc.stderr.trim(), proc.stdout.trim()].filter(Boolean).join("\n");
539
+ throw new Error(details.length > 0
540
+ ? `${input.label} failed: ${details}`
541
+ : `${input.label} failed with exit code ${proc.code ?? -1}`);
542
+ }
543
+ async function recordGitOperation(recorder, input) {
544
+ if (!recorder) {
545
+ return runGit(input.args, input.cwd);
546
+ }
547
+ let stdout = "";
548
+ let stderr = "";
549
+ let code = null;
550
+ await recorder.recordOperation({
551
+ phase: input.phase,
552
+ command: formatCommandForDisplay("git", input.args),
553
+ cwd: input.cwd,
554
+ metadata: input.metadata ?? null,
555
+ run: async () => {
556
+ const result = await executeProcess({
557
+ command: "git",
558
+ args: input.args,
559
+ cwd: input.cwd,
560
+ });
561
+ stdout = result.stdout;
562
+ stderr = result.stderr;
563
+ code = result.code;
564
+ return {
565
+ status: result.code === 0 ? "succeeded" : "failed",
566
+ exitCode: result.code,
567
+ stdout: result.stdout,
568
+ stderr: result.stderr,
569
+ system: result.code === 0 ? input.successMessage ?? null : null,
570
+ metadata: result.stdoutTruncated || result.stderrTruncated
571
+ ? {
572
+ stdoutTruncated: result.stdoutTruncated,
573
+ stderrTruncated: result.stderrTruncated,
574
+ stdoutBytes: result.stdoutBytes,
575
+ stderrBytes: result.stderrBytes,
576
+ }
577
+ : null,
578
+ };
579
+ },
580
+ });
581
+ if (code !== 0) {
582
+ const details = [stderr.trim(), stdout.trim()].filter(Boolean).join("\n");
583
+ throw new Error(details.length > 0
584
+ ? `${input.failureLabel ?? `git ${input.args.join(" ")}`} failed: ${details}`
585
+ : `${input.failureLabel ?? `git ${input.args.join(" ")}`} failed with exit code ${code ?? -1}`);
586
+ }
587
+ return stdout.trim();
588
+ }
589
+ async function recordWorkspaceCommandOperation(recorder, input) {
590
+ if (!recorder) {
591
+ await runWorkspaceCommand(input);
592
+ return null;
593
+ }
594
+ let stdout = "";
595
+ let stderr = "";
596
+ let code = null;
597
+ const operation = await recorder.recordOperation({
598
+ phase: input.phase,
599
+ command: input.command,
600
+ cwd: input.cwd,
601
+ metadata: input.metadata ?? null,
602
+ run: async () => {
603
+ const shell = resolveShell();
604
+ const result = await executeProcess({
605
+ command: shell,
606
+ args: ["-c", input.resolvedCommand ?? input.command],
607
+ cwd: input.cwd,
608
+ env: input.env,
609
+ });
610
+ stdout = result.stdout;
611
+ stderr = result.stderr;
612
+ code = result.code;
613
+ return {
614
+ status: result.code === 0 ? "succeeded" : "failed",
615
+ exitCode: result.code,
616
+ stdout: result.stdout,
617
+ stderr: result.stderr,
618
+ system: result.code === 0 ? input.successMessage ?? null : null,
619
+ metadata: result.stdoutTruncated || result.stderrTruncated
620
+ ? {
621
+ stdoutTruncated: result.stdoutTruncated,
622
+ stderrTruncated: result.stderrTruncated,
623
+ stdoutBytes: result.stdoutBytes,
624
+ stderrBytes: result.stderrBytes,
625
+ }
626
+ : null,
627
+ };
628
+ },
629
+ });
630
+ if (code === 0)
631
+ return operation;
632
+ const details = [stderr.trim(), stdout.trim()].filter(Boolean).join("\n");
633
+ throw new Error(details.length > 0
634
+ ? `${input.label} failed: ${details}`
635
+ : `${input.label} failed with exit code ${code ?? -1}`);
636
+ }
637
+ async function provisionExecutionWorktree(input) {
638
+ const provisionCommand = asString(input.strategy.provisionCommand, "").trim();
639
+ if (!provisionCommand)
640
+ return;
641
+ const resolvedProvisionCommand = resolveRepoManagedWorkspaceCommand(provisionCommand, input.repoRoot);
642
+ await recordWorkspaceCommandOperation(input.recorder, {
643
+ phase: "workspace_provision",
644
+ command: provisionCommand,
645
+ resolvedCommand: resolvedProvisionCommand,
646
+ cwd: input.worktreePath,
647
+ env: buildWorkspaceCommandEnv({
648
+ base: input.base,
649
+ repoRoot: input.repoRoot,
650
+ worktreePath: input.worktreePath,
651
+ branchName: input.branchName,
652
+ issue: input.issue,
653
+ agent: input.agent,
654
+ created: input.created,
655
+ }),
656
+ label: `Execution workspace provision command "${provisionCommand}"`,
657
+ metadata: {
658
+ repoRoot: input.repoRoot,
659
+ worktreePath: input.worktreePath,
660
+ branchName: input.branchName,
661
+ created: input.created,
662
+ resolvedCommand: resolvedProvisionCommand === provisionCommand ? null : resolvedProvisionCommand,
663
+ },
664
+ successMessage: `Provisioned workspace at ${input.worktreePath}\n`,
665
+ });
666
+ }
667
+ function buildExecutionWorkspaceCleanupEnv(input) {
668
+ const env = sanitizeRuntimeServiceBaseEnv(process.env);
669
+ env.EVERMORE_WORKSPACE_CWD = input.workspace.cwd ?? "";
670
+ env.EVERMORE_WORKSPACE_PATH = input.workspace.cwd ?? "";
671
+ env.EVERMORE_WORKSPACE_WORKTREE_PATH =
672
+ input.workspace.providerRef ?? input.workspace.cwd ?? "";
673
+ env.EVERMORE_WORKSPACE_BRANCH = input.workspace.branchName ?? "";
674
+ env.EVERMORE_WORKSPACE_BASE_CWD = input.projectWorkspaceCwd ?? "";
675
+ env.EVERMORE_WORKSPACE_REPO_ROOT = input.projectWorkspaceCwd ?? "";
676
+ env.EVERMORE_WORKSPACE_REPO_URL = input.workspace.repoUrl ?? "";
677
+ env.EVERMORE_WORKSPACE_REPO_REF = input.workspace.baseRef ?? "";
678
+ env.EVERMORE_PROJECT_ID = input.workspace.projectId ?? "";
679
+ env.EVERMORE_PROJECT_WORKSPACE_ID = input.workspace.projectWorkspaceId ?? "";
680
+ env.EVERMORE_ISSUE_ID = input.workspace.sourceIssueId ?? "";
681
+ return env;
682
+ }
683
+ async function resolveGitRepoRootForWorkspaceCleanup(worktreePath, projectWorkspaceCwd) {
684
+ if (projectWorkspaceCwd) {
685
+ const resolvedProjectWorkspaceCwd = path.resolve(projectWorkspaceCwd);
686
+ const gitDir = await runGit(["rev-parse", "--git-common-dir"], resolvedProjectWorkspaceCwd)
687
+ .catch(() => null);
688
+ if (gitDir) {
689
+ const resolvedGitDir = path.resolve(resolvedProjectWorkspaceCwd, gitDir);
690
+ return path.dirname(resolvedGitDir);
691
+ }
692
+ }
693
+ const gitDir = await runGit(["rev-parse", "--git-common-dir"], worktreePath).catch(() => null);
694
+ if (!gitDir)
695
+ return null;
696
+ const resolvedGitDir = path.resolve(worktreePath, gitDir);
697
+ return path.dirname(resolvedGitDir);
698
+ }
699
+ export async function realizeExecutionWorkspace(input) {
700
+ const rawStrategy = parseObject(input.config.workspaceStrategy);
701
+ const strategyType = asString(rawStrategy.type, "project_primary");
702
+ if (strategyType !== "git_worktree") {
703
+ return {
704
+ ...input.base,
705
+ strategy: "project_primary",
706
+ cwd: input.base.baseCwd,
707
+ branchName: null,
708
+ worktreePath: null,
709
+ warnings: [],
710
+ created: false,
711
+ };
712
+ }
713
+ const repoRoot = await resolveGitOwnerRepoRoot(input.base.baseCwd);
714
+ const branchTemplate = asString(rawStrategy.branchTemplate, "{{issue.identifier}}-{{slug}}");
715
+ const renderedBranch = renderWorkspaceTemplate(branchTemplate, {
716
+ issue: input.issue,
717
+ agent: input.agent,
718
+ projectId: input.base.projectId,
719
+ repoRef: input.base.repoRef,
720
+ });
721
+ const branchName = sanitizeBranchName(renderedBranch);
722
+ const configuredParentDir = asString(rawStrategy.worktreeParentDir, "");
723
+ const worktreeParentDir = configuredParentDir
724
+ ? resolveConfiguredPath(configuredParentDir, repoRoot)
725
+ : path.join(repoRoot, ".evermore", "worktrees");
726
+ const worktreePath = path.join(worktreeParentDir, branchName);
727
+ const configuredBaseRef = typeof rawStrategy.baseRef === "string" && rawStrategy.baseRef.length > 0
728
+ ? rawStrategy.baseRef
729
+ : input.base.repoRef ?? null;
730
+ const baseRef = configuredBaseRef
731
+ ?? await detectDefaultBranch(repoRoot)
732
+ ?? "HEAD";
733
+ await fs.mkdir(worktreeParentDir, { recursive: true });
734
+ async function reuseExistingWorktree(reusablePath) {
735
+ if (input.recorder) {
736
+ await input.recorder.recordOperation({
737
+ phase: "worktree_prepare",
738
+ cwd: repoRoot,
739
+ metadata: {
740
+ repoRoot,
741
+ worktreePath: reusablePath,
742
+ branchName,
743
+ baseRef,
744
+ created: false,
745
+ reused: true,
746
+ },
747
+ run: async () => ({
748
+ status: "succeeded",
749
+ exitCode: 0,
750
+ system: `Reused existing git worktree at ${reusablePath}\n`,
751
+ }),
752
+ });
753
+ }
754
+ await provisionExecutionWorktree({
755
+ strategy: rawStrategy,
756
+ base: input.base,
757
+ repoRoot,
758
+ worktreePath: reusablePath,
759
+ branchName,
760
+ issue: input.issue,
761
+ agent: input.agent,
762
+ created: false,
763
+ recorder: input.recorder ?? null,
764
+ });
765
+ return {
766
+ ...input.base,
767
+ strategy: "git_worktree",
768
+ cwd: reusablePath,
769
+ branchName,
770
+ worktreePath: reusablePath,
771
+ warnings: [],
772
+ created: false,
773
+ };
774
+ }
775
+ async function validateReusableWorktree(reusablePath) {
776
+ return await validateLinkedGitWorktree({
777
+ repoRoot,
778
+ worktreePath: reusablePath,
779
+ expectedBranchName: branchName,
780
+ }).catch(() => null);
781
+ }
782
+ const existingWorktree = await directoryExists(worktreePath);
783
+ if (existingWorktree) {
784
+ const validation = await validateReusableWorktree(worktreePath);
785
+ if (validation?.valid) {
786
+ return await reuseExistingWorktree(worktreePath);
787
+ }
788
+ const reason = validation && !validation.valid ? ` (${validation.reason})` : "";
789
+ throw new Error(`Configured worktree path "${worktreePath}" already exists and is not a reusable git worktree${reason}.`);
790
+ }
791
+ const registeredBranchWorktree = await findRegisteredGitWorktreeByBranch(repoRoot, branchName);
792
+ if (registeredBranchWorktree) {
793
+ const validation = await validateReusableWorktree(registeredBranchWorktree);
794
+ if (validation?.valid) {
795
+ return await reuseExistingWorktree(registeredBranchWorktree);
796
+ }
797
+ const reason = validation && !validation.valid ? ` (${validation.reason})` : "";
798
+ throw new Error(`Registered worktree for branch "${branchName}" at "${registeredBranchWorktree}" is not reusable${reason}.`);
799
+ }
800
+ try {
801
+ await recordGitOperation(input.recorder, {
802
+ phase: "worktree_prepare",
803
+ args: ["worktree", "add", "-b", branchName, worktreePath, baseRef],
804
+ cwd: repoRoot,
805
+ metadata: {
806
+ repoRoot,
807
+ worktreePath,
808
+ branchName,
809
+ baseRef,
810
+ created: true,
811
+ },
812
+ successMessage: `Created git worktree at ${worktreePath}\n`,
813
+ failureLabel: `git worktree add ${worktreePath}`,
814
+ });
815
+ }
816
+ catch (error) {
817
+ if (!gitErrorIncludes(error, "already exists")) {
818
+ throw error;
819
+ }
820
+ try {
821
+ await recordGitOperation(input.recorder, {
822
+ phase: "worktree_prepare",
823
+ args: ["worktree", "add", worktreePath, branchName],
824
+ cwd: repoRoot,
825
+ metadata: {
826
+ repoRoot,
827
+ worktreePath,
828
+ branchName,
829
+ baseRef,
830
+ created: false,
831
+ reusedExistingBranch: true,
832
+ },
833
+ successMessage: `Attached existing branch ${branchName} at ${worktreePath}\n`,
834
+ failureLabel: `git worktree add ${worktreePath}`,
835
+ });
836
+ }
837
+ catch (attachError) {
838
+ if (!gitErrorIncludes(attachError, "already checked out")) {
839
+ throw attachError;
840
+ }
841
+ const reusablePath = await findRegisteredGitWorktreeByBranch(repoRoot, branchName);
842
+ if (!reusablePath || !await isGitCheckout(reusablePath)) {
843
+ throw attachError;
844
+ }
845
+ return await reuseExistingWorktree(reusablePath);
846
+ }
847
+ }
848
+ await provisionExecutionWorktree({
849
+ strategy: rawStrategy,
850
+ base: input.base,
851
+ repoRoot,
852
+ worktreePath,
853
+ branchName,
854
+ issue: input.issue,
855
+ agent: input.agent,
856
+ created: true,
857
+ recorder: input.recorder ?? null,
858
+ });
859
+ return {
860
+ ...input.base,
861
+ strategy: "git_worktree",
862
+ cwd: worktreePath,
863
+ branchName,
864
+ worktreePath,
865
+ warnings: [],
866
+ created: true,
867
+ };
868
+ }
869
+ export async function ensurePersistedExecutionWorkspaceAvailable(input) {
870
+ const cwd = asString(input.workspace.cwd ?? input.workspace.providerRef, "").trim();
871
+ if (!cwd)
872
+ return null;
873
+ const strategy = input.workspace.strategyType === "git_worktree" ? "git_worktree" : "project_primary";
874
+ const realized = {
875
+ baseCwd: input.base.baseCwd,
876
+ source: input.workspace.mode === "shared_workspace" ? "project_primary" : "task_session",
877
+ projectId: input.workspace.projectId ?? input.base.projectId,
878
+ workspaceId: input.workspace.projectWorkspaceId ?? input.base.workspaceId,
879
+ repoUrl: input.workspace.repoUrl ?? input.base.repoUrl,
880
+ repoRef: input.workspace.baseRef ?? input.base.repoRef,
881
+ strategy,
882
+ cwd,
883
+ branchName: input.workspace.branchName ?? null,
884
+ worktreePath: strategy === "git_worktree" ? (input.workspace.providerRef ?? cwd) : null,
885
+ warnings: [],
886
+ created: false,
887
+ };
888
+ const provisionCommand = asString(input.workspace.config?.provisionCommand, "").trim();
889
+ if (strategy !== "git_worktree") {
890
+ return realized;
891
+ }
892
+ if (await directoryExists(cwd)) {
893
+ if (provisionCommand) {
894
+ const repoRoot = await runGit(["rev-parse", "--show-toplevel"], input.base.baseCwd);
895
+ await provisionExecutionWorktree({
896
+ strategy: {
897
+ type: "git_worktree",
898
+ provisionCommand,
899
+ },
900
+ base: input.base,
901
+ repoRoot,
902
+ worktreePath: realized.worktreePath ?? cwd,
903
+ branchName: realized.branchName ?? "",
904
+ issue: input.issue,
905
+ agent: input.agent,
906
+ created: false,
907
+ recorder: input.recorder ?? null,
908
+ });
909
+ }
910
+ return realized;
911
+ }
912
+ const repoRoot = await runGit(["rev-parse", "--show-toplevel"], input.base.baseCwd);
913
+ const worktreePath = realized.worktreePath ?? cwd;
914
+ const branchName = asString(input.workspace.branchName, "").trim();
915
+ if (!branchName) {
916
+ throw new Error(`Execution workspace "${cwd}" is missing and cannot be restored because no branch name is recorded.`);
917
+ }
918
+ await fs.mkdir(path.dirname(worktreePath), { recursive: true });
919
+ await runGit(["worktree", "prune"], repoRoot).catch(() => { });
920
+ let created = false;
921
+ try {
922
+ await recordGitOperation(input.recorder, {
923
+ phase: "worktree_prepare",
924
+ args: ["worktree", "add", worktreePath, branchName],
925
+ cwd: repoRoot,
926
+ metadata: {
927
+ repoRoot,
928
+ worktreePath,
929
+ branchName,
930
+ baseRef: input.workspace.baseRef ?? input.base.repoRef ?? null,
931
+ created: false,
932
+ restored: true,
933
+ },
934
+ successMessage: `Reattached missing git worktree at ${worktreePath}\n`,
935
+ failureLabel: `git worktree add ${worktreePath}`,
936
+ });
937
+ }
938
+ catch (error) {
939
+ if (!gitErrorIncludes(error, "invalid reference")
940
+ && !gitErrorIncludes(error, "not a commit")
941
+ && !gitErrorIncludes(error, "unknown revision")) {
942
+ throw error;
943
+ }
944
+ const baseRef = input.workspace.baseRef ?? await detectDefaultBranch(repoRoot) ?? "HEAD";
945
+ await recordGitOperation(input.recorder, {
946
+ phase: "worktree_prepare",
947
+ args: ["worktree", "add", "-b", branchName, worktreePath, baseRef],
948
+ cwd: repoRoot,
949
+ metadata: {
950
+ repoRoot,
951
+ worktreePath,
952
+ branchName,
953
+ baseRef,
954
+ created: true,
955
+ restored: true,
956
+ },
957
+ successMessage: `Recreated missing git worktree at ${worktreePath}\n`,
958
+ failureLabel: `git worktree add ${worktreePath}`,
959
+ });
960
+ created = true;
961
+ }
962
+ await provisionExecutionWorktree({
963
+ strategy: {
964
+ type: "git_worktree",
965
+ ...(provisionCommand ? { provisionCommand } : {}),
966
+ },
967
+ base: input.base,
968
+ repoRoot,
969
+ worktreePath,
970
+ branchName,
971
+ issue: input.issue,
972
+ agent: input.agent,
973
+ created,
974
+ recorder: input.recorder ?? null,
975
+ });
976
+ return {
977
+ ...realized,
978
+ cwd: worktreePath,
979
+ worktreePath,
980
+ created,
981
+ };
982
+ }
983
+ export async function cleanupExecutionWorkspaceArtifacts(input) {
984
+ const warnings = [];
985
+ const workspacePath = input.workspace.providerRef ?? input.workspace.cwd;
986
+ const repoRoot = input.workspace.providerType === "git_worktree" && workspacePath
987
+ ? await resolveGitRepoRootForWorkspaceCleanup(workspacePath, input.projectWorkspace?.cwd ?? null)
988
+ : null;
989
+ const cleanupEnv = buildExecutionWorkspaceCleanupEnv({
990
+ workspace: input.workspace,
991
+ projectWorkspaceCwd: input.projectWorkspace?.cwd ?? null,
992
+ });
993
+ const createdByRuntime = input.workspace.metadata?.createdByRuntime === true;
994
+ const cleanupCommands = [
995
+ input.cleanupCommand ?? null,
996
+ input.projectWorkspace?.cleanupCommand ?? null,
997
+ input.teardownCommand ?? null,
998
+ ]
999
+ .map((value) => asString(value, "").trim())
1000
+ .filter(Boolean);
1001
+ for (const command of cleanupCommands) {
1002
+ try {
1003
+ const resolvedCommand = repoRoot
1004
+ ? resolveRepoManagedWorkspaceCommand(command, repoRoot)
1005
+ : command;
1006
+ await recordWorkspaceCommandOperation(input.recorder, {
1007
+ phase: "workspace_teardown",
1008
+ command,
1009
+ resolvedCommand,
1010
+ cwd: workspacePath ?? input.projectWorkspace?.cwd ?? process.cwd(),
1011
+ env: cleanupEnv,
1012
+ label: `Execution workspace cleanup command "${command}"`,
1013
+ metadata: {
1014
+ workspaceId: input.workspace.id,
1015
+ workspacePath,
1016
+ branchName: input.workspace.branchName,
1017
+ providerType: input.workspace.providerType,
1018
+ resolvedCommand: resolvedCommand === command ? null : resolvedCommand,
1019
+ },
1020
+ successMessage: `Completed cleanup command "${command}"\n`,
1021
+ });
1022
+ }
1023
+ catch (err) {
1024
+ warnings.push(err instanceof Error ? err.message : String(err));
1025
+ }
1026
+ }
1027
+ if (input.workspace.providerType === "git_worktree" && workspacePath) {
1028
+ const worktreeExists = await directoryExists(workspacePath);
1029
+ if (worktreeExists) {
1030
+ if (!repoRoot) {
1031
+ warnings.push(`Could not resolve git repo root for "${workspacePath}".`);
1032
+ }
1033
+ else {
1034
+ try {
1035
+ await recordGitOperation(input.recorder, {
1036
+ phase: "worktree_cleanup",
1037
+ args: ["worktree", "remove", "--force", workspacePath],
1038
+ cwd: repoRoot,
1039
+ metadata: {
1040
+ workspaceId: input.workspace.id,
1041
+ workspacePath,
1042
+ branchName: input.workspace.branchName,
1043
+ cleanupAction: "worktree_remove",
1044
+ },
1045
+ successMessage: `Removed git worktree ${workspacePath}\n`,
1046
+ failureLabel: `git worktree remove ${workspacePath}`,
1047
+ });
1048
+ }
1049
+ catch (err) {
1050
+ warnings.push(err instanceof Error ? err.message : String(err));
1051
+ }
1052
+ }
1053
+ }
1054
+ if (createdByRuntime && input.workspace.branchName) {
1055
+ if (!repoRoot) {
1056
+ warnings.push(`Could not resolve git repo root to delete branch "${input.workspace.branchName}".`);
1057
+ }
1058
+ else {
1059
+ try {
1060
+ await recordGitOperation(input.recorder, {
1061
+ phase: "worktree_cleanup",
1062
+ args: ["branch", "-d", input.workspace.branchName],
1063
+ cwd: repoRoot,
1064
+ metadata: {
1065
+ workspaceId: input.workspace.id,
1066
+ workspacePath,
1067
+ branchName: input.workspace.branchName,
1068
+ cleanupAction: "branch_delete",
1069
+ },
1070
+ successMessage: `Deleted branch ${input.workspace.branchName}\n`,
1071
+ failureLabel: `git branch -d ${input.workspace.branchName}`,
1072
+ });
1073
+ }
1074
+ catch (err) {
1075
+ const message = err instanceof Error ? err.message : String(err);
1076
+ warnings.push(`Skipped deleting branch "${input.workspace.branchName}": ${message}`);
1077
+ }
1078
+ }
1079
+ }
1080
+ }
1081
+ else if (input.workspace.providerType === "local_fs" && createdByRuntime && workspacePath) {
1082
+ const projectWorkspaceCwd = input.projectWorkspace?.cwd ? path.resolve(input.projectWorkspace.cwd) : null;
1083
+ const resolvedWorkspacePath = path.resolve(workspacePath);
1084
+ const containsProjectWorkspace = projectWorkspaceCwd
1085
+ ? (resolvedWorkspacePath === projectWorkspaceCwd ||
1086
+ projectWorkspaceCwd.startsWith(`${resolvedWorkspacePath}${path.sep}`))
1087
+ : false;
1088
+ if (containsProjectWorkspace) {
1089
+ warnings.push(`Refusing to remove path "${workspacePath}" because it contains the project workspace.`);
1090
+ }
1091
+ else {
1092
+ await fs.rm(resolvedWorkspacePath, { recursive: true, force: true });
1093
+ if (input.recorder) {
1094
+ await input.recorder.recordOperation({
1095
+ phase: "workspace_teardown",
1096
+ cwd: projectWorkspaceCwd ?? process.cwd(),
1097
+ metadata: {
1098
+ workspaceId: input.workspace.id,
1099
+ workspacePath: resolvedWorkspacePath,
1100
+ cleanupAction: "remove_local_fs",
1101
+ },
1102
+ run: async () => ({
1103
+ status: "succeeded",
1104
+ exitCode: 0,
1105
+ system: `Removed local workspace directory ${resolvedWorkspacePath}\n`,
1106
+ }),
1107
+ });
1108
+ }
1109
+ }
1110
+ }
1111
+ const cleaned = !workspacePath ||
1112
+ !(await directoryExists(workspacePath));
1113
+ return {
1114
+ cleanedPath: workspacePath,
1115
+ cleaned,
1116
+ warnings,
1117
+ };
1118
+ }
1119
+ async function allocatePort() {
1120
+ return await new Promise((resolve, reject) => {
1121
+ const server = net.createServer();
1122
+ server.listen(0, "127.0.0.1", () => {
1123
+ const address = server.address();
1124
+ server.close((err) => {
1125
+ if (err) {
1126
+ reject(err);
1127
+ return;
1128
+ }
1129
+ if (!address || typeof address === "string") {
1130
+ reject(new Error("Failed to allocate port"));
1131
+ return;
1132
+ }
1133
+ resolve(address.port);
1134
+ });
1135
+ });
1136
+ server.on("error", reject);
1137
+ });
1138
+ }
1139
+ function buildTemplateData(input) {
1140
+ return {
1141
+ workspace: {
1142
+ cwd: input.workspace.cwd,
1143
+ branchName: input.workspace.branchName ?? "",
1144
+ worktreePath: input.workspace.worktreePath ?? "",
1145
+ repoUrl: input.workspace.repoUrl ?? "",
1146
+ repoRef: input.workspace.repoRef ?? "",
1147
+ env: input.adapterEnv,
1148
+ },
1149
+ issue: {
1150
+ id: input.issue?.id ?? "",
1151
+ identifier: input.issue?.identifier ?? "",
1152
+ title: input.issue?.title ?? "",
1153
+ },
1154
+ agent: {
1155
+ id: input.agent.id ?? "",
1156
+ name: input.agent.name,
1157
+ },
1158
+ port: input.port ?? "",
1159
+ };
1160
+ }
1161
+ function renderRuntimeServiceEnv(input) {
1162
+ const rendered = {};
1163
+ for (const [key, value] of Object.entries(input.envConfig)) {
1164
+ if (typeof value !== "string")
1165
+ continue;
1166
+ rendered[key] = renderTemplate(value, input.templateData);
1167
+ }
1168
+ return rendered;
1169
+ }
1170
+ function resolveRuntimeServiceReuseIdentity(input) {
1171
+ const serviceName = asString(input.service.name, "service");
1172
+ const lifecycle = asString(input.service.lifecycle, "shared") === "ephemeral" ? "ephemeral" : "shared";
1173
+ const command = asString(input.service.command, "");
1174
+ const serviceCwdTemplate = asString(input.service.cwd, ".");
1175
+ const portConfig = parseObject(input.service.port);
1176
+ const envConfig = parseObject(input.service.env);
1177
+ const explicitPort = asNumber(portConfig.value, asNumber(input.service.port, 0));
1178
+ const identityPort = explicitPort > 0 ? explicitPort : null;
1179
+ const templateData = buildTemplateData({
1180
+ workspace: input.workspace,
1181
+ agent: input.agent,
1182
+ issue: input.issue,
1183
+ adapterEnv: input.adapterEnv,
1184
+ port: identityPort,
1185
+ });
1186
+ const serviceCwd = resolveConfiguredPath(renderTemplate(serviceCwdTemplate, templateData), input.workspace.cwd);
1187
+ const renderedEnv = renderRuntimeServiceEnv({
1188
+ envConfig,
1189
+ templateData,
1190
+ });
1191
+ const envFingerprint = createHash("sha256").update(stableStringify(renderedEnv)).digest("hex");
1192
+ const reuseKey = lifecycle === "shared"
1193
+ ? createHash("sha256")
1194
+ .update(stableStringify({
1195
+ scopeType: input.scopeType,
1196
+ scopeId: input.scopeId,
1197
+ serviceName,
1198
+ command,
1199
+ cwd: serviceCwd,
1200
+ port: identityPort,
1201
+ env: renderedEnv,
1202
+ }))
1203
+ .digest("hex")
1204
+ : null;
1205
+ return {
1206
+ serviceName,
1207
+ lifecycle,
1208
+ command,
1209
+ serviceCwd,
1210
+ envConfig,
1211
+ envFingerprint,
1212
+ explicitPort,
1213
+ identityPort,
1214
+ reuseKey,
1215
+ };
1216
+ }
1217
+ function resolveWorkspaceCommandExecution(input) {
1218
+ const name = asString(input.command.name, "")
1219
+ || asString(input.command.label, "")
1220
+ || asString(input.command.title, "")
1221
+ || "workspace command";
1222
+ const command = asString(input.command.command, "");
1223
+ const templateData = buildTemplateData({
1224
+ workspace: input.workspace,
1225
+ agent: input.agent,
1226
+ issue: input.issue,
1227
+ adapterEnv: input.adapterEnv,
1228
+ port: null,
1229
+ });
1230
+ const cwd = resolveConfiguredPath(renderTemplate(asString(input.command.cwd, "."), templateData), input.workspace.cwd);
1231
+ const env = {
1232
+ ...sanitizeRuntimeServiceBaseEnv(process.env),
1233
+ ...input.adapterEnv,
1234
+ ...renderRuntimeServiceEnv({
1235
+ envConfig: parseObject(input.command.env),
1236
+ templateData,
1237
+ }),
1238
+ };
1239
+ return {
1240
+ name,
1241
+ command,
1242
+ cwd,
1243
+ env,
1244
+ };
1245
+ }
1246
+ export async function runWorkspaceJobForControl(input) {
1247
+ const resolved = resolveWorkspaceCommandExecution({
1248
+ command: input.command,
1249
+ workspace: input.workspace,
1250
+ agent: input.actor,
1251
+ issue: input.issue,
1252
+ adapterEnv: input.adapterEnv ?? {},
1253
+ });
1254
+ if (!resolved.command) {
1255
+ throw new Error(`Workspace job "${resolved.name}" is missing command`);
1256
+ }
1257
+ await ensureServerWorkspaceLinksCurrent(resolved.cwd);
1258
+ return await recordWorkspaceCommandOperation(input.recorder, {
1259
+ phase: "workspace_provision",
1260
+ command: resolved.command,
1261
+ cwd: resolved.cwd,
1262
+ env: resolved.env,
1263
+ label: `Workspace job "${resolved.name}"`,
1264
+ metadata: {
1265
+ workspaceCommandKind: "job",
1266
+ workspaceCommandName: resolved.name,
1267
+ ...(input.metadata ?? {}),
1268
+ },
1269
+ successMessage: `Completed workspace job "${resolved.name}"\n`,
1270
+ });
1271
+ }
1272
+ function resolveServiceScopeId(input) {
1273
+ const scopeTypeRaw = asString(input.service.reuseScope, input.service.lifecycle === "shared" ? "project_workspace" : "run");
1274
+ const scopeType = scopeTypeRaw === "project_workspace" ||
1275
+ scopeTypeRaw === "execution_workspace" ||
1276
+ scopeTypeRaw === "agent"
1277
+ ? scopeTypeRaw
1278
+ : "run";
1279
+ if (scopeType === "project_workspace")
1280
+ return { scopeType, scopeId: input.workspace.workspaceId ?? input.workspace.projectId };
1281
+ if (scopeType === "execution_workspace") {
1282
+ return { scopeType, scopeId: input.executionWorkspaceId ?? input.workspace.cwd };
1283
+ }
1284
+ if (scopeType === "agent")
1285
+ return { scopeType, scopeId: input.agent.id };
1286
+ return { scopeType: "run", scopeId: input.runId };
1287
+ }
1288
+ function looksLikeWorkspaceDevServerCommand(command) {
1289
+ const normalized = command.trim().toLowerCase();
1290
+ if (!normalized)
1291
+ return false;
1292
+ return /(?:^|\s)(?:pnpm|npm|yarn|bun)\s+(?:run\s+)?dev(?:\s|$)/.test(normalized);
1293
+ }
1294
+ export function resolveWorkspaceRuntimeReadinessTimeoutSec(service) {
1295
+ const readiness = parseObject(service.readiness);
1296
+ const explicitTimeoutSec = asNumber(readiness.timeoutSec, 0);
1297
+ if (explicitTimeoutSec > 0) {
1298
+ return Math.max(1, explicitTimeoutSec);
1299
+ }
1300
+ return looksLikeWorkspaceDevServerCommand(asString(service.command, "")) ? 90 : 30;
1301
+ }
1302
+ async function waitForReadiness(input) {
1303
+ const readiness = parseObject(input.service.readiness);
1304
+ const readinessType = asString(readiness.type, "");
1305
+ if (readinessType !== "http" || !input.url)
1306
+ return;
1307
+ const timeoutSec = resolveWorkspaceRuntimeReadinessTimeoutSec(input.service);
1308
+ const intervalMs = Math.max(100, asNumber(readiness.intervalMs, 500));
1309
+ const deadline = Date.now() + timeoutSec * 1000;
1310
+ let lastError = "service did not become ready";
1311
+ while (Date.now() < deadline) {
1312
+ try {
1313
+ const response = await fetch(input.url);
1314
+ if (response.ok)
1315
+ return;
1316
+ lastError = `received HTTP ${response.status}`;
1317
+ }
1318
+ catch (err) {
1319
+ lastError = err instanceof Error ? err.message : String(err);
1320
+ }
1321
+ await delay(intervalMs);
1322
+ }
1323
+ throw new Error(`Readiness check failed for ${input.url}: ${lastError}`);
1324
+ }
1325
+ async function isRuntimeServiceUrlHealthy(url) {
1326
+ if (!url)
1327
+ return true;
1328
+ try {
1329
+ const response = await fetch(url, { signal: AbortSignal.timeout(2_000) });
1330
+ return response.ok;
1331
+ }
1332
+ catch {
1333
+ return false;
1334
+ }
1335
+ }
1336
+ function toPersistedWorkspaceRuntimeService(record) {
1337
+ return {
1338
+ id: record.id,
1339
+ companyId: record.companyId,
1340
+ projectId: record.projectId,
1341
+ projectWorkspaceId: record.projectWorkspaceId,
1342
+ executionWorkspaceId: record.executionWorkspaceId,
1343
+ issueId: record.issueId,
1344
+ scopeType: record.scopeType,
1345
+ scopeId: record.scopeId,
1346
+ serviceName: record.serviceName,
1347
+ status: record.status,
1348
+ lifecycle: record.lifecycle,
1349
+ reuseKey: record.reuseKey,
1350
+ command: record.command,
1351
+ cwd: record.cwd,
1352
+ port: record.port,
1353
+ url: record.url,
1354
+ provider: record.provider,
1355
+ providerRef: record.providerRef,
1356
+ ownerAgentId: record.ownerAgentId,
1357
+ startedByRunId: record.startedByRunId,
1358
+ lastUsedAt: new Date(record.lastUsedAt),
1359
+ startedAt: new Date(record.startedAt),
1360
+ stoppedAt: record.stoppedAt ? new Date(record.stoppedAt) : null,
1361
+ stopPolicy: record.stopPolicy,
1362
+ healthStatus: record.healthStatus,
1363
+ updatedAt: new Date(),
1364
+ };
1365
+ }
1366
+ async function persistRuntimeServiceRecord(db, record) {
1367
+ if (!db)
1368
+ return;
1369
+ const values = toPersistedWorkspaceRuntimeService(record);
1370
+ await db
1371
+ .insert(workspaceRuntimeServices)
1372
+ .values(values)
1373
+ .onConflictDoUpdate({
1374
+ target: workspaceRuntimeServices.id,
1375
+ set: {
1376
+ projectId: values.projectId,
1377
+ projectWorkspaceId: values.projectWorkspaceId,
1378
+ executionWorkspaceId: values.executionWorkspaceId,
1379
+ issueId: values.issueId,
1380
+ scopeType: values.scopeType,
1381
+ scopeId: values.scopeId,
1382
+ serviceName: values.serviceName,
1383
+ status: values.status,
1384
+ lifecycle: values.lifecycle,
1385
+ reuseKey: values.reuseKey,
1386
+ command: values.command,
1387
+ cwd: values.cwd,
1388
+ port: values.port,
1389
+ url: values.url,
1390
+ provider: values.provider,
1391
+ providerRef: values.providerRef,
1392
+ ownerAgentId: values.ownerAgentId,
1393
+ startedByRunId: values.startedByRunId,
1394
+ lastUsedAt: values.lastUsedAt,
1395
+ startedAt: values.startedAt,
1396
+ stoppedAt: values.stoppedAt,
1397
+ stopPolicy: values.stopPolicy,
1398
+ healthStatus: values.healthStatus,
1399
+ updatedAt: values.updatedAt,
1400
+ },
1401
+ });
1402
+ }
1403
+ async function findStoppedRuntimeServiceReuseCandidate(input) {
1404
+ if (!input.db || !input.reuseKey)
1405
+ return null;
1406
+ const row = await input.db
1407
+ .select({
1408
+ id: workspaceRuntimeServices.id,
1409
+ port: workspaceRuntimeServices.port,
1410
+ })
1411
+ .from(workspaceRuntimeServices)
1412
+ .where(and(eq(workspaceRuntimeServices.companyId, input.companyId), eq(workspaceRuntimeServices.reuseKey, input.reuseKey), eq(workspaceRuntimeServices.provider, "local_process"), eq(workspaceRuntimeServices.status, "stopped")))
1413
+ .orderBy(desc(workspaceRuntimeServices.updatedAt))
1414
+ .limit(1)
1415
+ .then((rows) => rows[0] ?? null);
1416
+ return row ?? null;
1417
+ }
1418
+ function clearIdleTimer(record) {
1419
+ if (!record.idleTimer)
1420
+ return;
1421
+ clearTimeout(record.idleTimer);
1422
+ record.idleTimer = null;
1423
+ }
1424
+ export function normalizeAdapterManagedRuntimeServices(input) {
1425
+ const nowIso = (input.now ?? new Date()).toISOString();
1426
+ return input.reports.map((report) => {
1427
+ const scopeType = report.scopeType ?? "run";
1428
+ const scopeId = report.scopeId ??
1429
+ (scopeType === "project_workspace"
1430
+ ? input.workspace.workspaceId
1431
+ : scopeType === "execution_workspace"
1432
+ ? input.executionWorkspaceId ?? input.workspace.cwd
1433
+ : scopeType === "agent"
1434
+ ? input.agent.id
1435
+ : input.runId) ??
1436
+ null;
1437
+ const serviceName = asString(report.serviceName, "").trim() || "service";
1438
+ const status = report.status ?? "running";
1439
+ const lifecycle = report.lifecycle ?? "ephemeral";
1440
+ const healthStatus = report.healthStatus ??
1441
+ (status === "running" ? "healthy" : status === "failed" ? "unhealthy" : "unknown");
1442
+ return {
1443
+ id: stableRuntimeServiceId({
1444
+ adapterType: input.adapterType,
1445
+ runId: input.runId,
1446
+ scopeType,
1447
+ scopeId,
1448
+ serviceName,
1449
+ reportId: report.id ?? null,
1450
+ providerRef: report.providerRef ?? null,
1451
+ reuseKey: report.reuseKey ?? null,
1452
+ }),
1453
+ companyId: input.agent.companyId,
1454
+ projectId: report.projectId ?? input.workspace.projectId,
1455
+ projectWorkspaceId: report.projectWorkspaceId ?? input.workspace.workspaceId,
1456
+ executionWorkspaceId: input.executionWorkspaceId ?? null,
1457
+ issueId: report.issueId ?? input.issue?.id ?? null,
1458
+ serviceName,
1459
+ status,
1460
+ lifecycle,
1461
+ scopeType,
1462
+ scopeId,
1463
+ reuseKey: report.reuseKey ?? null,
1464
+ command: report.command ?? null,
1465
+ cwd: report.cwd ?? null,
1466
+ port: report.port ?? null,
1467
+ url: report.url ?? null,
1468
+ provider: "adapter_managed",
1469
+ providerRef: report.providerRef ?? null,
1470
+ ownerAgentId: report.ownerAgentId ?? input.agent.id ?? null,
1471
+ startedByRunId: input.runId,
1472
+ lastUsedAt: nowIso,
1473
+ startedAt: nowIso,
1474
+ stoppedAt: status === "running" || status === "starting" ? null : nowIso,
1475
+ stopPolicy: report.stopPolicy ?? null,
1476
+ healthStatus,
1477
+ reused: false,
1478
+ };
1479
+ });
1480
+ }
1481
+ async function startLocalRuntimeService(input) {
1482
+ const leaseRunId = input.leaseRunId === undefined ? input.runId : input.leaseRunId;
1483
+ const startedByRunId = input.startedByRunId === undefined ? input.runId : input.startedByRunId;
1484
+ const identity = resolveRuntimeServiceReuseIdentity({
1485
+ service: input.service,
1486
+ workspace: input.workspace,
1487
+ agent: input.agent,
1488
+ issue: input.issue,
1489
+ adapterEnv: input.adapterEnv,
1490
+ scopeType: input.scopeType,
1491
+ scopeId: input.scopeId,
1492
+ });
1493
+ const serviceName = identity.serviceName;
1494
+ const lifecycle = identity.lifecycle;
1495
+ const command = identity.command;
1496
+ if (!command)
1497
+ throw new Error(`Runtime service "${serviceName}" is missing command`);
1498
+ const portConfig = parseObject(input.service.port);
1499
+ const envConfig = identity.envConfig;
1500
+ const envFingerprint = identity.envFingerprint;
1501
+ const serviceIdentityFingerprint = input.reuseKey ?? envFingerprint;
1502
+ const explicitPort = identity.explicitPort;
1503
+ const identityPort = identity.identityPort;
1504
+ const stoppedReuseCandidate = await findStoppedRuntimeServiceReuseCandidate({
1505
+ db: input.db,
1506
+ companyId: input.agent.companyId,
1507
+ reuseKey: input.reuseKey,
1508
+ });
1509
+ const reusableStoppedPort = asString(portConfig.type, "") === "auto" && stoppedReuseCandidate?.port
1510
+ ? (await readLocalServicePortOwner(stoppedReuseCandidate.port))
1511
+ ? null
1512
+ : stoppedReuseCandidate.port
1513
+ : null;
1514
+ const port = asString(portConfig.type, "") === "auto"
1515
+ ? (reusableStoppedPort ?? await allocatePort())
1516
+ : explicitPort > 0
1517
+ ? explicitPort
1518
+ : null;
1519
+ const templateData = buildTemplateData({
1520
+ workspace: input.workspace,
1521
+ agent: input.agent,
1522
+ issue: input.issue,
1523
+ adapterEnv: input.adapterEnv,
1524
+ port,
1525
+ });
1526
+ const serviceCwd = port === identityPort
1527
+ ? identity.serviceCwd
1528
+ : resolveConfiguredPath(renderTemplate(asString(input.service.cwd, "."), templateData), input.workspace.cwd);
1529
+ const env = {
1530
+ ...sanitizeRuntimeServiceBaseEnv(process.env),
1531
+ ...input.adapterEnv,
1532
+ };
1533
+ for (const [key, value] of Object.entries(renderRuntimeServiceEnv({ envConfig, templateData }))) {
1534
+ env[key] = value;
1535
+ }
1536
+ if (port) {
1537
+ const portEnvKey = asString(portConfig.envKey, "PORT");
1538
+ env[portEnvKey] = String(port);
1539
+ }
1540
+ const expose = parseObject(input.service.expose);
1541
+ const readiness = parseObject(input.service.readiness);
1542
+ const urlTemplate = asString(expose.urlTemplate, "") ||
1543
+ asString(readiness.urlTemplate, "");
1544
+ const url = urlTemplate ? renderTemplate(urlTemplate, templateData) : null;
1545
+ const stopPolicy = parseObject(input.service.stopPolicy);
1546
+ const serviceKey = createLocalServiceKey({
1547
+ profileKind: "workspace-runtime",
1548
+ serviceName,
1549
+ cwd: serviceCwd,
1550
+ command,
1551
+ envFingerprint: serviceIdentityFingerprint,
1552
+ port: identityPort,
1553
+ scope: {
1554
+ scopeType: input.scopeType,
1555
+ scopeId: input.scopeId,
1556
+ executionWorkspaceId: input.executionWorkspaceId ?? null,
1557
+ reuseKey: input.reuseKey,
1558
+ },
1559
+ });
1560
+ const adoptedRecord = await findAdoptableLocalService({
1561
+ serviceKey,
1562
+ command,
1563
+ cwd: serviceCwd,
1564
+ envFingerprint: serviceIdentityFingerprint,
1565
+ port: identityPort,
1566
+ });
1567
+ if (adoptedRecord) {
1568
+ return {
1569
+ id: adoptedRecord.runtimeServiceId ?? randomUUID(),
1570
+ companyId: input.agent.companyId,
1571
+ projectId: input.workspace.projectId,
1572
+ projectWorkspaceId: input.workspace.workspaceId,
1573
+ executionWorkspaceId: input.executionWorkspaceId ?? null,
1574
+ issueId: input.issue?.id ?? null,
1575
+ serviceName,
1576
+ status: "running",
1577
+ lifecycle,
1578
+ scopeType: input.scopeType,
1579
+ scopeId: input.scopeId,
1580
+ reuseKey: input.reuseKey,
1581
+ command,
1582
+ cwd: serviceCwd,
1583
+ port: adoptedRecord.port ?? port,
1584
+ url: adoptedRecord.url ?? url,
1585
+ provider: "local_process",
1586
+ providerRef: String(adoptedRecord.pid),
1587
+ ownerAgentId: input.agent.id ?? null,
1588
+ startedByRunId,
1589
+ lastUsedAt: new Date().toISOString(),
1590
+ startedAt: adoptedRecord.startedAt,
1591
+ stoppedAt: null,
1592
+ stopPolicy,
1593
+ healthStatus: "healthy",
1594
+ reused: true,
1595
+ db: input.db,
1596
+ child: null,
1597
+ leaseRunIds: leaseRunId ? new Set([leaseRunId]) : new Set(),
1598
+ idleTimer: null,
1599
+ envFingerprint,
1600
+ serviceKey,
1601
+ profileKind: "workspace-runtime",
1602
+ processGroupId: adoptedRecord.processGroupId ?? null,
1603
+ };
1604
+ }
1605
+ if (identityPort) {
1606
+ const ownerPid = await readLocalServicePortOwner(identityPort);
1607
+ if (ownerPid) {
1608
+ throw new Error(`Runtime service "${serviceName}" could not start because port ${identityPort} is already in use by pid ${ownerPid}`);
1609
+ }
1610
+ }
1611
+ await ensureServerWorkspaceLinksCurrent(serviceCwd, {
1612
+ onLog: input.onLog,
1613
+ });
1614
+ const shell = resolveShell();
1615
+ const child = spawn(shell, ["-lc", command], {
1616
+ cwd: serviceCwd,
1617
+ env,
1618
+ detached: process.platform !== "win32",
1619
+ stdio: ["ignore", "pipe", "pipe"],
1620
+ });
1621
+ const spawnErrorPromise = new Promise((_, reject) => {
1622
+ child.once("error", (err) => {
1623
+ reject(err);
1624
+ });
1625
+ });
1626
+ let stderrExcerpt = "";
1627
+ let stdoutExcerpt = "";
1628
+ child.stdout?.on("data", async (chunk) => {
1629
+ const text = String(chunk);
1630
+ stdoutExcerpt = (stdoutExcerpt + text).slice(-4096);
1631
+ if (input.onLog)
1632
+ await input.onLog("stdout", `[service:${serviceName}] ${text}`);
1633
+ });
1634
+ child.stderr?.on("data", async (chunk) => {
1635
+ const text = String(chunk);
1636
+ stderrExcerpt = (stderrExcerpt + text).slice(-4096);
1637
+ if (input.onLog)
1638
+ await input.onLog("stderr", `[service:${serviceName}] ${text}`);
1639
+ });
1640
+ try {
1641
+ await Promise.race([
1642
+ waitForReadiness({ service: input.service, url }),
1643
+ spawnErrorPromise,
1644
+ ]);
1645
+ }
1646
+ catch (err) {
1647
+ terminateChildProcess(child);
1648
+ throw new Error(`Failed to start runtime service "${serviceName}": ${err instanceof Error ? err.message : String(err)}${stderrExcerpt ? ` | stderr: ${stderrExcerpt.trim()}` : ""}`);
1649
+ }
1650
+ const record = {
1651
+ id: stoppedReuseCandidate?.id ?? randomUUID(),
1652
+ companyId: input.agent.companyId,
1653
+ projectId: input.workspace.projectId,
1654
+ projectWorkspaceId: input.workspace.workspaceId,
1655
+ executionWorkspaceId: input.executionWorkspaceId ?? null,
1656
+ issueId: input.issue?.id ?? null,
1657
+ serviceName,
1658
+ status: "running",
1659
+ lifecycle,
1660
+ scopeType: input.scopeType,
1661
+ scopeId: input.scopeId,
1662
+ reuseKey: input.reuseKey,
1663
+ command,
1664
+ cwd: serviceCwd,
1665
+ port,
1666
+ url,
1667
+ provider: "local_process",
1668
+ providerRef: child.pid ? String(child.pid) : null,
1669
+ ownerAgentId: input.agent.id ?? null,
1670
+ startedByRunId,
1671
+ lastUsedAt: new Date().toISOString(),
1672
+ startedAt: new Date().toISOString(),
1673
+ stoppedAt: null,
1674
+ stopPolicy,
1675
+ healthStatus: "healthy",
1676
+ reused: false,
1677
+ db: input.db,
1678
+ child,
1679
+ leaseRunIds: leaseRunId ? new Set([leaseRunId]) : new Set(),
1680
+ idleTimer: null,
1681
+ envFingerprint,
1682
+ serviceKey,
1683
+ profileKind: "workspace-runtime",
1684
+ processGroupId: child.pid ?? null,
1685
+ };
1686
+ if (child.pid) {
1687
+ await writeLocalServiceRegistryRecord({
1688
+ version: 1,
1689
+ serviceKey,
1690
+ profileKind: "workspace-runtime",
1691
+ serviceName,
1692
+ command,
1693
+ cwd: serviceCwd,
1694
+ envFingerprint: serviceIdentityFingerprint,
1695
+ port,
1696
+ url,
1697
+ pid: child.pid,
1698
+ processGroupId: child.pid,
1699
+ provider: "local_process",
1700
+ runtimeServiceId: record.id,
1701
+ reuseKey: input.reuseKey,
1702
+ startedAt: record.startedAt,
1703
+ lastSeenAt: record.lastUsedAt,
1704
+ metadata: {
1705
+ projectId: record.projectId,
1706
+ projectWorkspaceId: record.projectWorkspaceId,
1707
+ executionWorkspaceId: record.executionWorkspaceId,
1708
+ issueId: record.issueId,
1709
+ scopeType: record.scopeType,
1710
+ scopeId: record.scopeId,
1711
+ },
1712
+ });
1713
+ }
1714
+ return record;
1715
+ }
1716
+ function scheduleIdleStop(record) {
1717
+ clearIdleTimer(record);
1718
+ const stopType = asString(record.stopPolicy?.type, "manual");
1719
+ if (stopType !== "idle_timeout")
1720
+ return;
1721
+ const idleSeconds = Math.max(1, asNumber(record.stopPolicy?.idleSeconds, 1800));
1722
+ record.idleTimer = setTimeout(() => {
1723
+ stopRuntimeService(record.id).catch(() => undefined);
1724
+ }, idleSeconds * 1000);
1725
+ }
1726
+ async function stopRuntimeService(serviceId) {
1727
+ const record = runtimeServicesById.get(serviceId);
1728
+ if (!record)
1729
+ return;
1730
+ clearIdleTimer(record);
1731
+ record.status = "stopped";
1732
+ record.healthStatus = "unknown";
1733
+ record.lastUsedAt = new Date().toISOString();
1734
+ record.stoppedAt = new Date().toISOString();
1735
+ runtimeServicesById.delete(serviceId);
1736
+ if (record.reuseKey && runtimeServicesByReuseKey.get(record.reuseKey) === record.id) {
1737
+ runtimeServicesByReuseKey.delete(record.reuseKey);
1738
+ }
1739
+ if (record.child && record.child.pid) {
1740
+ await terminateLocalService({
1741
+ pid: record.child.pid,
1742
+ processGroupId: record.processGroupId ?? record.child.pid,
1743
+ });
1744
+ }
1745
+ else if (record.providerRef) {
1746
+ const pid = Number.parseInt(record.providerRef, 10);
1747
+ if (Number.isInteger(pid) && pid > 0) {
1748
+ await terminateLocalService({
1749
+ pid,
1750
+ processGroupId: record.processGroupId,
1751
+ });
1752
+ }
1753
+ }
1754
+ await removeLocalServiceRegistryRecord(record.serviceKey);
1755
+ await persistRuntimeServiceRecord(record.db, record);
1756
+ }
1757
+ async function markPersistedRuntimeServicesStoppedForExecutionWorkspace(input) {
1758
+ const now = new Date();
1759
+ await input.db
1760
+ .update(workspaceRuntimeServices)
1761
+ .set({
1762
+ status: "stopped",
1763
+ healthStatus: "unknown",
1764
+ stoppedAt: now,
1765
+ lastUsedAt: now,
1766
+ updatedAt: now,
1767
+ })
1768
+ .where(and(eq(workspaceRuntimeServices.executionWorkspaceId, input.executionWorkspaceId), inArray(workspaceRuntimeServices.status, ["starting", "running"])));
1769
+ }
1770
+ function registerRuntimeService(db, record) {
1771
+ record.db = db;
1772
+ runtimeServicesById.set(record.id, record);
1773
+ if (record.reuseKey) {
1774
+ runtimeServicesByReuseKey.set(record.reuseKey, record.id);
1775
+ }
1776
+ record.child?.on("exit", (code, signal) => {
1777
+ const current = runtimeServicesById.get(record.id);
1778
+ if (!current)
1779
+ return;
1780
+ clearIdleTimer(current);
1781
+ current.status = code === 0 || signal === "SIGTERM" ? "stopped" : "failed";
1782
+ current.healthStatus = current.status === "failed" ? "unhealthy" : "unknown";
1783
+ current.lastUsedAt = new Date().toISOString();
1784
+ current.stoppedAt = new Date().toISOString();
1785
+ runtimeServicesById.delete(current.id);
1786
+ if (current.reuseKey && runtimeServicesByReuseKey.get(current.reuseKey) === current.id) {
1787
+ runtimeServicesByReuseKey.delete(current.reuseKey);
1788
+ }
1789
+ void removeLocalServiceRegistryRecord(current.serviceKey);
1790
+ void persistRuntimeServiceRecord(db, current);
1791
+ });
1792
+ }
1793
+ function readRuntimeServiceEntries(config) {
1794
+ return listWorkspaceServiceCommandDefinitions(parseObject(config.workspaceRuntime))
1795
+ .map((command) => command.rawConfig);
1796
+ }
1797
+ export function listConfiguredRuntimeServiceEntries(config) {
1798
+ return readRuntimeServiceEntries(config);
1799
+ }
1800
+ function readConfiguredServiceStates(config) {
1801
+ const raw = parseObject(config.serviceStates);
1802
+ const states = {};
1803
+ for (const [key, value] of Object.entries(raw)) {
1804
+ if (value === "running" || value === "stopped" || value === "manual") {
1805
+ states[key] = value;
1806
+ }
1807
+ }
1808
+ return states;
1809
+ }
1810
+ function readDesiredRuntimeState(value) {
1811
+ return value === "running" || value === "stopped" || value === "manual" ? value : null;
1812
+ }
1813
+ export function buildWorkspaceRuntimeDesiredStatePatch(input) {
1814
+ const configuredServices = listConfiguredRuntimeServiceEntries(input.config);
1815
+ const fallbackState = readDesiredRuntimeState(input.currentDesiredState) ?? "stopped";
1816
+ const nextServiceStates = {};
1817
+ for (let index = 0; index < configuredServices.length; index += 1) {
1818
+ nextServiceStates[String(index)] = input.currentServiceStates?.[String(index)] ?? fallbackState;
1819
+ }
1820
+ const nextState = input.action === "stop" ? "stopped" : "running";
1821
+ const applyActionState = (index) => {
1822
+ const key = String(index);
1823
+ // Manual services are intentionally left under operator control even when
1824
+ // an API action targets that individual service.
1825
+ if (nextServiceStates[key] === "manual")
1826
+ return;
1827
+ nextServiceStates[key] = nextState;
1828
+ };
1829
+ if (input.serviceIndex === undefined || input.serviceIndex === null) {
1830
+ for (let index = 0; index < configuredServices.length; index += 1) {
1831
+ applyActionState(index);
1832
+ }
1833
+ }
1834
+ else if (input.serviceIndex >= 0 && input.serviceIndex < configuredServices.length) {
1835
+ applyActionState(input.serviceIndex);
1836
+ }
1837
+ const desiredState = Object.values(nextServiceStates).some((state) => state === "running")
1838
+ ? "running"
1839
+ : Object.values(nextServiceStates).some((state) => state === "manual")
1840
+ ? "manual"
1841
+ : "stopped";
1842
+ return {
1843
+ desiredState,
1844
+ serviceStates: Object.keys(nextServiceStates).length > 0 ? nextServiceStates : null,
1845
+ };
1846
+ }
1847
+ function selectRuntimeServiceEntries(input) {
1848
+ const entries = listConfiguredRuntimeServiceEntries(input.config);
1849
+ const states = input.serviceStates ?? readConfiguredServiceStates(input.config);
1850
+ const fallbackState = readDesiredRuntimeState(input.defaultDesiredState) ?? "stopped";
1851
+ return entries.filter((_, index) => {
1852
+ if (input.serviceIndex !== undefined && input.serviceIndex !== null) {
1853
+ return index === input.serviceIndex;
1854
+ }
1855
+ if (!input.respectDesiredStates)
1856
+ return true;
1857
+ return (states[String(index)] ?? fallbackState) === "running";
1858
+ });
1859
+ }
1860
+ export async function ensureRuntimeServicesForRun(input) {
1861
+ const rawServices = selectRuntimeServiceEntries({
1862
+ config: input.config,
1863
+ respectDesiredStates: true,
1864
+ defaultDesiredState: readDesiredRuntimeState(input.config.desiredState) ?? "running",
1865
+ serviceStates: readConfiguredServiceStates(input.config),
1866
+ });
1867
+ const acquiredServiceIds = [];
1868
+ const refs = [];
1869
+ runtimeServiceLeasesByRun.set(input.runId, acquiredServiceIds);
1870
+ try {
1871
+ for (const service of rawServices) {
1872
+ const { scopeType, scopeId } = resolveServiceScopeId({
1873
+ service,
1874
+ workspace: input.workspace,
1875
+ executionWorkspaceId: input.executionWorkspaceId,
1876
+ issue: input.issue,
1877
+ runId: input.runId,
1878
+ agent: input.agent,
1879
+ });
1880
+ const reuseKey = resolveRuntimeServiceReuseIdentity({
1881
+ service,
1882
+ workspace: input.workspace,
1883
+ agent: input.agent,
1884
+ issue: input.issue,
1885
+ adapterEnv: input.adapterEnv,
1886
+ scopeType,
1887
+ scopeId,
1888
+ }).reuseKey;
1889
+ if (reuseKey) {
1890
+ const existingId = runtimeServicesByReuseKey.get(reuseKey);
1891
+ const existing = existingId ? runtimeServicesById.get(existingId) : null;
1892
+ if (existing && existing.status === "running") {
1893
+ existing.leaseRunIds.add(input.runId);
1894
+ existing.lastUsedAt = new Date().toISOString();
1895
+ existing.stoppedAt = null;
1896
+ clearIdleTimer(existing);
1897
+ void touchLocalServiceRegistryRecord(existing.serviceKey, {
1898
+ runtimeServiceId: existing.id,
1899
+ lastSeenAt: existing.lastUsedAt,
1900
+ });
1901
+ await persistRuntimeServiceRecord(input.db, existing);
1902
+ acquiredServiceIds.push(existing.id);
1903
+ refs.push(toRuntimeServiceRef(existing, { reused: true }));
1904
+ continue;
1905
+ }
1906
+ }
1907
+ const record = await startLocalRuntimeService({
1908
+ db: input.db,
1909
+ runId: input.runId,
1910
+ agent: input.agent,
1911
+ issue: input.issue,
1912
+ workspace: input.workspace,
1913
+ executionWorkspaceId: input.executionWorkspaceId,
1914
+ adapterEnv: input.adapterEnv,
1915
+ service,
1916
+ onLog: input.onLog,
1917
+ reuseKey,
1918
+ scopeType,
1919
+ scopeId,
1920
+ });
1921
+ registerRuntimeService(input.db, record);
1922
+ await persistRuntimeServiceRecord(input.db, record);
1923
+ acquiredServiceIds.push(record.id);
1924
+ refs.push(toRuntimeServiceRef(record));
1925
+ }
1926
+ }
1927
+ catch (err) {
1928
+ await releaseRuntimeServicesForRun(input.runId);
1929
+ throw err;
1930
+ }
1931
+ return refs;
1932
+ }
1933
+ export async function startRuntimeServicesForWorkspaceControl(input) {
1934
+ const rawServices = selectRuntimeServiceEntries({
1935
+ config: input.config,
1936
+ serviceIndex: input.serviceIndex,
1937
+ respectDesiredStates: input.respectDesiredStates,
1938
+ defaultDesiredState: readDesiredRuntimeState(input.config.desiredState) ?? "stopped",
1939
+ serviceStates: readConfiguredServiceStates(input.config),
1940
+ });
1941
+ const refs = [];
1942
+ const invocationId = input.invocationId ?? randomUUID();
1943
+ for (const service of rawServices) {
1944
+ const { scopeType, scopeId } = resolveServiceScopeId({
1945
+ service,
1946
+ workspace: input.workspace,
1947
+ executionWorkspaceId: input.executionWorkspaceId,
1948
+ issue: input.issue,
1949
+ runId: invocationId,
1950
+ agent: input.actor,
1951
+ });
1952
+ const reuseKey = resolveRuntimeServiceReuseIdentity({
1953
+ service,
1954
+ workspace: input.workspace,
1955
+ agent: input.actor,
1956
+ issue: input.issue,
1957
+ adapterEnv: input.adapterEnv,
1958
+ scopeType,
1959
+ scopeId,
1960
+ }).reuseKey;
1961
+ if (reuseKey) {
1962
+ const existingId = runtimeServicesByReuseKey.get(reuseKey);
1963
+ const existing = existingId ? runtimeServicesById.get(existingId) : null;
1964
+ if (existing && existing.status === "running") {
1965
+ existing.lastUsedAt = new Date().toISOString();
1966
+ existing.stoppedAt = null;
1967
+ clearIdleTimer(existing);
1968
+ void touchLocalServiceRegistryRecord(existing.serviceKey, {
1969
+ runtimeServiceId: existing.id,
1970
+ lastSeenAt: existing.lastUsedAt,
1971
+ });
1972
+ await persistRuntimeServiceRecord(input.db, existing);
1973
+ refs.push(toRuntimeServiceRef(existing, { reused: true }));
1974
+ continue;
1975
+ }
1976
+ }
1977
+ // Manually controlled services are not tied to a heartbeat run lifecycle, so they do not
1978
+ // retain a run lease and never persist a startedByRunId foreign key.
1979
+ const record = await startLocalRuntimeService({
1980
+ db: input.db,
1981
+ runId: invocationId,
1982
+ leaseRunId: null,
1983
+ startedByRunId: null,
1984
+ agent: input.actor,
1985
+ issue: input.issue,
1986
+ workspace: input.workspace,
1987
+ executionWorkspaceId: input.executionWorkspaceId,
1988
+ adapterEnv: input.adapterEnv,
1989
+ service,
1990
+ onLog: input.onLog,
1991
+ reuseKey,
1992
+ scopeType,
1993
+ scopeId,
1994
+ });
1995
+ registerRuntimeService(input.db, record);
1996
+ await persistRuntimeServiceRecord(input.db, record);
1997
+ refs.push(toRuntimeServiceRef(record));
1998
+ }
1999
+ return refs;
2000
+ }
2001
+ export async function releaseRuntimeServicesForRun(runId) {
2002
+ const acquired = runtimeServiceLeasesByRun.get(runId) ?? [];
2003
+ runtimeServiceLeasesByRun.delete(runId);
2004
+ for (const serviceId of acquired) {
2005
+ const record = runtimeServicesById.get(serviceId);
2006
+ if (!record)
2007
+ continue;
2008
+ record.leaseRunIds.delete(runId);
2009
+ record.lastUsedAt = new Date().toISOString();
2010
+ const stopType = asString(record.stopPolicy?.type, record.lifecycle === "ephemeral" ? "on_run_finish" : "manual");
2011
+ await persistRuntimeServiceRecord(record.db, record);
2012
+ if (record.leaseRunIds.size === 0) {
2013
+ if (record.lifecycle === "ephemeral" || stopType === "on_run_finish") {
2014
+ await stopRuntimeService(serviceId);
2015
+ continue;
2016
+ }
2017
+ scheduleIdleStop(record);
2018
+ }
2019
+ }
2020
+ }
2021
+ export async function stopRuntimeServicesForExecutionWorkspace(input) {
2022
+ const normalizedWorkspaceCwd = input.workspaceCwd ? path.resolve(input.workspaceCwd) : null;
2023
+ const matchingServiceIds = Array.from(runtimeServicesById.values())
2024
+ .filter((record) => {
2025
+ if (input.runtimeServiceId)
2026
+ return record.id === input.runtimeServiceId;
2027
+ if (record.executionWorkspaceId === input.executionWorkspaceId)
2028
+ return true;
2029
+ if (!normalizedWorkspaceCwd || !record.cwd)
2030
+ return false;
2031
+ const resolvedCwd = path.resolve(record.cwd);
2032
+ return (resolvedCwd === normalizedWorkspaceCwd ||
2033
+ resolvedCwd.startsWith(`${normalizedWorkspaceCwd}${path.sep}`));
2034
+ })
2035
+ .map((record) => record.id);
2036
+ for (const serviceId of matchingServiceIds) {
2037
+ await stopRuntimeService(serviceId);
2038
+ }
2039
+ if (input.db) {
2040
+ if (input.runtimeServiceId) {
2041
+ const now = new Date();
2042
+ await input.db
2043
+ .update(workspaceRuntimeServices)
2044
+ .set({
2045
+ status: "stopped",
2046
+ healthStatus: "unknown",
2047
+ stoppedAt: now,
2048
+ lastUsedAt: now,
2049
+ updatedAt: now,
2050
+ })
2051
+ .where(eq(workspaceRuntimeServices.id, input.runtimeServiceId));
2052
+ }
2053
+ else {
2054
+ await markPersistedRuntimeServicesStoppedForExecutionWorkspace({
2055
+ db: input.db,
2056
+ executionWorkspaceId: input.executionWorkspaceId,
2057
+ });
2058
+ }
2059
+ }
2060
+ }
2061
+ export async function stopRuntimeServicesForProjectWorkspace(input) {
2062
+ const matchingServiceIds = Array.from(runtimeServicesById.values())
2063
+ .filter((record) => {
2064
+ if (input.runtimeServiceId)
2065
+ return record.id === input.runtimeServiceId;
2066
+ return record.projectWorkspaceId === input.projectWorkspaceId && record.scopeType === "project_workspace";
2067
+ })
2068
+ .map((record) => record.id);
2069
+ for (const serviceId of matchingServiceIds) {
2070
+ await stopRuntimeService(serviceId);
2071
+ }
2072
+ if (input.db) {
2073
+ const now = new Date();
2074
+ await input.db
2075
+ .update(workspaceRuntimeServices)
2076
+ .set({
2077
+ status: "stopped",
2078
+ healthStatus: "unknown",
2079
+ stoppedAt: now,
2080
+ lastUsedAt: now,
2081
+ updatedAt: now,
2082
+ })
2083
+ .where(input.runtimeServiceId
2084
+ ? eq(workspaceRuntimeServices.id, input.runtimeServiceId)
2085
+ : and(eq(workspaceRuntimeServices.projectWorkspaceId, input.projectWorkspaceId), eq(workspaceRuntimeServices.scopeType, "project_workspace"), inArray(workspaceRuntimeServices.status, ["starting", "running"])));
2086
+ }
2087
+ }
2088
+ export async function listWorkspaceRuntimeServicesForProjectWorkspaces(db, companyId, projectWorkspaceIds) {
2089
+ if (projectWorkspaceIds.length === 0)
2090
+ return new Map();
2091
+ const rows = await db
2092
+ .select()
2093
+ .from(workspaceRuntimeServices)
2094
+ .where(and(eq(workspaceRuntimeServices.companyId, companyId), inArray(workspaceRuntimeServices.projectWorkspaceId, projectWorkspaceIds), eq(workspaceRuntimeServices.scopeType, "project_workspace")))
2095
+ .orderBy(desc(workspaceRuntimeServices.updatedAt), desc(workspaceRuntimeServices.createdAt));
2096
+ const grouped = new Map();
2097
+ for (const row of rows) {
2098
+ if (!row.projectWorkspaceId)
2099
+ continue;
2100
+ const existing = grouped.get(row.projectWorkspaceId);
2101
+ if (existing)
2102
+ existing.push(row);
2103
+ else
2104
+ grouped.set(row.projectWorkspaceId, [row]);
2105
+ }
2106
+ return grouped;
2107
+ }
2108
+ export async function reconcilePersistedRuntimeServicesOnStartup(db) {
2109
+ const rows = await db
2110
+ .select()
2111
+ .from(workspaceRuntimeServices)
2112
+ .where(and(eq(workspaceRuntimeServices.provider, "local_process"), inArray(workspaceRuntimeServices.status, ["starting", "running"])));
2113
+ if (rows.length === 0)
2114
+ return { reconciled: 0, adopted: 0, stopped: 0 };
2115
+ let adopted = 0;
2116
+ let stopped = 0;
2117
+ for (const row of rows) {
2118
+ const adoptedRecord = await findLocalServiceRegistryRecordByRuntimeServiceId({
2119
+ runtimeServiceId: row.id,
2120
+ profileKind: "workspace-runtime",
2121
+ });
2122
+ if (adoptedRecord) {
2123
+ const adoptedUrl = adoptedRecord.url ?? row.url ?? null;
2124
+ if (!(await isRuntimeServiceUrlHealthy(adoptedUrl))) {
2125
+ await removeLocalServiceRegistryRecord(adoptedRecord.serviceKey);
2126
+ }
2127
+ else {
2128
+ const record = {
2129
+ id: row.id,
2130
+ companyId: row.companyId,
2131
+ projectId: row.projectId ?? null,
2132
+ projectWorkspaceId: row.projectWorkspaceId ?? null,
2133
+ executionWorkspaceId: row.executionWorkspaceId ?? null,
2134
+ issueId: row.issueId ?? null,
2135
+ serviceName: row.serviceName,
2136
+ status: "running",
2137
+ lifecycle: row.lifecycle,
2138
+ scopeType: row.scopeType,
2139
+ scopeId: row.scopeId ?? null,
2140
+ reuseKey: row.reuseKey ?? null,
2141
+ command: row.command ?? null,
2142
+ cwd: row.cwd ?? null,
2143
+ port: adoptedRecord.port ?? row.port ?? null,
2144
+ url: adoptedRecord.url ?? row.url ?? null,
2145
+ provider: "local_process",
2146
+ providerRef: String(adoptedRecord.pid),
2147
+ ownerAgentId: row.ownerAgentId ?? null,
2148
+ startedByRunId: row.startedByRunId ?? null,
2149
+ lastUsedAt: new Date().toISOString(),
2150
+ startedAt: row.startedAt.toISOString(),
2151
+ stoppedAt: null,
2152
+ stopPolicy: row.stopPolicy ?? null,
2153
+ healthStatus: "healthy",
2154
+ reused: true,
2155
+ db,
2156
+ child: null,
2157
+ leaseRunIds: new Set(),
2158
+ idleTimer: null,
2159
+ envFingerprint: row.reuseKey ?? "",
2160
+ serviceKey: adoptedRecord.serviceKey,
2161
+ profileKind: "workspace-runtime",
2162
+ processGroupId: adoptedRecord.processGroupId ?? null,
2163
+ };
2164
+ registerRuntimeService(db, record);
2165
+ await touchLocalServiceRegistryRecord(adoptedRecord.serviceKey, {
2166
+ runtimeServiceId: row.id,
2167
+ lastSeenAt: record.lastUsedAt,
2168
+ });
2169
+ await persistRuntimeServiceRecord(db, record);
2170
+ adopted += 1;
2171
+ continue;
2172
+ }
2173
+ }
2174
+ const now = new Date();
2175
+ await db
2176
+ .update(workspaceRuntimeServices)
2177
+ .set({
2178
+ status: "stopped",
2179
+ healthStatus: "unknown",
2180
+ stoppedAt: now,
2181
+ lastUsedAt: now,
2182
+ updatedAt: now,
2183
+ })
2184
+ .where(eq(workspaceRuntimeServices.id, row.id));
2185
+ const registryRecord = await findLocalServiceRegistryRecordByRuntimeServiceId({
2186
+ runtimeServiceId: row.id,
2187
+ profileKind: "workspace-runtime",
2188
+ });
2189
+ if (registryRecord) {
2190
+ await removeLocalServiceRegistryRecord(registryRecord.serviceKey);
2191
+ }
2192
+ stopped += 1;
2193
+ }
2194
+ return { reconciled: rows.length, adopted, stopped };
2195
+ }
2196
+ export async function restartDesiredRuntimeServicesOnStartup(db) {
2197
+ let restarted = 0;
2198
+ let failed = 0;
2199
+ const projectWorkspaceRows = await db
2200
+ .select()
2201
+ .from(projectWorkspaces);
2202
+ const projectWorkspaceRowsById = new Map(projectWorkspaceRows.map((row) => [row.id, row]));
2203
+ for (const row of projectWorkspaceRows) {
2204
+ const runtimeConfig = readProjectWorkspaceRuntimeConfig(row.metadata ?? null);
2205
+ if (runtimeConfig?.desiredState !== "running" || !runtimeConfig.workspaceRuntime || !row.cwd)
2206
+ continue;
2207
+ try {
2208
+ const refs = await startRuntimeServicesForWorkspaceControl({
2209
+ db,
2210
+ actor: { id: null, name: "Evermore", companyId: row.companyId },
2211
+ issue: null,
2212
+ workspace: {
2213
+ baseCwd: row.cwd,
2214
+ source: "project_primary",
2215
+ projectId: row.projectId,
2216
+ workspaceId: row.id,
2217
+ repoUrl: row.repoUrl ?? null,
2218
+ repoRef: row.repoRef ?? null,
2219
+ strategy: "project_primary",
2220
+ cwd: row.cwd,
2221
+ branchName: row.defaultRef ?? row.repoRef ?? null,
2222
+ worktreePath: null,
2223
+ warnings: [],
2224
+ created: false,
2225
+ },
2226
+ config: {
2227
+ workspaceRuntime: runtimeConfig.workspaceRuntime,
2228
+ desiredState: runtimeConfig.desiredState,
2229
+ serviceStates: runtimeConfig.serviceStates ?? null,
2230
+ },
2231
+ adapterEnv: {},
2232
+ respectDesiredStates: true,
2233
+ });
2234
+ if (refs.length > 0)
2235
+ restarted += refs.filter((ref) => !ref.reused).length;
2236
+ }
2237
+ catch {
2238
+ failed += 1;
2239
+ }
2240
+ }
2241
+ const executionWorkspaceRows = await db
2242
+ .select()
2243
+ .from(executionWorkspaces)
2244
+ .where(inArray(executionWorkspaces.status, ["active", "idle", "in_review", "cleanup_failed"]));
2245
+ for (const row of executionWorkspaceRows) {
2246
+ const config = readExecutionWorkspaceConfig(row.metadata ?? null);
2247
+ const inheritedRuntimeConfig = row.projectWorkspaceId
2248
+ ? readProjectWorkspaceRuntimeConfig(projectWorkspaceRowsById.get(row.projectWorkspaceId)?.metadata ?? null)?.workspaceRuntime ?? null
2249
+ : null;
2250
+ const effectiveRuntimeConfig = config?.workspaceRuntime ?? inheritedRuntimeConfig;
2251
+ if (config?.desiredState !== "running" || !effectiveRuntimeConfig || !row.cwd)
2252
+ continue;
2253
+ try {
2254
+ const refs = await startRuntimeServicesForWorkspaceControl({
2255
+ db,
2256
+ actor: { id: null, name: "Evermore", companyId: row.companyId },
2257
+ issue: row.sourceIssueId
2258
+ ? {
2259
+ id: row.sourceIssueId,
2260
+ identifier: null,
2261
+ title: row.name,
2262
+ }
2263
+ : null,
2264
+ workspace: {
2265
+ baseCwd: row.cwd,
2266
+ source: row.mode === "shared_workspace" ? "project_primary" : "task_session",
2267
+ projectId: row.projectId,
2268
+ workspaceId: row.projectWorkspaceId ?? null,
2269
+ repoUrl: row.repoUrl ?? null,
2270
+ repoRef: row.baseRef ?? null,
2271
+ strategy: row.strategyType === "git_worktree" ? "git_worktree" : "project_primary",
2272
+ cwd: row.cwd,
2273
+ branchName: row.branchName ?? null,
2274
+ worktreePath: row.strategyType === "git_worktree" ? row.cwd : null,
2275
+ warnings: [],
2276
+ created: false,
2277
+ },
2278
+ executionWorkspaceId: row.id,
2279
+ config: {
2280
+ workspaceRuntime: effectiveRuntimeConfig,
2281
+ desiredState: config.desiredState,
2282
+ serviceStates: config.serviceStates ?? null,
2283
+ },
2284
+ adapterEnv: {},
2285
+ respectDesiredStates: true,
2286
+ });
2287
+ if (refs.length > 0)
2288
+ restarted += refs.filter((ref) => !ref.reused).length;
2289
+ }
2290
+ catch {
2291
+ failed += 1;
2292
+ }
2293
+ }
2294
+ return { restarted, failed };
2295
+ }
2296
+ export async function persistAdapterManagedRuntimeServices(input) {
2297
+ const refs = normalizeAdapterManagedRuntimeServices(input);
2298
+ if (refs.length === 0)
2299
+ return refs;
2300
+ const existingRows = await input.db
2301
+ .select()
2302
+ .from(workspaceRuntimeServices)
2303
+ .where(inArray(workspaceRuntimeServices.id, refs.map((ref) => ref.id)));
2304
+ const existingById = new Map(existingRows.map((row) => [row.id, row]));
2305
+ for (const ref of refs) {
2306
+ const existing = existingById.get(ref.id);
2307
+ const startedAt = existing?.startedAt ?? new Date(ref.startedAt);
2308
+ const createdAt = existing?.createdAt ?? new Date();
2309
+ await input.db
2310
+ .insert(workspaceRuntimeServices)
2311
+ .values({
2312
+ id: ref.id,
2313
+ companyId: ref.companyId,
2314
+ projectId: ref.projectId,
2315
+ projectWorkspaceId: ref.projectWorkspaceId,
2316
+ executionWorkspaceId: ref.executionWorkspaceId,
2317
+ issueId: ref.issueId,
2318
+ scopeType: ref.scopeType,
2319
+ scopeId: ref.scopeId,
2320
+ serviceName: ref.serviceName,
2321
+ status: ref.status,
2322
+ lifecycle: ref.lifecycle,
2323
+ reuseKey: ref.reuseKey,
2324
+ command: ref.command,
2325
+ cwd: ref.cwd,
2326
+ port: ref.port,
2327
+ url: ref.url,
2328
+ provider: ref.provider,
2329
+ providerRef: ref.providerRef,
2330
+ ownerAgentId: ref.ownerAgentId,
2331
+ startedByRunId: ref.startedByRunId,
2332
+ lastUsedAt: new Date(ref.lastUsedAt),
2333
+ startedAt,
2334
+ stoppedAt: ref.stoppedAt ? new Date(ref.stoppedAt) : null,
2335
+ stopPolicy: ref.stopPolicy,
2336
+ healthStatus: ref.healthStatus,
2337
+ createdAt,
2338
+ updatedAt: new Date(),
2339
+ })
2340
+ .onConflictDoUpdate({
2341
+ target: workspaceRuntimeServices.id,
2342
+ set: {
2343
+ projectId: ref.projectId,
2344
+ projectWorkspaceId: ref.projectWorkspaceId,
2345
+ executionWorkspaceId: ref.executionWorkspaceId,
2346
+ issueId: ref.issueId,
2347
+ scopeType: ref.scopeType,
2348
+ scopeId: ref.scopeId,
2349
+ serviceName: ref.serviceName,
2350
+ status: ref.status,
2351
+ lifecycle: ref.lifecycle,
2352
+ reuseKey: ref.reuseKey,
2353
+ command: ref.command,
2354
+ cwd: ref.cwd,
2355
+ port: ref.port,
2356
+ url: ref.url,
2357
+ provider: ref.provider,
2358
+ providerRef: ref.providerRef,
2359
+ ownerAgentId: ref.ownerAgentId,
2360
+ startedByRunId: ref.startedByRunId,
2361
+ lastUsedAt: new Date(ref.lastUsedAt),
2362
+ startedAt,
2363
+ stoppedAt: ref.stoppedAt ? new Date(ref.stoppedAt) : null,
2364
+ stopPolicy: ref.stopPolicy,
2365
+ healthStatus: ref.healthStatus,
2366
+ updatedAt: new Date(),
2367
+ },
2368
+ });
2369
+ }
2370
+ return refs;
2371
+ }
2372
+ export function buildWorkspaceReadyComment(input) {
2373
+ const lines = ["## Workspace Ready", ""];
2374
+ lines.push(`- Strategy: \`${input.workspace.strategy}\``);
2375
+ if (input.workspace.branchName)
2376
+ lines.push(`- Branch: \`${input.workspace.branchName}\``);
2377
+ lines.push(`- CWD: \`${input.workspace.cwd}\``);
2378
+ if (input.workspace.worktreePath && input.workspace.worktreePath !== input.workspace.cwd) {
2379
+ lines.push(`- Worktree: \`${input.workspace.worktreePath}\``);
2380
+ }
2381
+ for (const service of input.runtimeServices) {
2382
+ const detail = service.url ? `${service.serviceName}: ${service.url}` : `${service.serviceName}: running`;
2383
+ const suffix = service.reused ? " (reused)" : "";
2384
+ lines.push(`- Service: ${detail}${suffix}`);
2385
+ }
2386
+ return lines.join("\n");
2387
+ }
2388
+ //# sourceMappingURL=workspace-runtime.js.map