@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,19 @@
1
+ /**
2
+ * Daemon log viewing utilities.
3
+ *
4
+ * Provides tail-like functionality for the daemon log file,
5
+ * including follow mode (like `tail -f`).
6
+ */
7
+ /**
8
+ * Print the last N lines from a file.
9
+ */
10
+ export declare function tailFile(filePath: string, lines: number): Promise<void>;
11
+ /**
12
+ * Follow a log file, printing new lines as they appear.
13
+ * Returns a cleanup function that stops the follow.
14
+ *
15
+ * Uses fs.watchFile for polling-based watching (works across
16
+ * all platforms and with log rotation).
17
+ */
18
+ export declare function followFile(filePath: string): () => void;
19
+ //# sourceMappingURL=daemon-logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-logs.d.ts","sourceRoot":"","sources":["../src/daemon-logs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;GAEG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB7E;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,IAAI,CAkDvD"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Daemon log viewing utilities.
3
+ *
4
+ * Provides tail-like functionality for the daemon log file,
5
+ * including follow mode (like `tail -f`).
6
+ */
7
+ import { createReadStream, existsSync, statSync, watchFile, unwatchFile } from 'node:fs';
8
+ import { createInterface } from 'node:readline';
9
+ /**
10
+ * Print the last N lines from a file.
11
+ */
12
+ export async function tailFile(filePath, lines) {
13
+ if (!existsSync(filePath)) {
14
+ console.error(`Log file not found: ${filePath}`);
15
+ return;
16
+ }
17
+ // Read the entire file and print the last N lines
18
+ const allLines = [];
19
+ const rl = createInterface({
20
+ input: createReadStream(filePath, { encoding: 'utf-8' }),
21
+ crlfDelay: Infinity,
22
+ });
23
+ for await (const line of rl) {
24
+ allLines.push(line);
25
+ }
26
+ const startIdx = Math.max(0, allLines.length - lines);
27
+ for (let i = startIdx; i < allLines.length; i++) {
28
+ console.log(allLines[i]);
29
+ }
30
+ }
31
+ /**
32
+ * Follow a log file, printing new lines as they appear.
33
+ * Returns a cleanup function that stops the follow.
34
+ *
35
+ * Uses fs.watchFile for polling-based watching (works across
36
+ * all platforms and with log rotation).
37
+ */
38
+ export function followFile(filePath) {
39
+ if (!existsSync(filePath)) {
40
+ console.error(`Log file not found: ${filePath}`);
41
+ console.error('Start the daemon first, then run logs --follow');
42
+ process.exit(1);
43
+ }
44
+ let position = statSync(filePath).size;
45
+ let stopped = false;
46
+ const pollIntervalMs = 500;
47
+ watchFile(filePath, { interval: pollIntervalMs }, () => {
48
+ if (stopped)
49
+ return;
50
+ try {
51
+ const currentSize = statSync(filePath).size;
52
+ if (currentSize < position) {
53
+ // File was truncated or rotated -- start from beginning
54
+ position = 0;
55
+ }
56
+ if (currentSize > position) {
57
+ const stream = createReadStream(filePath, {
58
+ start: position,
59
+ encoding: 'utf-8',
60
+ });
61
+ stream.on('data', (chunk) => {
62
+ process.stdout.write(chunk);
63
+ });
64
+ stream.on('end', () => {
65
+ position = currentSize;
66
+ });
67
+ stream.on('error', (err) => {
68
+ console.error(`Error reading log file: ${err.message}`);
69
+ });
70
+ }
71
+ }
72
+ catch {
73
+ // File may have been deleted during rotation
74
+ }
75
+ });
76
+ return () => {
77
+ stopped = true;
78
+ unwatchFile(filePath);
79
+ };
80
+ }
81
+ //# sourceMappingURL=daemon-logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-logs.js","sourceRoot":"","sources":["../src/daemon-logs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Daemon process management utilities for CLI commands.
3
+ *
4
+ * Provides helpers for:
5
+ * - Reading PID files and checking daemon liveness
6
+ * - Sending signals (stop, status)
7
+ * - Spawning the daemon as a background process
8
+ * - Auto-rebuilding TypeScript before starting
9
+ */
10
+ /**
11
+ * Resolve the global daemon state directory (~/.telora/).
12
+ *
13
+ * Process-level state (PID lock, metadata, canonical log) lives here
14
+ * because the daemon is a user-scoped singleton -- one process per user,
15
+ * potentially managing multiple product repositories.
16
+ *
17
+ * Per-product state (worktrees, session logs) remains in each repo's
18
+ * .telora/ directory, configured via configForProduct().
19
+ *
20
+ * Override with TELORA_STATE_DIR for testing.
21
+ */
22
+ export declare function resolveGlobalStateDir(): string;
23
+ /**
24
+ * Ensure the global state directory (~/.telora/) exists.
25
+ * Called during daemon startup.
26
+ */
27
+ export declare function ensureGlobalStateDir(): void;
28
+ /**
29
+ * Resolve the PID file path in the global state directory (~/.telora/).
30
+ */
31
+ export declare function resolvePidFilePath(): string;
32
+ /**
33
+ * Read the PID from the daemon PID file.
34
+ * Returns null if the file doesn't exist or contains invalid data.
35
+ */
36
+ export declare function readDaemonPid(pidFilePath: string): number | null;
37
+ export interface DaemonStatus {
38
+ running: boolean;
39
+ pid: number | null;
40
+ pidFilePath: string;
41
+ logPath: string | null;
42
+ startedAt: string | null;
43
+ }
44
+ /**
45
+ * Metadata written alongside the PID file for daemon discoverability.
46
+ */
47
+ export interface DaemonMeta {
48
+ pid: number;
49
+ logPath: string;
50
+ startedAt: string;
51
+ }
52
+ /**
53
+ * Check if the daemon is currently running.
54
+ */
55
+ export declare function getDaemonStatus(): DaemonStatus;
56
+ /**
57
+ * Send SIGTERM to the running daemon and wait for it to exit.
58
+ * Returns true if the daemon was stopped, false if it wasn't running.
59
+ * Throws if the daemon doesn't exit within the timeout.
60
+ */
61
+ export declare function stopDaemon(timeoutMs?: number): Promise<boolean>;
62
+ /**
63
+ * Check if dist/ is stale relative to src/ files.
64
+ * Returns true if any src/ file is newer than the newest dist/ file,
65
+ * or if dist/ doesn't exist.
66
+ */
67
+ export declare function needsRebuild(): boolean;
68
+ /**
69
+ * Rebuild the daemon TypeScript project.
70
+ * Runs `npm run build` in the daemon package directory.
71
+ */
72
+ export declare function rebuildDaemon(): void;
73
+ /**
74
+ * Auto-rebuild if dist/ is stale. Used by start command.
75
+ */
76
+ export declare function autoRebuildIfNeeded(): void;
77
+ export interface StartOptions {
78
+ /** Path to config file. */
79
+ config?: string;
80
+ /** Enable verbose logging. */
81
+ verbose?: boolean;
82
+ /** Engine filter (strategy or factory). */
83
+ engine?: string;
84
+ /** Skip crash recovery. */
85
+ skipRecovery?: boolean;
86
+ /** Disable auto-update. */
87
+ noAutoUpdate?: boolean;
88
+ /** Run in foreground (don't daemonize). */
89
+ foreground?: boolean;
90
+ /** Auto-rebuild before starting. */
91
+ rebuild?: boolean;
92
+ }
93
+ /**
94
+ * Resolve the path to the daemon log file in the global state directory.
95
+ */
96
+ export declare function resolveDaemonLogPath(): string;
97
+ /**
98
+ * Start the daemon as a background process.
99
+ *
100
+ * Spawns a detached child process that writes stdout/stderr to the
101
+ * daemon log file. The child process runs `telora-daemon run` with
102
+ * the provided options.
103
+ *
104
+ * Returns the PID of the spawned process.
105
+ */
106
+ export declare function startDaemonBackground(opts: StartOptions): number;
107
+ /**
108
+ * Wait for the daemon to become healthy after background start.
109
+ * Checks that the PID file appears and the process is running.
110
+ * Returns true if healthy, false if the process died or timed out.
111
+ */
112
+ export declare function waitForHealthy(timeoutMs?: number): Promise<boolean>;
113
+ /**
114
+ * Clean up stale PID file if the process isn't running.
115
+ * Returns true if a stale file was removed.
116
+ */
117
+ export declare function cleanStalePidFile(): boolean;
118
+ /**
119
+ * Resolve the path to the daemon metadata file in the global state directory.
120
+ */
121
+ export declare function resolveDaemonMetaPath(): string;
122
+ /**
123
+ * Write daemon metadata alongside the PID file.
124
+ * Called during daemon startup to record the log file path and start time.
125
+ */
126
+ export declare function writeDaemonMeta(logPath?: string): void;
127
+ /**
128
+ * Read daemon metadata. Returns null if the file doesn't exist or is invalid.
129
+ */
130
+ export declare function readDaemonMeta(): DaemonMeta | null;
131
+ /**
132
+ * Remove daemon metadata file. Called during shutdown alongside PID lock release.
133
+ */
134
+ export declare function removeDaemonMeta(): void;
135
+ /**
136
+ * Rotate the canonical daemon log on startup.
137
+ *
138
+ * Renames the existing daemon.log to daemon.log.prev so each daemon run
139
+ * starts with a fresh log. Only one previous log is kept — this is enough
140
+ * for quick debugging without accumulating unbounded history.
141
+ */
142
+ export declare function rotateDaemonLog(): void;
143
+ /**
144
+ * Set up canonical log file output for foreground mode.
145
+ *
146
+ * When the daemon runs in the foreground, stdout/stderr go to the terminal.
147
+ * This function additionally pipes both streams to the canonical log file
148
+ * so that `telora-daemon logs` always has something to read, regardless
149
+ * of how the daemon was started.
150
+ *
151
+ * Returns a cleanup function that closes the log stream.
152
+ */
153
+ export declare function setupCanonicalLogTee(): () => void;
154
+ //# sourceMappingURL=daemon-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-process.d.ts","sourceRoot":"","sources":["../src/daemon-process.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyBH;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAK3C;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWhE;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAiB9C;AAMD;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,SAAS,SAAS,GACjB,OAAO,CAAC,OAAO,CAAC,CA8BlB;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAoBtC;AAuBD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAiBpC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAMD,MAAM,WAAW,YAAY;IAC3B,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAsDhE;AAMD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,SAAS,SAAS,GACjB,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAgB3C;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAUtD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,UAAU,GAAG,IAAI,CAYlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CASvC;AAMD;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAUtC;AAMD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,IAAI,CAwBjD"}
@@ -0,0 +1,427 @@
1
+ /**
2
+ * Daemon process management utilities for CLI commands.
3
+ *
4
+ * Provides helpers for:
5
+ * - Reading PID files and checking daemon liveness
6
+ * - Sending signals (stop, status)
7
+ * - Spawning the daemon as a background process
8
+ * - Auto-rebuilding TypeScript before starting
9
+ */
10
+ import { closeSync, createWriteStream, existsSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
11
+ import { resolve, dirname, join } from 'node:path';
12
+ import { spawn, execFileSync } from 'node:child_process';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { homedir } from 'node:os';
15
+ /**
16
+ * Check if a process with the given PID is currently running.
17
+ * Uses kill(pid, 0) for existence check without delivering a signal.
18
+ */
19
+ function isProcessRunning(pid) {
20
+ try {
21
+ process.kill(pid, 0);
22
+ return true;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ // ---------------------------------------------------------------------------
29
+ // Global state directory
30
+ // ---------------------------------------------------------------------------
31
+ /**
32
+ * Resolve the global daemon state directory (~/.telora/).
33
+ *
34
+ * Process-level state (PID lock, metadata, canonical log) lives here
35
+ * because the daemon is a user-scoped singleton -- one process per user,
36
+ * potentially managing multiple product repositories.
37
+ *
38
+ * Per-product state (worktrees, session logs) remains in each repo's
39
+ * .telora/ directory, configured via configForProduct().
40
+ *
41
+ * Override with TELORA_STATE_DIR for testing.
42
+ */
43
+ export function resolveGlobalStateDir() {
44
+ return process.env.TELORA_STATE_DIR || resolve(homedir(), '.telora');
45
+ }
46
+ /**
47
+ * Ensure the global state directory (~/.telora/) exists.
48
+ * Called during daemon startup.
49
+ */
50
+ export function ensureGlobalStateDir() {
51
+ const dir = resolveGlobalStateDir();
52
+ if (!existsSync(dir)) {
53
+ mkdirSync(dir, { recursive: true });
54
+ }
55
+ }
56
+ // ---------------------------------------------------------------------------
57
+ // PID file helpers
58
+ // ---------------------------------------------------------------------------
59
+ /**
60
+ * Resolve the PID file path in the global state directory (~/.telora/).
61
+ */
62
+ export function resolvePidFilePath() {
63
+ return resolve(resolveGlobalStateDir(), 'daemon.pid');
64
+ }
65
+ /**
66
+ * Read the PID from the daemon PID file.
67
+ * Returns null if the file doesn't exist or contains invalid data.
68
+ */
69
+ export function readDaemonPid(pidFilePath) {
70
+ if (!existsSync(pidFilePath))
71
+ return null;
72
+ try {
73
+ const contents = readFileSync(pidFilePath, 'utf-8').trim();
74
+ const pid = parseInt(contents, 10);
75
+ if (isNaN(pid) || pid <= 0)
76
+ return null;
77
+ return pid;
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ }
83
+ /**
84
+ * Check if the daemon is currently running.
85
+ */
86
+ export function getDaemonStatus() {
87
+ const pidFilePath = resolvePidFilePath();
88
+ const pid = readDaemonPid(pidFilePath);
89
+ if (pid === null) {
90
+ return { running: false, pid: null, pidFilePath, logPath: null, startedAt: null };
91
+ }
92
+ const running = isProcessRunning(pid);
93
+ const meta = readDaemonMeta();
94
+ return {
95
+ running,
96
+ pid: running ? pid : null,
97
+ pidFilePath,
98
+ logPath: meta?.logPath ?? null,
99
+ startedAt: meta?.startedAt ?? null,
100
+ };
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // Stop
104
+ // ---------------------------------------------------------------------------
105
+ /**
106
+ * Send SIGTERM to the running daemon and wait for it to exit.
107
+ * Returns true if the daemon was stopped, false if it wasn't running.
108
+ * Throws if the daemon doesn't exit within the timeout.
109
+ */
110
+ export async function stopDaemon(timeoutMs = 30_000) {
111
+ const status = getDaemonStatus();
112
+ if (!status.running || status.pid === null) {
113
+ return false;
114
+ }
115
+ // Send SIGTERM
116
+ try {
117
+ process.kill(status.pid, 'SIGTERM');
118
+ }
119
+ catch {
120
+ // Process already gone
121
+ return false;
122
+ }
123
+ // Wait for the process to exit
124
+ const startTime = Date.now();
125
+ const pollIntervalMs = 200;
126
+ while (Date.now() - startTime < timeoutMs) {
127
+ if (!isProcessRunning(status.pid)) {
128
+ return true;
129
+ }
130
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
131
+ }
132
+ throw new Error(`Daemon (PID ${status.pid}) did not exit within ${Math.round(timeoutMs / 1000)}s. ` +
133
+ `Use 'kill -9 ${status.pid}' to force kill.`);
134
+ }
135
+ // ---------------------------------------------------------------------------
136
+ // Auto-rebuild
137
+ // ---------------------------------------------------------------------------
138
+ /**
139
+ * Check if dist/ is stale relative to src/ files.
140
+ * Returns true if any src/ file is newer than the newest dist/ file,
141
+ * or if dist/ doesn't exist.
142
+ */
143
+ export function needsRebuild() {
144
+ const thisDir = dirname(fileURLToPath(import.meta.url));
145
+ const pkgRoot = resolve(thisDir, '..');
146
+ const distDir = resolve(pkgRoot, 'dist');
147
+ const srcDir = resolve(pkgRoot, 'src');
148
+ // If dist doesn't exist, rebuild is needed
149
+ if (!existsSync(distDir))
150
+ return true;
151
+ // If running from source (tsx), no rebuild needed -- dev mode
152
+ if (import.meta.url.endsWith('.ts'))
153
+ return false;
154
+ // Find newest src file and newest dist file
155
+ const newestSrc = newestMtime(srcDir);
156
+ const newestDist = newestMtime(distDir);
157
+ if (newestSrc === 0)
158
+ return false; // No src files?
159
+ if (newestDist === 0)
160
+ return true; // Empty dist/
161
+ return newestSrc > newestDist;
162
+ }
163
+ function newestMtime(dir) {
164
+ let newest = 0;
165
+ try {
166
+ const entries = readdirSync(dir, { withFileTypes: true });
167
+ for (const entry of entries) {
168
+ const fullPath = join(dir, entry.name);
169
+ if (entry.isDirectory()) {
170
+ if (entry.name === 'node_modules' || entry.name === '__tests__')
171
+ continue;
172
+ const sub = newestMtime(fullPath);
173
+ if (sub > newest)
174
+ newest = sub;
175
+ }
176
+ else if (entry.isFile()) {
177
+ const stat = statSync(fullPath);
178
+ if (stat.mtimeMs > newest)
179
+ newest = stat.mtimeMs;
180
+ }
181
+ }
182
+ }
183
+ catch {
184
+ // Directory may not exist
185
+ }
186
+ return newest;
187
+ }
188
+ /**
189
+ * Rebuild the daemon TypeScript project.
190
+ * Runs `npm run build` in the daemon package directory.
191
+ */
192
+ export function rebuildDaemon() {
193
+ const thisDir = dirname(fileURLToPath(import.meta.url));
194
+ const pkgRoot = resolve(thisDir, '..');
195
+ console.log('[cli] Rebuilding daemon...');
196
+ try {
197
+ execFileSync('npm', ['run', 'build'], {
198
+ cwd: pkgRoot,
199
+ stdio: 'inherit',
200
+ timeout: 60_000,
201
+ });
202
+ console.log('[cli] Rebuild complete');
203
+ }
204
+ catch (err) {
205
+ throw new Error(`Failed to rebuild daemon: ${err instanceof Error ? err.message : String(err)}`);
206
+ }
207
+ }
208
+ /**
209
+ * Auto-rebuild if dist/ is stale. Used by start command.
210
+ */
211
+ export function autoRebuildIfNeeded() {
212
+ if (needsRebuild()) {
213
+ console.log('[cli] dist/ is stale, rebuilding...');
214
+ rebuildDaemon();
215
+ }
216
+ }
217
+ /**
218
+ * Resolve the path to the daemon log file in the global state directory.
219
+ */
220
+ export function resolveDaemonLogPath() {
221
+ return resolve(resolveGlobalStateDir(), 'daemon.log');
222
+ }
223
+ /**
224
+ * Start the daemon as a background process.
225
+ *
226
+ * Spawns a detached child process that writes stdout/stderr to the
227
+ * daemon log file. The child process runs `telora-daemon run` with
228
+ * the provided options.
229
+ *
230
+ * Returns the PID of the spawned process.
231
+ */
232
+ export function startDaemonBackground(opts) {
233
+ const repoPath = process.env.TELORA_REPO_PATH || process.cwd();
234
+ // Ensure global state directory exists
235
+ ensureGlobalStateDir();
236
+ const logPath = resolveDaemonLogPath();
237
+ // Rotate log BEFORE opening the fd so the child's stdout/stderr
238
+ // file descriptor points to the fresh daemon.log, not the rotated
239
+ // daemon.log.prev. The child will skip its own rotation when it
240
+ // detects stdout is not a TTY (background mode).
241
+ rotateDaemonLog();
242
+ // Build args for the child process
243
+ const args = ['run'];
244
+ if (opts.config) {
245
+ args.push('--config', opts.config);
246
+ }
247
+ if (opts.verbose) {
248
+ args.push('--verbose');
249
+ }
250
+ if (opts.engine) {
251
+ args.push('--engine', opts.engine);
252
+ }
253
+ if (opts.skipRecovery) {
254
+ args.push('--skip-recovery');
255
+ }
256
+ if (opts.noAutoUpdate) {
257
+ args.push('--no-auto-update');
258
+ }
259
+ // Resolve the daemon entry point
260
+ const thisDir = dirname(fileURLToPath(import.meta.url));
261
+ const entryPoint = resolve(thisDir, 'index.js');
262
+ // Open log file for appending
263
+ const logFd = openSync(logPath, 'a');
264
+ const child = spawn(process.execPath, [entryPoint, ...args], {
265
+ detached: true,
266
+ stdio: ['ignore', logFd, logFd],
267
+ cwd: repoPath,
268
+ env: { ...process.env },
269
+ });
270
+ // Let the child run independently
271
+ child.unref();
272
+ // Close our copy of the file descriptor
273
+ closeSync(logFd);
274
+ return child.pid ?? 0;
275
+ }
276
+ // ---------------------------------------------------------------------------
277
+ // Health confirmation
278
+ // ---------------------------------------------------------------------------
279
+ /**
280
+ * Wait for the daemon to become healthy after background start.
281
+ * Checks that the PID file appears and the process is running.
282
+ * Returns true if healthy, false if the process died or timed out.
283
+ */
284
+ export async function waitForHealthy(timeoutMs = 10_000) {
285
+ const startTime = Date.now();
286
+ const pollIntervalMs = 500;
287
+ while (Date.now() - startTime < timeoutMs) {
288
+ const status = getDaemonStatus();
289
+ if (status.running && status.pid !== null) {
290
+ return true;
291
+ }
292
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
293
+ }
294
+ return false;
295
+ }
296
+ /**
297
+ * Clean up stale PID file if the process isn't running.
298
+ * Returns true if a stale file was removed.
299
+ */
300
+ export function cleanStalePidFile() {
301
+ const pidFilePath = resolvePidFilePath();
302
+ const pid = readDaemonPid(pidFilePath);
303
+ if (pid === null)
304
+ return false;
305
+ if (!isProcessRunning(pid)) {
306
+ try {
307
+ unlinkSync(pidFilePath);
308
+ console.log(`[cli] Removed stale PID file (PID ${pid} is not running)`);
309
+ return true;
310
+ }
311
+ catch {
312
+ return false;
313
+ }
314
+ }
315
+ return false;
316
+ }
317
+ // ---------------------------------------------------------------------------
318
+ // Daemon metadata (log path, start time)
319
+ // ---------------------------------------------------------------------------
320
+ /**
321
+ * Resolve the path to the daemon metadata file in the global state directory.
322
+ */
323
+ export function resolveDaemonMetaPath() {
324
+ return resolve(resolveGlobalStateDir(), 'daemon.meta.json');
325
+ }
326
+ /**
327
+ * Write daemon metadata alongside the PID file.
328
+ * Called during daemon startup to record the log file path and start time.
329
+ */
330
+ export function writeDaemonMeta(logPath) {
331
+ const metaPath = resolveDaemonMetaPath();
332
+ const meta = {
333
+ pid: process.pid,
334
+ logPath: logPath ?? resolveDaemonLogPath(),
335
+ startedAt: new Date().toISOString(),
336
+ };
337
+ ensureGlobalStateDir();
338
+ writeFileSync(metaPath, JSON.stringify(meta, null, 2) + '\n');
339
+ }
340
+ /**
341
+ * Read daemon metadata. Returns null if the file doesn't exist or is invalid.
342
+ */
343
+ export function readDaemonMeta() {
344
+ const metaPath = resolveDaemonMetaPath();
345
+ if (!existsSync(metaPath))
346
+ return null;
347
+ try {
348
+ const contents = readFileSync(metaPath, 'utf-8');
349
+ const meta = JSON.parse(contents);
350
+ if (typeof meta.pid !== 'number' || typeof meta.logPath !== 'string')
351
+ return null;
352
+ return meta;
353
+ }
354
+ catch {
355
+ return null;
356
+ }
357
+ }
358
+ /**
359
+ * Remove daemon metadata file. Called during shutdown alongside PID lock release.
360
+ */
361
+ export function removeDaemonMeta() {
362
+ const metaPath = resolveDaemonMetaPath();
363
+ try {
364
+ if (existsSync(metaPath)) {
365
+ unlinkSync(metaPath);
366
+ }
367
+ }
368
+ catch {
369
+ // Best-effort cleanup
370
+ }
371
+ }
372
+ // ---------------------------------------------------------------------------
373
+ // Log rotation
374
+ // ---------------------------------------------------------------------------
375
+ /**
376
+ * Rotate the canonical daemon log on startup.
377
+ *
378
+ * Renames the existing daemon.log to daemon.log.prev so each daemon run
379
+ * starts with a fresh log. Only one previous log is kept — this is enough
380
+ * for quick debugging without accumulating unbounded history.
381
+ */
382
+ export function rotateDaemonLog() {
383
+ const logPath = resolveDaemonLogPath();
384
+ if (!existsSync(logPath))
385
+ return;
386
+ const prevPath = logPath + '.prev';
387
+ try {
388
+ renameSync(logPath, prevPath);
389
+ }
390
+ catch {
391
+ // Log file may be in use or inaccessible — not fatal
392
+ }
393
+ }
394
+ // ---------------------------------------------------------------------------
395
+ // Canonical log tee (foreground mode)
396
+ // ---------------------------------------------------------------------------
397
+ /**
398
+ * Set up canonical log file output for foreground mode.
399
+ *
400
+ * When the daemon runs in the foreground, stdout/stderr go to the terminal.
401
+ * This function additionally pipes both streams to the canonical log file
402
+ * so that `telora-daemon logs` always has something to read, regardless
403
+ * of how the daemon was started.
404
+ *
405
+ * Returns a cleanup function that closes the log stream.
406
+ */
407
+ export function setupCanonicalLogTee() {
408
+ ensureGlobalStateDir();
409
+ const logPath = resolveDaemonLogPath();
410
+ const logStream = createWriteStream(logPath, { flags: 'a' });
411
+ const origStdoutWrite = process.stdout.write.bind(process.stdout);
412
+ const origStderrWrite = process.stderr.write.bind(process.stderr);
413
+ process.stdout.write = function (chunk, ...args) {
414
+ logStream.write(chunk);
415
+ return origStdoutWrite(chunk, ...args);
416
+ };
417
+ process.stderr.write = function (chunk, ...args) {
418
+ logStream.write(chunk);
419
+ return origStderrWrite(chunk, ...args);
420
+ };
421
+ return () => {
422
+ process.stdout.write = origStdoutWrite;
423
+ process.stderr.write = origStderrWrite;
424
+ logStream.end();
425
+ };
426
+ }
427
+ //# sourceMappingURL=daemon-process.js.map