@mindfoldhq/trellis 0.6.0-beta.2 → 0.6.0-beta.20

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 (330) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.d.ts +1 -1
  3. package/dist/cli/index.d.ts.map +1 -1
  4. package/dist/cli/index.js +58 -2
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/commands/channel/adapters/claude.d.ts +29 -0
  7. package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
  8. package/dist/commands/channel/adapters/claude.js +203 -0
  9. package/dist/commands/channel/adapters/claude.js.map +1 -0
  10. package/dist/commands/channel/adapters/codex.d.ts +85 -0
  11. package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
  12. package/dist/commands/channel/adapters/codex.js +505 -0
  13. package/dist/commands/channel/adapters/codex.js.map +1 -0
  14. package/dist/commands/channel/adapters/index.d.ts +84 -0
  15. package/dist/commands/channel/adapters/index.d.ts.map +1 -0
  16. package/dist/commands/channel/adapters/index.js +115 -0
  17. package/dist/commands/channel/adapters/index.js.map +1 -0
  18. package/dist/commands/channel/adapters/types.d.ts +33 -0
  19. package/dist/commands/channel/adapters/types.d.ts.map +1 -0
  20. package/dist/commands/channel/adapters/types.js +2 -0
  21. package/dist/commands/channel/adapters/types.js.map +1 -0
  22. package/dist/commands/channel/agent-loader.d.ts +32 -0
  23. package/dist/commands/channel/agent-loader.d.ts.map +1 -0
  24. package/dist/commands/channel/agent-loader.js +154 -0
  25. package/dist/commands/channel/agent-loader.js.map +1 -0
  26. package/dist/commands/channel/context-loader.d.ts +26 -0
  27. package/dist/commands/channel/context-loader.d.ts.map +1 -0
  28. package/dist/commands/channel/context-loader.js +290 -0
  29. package/dist/commands/channel/context-loader.js.map +1 -0
  30. package/dist/commands/channel/context.d.ts +16 -0
  31. package/dist/commands/channel/context.d.ts.map +1 -0
  32. package/dist/commands/channel/context.js +83 -0
  33. package/dist/commands/channel/context.js.map +1 -0
  34. package/dist/commands/channel/create.d.ts +27 -0
  35. package/dist/commands/channel/create.d.ts.map +1 -0
  36. package/dist/commands/channel/create.js +39 -0
  37. package/dist/commands/channel/create.js.map +1 -0
  38. package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
  39. package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
  40. package/dist/commands/channel/dev-parse-trace.js +70 -0
  41. package/dist/commands/channel/dev-parse-trace.js.map +1 -0
  42. package/dist/commands/channel/guard.d.ts +150 -0
  43. package/dist/commands/channel/guard.d.ts.map +1 -0
  44. package/dist/commands/channel/guard.js +474 -0
  45. package/dist/commands/channel/guard.js.map +1 -0
  46. package/dist/commands/channel/index.d.ts +3 -0
  47. package/dist/commands/channel/index.d.ts.map +1 -0
  48. package/dist/commands/channel/index.js +531 -0
  49. package/dist/commands/channel/index.js.map +1 -0
  50. package/dist/commands/channel/interrupt.d.ts +10 -0
  51. package/dist/commands/channel/interrupt.d.ts.map +1 -0
  52. package/dist/commands/channel/interrupt.js +22 -0
  53. package/dist/commands/channel/interrupt.js.map +1 -0
  54. package/dist/commands/channel/kill.d.ts +7 -0
  55. package/dist/commands/channel/kill.d.ts.map +1 -0
  56. package/dist/commands/channel/kill.js +121 -0
  57. package/dist/commands/channel/kill.js.map +1 -0
  58. package/dist/commands/channel/list.d.ts +17 -0
  59. package/dist/commands/channel/list.d.ts.map +1 -0
  60. package/dist/commands/channel/list.js +233 -0
  61. package/dist/commands/channel/list.js.map +1 -0
  62. package/dist/commands/channel/messages.d.ts +15 -0
  63. package/dist/commands/channel/messages.d.ts.map +1 -0
  64. package/dist/commands/channel/messages.js +245 -0
  65. package/dist/commands/channel/messages.js.map +1 -0
  66. package/dist/commands/channel/rm.d.ts +27 -0
  67. package/dist/commands/channel/rm.d.ts.map +1 -0
  68. package/dist/commands/channel/rm.js +216 -0
  69. package/dist/commands/channel/rm.js.map +1 -0
  70. package/dist/commands/channel/run.d.ts +30 -0
  71. package/dist/commands/channel/run.d.ts.map +1 -0
  72. package/dist/commands/channel/run.js +130 -0
  73. package/dist/commands/channel/run.js.map +1 -0
  74. package/dist/commands/channel/send.d.ts +11 -0
  75. package/dist/commands/channel/send.d.ts.map +1 -0
  76. package/dist/commands/channel/send.js +24 -0
  77. package/dist/commands/channel/send.js.map +1 -0
  78. package/dist/commands/channel/spawn.d.ts +40 -0
  79. package/dist/commands/channel/spawn.d.ts.map +1 -0
  80. package/dist/commands/channel/spawn.js +244 -0
  81. package/dist/commands/channel/spawn.js.map +1 -0
  82. package/dist/commands/channel/store/events.d.ts +39 -0
  83. package/dist/commands/channel/store/events.d.ts.map +1 -0
  84. package/dist/commands/channel/store/events.js +87 -0
  85. package/dist/commands/channel/store/events.js.map +1 -0
  86. package/dist/commands/channel/store/filter.d.ts +3 -0
  87. package/dist/commands/channel/store/filter.d.ts.map +1 -0
  88. package/dist/commands/channel/store/filter.js +2 -0
  89. package/dist/commands/channel/store/filter.js.map +1 -0
  90. package/dist/commands/channel/store/lock.d.ts +23 -0
  91. package/dist/commands/channel/store/lock.d.ts.map +1 -0
  92. package/dist/commands/channel/store/lock.js +99 -0
  93. package/dist/commands/channel/store/lock.js.map +1 -0
  94. package/dist/commands/channel/store/paths.d.ts +63 -0
  95. package/dist/commands/channel/store/paths.d.ts.map +1 -0
  96. package/dist/commands/channel/store/paths.js +246 -0
  97. package/dist/commands/channel/store/paths.js.map +1 -0
  98. package/dist/commands/channel/store/schema.d.ts +27 -0
  99. package/dist/commands/channel/store/schema.d.ts.map +1 -0
  100. package/dist/commands/channel/store/schema.js +34 -0
  101. package/dist/commands/channel/store/schema.js.map +1 -0
  102. package/dist/commands/channel/store/thread-state.d.ts +5 -0
  103. package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
  104. package/dist/commands/channel/store/thread-state.js +16 -0
  105. package/dist/commands/channel/store/thread-state.js.map +1 -0
  106. package/dist/commands/channel/store/watch.d.ts +19 -0
  107. package/dist/commands/channel/store/watch.d.ts.map +1 -0
  108. package/dist/commands/channel/store/watch.js +146 -0
  109. package/dist/commands/channel/store/watch.js.map +1 -0
  110. package/dist/commands/channel/supervisor/idle.d.ts +46 -0
  111. package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
  112. package/dist/commands/channel/supervisor/idle.js +72 -0
  113. package/dist/commands/channel/supervisor/idle.js.map +1 -0
  114. package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
  115. package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
  116. package/dist/commands/channel/supervisor/inbox.js +160 -0
  117. package/dist/commands/channel/supervisor/inbox.js.map +1 -0
  118. package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
  119. package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
  120. package/dist/commands/channel/supervisor/shutdown.js +146 -0
  121. package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
  122. package/dist/commands/channel/supervisor/stdout.d.ts +51 -0
  123. package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
  124. package/dist/commands/channel/supervisor/stdout.js +121 -0
  125. package/dist/commands/channel/supervisor/stdout.js.map +1 -0
  126. package/dist/commands/channel/supervisor/turns.d.ts +31 -0
  127. package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
  128. package/dist/commands/channel/supervisor/turns.js +45 -0
  129. package/dist/commands/channel/supervisor/turns.js.map +1 -0
  130. package/dist/commands/channel/supervisor/warning.d.ts +48 -0
  131. package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
  132. package/dist/commands/channel/supervisor/warning.js +77 -0
  133. package/dist/commands/channel/supervisor/warning.js.map +1 -0
  134. package/dist/commands/channel/supervisor.d.ts +59 -0
  135. package/dist/commands/channel/supervisor.d.ts.map +1 -0
  136. package/dist/commands/channel/supervisor.js +344 -0
  137. package/dist/commands/channel/supervisor.js.map +1 -0
  138. package/dist/commands/channel/text-body.d.ts +13 -0
  139. package/dist/commands/channel/text-body.d.ts.map +1 -0
  140. package/dist/commands/channel/text-body.js +47 -0
  141. package/dist/commands/channel/text-body.js.map +1 -0
  142. package/dist/commands/channel/threads.d.ts +39 -0
  143. package/dist/commands/channel/threads.d.ts.map +1 -0
  144. package/dist/commands/channel/threads.js +106 -0
  145. package/dist/commands/channel/threads.js.map +1 -0
  146. package/dist/commands/channel/title.d.ts +12 -0
  147. package/dist/commands/channel/title.d.ts.map +1 -0
  148. package/dist/commands/channel/title.js +24 -0
  149. package/dist/commands/channel/title.js.map +1 -0
  150. package/dist/commands/channel/wait.d.ts +17 -0
  151. package/dist/commands/channel/wait.d.ts.map +1 -0
  152. package/dist/commands/channel/wait.js +75 -0
  153. package/dist/commands/channel/wait.js.map +1 -0
  154. package/dist/commands/init.d.ts +2 -0
  155. package/dist/commands/init.d.ts.map +1 -1
  156. package/dist/commands/init.js +97 -42
  157. package/dist/commands/init.js.map +1 -1
  158. package/dist/commands/mem.d.ts +13 -117
  159. package/dist/commands/mem.d.ts.map +1 -1
  160. package/dist/commands/mem.js +168 -1074
  161. package/dist/commands/mem.js.map +1 -1
  162. package/dist/commands/uninstall.d.ts.map +1 -1
  163. package/dist/commands/uninstall.js +28 -2
  164. package/dist/commands/uninstall.js.map +1 -1
  165. package/dist/commands/update.d.ts.map +1 -1
  166. package/dist/commands/update.js +31 -111
  167. package/dist/commands/update.js.map +1 -1
  168. package/dist/commands/upgrade.d.ts +28 -0
  169. package/dist/commands/upgrade.d.ts.map +1 -0
  170. package/dist/commands/upgrade.js +84 -0
  171. package/dist/commands/upgrade.js.map +1 -0
  172. package/dist/commands/workflow.d.ts +35 -0
  173. package/dist/commands/workflow.d.ts.map +1 -0
  174. package/dist/commands/workflow.js +219 -0
  175. package/dist/commands/workflow.js.map +1 -0
  176. package/dist/configurators/claude.d.ts.map +1 -1
  177. package/dist/configurators/claude.js +1 -0
  178. package/dist/configurators/claude.js.map +1 -1
  179. package/dist/configurators/codex.d.ts.map +1 -1
  180. package/dist/configurators/codex.js +5 -3
  181. package/dist/configurators/codex.js.map +1 -1
  182. package/dist/configurators/shared.js +4 -4
  183. package/dist/configurators/shared.js.map +1 -1
  184. package/dist/configurators/workflow.d.ts +8 -0
  185. package/dist/configurators/workflow.d.ts.map +1 -1
  186. package/dist/configurators/workflow.js +3 -2
  187. package/dist/configurators/workflow.js.map +1 -1
  188. package/dist/migrations/manifests/0.5.10.json +9 -0
  189. package/dist/migrations/manifests/0.5.11.json +16 -0
  190. package/dist/migrations/manifests/0.5.12.json +9 -0
  191. package/dist/migrations/manifests/0.5.13.json +9 -0
  192. package/dist/migrations/manifests/0.5.14.json +9 -0
  193. package/dist/migrations/manifests/0.5.15.json +9 -0
  194. package/dist/migrations/manifests/0.5.16.json +9 -0
  195. package/dist/migrations/manifests/0.5.17.json +9 -0
  196. package/dist/migrations/manifests/0.5.18.json +9 -0
  197. package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
  198. package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
  199. package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
  200. package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
  201. package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
  202. package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
  203. package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
  204. package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
  205. package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
  206. package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
  207. package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
  208. package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
  209. package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
  210. package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
  211. package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
  212. package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
  213. package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
  214. package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
  215. package/dist/templates/claude/agents/trellis-check.md +13 -7
  216. package/dist/templates/claude/agents/trellis-implement.md +8 -7
  217. package/dist/templates/claude/settings.json +4 -4
  218. package/dist/templates/codebuddy/agents/trellis-check.md +13 -7
  219. package/dist/templates/codebuddy/agents/trellis-implement.md +8 -7
  220. package/dist/templates/codebuddy/settings.json +4 -4
  221. package/dist/templates/codex/agents/trellis-check.toml +4 -4
  222. package/dist/templates/codex/agents/trellis-implement.toml +4 -4
  223. package/dist/templates/codex/config.toml +5 -3
  224. package/dist/templates/codex/hooks/session-start.py +205 -119
  225. package/dist/templates/codex/hooks.json +2 -2
  226. package/dist/templates/codex/skills/before-dev/SKILL.md +12 -6
  227. package/dist/templates/codex/skills/brainstorm/SKILL.md +69 -457
  228. package/dist/templates/codex/skills/check/SKILL.md +86 -18
  229. package/dist/templates/codex/skills/start/SKILL.md +33 -323
  230. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +7 -4
  231. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +1 -1
  232. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +3 -2
  233. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +5 -5
  234. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +1 -1
  235. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +35 -6
  236. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +5 -4
  237. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/SKILL.md +41 -0
  238. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/mcp-setup.md +90 -0
  239. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/repository-analysis.md +59 -0
  240. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-task-planning.md +61 -0
  241. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-writing.md +70 -0
  242. package/dist/templates/common/commands/continue.md +6 -5
  243. package/dist/templates/common/commands/start.md +9 -6
  244. package/dist/templates/common/skills/before-dev.md +12 -6
  245. package/dist/templates/common/skills/brainstorm.md +68 -504
  246. package/dist/templates/common/skills/check.md +7 -1
  247. package/dist/templates/copilot/hooks/session-start.py +219 -101
  248. package/dist/templates/copilot/hooks.json +2 -2
  249. package/dist/templates/copilot/prompts/before-dev.prompt.md +12 -6
  250. package/dist/templates/copilot/prompts/brainstorm.prompt.md +69 -457
  251. package/dist/templates/copilot/prompts/check.prompt.md +86 -18
  252. package/dist/templates/copilot/prompts/parallel.prompt.md +16 -8
  253. package/dist/templates/copilot/prompts/start.prompt.md +33 -367
  254. package/dist/templates/cursor/agents/trellis-check.md +13 -7
  255. package/dist/templates/cursor/agents/trellis-implement.md +8 -7
  256. package/dist/templates/cursor/hooks.json +1 -7
  257. package/dist/templates/droid/droids/trellis-check.md +13 -7
  258. package/dist/templates/droid/droids/trellis-implement.md +8 -7
  259. package/dist/templates/droid/settings.json +4 -4
  260. package/dist/templates/gemini/agents/trellis-check.md +11 -5
  261. package/dist/templates/gemini/agents/trellis-implement.md +7 -6
  262. package/dist/templates/gemini/settings.json +2 -2
  263. package/dist/templates/kiro/agents/trellis-check.json +1 -1
  264. package/dist/templates/kiro/agents/trellis-implement.json +1 -1
  265. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +127 -9
  266. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +171 -6
  267. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +333 -43
  268. package/dist/templates/markdown/spec/guides/index.md.txt +18 -0
  269. package/dist/templates/opencode/agents/trellis-check.md +13 -7
  270. package/dist/templates/opencode/agents/trellis-implement.md +9 -8
  271. package/dist/templates/opencode/lib/session-utils.js +212 -123
  272. package/dist/templates/opencode/lib/trellis-context.js +73 -11
  273. package/dist/templates/opencode/plugins/inject-subagent-context.js +131 -29
  274. package/dist/templates/opencode/plugins/inject-workflow-state.js +9 -5
  275. package/dist/templates/opencode/plugins/session-start.js +9 -1
  276. package/dist/templates/pi/agents/trellis-check.md +5 -4
  277. package/dist/templates/pi/agents/trellis-implement.md +5 -4
  278. package/dist/templates/pi/extensions/trellis/index.ts.txt +1357 -754
  279. package/dist/templates/qoder/agents/trellis-check.md +11 -5
  280. package/dist/templates/qoder/agents/trellis-implement.md +7 -6
  281. package/dist/templates/qoder/settings.json +4 -4
  282. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  283. package/dist/templates/shared-hooks/index.js +0 -1
  284. package/dist/templates/shared-hooks/index.js.map +1 -1
  285. package/dist/templates/shared-hooks/inject-subagent-context.py +36 -14
  286. package/dist/templates/shared-hooks/inject-workflow-state.py +40 -42
  287. package/dist/templates/shared-hooks/session-start.py +222 -171
  288. package/dist/templates/trellis/config.yaml +38 -0
  289. package/dist/templates/trellis/index.d.ts +1 -0
  290. package/dist/templates/trellis/index.d.ts.map +1 -1
  291. package/dist/templates/trellis/index.js +2 -0
  292. package/dist/templates/trellis/index.js.map +1 -1
  293. package/dist/templates/trellis/scripts/add_session.py +50 -24
  294. package/dist/templates/trellis/scripts/common/config.py +57 -1
  295. package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
  296. package/dist/templates/trellis/scripts/common/session_context.py +384 -137
  297. package/dist/templates/trellis/scripts/common/task_context.py +3 -3
  298. package/dist/templates/trellis/scripts/common/task_store.py +161 -15
  299. package/dist/templates/trellis/scripts/common/workflow_phase.py +7 -10
  300. package/dist/templates/trellis/scripts/task.py +3 -3
  301. package/dist/templates/trellis/workflow.md +119 -98
  302. package/dist/utils/cwd-guard.d.ts +38 -0
  303. package/dist/utils/cwd-guard.d.ts.map +1 -0
  304. package/dist/utils/cwd-guard.js +62 -0
  305. package/dist/utils/cwd-guard.js.map +1 -0
  306. package/dist/utils/file-writer.d.ts +13 -0
  307. package/dist/utils/file-writer.d.ts.map +1 -1
  308. package/dist/utils/file-writer.js +59 -1
  309. package/dist/utils/file-writer.js.map +1 -1
  310. package/dist/utils/manifest-prune.d.ts +61 -0
  311. package/dist/utils/manifest-prune.d.ts.map +1 -0
  312. package/dist/utils/manifest-prune.js +136 -0
  313. package/dist/utils/manifest-prune.js.map +1 -0
  314. package/dist/utils/task-json.d.ts +9 -42
  315. package/dist/utils/task-json.d.ts.map +1 -1
  316. package/dist/utils/task-json.js +8 -45
  317. package/dist/utils/task-json.js.map +1 -1
  318. package/dist/utils/template-hash.d.ts +32 -6
  319. package/dist/utils/template-hash.d.ts.map +1 -1
  320. package/dist/utils/template-hash.js +53 -31
  321. package/dist/utils/template-hash.js.map +1 -1
  322. package/dist/utils/uninstall-scrubbers.d.ts +1 -0
  323. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  324. package/dist/utils/uninstall-scrubbers.js +21 -0
  325. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  326. package/dist/utils/workflow-resolver.d.ts +86 -0
  327. package/dist/utils/workflow-resolver.d.ts.map +1 -0
  328. package/dist/utils/workflow-resolver.js +265 -0
  329. package/dist/utils/workflow-resolver.js.map +1 -0
  330. package/package.json +9 -8
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Channel worker OOM guard policy.
3
+ *
4
+ * Resolves idle-cleanup TTL and live-worker budget from CLI flag /
5
+ * environment / project config / built-in defaults (in that precedence
6
+ * order), then scans the live worker registry inside a project bucket
7
+ * to enforce both constraints at spawn time.
8
+ *
9
+ * Boundary: this module lives in the CLI runtime layer. Core owns
10
+ * worker activity / `idleSince` projection; the supervisor owns process
11
+ * launch + signals. The guard only consumes that durable state and
12
+ * sends OS signals through pid files.
13
+ */
14
+ import { type WorkerState } from "@mindfoldhq/trellis-core/channel";
15
+ /** Built-in default idle-cleanup TTL for spawned workers (5 minutes). */
16
+ export declare const DEFAULT_IDLE_TTL_MS: number;
17
+ /** Built-in default live-worker budget per project/scope. */
18
+ export declare const DEFAULT_MAX_LIVE_WORKERS = 6;
19
+ /** Env var override for the idle-cleanup TTL. */
20
+ export declare const ENV_IDLE_TIMEOUT = "TRELLIS_CHANNEL_WORKER_IDLE_TIMEOUT";
21
+ /** Env var override for the live-worker budget. */
22
+ export declare const ENV_MAX_LIVE_WORKERS = "TRELLIS_CHANNEL_MAX_LIVE_WORKERS";
23
+ export interface WorkerGuardConfig {
24
+ /** Idle-cleanup TTL in ms. `0` disables idle cleanup for new spawns. */
25
+ idleTimeoutMs: number;
26
+ /** Live-worker budget. `0` disables the spawn-time budget check. */
27
+ maxLiveWorkers: number;
28
+ }
29
+ export interface ResolveGuardOptions {
30
+ /** CLI `--idle-timeout` value (already millisecond-parsed). */
31
+ flagIdleTimeoutMs?: number;
32
+ /** CLI `--max-live-workers` value. */
33
+ flagMaxLiveWorkers?: number;
34
+ /** Override cwd for config lookup (default `process.cwd()`). */
35
+ cwd?: string;
36
+ /** Override env source (default `process.env`). */
37
+ env?: NodeJS.ProcessEnv;
38
+ }
39
+ /**
40
+ * Resolve the effective guard policy. Precedence:
41
+ * 1. CLI flag (`flag*Ms` / `flagMaxLiveWorkers`)
42
+ * 2. environment variable
43
+ * 3. `.trellis/config.yaml` `channel.worker_guard`
44
+ * 4. built-in default constant
45
+ */
46
+ export declare function resolveWorkerGuardConfig(opts?: ResolveGuardOptions): WorkerGuardConfig;
47
+ interface ProjectGuardConfig {
48
+ idleTimeoutMs?: number;
49
+ maxLiveWorkers?: number;
50
+ }
51
+ /**
52
+ * Parse the `channel.worker_guard` section out of `.trellis/config.yaml`.
53
+ * Mirrors the lightweight line-scanner used elsewhere in update.ts so we
54
+ * don't pull in a YAML dependency just for this two-field section.
55
+ */
56
+ export declare function loadWorkerGuardConfig(cwd: string): ProjectGuardConfig | undefined;
57
+ /** Exposed for unit tests. */
58
+ export declare function parseWorkerGuardSection(content: string): ProjectGuardConfig | undefined;
59
+ /**
60
+ * Live worker observed inside the spawn-time guard scan.
61
+ */
62
+ export interface LiveWorker {
63
+ channel: string;
64
+ workerId: string;
65
+ state: WorkerState;
66
+ /** Supervisor pid that owns this worker, when readable + alive. */
67
+ supervisorPid?: number;
68
+ /** True when the OS command line still looks like this worker's supervisor. */
69
+ supervisorVerified?: boolean;
70
+ /** Worker child pid, when readable. */
71
+ workerPid?: number;
72
+ }
73
+ export interface ScanLiveWorkersOptions {
74
+ /** Project bucket key (default current). */
75
+ projectKey?: string;
76
+ /** Override channel root scan (default uses real channelRoot()). */
77
+ root?: string;
78
+ /** Override supervisor process verification (used by tests). */
79
+ isSupervisorProcess?: (pid: number, channel: string, worker: string) => boolean;
80
+ }
81
+ /**
82
+ * Enumerate live (non-terminal + supervisor-pid alive) workers across
83
+ * every channel in the given project bucket.
84
+ */
85
+ export declare function scanLiveWorkers(opts?: ScanLiveWorkersOptions): LiveWorker[];
86
+ export declare function isSupervisorProcess(pid: number, channel: string, worker: string): boolean;
87
+ /**
88
+ * Pure predicate: is this live worker eligible for idle-cleanup right
89
+ * now? Mid-turn workers and workers without `idleSince` (e.g. they
90
+ * never spawned cleanly) are never killed by the guard.
91
+ */
92
+ export declare function isIdleCleanupEligible(live: LiveWorker, idleTimeoutMs: number, now: number): boolean;
93
+ export interface CleanupResult {
94
+ killed: LiveWorker[];
95
+ failed: {
96
+ worker: LiveWorker;
97
+ error: string;
98
+ }[];
99
+ }
100
+ /**
101
+ * Kill workers whose idle TTL has expired. Writes a one-shot shutdown
102
+ * reason sidecar before signalling the supervisor so the supervisor's
103
+ * existing shutdown funnel emits the single terminal `killed` event.
104
+ *
105
+ * Returns the workers that were signalled. Failures are collected — a
106
+ * dead pid or read race is not fatal; the next scan re-evaluates.
107
+ */
108
+ export declare function cleanupExpiredIdleWorkers(candidates: LiveWorker[], idleTimeoutMs: number, opts?: {
109
+ project?: string;
110
+ now?: number;
111
+ }): Promise<CleanupResult>;
112
+ export interface EnforceBudgetInput {
113
+ /** Project bucket key (default current). */
114
+ projectKey?: string;
115
+ /** Override channel root scan path (used by tests). */
116
+ root?: string;
117
+ /** Effective guard policy. */
118
+ policy: WorkerGuardConfig;
119
+ /** Override `now` for deterministic tests. */
120
+ now?: number;
121
+ /** Override supervisor process verification (used by tests). */
122
+ isSupervisorProcess?: ScanLiveWorkersOptions["isSupervisorProcess"];
123
+ }
124
+ export interface EnforceBudgetResult {
125
+ /** Workers killed by expired-idle cleanup during this enforcement. */
126
+ cleaned: LiveWorker[];
127
+ /** Live workers remaining after cleanup. */
128
+ remaining: LiveWorker[];
129
+ /** True when a new spawn is allowed; false when budget is exceeded. */
130
+ allowed: boolean;
131
+ }
132
+ /**
133
+ * Run the spawn-time guard for a project bucket. Cleans expired idle
134
+ * workers, re-scans, then decides whether the live worker budget has
135
+ * room for one more spawn.
136
+ */
137
+ export declare function enforceSpawnBudget(input: EnforceBudgetInput): Promise<EnforceBudgetResult>;
138
+ /** Build a multi-line, actionable overflow error string. */
139
+ export declare function formatBudgetOverflowError(args: {
140
+ projectKey: string;
141
+ live: LiveWorker[];
142
+ limit: number;
143
+ }): string;
144
+ /**
145
+ * Convenience helper: ensure `channelRoot()` is initialised before scan
146
+ * (otherwise the project dir may not yet exist on first spawn).
147
+ */
148
+ export declare function ensureRootExists(): void;
149
+ export {};
150
+ //# sourceMappingURL=guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,474 @@
1
+ /**
2
+ * Channel worker OOM guard policy.
3
+ *
4
+ * Resolves idle-cleanup TTL and live-worker budget from CLI flag /
5
+ * environment / project config / built-in defaults (in that precedence
6
+ * order), then scans the live worker registry inside a project bucket
7
+ * to enforce both constraints at spawn time.
8
+ *
9
+ * Boundary: this module lives in the CLI runtime layer. Core owns
10
+ * worker activity / `idleSince` projection; the supervisor owns process
11
+ * launch + signals. The guard only consumes that durable state and
12
+ * sends OS signals through pid files.
13
+ */
14
+ import { execFileSync } from "node:child_process";
15
+ import fs from "node:fs";
16
+ import path from "node:path";
17
+ import { isTerminalLifecycle, reduceWorkerRegistry, } from "@mindfoldhq/trellis-core/channel";
18
+ import { DIR_NAMES } from "../../constants/paths.js";
19
+ import { channelRoot, currentProjectKey, projectDir, workerFile, } from "./store/paths.js";
20
+ import { parseDuration } from "./wait.js";
21
+ /** Built-in default idle-cleanup TTL for spawned workers (5 minutes). */
22
+ export const DEFAULT_IDLE_TTL_MS = 5 * 60 * 1000;
23
+ /** Built-in default live-worker budget per project/scope. */
24
+ export const DEFAULT_MAX_LIVE_WORKERS = 6;
25
+ /** Env var override for the idle-cleanup TTL. */
26
+ export const ENV_IDLE_TIMEOUT = "TRELLIS_CHANNEL_WORKER_IDLE_TIMEOUT";
27
+ /** Env var override for the live-worker budget. */
28
+ export const ENV_MAX_LIVE_WORKERS = "TRELLIS_CHANNEL_MAX_LIVE_WORKERS";
29
+ /**
30
+ * Resolve the effective guard policy. Precedence:
31
+ * 1. CLI flag (`flag*Ms` / `flagMaxLiveWorkers`)
32
+ * 2. environment variable
33
+ * 3. `.trellis/config.yaml` `channel.worker_guard`
34
+ * 4. built-in default constant
35
+ */
36
+ export function resolveWorkerGuardConfig(opts = {}) {
37
+ const cwd = opts.cwd ?? process.cwd();
38
+ const env = opts.env ?? process.env;
39
+ const fromConfig = loadWorkerGuardConfig(cwd);
40
+ const idleTimeoutMs = pickNonNegativeMs(opts.flagIdleTimeoutMs, parseEnvDuration(env[ENV_IDLE_TIMEOUT], ENV_IDLE_TIMEOUT), fromConfig?.idleTimeoutMs, DEFAULT_IDLE_TTL_MS);
41
+ const maxLiveWorkers = pickNonNegativeInt(opts.flagMaxLiveWorkers, parseEnvInt(env[ENV_MAX_LIVE_WORKERS], ENV_MAX_LIVE_WORKERS), fromConfig?.maxLiveWorkers, DEFAULT_MAX_LIVE_WORKERS);
42
+ return { idleTimeoutMs, maxLiveWorkers };
43
+ }
44
+ function pickNonNegativeMs(...candidates) {
45
+ for (const c of candidates) {
46
+ if (c === undefined)
47
+ continue;
48
+ if (!Number.isFinite(c) || c < 0) {
49
+ throw new Error(`Idle timeout must be a non-negative duration (got ${c})`);
50
+ }
51
+ return c;
52
+ }
53
+ return DEFAULT_IDLE_TTL_MS;
54
+ }
55
+ function pickNonNegativeInt(...candidates) {
56
+ for (const c of candidates) {
57
+ if (c === undefined)
58
+ continue;
59
+ if (!Number.isInteger(c) || c < 0) {
60
+ throw new Error(`Max live workers must be a non-negative integer (got ${c})`);
61
+ }
62
+ return c;
63
+ }
64
+ return DEFAULT_MAX_LIVE_WORKERS;
65
+ }
66
+ function parseEnvDuration(raw, envName) {
67
+ if (raw === undefined || raw === "")
68
+ return undefined;
69
+ try {
70
+ return parseDuration(raw);
71
+ }
72
+ catch (err) {
73
+ throw new Error(`${envName}: ${err instanceof Error ? err.message : String(err)}`);
74
+ }
75
+ }
76
+ function parseEnvInt(raw, envName) {
77
+ if (raw === undefined || raw === "")
78
+ return undefined;
79
+ const n = Number(raw);
80
+ if (!Number.isInteger(n) || n < 0) {
81
+ throw new Error(`${envName} must be a non-negative integer (got '${raw}')`);
82
+ }
83
+ return n;
84
+ }
85
+ /**
86
+ * Parse the `channel.worker_guard` section out of `.trellis/config.yaml`.
87
+ * Mirrors the lightweight line-scanner used elsewhere in update.ts so we
88
+ * don't pull in a YAML dependency just for this two-field section.
89
+ */
90
+ export function loadWorkerGuardConfig(cwd) {
91
+ const configPath = path.join(cwd, DIR_NAMES.WORKFLOW, "config.yaml");
92
+ if (!fs.existsSync(configPath))
93
+ return undefined;
94
+ let content;
95
+ try {
96
+ content = fs.readFileSync(configPath, "utf-8");
97
+ }
98
+ catch {
99
+ return undefined;
100
+ }
101
+ return parseWorkerGuardSection(content);
102
+ }
103
+ /** Exposed for unit tests. */
104
+ export function parseWorkerGuardSection(content) {
105
+ const lines = content.split("\n");
106
+ let inChannel = false;
107
+ let inGuard = false;
108
+ const found = {};
109
+ let any = false;
110
+ for (const raw of lines) {
111
+ const line = raw.replace(/\r$/, "");
112
+ const trimmed = line.trimEnd();
113
+ if (trimmed === "" || trimmed.trimStart().startsWith("#"))
114
+ continue;
115
+ if (/^channel:\s*$/.test(trimmed)) {
116
+ inChannel = true;
117
+ inGuard = false;
118
+ continue;
119
+ }
120
+ if (inChannel && /^ {2}worker_guard:\s*$/.test(trimmed)) {
121
+ inGuard = true;
122
+ continue;
123
+ }
124
+ if (inGuard) {
125
+ const idle = trimmed.match(/^ {4}idle_timeout:\s*(.+)$/);
126
+ if (idle) {
127
+ const val = stripValue(idle[1]);
128
+ found.idleTimeoutMs = parseGuardDuration(val, "idle_timeout");
129
+ any = true;
130
+ continue;
131
+ }
132
+ const max = trimmed.match(/^ {4}max_live_workers:\s*(.+)$/);
133
+ if (max) {
134
+ const val = stripValue(max[1]);
135
+ const n = Number(val);
136
+ if (!Number.isInteger(n) || n < 0) {
137
+ throw new Error(`channel.worker_guard.max_live_workers must be a non-negative integer (got '${val}')`);
138
+ }
139
+ found.maxLiveWorkers = n;
140
+ any = true;
141
+ continue;
142
+ }
143
+ // Anything else at the same indent (or shallower) ends the section.
144
+ if (!/^ {4}\S/.test(line)) {
145
+ inGuard = false;
146
+ }
147
+ }
148
+ if (inChannel && !/^ {2}\S/.test(line) && /^\S/.test(line)) {
149
+ inChannel = false;
150
+ inGuard = false;
151
+ }
152
+ }
153
+ return any ? found : undefined;
154
+ }
155
+ function stripValue(s) {
156
+ return s
157
+ .trim()
158
+ .replace(/\s*#.*$/, "")
159
+ .trim()
160
+ .replace(/^['"]|['"]$/g, "");
161
+ }
162
+ function parseGuardDuration(raw, key) {
163
+ // Allow bare integer = milliseconds (so `0` disables cleanly).
164
+ const asInt = Number(raw);
165
+ if (Number.isFinite(asInt) && /^\d+$/.test(raw)) {
166
+ if (asInt < 0) {
167
+ throw new Error(`channel.worker_guard.${key} must be non-negative (got '${raw}')`);
168
+ }
169
+ // Bare integer 0 = disabled; >0 with no unit = milliseconds.
170
+ return asInt;
171
+ }
172
+ try {
173
+ return parseDuration(raw) ?? 0;
174
+ }
175
+ catch (err) {
176
+ throw new Error(`channel.worker_guard.${key}: ${err instanceof Error ? err.message : String(err)}`);
177
+ }
178
+ }
179
+ /**
180
+ * Enumerate live (non-terminal + supervisor-pid alive) workers across
181
+ * every channel in the given project bucket.
182
+ */
183
+ export function scanLiveWorkers(opts = {}) {
184
+ const project = opts.projectKey ?? currentProjectKey();
185
+ const bucket = opts.root
186
+ ? path.join(opts.root, project)
187
+ : projectDir(project);
188
+ if (!fs.existsSync(bucket))
189
+ return [];
190
+ let entries;
191
+ try {
192
+ entries = fs.readdirSync(bucket);
193
+ }
194
+ catch {
195
+ return [];
196
+ }
197
+ const out = [];
198
+ for (const entry of entries) {
199
+ if (entry.startsWith("."))
200
+ continue;
201
+ const dir = path.join(bucket, entry);
202
+ try {
203
+ if (!fs.statSync(dir).isDirectory())
204
+ continue;
205
+ }
206
+ catch {
207
+ continue;
208
+ }
209
+ const events = path.join(dir, "events.jsonl");
210
+ if (!fs.existsSync(events))
211
+ continue;
212
+ let workers;
213
+ try {
214
+ const all = readFileEventsSync(events);
215
+ workers = reduceWorkerRegistry(all).workers;
216
+ }
217
+ catch {
218
+ continue;
219
+ }
220
+ for (const state of workers) {
221
+ if (state.terminal || isTerminalLifecycle(state.lifecycle))
222
+ continue;
223
+ const supervisorPid = readPid(workerFile(entry, state.workerId, "pid", project));
224
+ if (supervisorPid === undefined || !pidAlive(supervisorPid)) {
225
+ // Supervisor pid file missing or dead → not a live OS process,
226
+ // even if durable state still shows running. Reconciler / future
227
+ // CLI cleanup will catch up; the guard ignores it.
228
+ continue;
229
+ }
230
+ const supervisorVerified = opts.isSupervisorProcess
231
+ ? opts.isSupervisorProcess(supervisorPid, entry, state.workerId)
232
+ : isSupervisorProcess(supervisorPid, entry, state.workerId);
233
+ const workerPid = readPid(workerFile(entry, state.workerId, "worker-pid", project));
234
+ out.push({
235
+ channel: entry,
236
+ workerId: state.workerId,
237
+ state,
238
+ supervisorPid,
239
+ supervisorVerified,
240
+ ...(workerPid !== undefined ? { workerPid } : {}),
241
+ });
242
+ }
243
+ for (const state of readReservationWorkers(entry, project)) {
244
+ if (out.some((w) => w.channel === entry && w.workerId === state.workerId)) {
245
+ continue;
246
+ }
247
+ const supervisorPid = readPid(workerFile(entry, state.workerId, "pid", project));
248
+ if (supervisorPid === undefined || !pidAlive(supervisorPid))
249
+ continue;
250
+ const supervisorVerified = opts.isSupervisorProcess
251
+ ? opts.isSupervisorProcess(supervisorPid, entry, state.workerId)
252
+ : isSupervisorProcess(supervisorPid, entry, state.workerId);
253
+ out.push({
254
+ channel: entry,
255
+ workerId: state.workerId,
256
+ state,
257
+ supervisorPid,
258
+ supervisorVerified,
259
+ });
260
+ }
261
+ }
262
+ return out;
263
+ }
264
+ function readReservationWorkers(channel, project) {
265
+ const dir = path.join(projectDir(project), channel);
266
+ let files;
267
+ try {
268
+ files = fs.readdirSync(dir);
269
+ }
270
+ catch {
271
+ return [];
272
+ }
273
+ const workers = [];
274
+ for (const file of files) {
275
+ if (!file.endsWith(".reservation"))
276
+ continue;
277
+ const worker = file.slice(0, -".reservation".length);
278
+ workers.push({
279
+ workerId: worker,
280
+ lifecycle: "starting",
281
+ terminal: false,
282
+ activity: "idle",
283
+ pendingMessageCount: 0,
284
+ inboxPolicy: "explicitOnly",
285
+ updatedAt: new Date(0).toISOString(),
286
+ lastSeq: 0,
287
+ });
288
+ }
289
+ return workers;
290
+ }
291
+ function readFileEventsSync(file) {
292
+ const text = fs.readFileSync(file, "utf-8");
293
+ const events = [];
294
+ for (const line of text.split("\n")) {
295
+ if (!line.trim())
296
+ continue;
297
+ try {
298
+ events.push(JSON.parse(line));
299
+ }
300
+ catch {
301
+ continue;
302
+ }
303
+ }
304
+ return events;
305
+ }
306
+ function readPid(p) {
307
+ try {
308
+ const n = Number(fs.readFileSync(p, "utf-8").trim());
309
+ return Number.isFinite(n) && n > 0 ? n : undefined;
310
+ }
311
+ catch {
312
+ return undefined;
313
+ }
314
+ }
315
+ function pidAlive(pid) {
316
+ try {
317
+ process.kill(pid, 0);
318
+ return true;
319
+ }
320
+ catch {
321
+ return false;
322
+ }
323
+ }
324
+ export function isSupervisorProcess(pid, channel, worker) {
325
+ if (process.platform === "win32")
326
+ return false;
327
+ try {
328
+ const command = execFileSync("ps", ["-p", String(pid), "-o", "command="], {
329
+ encoding: "utf-8",
330
+ timeout: 1000,
331
+ stdio: ["ignore", "pipe", "ignore"],
332
+ }).trim();
333
+ const pattern = new RegExp([
334
+ "(?:^|\\s)channel\\s+__supervisor\\s+",
335
+ escapeRegExp(channel),
336
+ "\\s+",
337
+ escapeRegExp(worker),
338
+ "(?:\\s|$)",
339
+ ].join(""));
340
+ return pattern.test(command);
341
+ }
342
+ catch {
343
+ return false;
344
+ }
345
+ }
346
+ function escapeRegExp(s) {
347
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
348
+ }
349
+ /**
350
+ * Pure predicate: is this live worker eligible for idle-cleanup right
351
+ * now? Mid-turn workers and workers without `idleSince` (e.g. they
352
+ * never spawned cleanly) are never killed by the guard.
353
+ */
354
+ export function isIdleCleanupEligible(live, idleTimeoutMs, now) {
355
+ if (idleTimeoutMs <= 0)
356
+ return false;
357
+ const { state } = live;
358
+ if (state.activity !== "idle")
359
+ return false;
360
+ if (!state.idleSince)
361
+ return false;
362
+ if (state.terminal)
363
+ return false;
364
+ const idleSinceMs = Date.parse(state.idleSince);
365
+ if (!Number.isFinite(idleSinceMs))
366
+ return false;
367
+ return now - idleSinceMs >= idleTimeoutMs;
368
+ }
369
+ /**
370
+ * Kill workers whose idle TTL has expired. Writes a one-shot shutdown
371
+ * reason sidecar before signalling the supervisor so the supervisor's
372
+ * existing shutdown funnel emits the single terminal `killed` event.
373
+ *
374
+ * Returns the workers that were signalled. Failures are collected — a
375
+ * dead pid or read race is not fatal; the next scan re-evaluates.
376
+ */
377
+ export async function cleanupExpiredIdleWorkers(candidates, idleTimeoutMs, opts = {}) {
378
+ const result = { killed: [], failed: [] };
379
+ if (idleTimeoutMs <= 0)
380
+ return result;
381
+ const now = opts.now ?? Date.now();
382
+ for (const live of candidates) {
383
+ if (!isIdleCleanupEligible(live, idleTimeoutMs, now))
384
+ continue;
385
+ try {
386
+ const project = opts.project ?? currentProjectKey();
387
+ if (live.supervisorPid === undefined ||
388
+ live.supervisorVerified !== true ||
389
+ !pidAlive(live.supervisorPid)) {
390
+ continue;
391
+ }
392
+ const reasonFile = workerFile(live.channel, live.workerId, "shutdown-reason", project);
393
+ fs.writeFileSync(reasonFile, "idle-timeout\n", "utf-8");
394
+ try {
395
+ process.kill(live.supervisorPid, "SIGTERM");
396
+ }
397
+ catch (err) {
398
+ try {
399
+ fs.unlinkSync(reasonFile);
400
+ }
401
+ catch {
402
+ // already gone
403
+ }
404
+ throw err;
405
+ }
406
+ result.killed.push(live);
407
+ }
408
+ catch (err) {
409
+ result.failed.push({
410
+ worker: live,
411
+ error: err instanceof Error ? err.message : String(err),
412
+ });
413
+ }
414
+ }
415
+ return result;
416
+ }
417
+ /**
418
+ * Run the spawn-time guard for a project bucket. Cleans expired idle
419
+ * workers, re-scans, then decides whether the live worker budget has
420
+ * room for one more spawn.
421
+ */
422
+ export async function enforceSpawnBudget(input) {
423
+ const project = input.projectKey ?? currentProjectKey();
424
+ const scanOpts = {
425
+ projectKey: project,
426
+ ...(input.root !== undefined ? { root: input.root } : {}),
427
+ ...(input.isSupervisorProcess !== undefined
428
+ ? { isSupervisorProcess: input.isSupervisorProcess }
429
+ : {}),
430
+ };
431
+ const initial = scanLiveWorkers(scanOpts);
432
+ const cleanup = await cleanupExpiredIdleWorkers(initial, input.policy.idleTimeoutMs, { project, ...(input.now !== undefined ? { now: input.now } : {}) });
433
+ // Re-probe after cleanup so we don't double-count workers that have
434
+ // been signalled but haven't actually torn down their pid files yet.
435
+ // Wait briefly for the SIGTERM to translate into pid-file removal; if
436
+ // a worker is taking its grace period, just exclude killed workers
437
+ // from the count.
438
+ const killedIds = new Set(cleanup.killed.map((w) => `${w.channel}::${w.workerId}`));
439
+ const remaining = scanLiveWorkers(scanOpts).filter((w) => !killedIds.has(`${w.channel}::${w.workerId}`));
440
+ const allowed = input.policy.maxLiveWorkers <= 0 ||
441
+ remaining.length < input.policy.maxLiveWorkers;
442
+ return { cleaned: cleanup.killed, remaining, allowed };
443
+ }
444
+ /** Build a multi-line, actionable overflow error string. */
445
+ export function formatBudgetOverflowError(args) {
446
+ const { projectKey, live, limit } = args;
447
+ const header = `Live worker budget exhausted for project '${projectKey}': ${live.length}/${limit} live worker(s).`;
448
+ const rows = live
449
+ .map((w) => {
450
+ const provider = w.state.provider ?? "?";
451
+ const lifecycle = w.state.lifecycle;
452
+ const activity = w.state.activity;
453
+ const pid = w.supervisorPid ?? "?";
454
+ const verified = w.supervisorVerified === false ? " supervisor=unverified" : "";
455
+ return ` • channel='${w.channel}' worker='${w.workerId}' provider=${provider} lifecycle=${lifecycle} activity=${activity} pid=${pid}${verified}`;
456
+ })
457
+ .join("\n");
458
+ const hint = [
459
+ "Free a slot before spawning, e.g.:",
460
+ ` trellis channel kill <channel> --as <worker>`,
461
+ "Or override per spawn:",
462
+ ` trellis channel spawn ... --max-live-workers ${live.length + 1}`,
463
+ "Or raise the default in .trellis/config.yaml under channel.worker_guard.max_live_workers.",
464
+ ].join("\n");
465
+ return [header, rows, hint].join("\n");
466
+ }
467
+ /**
468
+ * Convenience helper: ensure `channelRoot()` is initialised before scan
469
+ * (otherwise the project dir may not yet exist on first spawn).
470
+ */
471
+ export function ensureRootExists() {
472
+ fs.mkdirSync(channelRoot(), { recursive: true });
473
+ }
474
+ //# sourceMappingURL=guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../src/commands/channel/guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type Command } from "commander";
2
+ export declare function registerChannelCommand(program: Command): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAuC/D,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAo4B7D"}