@telora/daemon 0.12.33

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 (473) hide show
  1. package/.env.example +64 -0
  2. package/README.md +229 -0
  3. package/build-info.json +4 -0
  4. package/dist/activity-tracker.d.ts +13 -0
  5. package/dist/activity-tracker.d.ts.map +1 -0
  6. package/dist/activity-tracker.js +19 -0
  7. package/dist/activity-tracker.js.map +1 -0
  8. package/dist/agent-state.d.ts +45 -0
  9. package/dist/agent-state.d.ts.map +1 -0
  10. package/dist/agent-state.js +61 -0
  11. package/dist/agent-state.js.map +1 -0
  12. package/dist/audit-hooks.d.ts +12 -0
  13. package/dist/audit-hooks.d.ts.map +1 -0
  14. package/dist/audit-hooks.js +45 -0
  15. package/dist/audit-hooks.js.map +1 -0
  16. package/dist/auto-update.d.ts +42 -0
  17. package/dist/auto-update.d.ts.map +1 -0
  18. package/dist/auto-update.js +96 -0
  19. package/dist/auto-update.js.map +1 -0
  20. package/dist/branch-status.d.ts +40 -0
  21. package/dist/branch-status.d.ts.map +1 -0
  22. package/dist/branch-status.js +107 -0
  23. package/dist/branch-status.js.map +1 -0
  24. package/dist/completion-detector.d.ts +87 -0
  25. package/dist/completion-detector.d.ts.map +1 -0
  26. package/dist/completion-detector.js +160 -0
  27. package/dist/completion-detector.js.map +1 -0
  28. package/dist/completion-handler.d.ts +48 -0
  29. package/dist/completion-handler.d.ts.map +1 -0
  30. package/dist/completion-handler.js +200 -0
  31. package/dist/completion-handler.js.map +1 -0
  32. package/dist/condition-evaluators.d.ts +31 -0
  33. package/dist/condition-evaluators.d.ts.map +1 -0
  34. package/dist/condition-evaluators.js +416 -0
  35. package/dist/condition-evaluators.js.map +1 -0
  36. package/dist/config.d.ts +55 -0
  37. package/dist/config.d.ts.map +1 -0
  38. package/dist/config.js +311 -0
  39. package/dist/config.js.map +1 -0
  40. package/dist/control-state.d.ts +41 -0
  41. package/dist/control-state.d.ts.map +1 -0
  42. package/dist/control-state.js +204 -0
  43. package/dist/control-state.js.map +1 -0
  44. package/dist/crash-recovery-cleanup.d.ts +21 -0
  45. package/dist/crash-recovery-cleanup.d.ts.map +1 -0
  46. package/dist/crash-recovery-cleanup.js +198 -0
  47. package/dist/crash-recovery-cleanup.js.map +1 -0
  48. package/dist/crash-recovery-scan.d.ts +19 -0
  49. package/dist/crash-recovery-scan.d.ts.map +1 -0
  50. package/dist/crash-recovery-scan.js +145 -0
  51. package/dist/crash-recovery-scan.js.map +1 -0
  52. package/dist/crash-recovery-types.d.ts +54 -0
  53. package/dist/crash-recovery-types.d.ts.map +1 -0
  54. package/dist/crash-recovery-types.js +13 -0
  55. package/dist/crash-recovery-types.js.map +1 -0
  56. package/dist/crash-recovery.d.ts +88 -0
  57. package/dist/crash-recovery.d.ts.map +1 -0
  58. package/dist/crash-recovery.js +448 -0
  59. package/dist/crash-recovery.js.map +1 -0
  60. package/dist/daemon-logs.d.ts +19 -0
  61. package/dist/daemon-logs.d.ts.map +1 -0
  62. package/dist/daemon-logs.js +81 -0
  63. package/dist/daemon-logs.js.map +1 -0
  64. package/dist/daemon-process.d.ts +154 -0
  65. package/dist/daemon-process.d.ts.map +1 -0
  66. package/dist/daemon-process.js +427 -0
  67. package/dist/daemon-process.js.map +1 -0
  68. package/dist/dag-validator.d.ts +52 -0
  69. package/dist/dag-validator.d.ts.map +1 -0
  70. package/dist/dag-validator.js +199 -0
  71. package/dist/dag-validator.js.map +1 -0
  72. package/dist/delivery-guards.d.ts +41 -0
  73. package/dist/delivery-guards.d.ts.map +1 -0
  74. package/dist/delivery-guards.js +195 -0
  75. package/dist/delivery-guards.js.map +1 -0
  76. package/dist/delivery-lifecycle.d.ts +110 -0
  77. package/dist/delivery-lifecycle.d.ts.map +1 -0
  78. package/dist/delivery-lifecycle.js +353 -0
  79. package/dist/delivery-lifecycle.js.map +1 -0
  80. package/dist/delivery-merge.d.ts +17 -0
  81. package/dist/delivery-merge.d.ts.map +1 -0
  82. package/dist/delivery-merge.js +89 -0
  83. package/dist/delivery-merge.js.map +1 -0
  84. package/dist/dependency-resolver.d.ts +77 -0
  85. package/dist/dependency-resolver.d.ts.map +1 -0
  86. package/dist/dependency-resolver.js +337 -0
  87. package/dist/dependency-resolver.js.map +1 -0
  88. package/dist/evaluation-context.d.ts +49 -0
  89. package/dist/evaluation-context.d.ts.map +1 -0
  90. package/dist/evaluation-context.js +98 -0
  91. package/dist/evaluation-context.js.map +1 -0
  92. package/dist/git-activity.d.ts +24 -0
  93. package/dist/git-activity.d.ts.map +1 -0
  94. package/dist/git-activity.js +97 -0
  95. package/dist/git-activity.js.map +1 -0
  96. package/dist/git-branch.d.ts +33 -0
  97. package/dist/git-branch.d.ts.map +1 -0
  98. package/dist/git-branch.js +88 -0
  99. package/dist/git-branch.js.map +1 -0
  100. package/dist/git-integration.d.ts +27 -0
  101. package/dist/git-integration.d.ts.map +1 -0
  102. package/dist/git-integration.js +82 -0
  103. package/dist/git-integration.js.map +1 -0
  104. package/dist/git-merge-helpers.d.ts +48 -0
  105. package/dist/git-merge-helpers.d.ts.map +1 -0
  106. package/dist/git-merge-helpers.js +105 -0
  107. package/dist/git-merge-helpers.js.map +1 -0
  108. package/dist/git-merge-lock.d.ts +67 -0
  109. package/dist/git-merge-lock.d.ts.map +1 -0
  110. package/dist/git-merge-lock.js +157 -0
  111. package/dist/git-merge-lock.js.map +1 -0
  112. package/dist/git-merge-strategies.d.ts +39 -0
  113. package/dist/git-merge-strategies.d.ts.map +1 -0
  114. package/dist/git-merge-strategies.js +127 -0
  115. package/dist/git-merge-strategies.js.map +1 -0
  116. package/dist/git-merge.d.ts +80 -0
  117. package/dist/git-merge.d.ts.map +1 -0
  118. package/dist/git-merge.js +373 -0
  119. package/dist/git-merge.js.map +1 -0
  120. package/dist/git-state-detector.d.ts +24 -0
  121. package/dist/git-state-detector.d.ts.map +1 -0
  122. package/dist/git-state-detector.js +122 -0
  123. package/dist/git-state-detector.js.map +1 -0
  124. package/dist/git-types.d.ts +40 -0
  125. package/dist/git-types.d.ts.map +1 -0
  126. package/dist/git-types.js +23 -0
  127. package/dist/git-types.js.map +1 -0
  128. package/dist/git-utils.d.ts +28 -0
  129. package/dist/git-utils.d.ts.map +1 -0
  130. package/dist/git-utils.js +57 -0
  131. package/dist/git-utils.js.map +1 -0
  132. package/dist/git.d.ts +24 -0
  133. package/dist/git.d.ts.map +1 -0
  134. package/dist/git.js +64 -0
  135. package/dist/git.js.map +1 -0
  136. package/dist/guard-engine.d.ts +19 -0
  137. package/dist/guard-engine.d.ts.map +1 -0
  138. package/dist/guard-engine.js +21 -0
  139. package/dist/guard-engine.js.map +1 -0
  140. package/dist/guard-evaluator.d.ts +47 -0
  141. package/dist/guard-evaluator.d.ts.map +1 -0
  142. package/dist/guard-evaluator.js +193 -0
  143. package/dist/guard-evaluator.js.map +1 -0
  144. package/dist/heartbeat.d.ts +73 -0
  145. package/dist/heartbeat.d.ts.map +1 -0
  146. package/dist/heartbeat.js +306 -0
  147. package/dist/heartbeat.js.map +1 -0
  148. package/dist/index.d.ts +32 -0
  149. package/dist/index.d.ts.map +1 -0
  150. package/dist/index.js +493 -0
  151. package/dist/index.js.map +1 -0
  152. package/dist/listener-auto-advance.d.ts +29 -0
  153. package/dist/listener-auto-advance.d.ts.map +1 -0
  154. package/dist/listener-auto-advance.js +172 -0
  155. package/dist/listener-auto-advance.js.map +1 -0
  156. package/dist/listener-review.d.ts +37 -0
  157. package/dist/listener-review.d.ts.map +1 -0
  158. package/dist/listener-review.js +217 -0
  159. package/dist/listener-review.js.map +1 -0
  160. package/dist/listener.d.ts +57 -0
  161. package/dist/listener.d.ts.map +1 -0
  162. package/dist/listener.js +361 -0
  163. package/dist/listener.js.map +1 -0
  164. package/dist/log-manager.d.ts +18 -0
  165. package/dist/log-manager.d.ts.map +1 -0
  166. package/dist/log-manager.js +18 -0
  167. package/dist/log-manager.js.map +1 -0
  168. package/dist/otlp-log-parser.d.ts +21 -0
  169. package/dist/otlp-log-parser.d.ts.map +1 -0
  170. package/dist/otlp-log-parser.js +143 -0
  171. package/dist/otlp-log-parser.js.map +1 -0
  172. package/dist/otlp-metric-parser.d.ts +20 -0
  173. package/dist/otlp-metric-parser.d.ts.map +1 -0
  174. package/dist/otlp-metric-parser.js +113 -0
  175. package/dist/otlp-metric-parser.js.map +1 -0
  176. package/dist/otlp-port-manager.d.ts +26 -0
  177. package/dist/otlp-port-manager.d.ts.map +1 -0
  178. package/dist/otlp-port-manager.js +130 -0
  179. package/dist/otlp-port-manager.js.map +1 -0
  180. package/dist/otlp-receiver.d.ts +51 -0
  181. package/dist/otlp-receiver.d.ts.map +1 -0
  182. package/dist/otlp-receiver.js +663 -0
  183. package/dist/otlp-receiver.js.map +1 -0
  184. package/dist/otlp-types.d.ts +92 -0
  185. package/dist/otlp-types.d.ts.map +1 -0
  186. package/dist/otlp-types.js +133 -0
  187. package/dist/otlp-types.js.map +1 -0
  188. package/dist/output-monitor.d.ts +33 -0
  189. package/dist/output-monitor.d.ts.map +1 -0
  190. package/dist/output-monitor.js +67 -0
  191. package/dist/output-monitor.js.map +1 -0
  192. package/dist/planning-prompt-builder.d.ts +67 -0
  193. package/dist/planning-prompt-builder.d.ts.map +1 -0
  194. package/dist/planning-prompt-builder.js +515 -0
  195. package/dist/planning-prompt-builder.js.map +1 -0
  196. package/dist/prompt-builder.d.ts +14 -0
  197. package/dist/prompt-builder.d.ts.map +1 -0
  198. package/dist/prompt-builder.js +174 -0
  199. package/dist/prompt-builder.js.map +1 -0
  200. package/dist/qa-crash-recovery.d.ts +77 -0
  201. package/dist/qa-crash-recovery.d.ts.map +1 -0
  202. package/dist/qa-crash-recovery.js +243 -0
  203. package/dist/qa-crash-recovery.js.map +1 -0
  204. package/dist/qa-dev-server.d.ts +73 -0
  205. package/dist/qa-dev-server.d.ts.map +1 -0
  206. package/dist/qa-dev-server.js +279 -0
  207. package/dist/qa-dev-server.js.map +1 -0
  208. package/dist/qa-orchestrator.d.ts +79 -0
  209. package/dist/qa-orchestrator.d.ts.map +1 -0
  210. package/dist/qa-orchestrator.js +349 -0
  211. package/dist/qa-orchestrator.js.map +1 -0
  212. package/dist/qa-port-allocator.d.ts +34 -0
  213. package/dist/qa-port-allocator.d.ts.map +1 -0
  214. package/dist/qa-port-allocator.js +75 -0
  215. package/dist/qa-port-allocator.js.map +1 -0
  216. package/dist/qa-provisioner.d.ts +33 -0
  217. package/dist/qa-provisioner.d.ts.map +1 -0
  218. package/dist/qa-provisioner.js +141 -0
  219. package/dist/qa-provisioner.js.map +1 -0
  220. package/dist/qa-state.d.ts +93 -0
  221. package/dist/qa-state.d.ts.map +1 -0
  222. package/dist/qa-state.js +74 -0
  223. package/dist/qa-state.js.map +1 -0
  224. package/dist/queries/control-state.d.ts +25 -0
  225. package/dist/queries/control-state.d.ts.map +1 -0
  226. package/dist/queries/control-state.js +34 -0
  227. package/dist/queries/control-state.js.map +1 -0
  228. package/dist/queries/daemon-connection.d.ts +25 -0
  229. package/dist/queries/daemon-connection.d.ts.map +1 -0
  230. package/dist/queries/daemon-connection.js +28 -0
  231. package/dist/queries/daemon-connection.js.map +1 -0
  232. package/dist/queries/deliveries.d.ts +100 -0
  233. package/dist/queries/deliveries.d.ts.map +1 -0
  234. package/dist/queries/deliveries.js +184 -0
  235. package/dist/queries/deliveries.js.map +1 -0
  236. package/dist/queries/git-activity.d.ts +20 -0
  237. package/dist/queries/git-activity.d.ts.map +1 -0
  238. package/dist/queries/git-activity.js +22 -0
  239. package/dist/queries/git-activity.js.map +1 -0
  240. package/dist/queries/guards.d.ts +47 -0
  241. package/dist/queries/guards.d.ts.map +1 -0
  242. package/dist/queries/guards.js +138 -0
  243. package/dist/queries/guards.js.map +1 -0
  244. package/dist/queries/index.d.ts +19 -0
  245. package/dist/queries/index.d.ts.map +1 -0
  246. package/dist/queries/index.js +17 -0
  247. package/dist/queries/index.js.map +1 -0
  248. package/dist/queries/issues.d.ts +41 -0
  249. package/dist/queries/issues.d.ts.map +1 -0
  250. package/dist/queries/issues.js +67 -0
  251. package/dist/queries/issues.js.map +1 -0
  252. package/dist/queries/qa.d.ts +79 -0
  253. package/dist/queries/qa.d.ts.map +1 -0
  254. package/dist/queries/qa.js +85 -0
  255. package/dist/queries/qa.js.map +1 -0
  256. package/dist/queries/roles.d.ts +13 -0
  257. package/dist/queries/roles.d.ts.map +1 -0
  258. package/dist/queries/roles.js +39 -0
  259. package/dist/queries/roles.js.map +1 -0
  260. package/dist/queries/schemas.d.ts +777 -0
  261. package/dist/queries/schemas.d.ts.map +1 -0
  262. package/dist/queries/schemas.js +391 -0
  263. package/dist/queries/schemas.js.map +1 -0
  264. package/dist/queries/sessions.d.ts +64 -0
  265. package/dist/queries/sessions.d.ts.map +1 -0
  266. package/dist/queries/sessions.js +100 -0
  267. package/dist/queries/sessions.js.map +1 -0
  268. package/dist/queries/shared.d.ts +61 -0
  269. package/dist/queries/shared.d.ts.map +1 -0
  270. package/dist/queries/shared.js +187 -0
  271. package/dist/queries/shared.js.map +1 -0
  272. package/dist/queries/strategies.d.ts +69 -0
  273. package/dist/queries/strategies.d.ts.map +1 -0
  274. package/dist/queries/strategies.js +80 -0
  275. package/dist/queries/strategies.js.map +1 -0
  276. package/dist/queries/workflows.d.ts +17 -0
  277. package/dist/queries/workflows.d.ts.map +1 -0
  278. package/dist/queries/workflows.js +49 -0
  279. package/dist/queries/workflows.js.map +1 -0
  280. package/dist/queries/worktrees.d.ts +38 -0
  281. package/dist/queries/worktrees.d.ts.map +1 -0
  282. package/dist/queries/worktrees.js +37 -0
  283. package/dist/queries/worktrees.js.map +1 -0
  284. package/dist/self-update.d.ts +94 -0
  285. package/dist/self-update.d.ts.map +1 -0
  286. package/dist/self-update.js +438 -0
  287. package/dist/self-update.js.map +1 -0
  288. package/dist/session-lifecycle.d.ts +77 -0
  289. package/dist/session-lifecycle.d.ts.map +1 -0
  290. package/dist/session-lifecycle.js +379 -0
  291. package/dist/session-lifecycle.js.map +1 -0
  292. package/dist/shutdown-state.d.ts +17 -0
  293. package/dist/shutdown-state.d.ts.map +1 -0
  294. package/dist/shutdown-state.js +22 -0
  295. package/dist/shutdown-state.js.map +1 -0
  296. package/dist/spawn-cooldown.d.ts +14 -0
  297. package/dist/spawn-cooldown.d.ts.map +1 -0
  298. package/dist/spawn-cooldown.js +34 -0
  299. package/dist/spawn-cooldown.js.map +1 -0
  300. package/dist/spawn-environment.d.ts +35 -0
  301. package/dist/spawn-environment.d.ts.map +1 -0
  302. package/dist/spawn-environment.js +48 -0
  303. package/dist/spawn-environment.js.map +1 -0
  304. package/dist/spawner-liveness.d.ts +23 -0
  305. package/dist/spawner-liveness.d.ts.map +1 -0
  306. package/dist/spawner-liveness.js +99 -0
  307. package/dist/spawner-liveness.js.map +1 -0
  308. package/dist/spawner-resolution.d.ts +27 -0
  309. package/dist/spawner-resolution.d.ts.map +1 -0
  310. package/dist/spawner-resolution.js +99 -0
  311. package/dist/spawner-resolution.js.map +1 -0
  312. package/dist/spawner-timeout.d.ts +32 -0
  313. package/dist/spawner-timeout.d.ts.map +1 -0
  314. package/dist/spawner-timeout.js +124 -0
  315. package/dist/spawner-timeout.js.map +1 -0
  316. package/dist/spawner.d.ts +77 -0
  317. package/dist/spawner.d.ts.map +1 -0
  318. package/dist/spawner.js +734 -0
  319. package/dist/spawner.js.map +1 -0
  320. package/dist/strategy-completion.d.ts +110 -0
  321. package/dist/strategy-completion.d.ts.map +1 -0
  322. package/dist/strategy-completion.js +434 -0
  323. package/dist/strategy-completion.js.map +1 -0
  324. package/dist/strategy-engine.d.ts +47 -0
  325. package/dist/strategy-engine.d.ts.map +1 -0
  326. package/dist/strategy-engine.js +419 -0
  327. package/dist/strategy-engine.js.map +1 -0
  328. package/dist/strategy-executor.d.ts +93 -0
  329. package/dist/strategy-executor.d.ts.map +1 -0
  330. package/dist/strategy-executor.js +775 -0
  331. package/dist/strategy-executor.js.map +1 -0
  332. package/dist/strategy-lifecycle.d.ts +61 -0
  333. package/dist/strategy-lifecycle.d.ts.map +1 -0
  334. package/dist/strategy-lifecycle.js +516 -0
  335. package/dist/strategy-lifecycle.js.map +1 -0
  336. package/dist/strategy-merge.d.ts +72 -0
  337. package/dist/strategy-merge.d.ts.map +1 -0
  338. package/dist/strategy-merge.js +371 -0
  339. package/dist/strategy-merge.js.map +1 -0
  340. package/dist/strategy-prompt-builder.d.ts +62 -0
  341. package/dist/strategy-prompt-builder.d.ts.map +1 -0
  342. package/dist/strategy-prompt-builder.js +538 -0
  343. package/dist/strategy-prompt-builder.js.map +1 -0
  344. package/dist/strategy-provisioning.d.ts +16 -0
  345. package/dist/strategy-provisioning.d.ts.map +1 -0
  346. package/dist/strategy-provisioning.js +119 -0
  347. package/dist/strategy-provisioning.js.map +1 -0
  348. package/dist/strategy-team-state.d.ts +24 -0
  349. package/dist/strategy-team-state.d.ts.map +1 -0
  350. package/dist/strategy-team-state.js +43 -0
  351. package/dist/strategy-team-state.js.map +1 -0
  352. package/dist/strategy-teardown.d.ts +24 -0
  353. package/dist/strategy-teardown.d.ts.map +1 -0
  354. package/dist/strategy-teardown.js +158 -0
  355. package/dist/strategy-teardown.js.map +1 -0
  356. package/dist/strategy-worktree-state.d.ts +47 -0
  357. package/dist/strategy-worktree-state.d.ts.map +1 -0
  358. package/dist/strategy-worktree-state.js +104 -0
  359. package/dist/strategy-worktree-state.js.map +1 -0
  360. package/dist/supabase.d.ts +36 -0
  361. package/dist/supabase.d.ts.map +1 -0
  362. package/dist/supabase.js +50 -0
  363. package/dist/supabase.js.map +1 -0
  364. package/dist/task-converter.d.ts +61 -0
  365. package/dist/task-converter.d.ts.map +1 -0
  366. package/dist/task-converter.js +286 -0
  367. package/dist/task-converter.js.map +1 -0
  368. package/dist/task-dag-builder.d.ts +14 -0
  369. package/dist/task-dag-builder.d.ts.map +1 -0
  370. package/dist/task-dag-builder.js +17 -0
  371. package/dist/task-dag-builder.js.map +1 -0
  372. package/dist/team-prompt-base.d.ts +114 -0
  373. package/dist/team-prompt-base.d.ts.map +1 -0
  374. package/dist/team-prompt-base.js +531 -0
  375. package/dist/team-prompt-base.js.map +1 -0
  376. package/dist/team-prompt-variants.d.ts +27 -0
  377. package/dist/team-prompt-variants.d.ts.map +1 -0
  378. package/dist/team-prompt-variants.js +134 -0
  379. package/dist/team-prompt-variants.js.map +1 -0
  380. package/dist/team-spawner.d.ts +50 -0
  381. package/dist/team-spawner.d.ts.map +1 -0
  382. package/dist/team-spawner.js +410 -0
  383. package/dist/team-spawner.js.map +1 -0
  384. package/dist/telemetry-writer.d.ts +66 -0
  385. package/dist/telemetry-writer.d.ts.map +1 -0
  386. package/dist/telemetry-writer.js +96 -0
  387. package/dist/telemetry-writer.js.map +1 -0
  388. package/dist/trigger-executor.d.ts +56 -0
  389. package/dist/trigger-executor.d.ts.map +1 -0
  390. package/dist/trigger-executor.js +313 -0
  391. package/dist/trigger-executor.js.map +1 -0
  392. package/dist/types/config.d.ts +60 -0
  393. package/dist/types/config.d.ts.map +1 -0
  394. package/dist/types/config.js +5 -0
  395. package/dist/types/config.js.map +1 -0
  396. package/dist/types/dag.d.ts +53 -0
  397. package/dist/types/dag.d.ts.map +1 -0
  398. package/dist/types/dag.js +5 -0
  399. package/dist/types/dag.js.map +1 -0
  400. package/dist/types/delivery.d.ts +71 -0
  401. package/dist/types/delivery.d.ts.map +1 -0
  402. package/dist/types/delivery.js +5 -0
  403. package/dist/types/delivery.js.map +1 -0
  404. package/dist/types/index.d.ts +15 -0
  405. package/dist/types/index.d.ts.map +1 -0
  406. package/dist/types/index.js +15 -0
  407. package/dist/types/index.js.map +1 -0
  408. package/dist/types/issue.d.ts +22 -0
  409. package/dist/types/issue.d.ts.map +1 -0
  410. package/dist/types/issue.js +5 -0
  411. package/dist/types/issue.js.map +1 -0
  412. package/dist/types/merge.d.ts +28 -0
  413. package/dist/types/merge.d.ts.map +1 -0
  414. package/dist/types/merge.js +5 -0
  415. package/dist/types/merge.js.map +1 -0
  416. package/dist/types/session.d.ts +98 -0
  417. package/dist/types/session.d.ts.map +1 -0
  418. package/dist/types/session.js +5 -0
  419. package/dist/types/session.js.map +1 -0
  420. package/dist/types/strategy.d.ts +175 -0
  421. package/dist/types/strategy.d.ts.map +1 -0
  422. package/dist/types/strategy.js +5 -0
  423. package/dist/types/strategy.js.map +1 -0
  424. package/dist/types/workflow.d.ts +34 -0
  425. package/dist/types/workflow.d.ts.map +1 -0
  426. package/dist/types/workflow.js +9 -0
  427. package/dist/types/workflow.js.map +1 -0
  428. package/dist/types.d.ts +9 -0
  429. package/dist/types.d.ts.map +1 -0
  430. package/dist/types.js +9 -0
  431. package/dist/types.js.map +1 -0
  432. package/dist/unified-init.d.ts +16 -0
  433. package/dist/unified-init.d.ts.map +1 -0
  434. package/dist/unified-init.js +183 -0
  435. package/dist/unified-init.js.map +1 -0
  436. package/dist/unified-shell-config.d.ts +34 -0
  437. package/dist/unified-shell-config.d.ts.map +1 -0
  438. package/dist/unified-shell-config.js +238 -0
  439. package/dist/unified-shell-config.js.map +1 -0
  440. package/dist/unified-shell-status.d.ts +15 -0
  441. package/dist/unified-shell-status.d.ts.map +1 -0
  442. package/dist/unified-shell-status.js +100 -0
  443. package/dist/unified-shell-status.js.map +1 -0
  444. package/dist/unified-shell.d.ts +50 -0
  445. package/dist/unified-shell.d.ts.map +1 -0
  446. package/dist/unified-shell.js +682 -0
  447. package/dist/unified-shell.js.map +1 -0
  448. package/dist/version-check.d.ts +19 -0
  449. package/dist/version-check.d.ts.map +1 -0
  450. package/dist/version-check.js +67 -0
  451. package/dist/version-check.js.map +1 -0
  452. package/dist/workflow-engine.d.ts +95 -0
  453. package/dist/workflow-engine.d.ts.map +1 -0
  454. package/dist/workflow-engine.js +165 -0
  455. package/dist/workflow-engine.js.map +1 -0
  456. package/dist/worktree-merge.d.ts +23 -0
  457. package/dist/worktree-merge.d.ts.map +1 -0
  458. package/dist/worktree-merge.js +57 -0
  459. package/dist/worktree-merge.js.map +1 -0
  460. package/dist/worktree-safety.d.ts +48 -0
  461. package/dist/worktree-safety.d.ts.map +1 -0
  462. package/dist/worktree-safety.js +113 -0
  463. package/dist/worktree-safety.js.map +1 -0
  464. package/dist/worktree-strategy.d.ts +69 -0
  465. package/dist/worktree-strategy.d.ts.map +1 -0
  466. package/dist/worktree-strategy.js +214 -0
  467. package/dist/worktree-strategy.js.map +1 -0
  468. package/dist/worktree.d.ts +159 -0
  469. package/dist/worktree.d.ts.map +1 -0
  470. package/dist/worktree.js +512 -0
  471. package/dist/worktree.js.map +1 -0
  472. package/package.json +76 -0
  473. package/scripts/telora-daemon-wrapper.sh +31 -0
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Control state handler for the daemon.
3
+ *
4
+ * Polls for strategies with non-running control states and dispatches
5
+ * to the appropriate handler:
6
+ * - human_control: SIGSTOP the team lead process
7
+ * - resuming: SIGCONT the team lead process, inject note, set running
8
+ * - stopped: graceful shutdown (message + SIGTERM)
9
+ *
10
+ * Called from the poll loop alongside existing checks.
11
+ */
12
+ import { getActiveTeams, terminateTeam } from './strategy-executor.js';
13
+ import { getControlStateChanges, setControlStateRunning } from './queries/control-state.js';
14
+ import { sendMessage } from '@telora/daemon-core';
15
+ // Track strategies that have already been suspended to avoid repeated SIGSTOP.
16
+ const suspendedStrategies = new Set();
17
+ /**
18
+ * Check for control state changes and dispatch to appropriate handlers.
19
+ *
20
+ * Called from the poll loop. Queries for strategies and factory instances
21
+ * with non-running control states, then dispatches to the correct handler.
22
+ */
23
+ export async function checkControlStateChanges(config) {
24
+ let changes;
25
+ try {
26
+ changes = await getControlStateChanges(config.productId);
27
+ }
28
+ catch (err) {
29
+ console.warn('[control-state] Failed to check control state changes:', err.message);
30
+ return;
31
+ }
32
+ if (changes.length === 0) {
33
+ // Clean up suspended set: remove strategies that have returned to running
34
+ // (they won't appear in the changes list since the API only returns non-running)
35
+ const activeTeams = getActiveTeams();
36
+ for (const strategyId of suspendedStrategies) {
37
+ if (!activeTeams.has(strategyId)) {
38
+ suspendedStrategies.delete(strategyId);
39
+ }
40
+ }
41
+ return;
42
+ }
43
+ for (const change of changes) {
44
+ // Only handle strategy entities for now (factory instances use a different execution model)
45
+ if (change.entityType !== 'strategy')
46
+ continue;
47
+ try {
48
+ switch (change.controlState) {
49
+ case 'human_control':
50
+ handleHumanControl(change);
51
+ break;
52
+ case 'resuming':
53
+ await handleResuming(change);
54
+ break;
55
+ case 'stopped':
56
+ handleStopped(change);
57
+ break;
58
+ default:
59
+ console.warn(`[control-state] Unknown control state: ${change.controlState} for ${change.entityId}`);
60
+ }
61
+ }
62
+ catch (err) {
63
+ console.error(`[control-state] Failed to handle ${change.controlState} for ${change.entityType} ${change.entityId}:`, err.message);
64
+ }
65
+ }
66
+ }
67
+ /**
68
+ * Handle human_control: suspend the agent by sending SIGSTOP.
69
+ */
70
+ export function handleHumanControl(change) {
71
+ const { entityId } = change;
72
+ const activeTeams = getActiveTeams();
73
+ const team = activeTeams.get(entityId);
74
+ if (!team) {
75
+ console.log(`[control-state] No active team for strategy ${entityId} -- acknowledging human_control`);
76
+ return;
77
+ }
78
+ // Avoid repeated SIGSTOP
79
+ if (suspendedStrategies.has(entityId)) {
80
+ return;
81
+ }
82
+ if (!team.leadPid) {
83
+ console.warn(`[control-state] Team for "${team.strategyName}" has no PID -- cannot suspend`);
84
+ return;
85
+ }
86
+ try {
87
+ process.kill(team.leadPid, 'SIGSTOP');
88
+ suspendedStrategies.add(entityId);
89
+ console.log(`[control-state] Suspended team "${team.strategyName}" (PID: ${team.leadPid}) -- human_control`);
90
+ }
91
+ catch (err) {
92
+ console.error(`[control-state] Failed to SIGSTOP PID ${team.leadPid} for "${team.strategyName}":`, err.message);
93
+ }
94
+ }
95
+ /**
96
+ * Handle resuming: send SIGCONT, inject operator note, update to running.
97
+ */
98
+ export async function handleResuming(change) {
99
+ const { entityId, entityType, controlNote } = change;
100
+ const activeTeams = getActiveTeams();
101
+ const team = activeTeams.get(entityId);
102
+ if (!team) {
103
+ console.log(`[control-state] No active team for strategy ${entityId} -- setting to running`);
104
+ try {
105
+ await setControlStateRunning(entityType, entityId);
106
+ }
107
+ catch (err) {
108
+ console.warn(`[control-state] Failed to set control state to running for strategy ${entityId}:`, err.message);
109
+ }
110
+ suspendedStrategies.delete(entityId);
111
+ return;
112
+ }
113
+ if (!team.leadPid) {
114
+ console.warn(`[control-state] Team for "${team.strategyName}" has no PID -- setting to running`);
115
+ try {
116
+ await setControlStateRunning(entityType, entityId);
117
+ }
118
+ catch (err) {
119
+ console.warn(`[control-state] Failed to set control state to running for "${team.strategyName}":`, err.message);
120
+ }
121
+ suspendedStrategies.delete(entityId);
122
+ return;
123
+ }
124
+ // Send SIGCONT to resume the suspended process
125
+ try {
126
+ process.kill(team.leadPid, 'SIGCONT');
127
+ console.log(`[control-state] Resumed team "${team.strategyName}" (PID: ${team.leadPid}) -- SIGCONT sent`);
128
+ }
129
+ catch (err) {
130
+ console.error(`[control-state] Failed to SIGCONT PID ${team.leadPid} for "${team.strategyName}":`, err.message);
131
+ }
132
+ // Inject operator note if present
133
+ if (controlNote && team.leadStdin) {
134
+ try {
135
+ sendMessage(team.leadStdin, `Human operator note: ${controlNote}`);
136
+ console.log(`[control-state] Injected operator note for "${team.strategyName}"`);
137
+ }
138
+ catch (err) {
139
+ console.warn(`[control-state] Failed to inject operator note for "${team.strategyName}":`, err.message);
140
+ }
141
+ }
142
+ // Update control state to running
143
+ try {
144
+ await setControlStateRunning(entityType, entityId);
145
+ }
146
+ catch (err) {
147
+ console.warn(`[control-state] Failed to set control state to running for "${team.strategyName}":`, err.message);
148
+ }
149
+ suspendedStrategies.delete(entityId);
150
+ }
151
+ /**
152
+ * Handle stopped: graceful halt with message + SIGTERM.
153
+ */
154
+ export function handleStopped(change) {
155
+ const { entityId } = change;
156
+ const activeTeams = getActiveTeams();
157
+ const team = activeTeams.get(entityId);
158
+ if (!team) {
159
+ console.log(`[control-state] No active team for strategy ${entityId} -- acknowledging stopped`);
160
+ suspendedStrategies.delete(entityId);
161
+ return;
162
+ }
163
+ // If the team was suspended (human_control -> stopped), resume first so it can process the message
164
+ if (suspendedStrategies.has(entityId) && team.leadPid) {
165
+ try {
166
+ process.kill(team.leadPid, 'SIGCONT');
167
+ console.log(`[control-state] Sent SIGCONT before stop for "${team.strategyName}" (was suspended)`);
168
+ }
169
+ catch (err) {
170
+ console.debug(`[control-state] SIGCONT before stop failed (process may have exited):`, err.message);
171
+ }
172
+ }
173
+ // Send a shutdown message via stdin
174
+ if (team.leadStdin) {
175
+ try {
176
+ sendMessage(team.leadStdin, 'Execution has been stopped by the operator. Commit your current work and exit.');
177
+ console.log(`[control-state] Sent stop message to "${team.strategyName}"`);
178
+ }
179
+ catch (err) {
180
+ console.warn(`[control-state] Failed to send stop message to "${team.strategyName}":`, err.message);
181
+ }
182
+ }
183
+ // After a grace period, send SIGTERM via the existing terminateTeam flow
184
+ setTimeout(() => {
185
+ if (activeTeams.has(entityId)) {
186
+ console.log(`[control-state] Grace period expired for "${team.strategyName}" -- terminating`);
187
+ terminateTeam(entityId);
188
+ }
189
+ }, 10000);
190
+ suspendedStrategies.delete(entityId);
191
+ }
192
+ /**
193
+ * Get the set of suspended strategy IDs (for testing).
194
+ */
195
+ export function getSuspendedStrategies() {
196
+ return suspendedStrategies;
197
+ }
198
+ /**
199
+ * Clear all tracked suspended strategies (for testing).
200
+ */
201
+ export function clearSuspendedStrategies() {
202
+ suspendedStrategies.clear();
203
+ }
204
+ //# sourceMappingURL=control-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-state.js","sourceRoot":"","sources":["../src/control-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Orphan cleanup and stale branch pruning for crash recovery.
3
+ *
4
+ * Processes orphaned worktrees (safety-commit, merge check, remove/preserve)
5
+ * and prunes stale agent branches with no worktree and no unmerged commits.
6
+ */
7
+ import type { DaemonConfig } from './types.js';
8
+ import type { OrphanedWorktree, CleanupAction, RecoveryDeps } from './crash-recovery-types.js';
9
+ /**
10
+ * Clean up all orphaned worktrees. Returns actions taken and
11
+ * any preserved orphans that need escalation.
12
+ */
13
+ export declare function cleanupOrphanedWorktrees(orphans: OrphanedWorktree[], config: DaemonConfig, deps?: RecoveryDeps): Promise<CleanupAction[]>;
14
+ /**
15
+ * Prune stale agent branches that have no worktree and no unmerged commits.
16
+ */
17
+ export declare function pruneStaleAgentBranches(config: DaemonConfig): {
18
+ pruned: string[];
19
+ preserved: string[];
20
+ };
21
+ //# sourceMappingURL=crash-recovery-cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-recovery-cleanup.d.ts","sourceRoot":"","sources":["../src/crash-recovery-cleanup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAmG/F;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,gBAAgB,EAAE,EAC3B,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,YAA0B,GAC/B,OAAO,CAAC,aAAa,EAAE,CAAC,CAoE1B;AAgBD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,YAAY,GACnB;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAwC3C"}
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Orphan cleanup and stale branch pruning for crash recovery.
3
+ *
4
+ * Processes orphaned worktrees (safety-commit, merge check, remove/preserve)
5
+ * and prunes stale agent branches with no worktree and no unmerged commits.
6
+ */
7
+ import { existsSync } from 'node:fs';
8
+ import { runGitSync } from './git.js';
9
+ import { worktreeHasUncommittedChanges, branchHasUnmergedCommits, safetyCommitWorktree, removeWorktree, } from './worktree.js';
10
+ import { ESCALATION_REASONS } from '@telora/daemon-core';
11
+ import { defaultDeps } from './crash-recovery-types.js';
12
+ import { parseWorktreeList } from './crash-recovery-scan.js';
13
+ // ── Helpers ──────────────────────────────────────────────────────
14
+ /**
15
+ * Count unmerged commits on a branch relative to integration.
16
+ */
17
+ function countUnmergedCommits(branchName, integrationBranch, repoPath) {
18
+ const result = runGitSync(['log', '--oneline', `${integrationBranch}..${branchName}`, '--'], repoPath);
19
+ if (!result.success)
20
+ return 0;
21
+ const lines = result.output.trim();
22
+ if (lines.length === 0)
23
+ return 0;
24
+ return lines.split('\n').length;
25
+ }
26
+ /**
27
+ * Process a single orphaned worktree: safety-commit if dirty,
28
+ * then remove if merged or preserve if unmerged.
29
+ *
30
+ * Returns the action taken.
31
+ */
32
+ function cleanupSingleOrphan(orphan, config) {
33
+ const { worktreePath, branchName } = orphan;
34
+ const { repoPath, integrationBranch } = config;
35
+ let commitHash;
36
+ // Step 1: Safety-commit if dirty
37
+ if (existsSync(worktreePath) && worktreeHasUncommittedChanges(worktreePath)) {
38
+ const deliveryName = branchName.split('/').slice(2).join('/') || 'unknown';
39
+ console.log(`[crash-recovery] Safety-committing dirty worktree: ${worktreePath}`);
40
+ const hash = safetyCommitWorktree(worktreePath, deliveryName);
41
+ if (hash) {
42
+ commitHash = hash.trim();
43
+ console.log(`[crash-recovery] Safety commit created: ${commitHash.slice(0, 8)} on ${branchName}`);
44
+ }
45
+ else {
46
+ console.warn(`[crash-recovery] Safety commit failed for ${worktreePath}, preserving as-is`);
47
+ return {
48
+ worktreePath,
49
+ branchName,
50
+ action: 'preserved',
51
+ };
52
+ }
53
+ }
54
+ // Step 2: Check if branch is already merged to integration
55
+ const hasUnmerged = branchHasUnmergedCommits(branchName, integrationBranch, repoPath);
56
+ if (!hasUnmerged) {
57
+ // Fully merged -- safe to remove
58
+ console.log(`[crash-recovery] Removing merged orphan: ${worktreePath} [${branchName}]`);
59
+ removeWorktree(repoPath, worktreePath, {
60
+ branchName,
61
+ integrationBranch,
62
+ mergeSucceeded: true,
63
+ });
64
+ // Also delete the branch since it's merged
65
+ const deleteResult = runGitSync(['branch', '-d', branchName], repoPath);
66
+ if (deleteResult.success) {
67
+ console.log(`[crash-recovery] Deleted merged branch: ${branchName}`);
68
+ }
69
+ return {
70
+ worktreePath,
71
+ branchName,
72
+ action: commitHash ? 'safety-committed-and-removed' : 'removed',
73
+ commitHash,
74
+ };
75
+ }
76
+ // Step 3: Unmerged commits -- preserve
77
+ const unmergedCount = countUnmergedCommits(branchName, integrationBranch, repoPath);
78
+ console.log(`[crash-recovery] Preserving orphan with ${unmergedCount} unmerged commit(s): ${worktreePath} [${branchName}]`);
79
+ return {
80
+ worktreePath,
81
+ branchName,
82
+ action: commitHash ? 'safety-committed' : 'preserved',
83
+ commitHash,
84
+ unmergedCommitCount: unmergedCount,
85
+ };
86
+ }
87
+ // ── Orphan cleanup ───────────────────────────────────────────────
88
+ /**
89
+ * Clean up all orphaned worktrees. Returns actions taken and
90
+ * any preserved orphans that need escalation.
91
+ */
92
+ export async function cleanupOrphanedWorktrees(orphans, config, deps = defaultDeps) {
93
+ const actions = [];
94
+ // Mark orphaned sessions as failed in DB
95
+ for (const orphan of orphans) {
96
+ if (orphan.session) {
97
+ try {
98
+ await deps.updateSession(orphan.session.id, {
99
+ status: 'failed',
100
+ exit_reason: 'Daemon crash recovery: session was active when daemon restarted',
101
+ ended_at: new Date().toISOString(),
102
+ });
103
+ console.log(`[crash-recovery] Marked session ${orphan.session.id} as failed (crash recovery)`);
104
+ }
105
+ catch (err) {
106
+ console.warn(`[crash-recovery] Failed to update session ${orphan.session.id}: ${err instanceof Error ? err.message : String(err)}`);
107
+ }
108
+ }
109
+ }
110
+ // Process each orphan
111
+ for (const orphan of orphans) {
112
+ try {
113
+ const action = cleanupSingleOrphan(orphan, config);
114
+ actions.push(action);
115
+ }
116
+ catch (err) {
117
+ console.error(`[crash-recovery] Error cleaning up orphan ${orphan.worktreePath}: ${err instanceof Error ? err.message : String(err)}`);
118
+ }
119
+ }
120
+ // Escalate preserved orphans
121
+ const preserved = actions.filter((a) => a.action === 'preserved' || a.action === 'safety-committed');
122
+ if (preserved.length > 0) {
123
+ const lines = preserved.map((a) => `- ${a.branchName} (${a.worktreePath})` +
124
+ (a.unmergedCommitCount ? ` -- ${a.unmergedCommitCount} unmerged commit(s)` : '') +
125
+ (a.commitHash ? ` -- safety commit: ${a.commitHash.slice(0, 8)}` : ''));
126
+ const description = `Daemon crash recovery found ${preserved.length} orphaned worktree(s) with unmerged work:\n\n` +
127
+ lines.join('\n') +
128
+ '\n\nThese worktrees have been preserved for manual inspection.';
129
+ try {
130
+ await deps.createEscalation({
131
+ organizationId: config.organizationId,
132
+ sessionId: preserved[0].branchName, // No session available, use branch as context
133
+ issueId: null,
134
+ reasonType: ESCALATION_REASONS.NEEDS_CLARIFICATION,
135
+ description,
136
+ whatWasTried: 'Daemon crash recovery scanned for orphaned worktrees and preserved those with unmerged commits.',
137
+ helpNeeded: 'Inspect the preserved branches and either merge them to integration or delete them.',
138
+ });
139
+ console.log(`[crash-recovery] Created escalation for ${preserved.length} preserved orphan(s)`);
140
+ }
141
+ catch (err) {
142
+ console.warn(`[crash-recovery] Failed to create escalation: ${err instanceof Error ? err.message : String(err)}`);
143
+ }
144
+ }
145
+ return actions;
146
+ }
147
+ // ── Stale branch pruning ─────────────────────────────────────────
148
+ /**
149
+ * List all local branches matching the agent/* pattern.
150
+ */
151
+ function listAgentBranches(repoPath) {
152
+ const result = runGitSync(['branch', '--list', 'agent/*'], repoPath);
153
+ if (!result.success)
154
+ return [];
155
+ return result.output
156
+ .split('\n')
157
+ .map((line) => line.replace(/^[*+]?\s+/, '').trim())
158
+ .filter(Boolean);
159
+ }
160
+ /**
161
+ * Prune stale agent branches that have no worktree and no unmerged commits.
162
+ */
163
+ export function pruneStaleAgentBranches(config) {
164
+ const { repoPath, integrationBranch } = config;
165
+ const branches = listAgentBranches(repoPath);
166
+ const pruned = [];
167
+ const preserved = [];
168
+ if (branches.length === 0) {
169
+ console.log('[crash-recovery] No stale agent branches found');
170
+ return { pruned, preserved };
171
+ }
172
+ // Get set of branches that have active worktrees
173
+ const worktreeMap = parseWorktreeList(repoPath);
174
+ const worktreeBranches = new Set(worktreeMap.values());
175
+ for (const branch of branches) {
176
+ // Skip branches with active worktrees
177
+ if (worktreeBranches.has(branch))
178
+ continue;
179
+ // Check for unmerged commits
180
+ if (branchHasUnmergedCommits(branch, integrationBranch, repoPath)) {
181
+ console.log(`[crash-recovery] Preserving stale branch with unmerged commits: ${branch}`);
182
+ preserved.push(branch);
183
+ continue;
184
+ }
185
+ // Safe to delete
186
+ const deleteResult = runGitSync(['branch', '-D', branch], repoPath);
187
+ if (deleteResult.success) {
188
+ console.log(`[crash-recovery] Pruned stale branch: ${branch}`);
189
+ pruned.push(branch);
190
+ }
191
+ else {
192
+ console.warn(`[crash-recovery] Failed to prune branch ${branch}: ${deleteResult.error}`);
193
+ }
194
+ }
195
+ console.log(`[crash-recovery] Branch pruning: ${pruned.length} pruned, ${preserved.length} preserved with unmerged work`);
196
+ return { pruned, preserved };
197
+ }
198
+ //# sourceMappingURL=crash-recovery-cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-recovery-cleanup.js","sourceRoot":"","sources":["../src/crash-recovery-cleanup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Worktree scanning for crash recovery.
3
+ *
4
+ * Parses `git worktree list` output and reconciles against DB sessions
5
+ * and active strategies to classify worktrees as active or orphaned.
6
+ */
7
+ import type { DaemonConfig } from './types.js';
8
+ import type { OrphanedWorktree, RecoveryDeps } from './crash-recovery-types.js';
9
+ /**
10
+ * Parse `git worktree list --porcelain` to build a map of
11
+ * worktree path -> branch name for all registered worktrees.
12
+ */
13
+ export declare function parseWorktreeList(repoPath: string): Map<string, string>;
14
+ /**
15
+ * Scan the worktree directory and reconcile against active DB sessions
16
+ * to classify each worktree as active or orphaned.
17
+ */
18
+ export declare function detectOrphanedWorktrees(config: DaemonConfig, deps?: RecoveryDeps): Promise<OrphanedWorktree[]>;
19
+ //# sourceMappingURL=crash-recovery-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-recovery-scan.d.ts","sourceRoot":"","sources":["../src/crash-recovery-scan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAgBhF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBvE;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,YAA0B,GAC/B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA+G7B"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Worktree scanning for crash recovery.
3
+ *
4
+ * Parses `git worktree list` output and reconciles against DB sessions
5
+ * and active strategies to classify worktrees as active or orphaned.
6
+ */
7
+ import { existsSync, readdirSync, statSync } from 'node:fs';
8
+ import { join, resolve } from 'node:path';
9
+ import { runGitSync } from './git.js';
10
+ import { defaultDeps } from './crash-recovery-types.js';
11
+ // ── Helpers ──────────────────────────────────────────────────────
12
+ /**
13
+ * Extract the strategy ID prefix (last 8 hex chars) from a worktree directory name.
14
+ * Strategy worktree directories follow: agent-{role}-{name}-{8-char-id}
15
+ */
16
+ function extractStrategyIdPrefix(dirName) {
17
+ const match = dirName.match(/-([0-9a-f]{8})$/);
18
+ return match ? match[1] : null;
19
+ }
20
+ // ── Worktree scanning ────────────────────────────────────────────
21
+ /**
22
+ * Parse `git worktree list --porcelain` to build a map of
23
+ * worktree path -> branch name for all registered worktrees.
24
+ */
25
+ export function parseWorktreeList(repoPath) {
26
+ const result = runGitSync(['worktree', 'list', '--porcelain'], repoPath);
27
+ const map = new Map();
28
+ if (!result.success)
29
+ return map;
30
+ let currentPath = null;
31
+ for (const line of result.output.split('\n')) {
32
+ if (line.startsWith('worktree ')) {
33
+ currentPath = line.slice('worktree '.length);
34
+ }
35
+ else if (line.startsWith('branch refs/heads/') && currentPath) {
36
+ map.set(currentPath, line.slice('branch refs/heads/'.length));
37
+ currentPath = null;
38
+ }
39
+ else if (line === '') {
40
+ currentPath = null;
41
+ }
42
+ }
43
+ return map;
44
+ }
45
+ /**
46
+ * Scan the worktree directory and reconcile against active DB sessions
47
+ * to classify each worktree as active or orphaned.
48
+ */
49
+ export async function detectOrphanedWorktrees(config, deps = defaultDeps) {
50
+ const { worktreeDir, repoPath } = config;
51
+ // 1. Read all subdirectories in worktreeDir
52
+ if (!existsSync(worktreeDir))
53
+ return [];
54
+ const entries = readdirSync(worktreeDir);
55
+ const subdirs = entries.filter((entry) => {
56
+ const fullPath = join(worktreeDir, entry);
57
+ try {
58
+ return statSync(fullPath).isDirectory();
59
+ }
60
+ catch (e) {
61
+ console.debug(`[crash-recovery] Failed to stat ${fullPath} (may have been deleted):`, e.message);
62
+ return false;
63
+ }
64
+ });
65
+ if (subdirs.length === 0)
66
+ return [];
67
+ // 2. Parse git worktree list to map paths -> branch names
68
+ const worktreeMap = parseWorktreeList(repoPath);
69
+ // Build a reverse lookup: resolve worktree paths so we can match
70
+ const pathToBranch = new Map();
71
+ for (const [wtPath, branch] of worktreeMap) {
72
+ pathToBranch.set(resolve(wtPath), branch);
73
+ }
74
+ // 3. Query active sessions from DB
75
+ let activeSessions = [];
76
+ try {
77
+ activeSessions = await deps.getActiveSessions();
78
+ }
79
+ catch (err) {
80
+ console.warn(`[crash-recovery] Failed to query active sessions from DB: ${err instanceof Error ? err.message : String(err)}. ` +
81
+ `Treating all worktrees as orphaned.`);
82
+ }
83
+ // Build set of branch names with active sessions
84
+ const activeBranches = new Set(activeSessions.map((s) => s.branch_name));
85
+ // Build map of branch -> session for linking
86
+ const branchToSession = new Map();
87
+ for (const session of activeSessions) {
88
+ branchToSession.set(session.branch_name, session);
89
+ }
90
+ // 3b. Query active strategies to preserve persistent worktrees
91
+ const activeStrategyIdPrefixes = new Set();
92
+ try {
93
+ const activeStrategies = await deps.getActiveStrategies(config.organizationId, config.productId);
94
+ for (const s of activeStrategies) {
95
+ activeStrategyIdPrefixes.add(s.strategy_id.slice(0, 8));
96
+ }
97
+ }
98
+ catch (err) {
99
+ console.warn(`[crash-recovery] Failed to query active strategies: ${err instanceof Error ? err.message : String(err)}. ` +
100
+ `Persistent strategy worktrees may be incorrectly classified as orphaned.`);
101
+ }
102
+ // 4. Classify each worktree subdirectory
103
+ const orphans = [];
104
+ for (const subdir of subdirs) {
105
+ const fullPath = resolve(join(worktreeDir, subdir));
106
+ const branchName = pathToBranch.get(fullPath);
107
+ if (!branchName) {
108
+ // Directory exists but no git worktree entry -- likely a stale directory.
109
+ // Check if it belongs to an active strategy before classifying as orphan.
110
+ const idPrefix = extractStrategyIdPrefix(subdir);
111
+ if (idPrefix && activeStrategyIdPrefixes.has(idPrefix)) {
112
+ console.log(`[crash-recovery] Worktree belongs to active strategy (persistent, no git entry): ${fullPath}`);
113
+ continue;
114
+ }
115
+ // Try to infer branch from directory name (agent-role-delivery pattern).
116
+ console.log(`[crash-recovery] Worktree directory has no git entry: ${fullPath}`);
117
+ orphans.push({
118
+ worktreePath: fullPath,
119
+ branchName: subdir.replace(/-/g, '/').replace(/^agent\//, 'agent/'),
120
+ session: null,
121
+ });
122
+ continue;
123
+ }
124
+ if (activeBranches.has(branchName)) {
125
+ // Active session exists -- leave alone
126
+ console.log(`[crash-recovery] Worktree is active (has DB session): ${fullPath} [${branchName}]`);
127
+ continue;
128
+ }
129
+ // Check if this worktree belongs to an active strategy (persistent worktree)
130
+ const idPrefix = extractStrategyIdPrefix(subdir);
131
+ if (idPrefix && activeStrategyIdPrefixes.has(idPrefix)) {
132
+ console.log(`[crash-recovery] Worktree belongs to active strategy (persistent): ${fullPath} [${branchName}]`);
133
+ continue;
134
+ }
135
+ // No active session and no active strategy -- orphaned
136
+ const session = branchToSession.get(branchName) ?? null;
137
+ orphans.push({
138
+ worktreePath: fullPath,
139
+ branchName,
140
+ session,
141
+ });
142
+ }
143
+ return orphans;
144
+ }
145
+ //# sourceMappingURL=crash-recovery-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-recovery-scan.js","sourceRoot":"","sources":["../src/crash-recovery-scan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,oEAAoE;AAEpE;;;GAGG;AACH,SAAS,uBAAuB,CAAC,OAAe;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,oEAAoE;AAEpE;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,QAAQ,CAAC,CAAC;IACzE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC;IAEhC,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACjC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC/C,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,IAAI,WAAW,EAAE,CAAC;YAChE,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC9D,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;aAAM,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;YACvB,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAoB,EACpB,OAAqB,WAAW;IAEhC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAEzC,4CAA4C;IAC5C,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,CAAC;IAExC,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,mCAAmC,QAAQ,2BAA2B,EAAG,CAAW,CAAC,OAAO,CAAC,CAAC;YAC5G,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,0DAA0D;IAC1D,MAAM,WAAW,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEhD,iEAAiE;IACjE,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC/C,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC3C,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,mCAAmC;IACnC,IAAI,cAAc,GAAmB,EAAE,CAAC;IACxC,IAAI,CAAC;QACH,cAAc,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAClD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,6DAA6D,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI;YACjH,qCAAqC,CACtC,CAAC;IACJ,CAAC;IAED,iDAAiD;IACjD,MAAM,cAAc,GAAG,IAAI,GAAG,CAC5B,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CACzC,CAAC;IAEF,6CAA6C;IAC7C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAwB,CAAC;IACxD,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,+DAA+D;IAC/D,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAU,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACjG,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;YACjC,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,uDAAuD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI;YAC3G,0EAA0E,CAC3E,CAAC;IACJ,CAAC;IAED,yCAAyC;IACzC,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE9C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,0EAA0E;YAC1E,0EAA0E;YAC1E,MAAM,QAAQ,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;YACjD,IAAI,QAAQ,IAAI,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,oFAAoF,QAAQ,EAAE,CAAC,CAAC;gBAC5G,SAAS;YACX,CAAC;YACD,yEAAyE;YACzE,OAAO,CAAC,GAAG,CAAC,yDAAyD,QAAQ,EAAE,CAAC,CAAC;YACjF,OAAO,CAAC,IAAI,CAAC;gBACX,YAAY,EAAE,QAAQ;gBACtB,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;gBACnE,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,uCAAuC;YACvC,OAAO,CAAC,GAAG,CAAC,yDAAyD,QAAQ,KAAK,UAAU,GAAG,CAAC,CAAC;YACjG,SAAS;QACX,CAAC;QAED,6EAA6E;QAC7E,MAAM,QAAQ,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,QAAQ,IAAI,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,sEAAsE,QAAQ,KAAK,UAAU,GAAG,CAAC,CAAC;YAC9G,SAAS;QACX,CAAC;QAED,uDAAuD;QACvD,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC;YACX,YAAY,EAAE,QAAQ;YACtB,UAAU;YACV,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}