@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,121 @@
1
+ import fs from "node:fs";
2
+ import { appendEvent } from "./store/events.js";
3
+ import { withLock } from "./store/lock.js";
4
+ import { resolveExistingChannelRef, workerFile, workerLockPath, } from "./store/paths.js";
5
+ import { parseChannelScope } from "./store/schema.js";
6
+ const POLL_INTERVAL_MS = 100;
7
+ const KILL_GRACE_MS = 8000; // generous: supervisor's own grace is ~6s
8
+ export async function channelKill(channelName, opts) {
9
+ const ref = resolveExistingChannelRef(channelName, {
10
+ scope: parseChannelScope(opts.scope),
11
+ });
12
+ // Take the worker lock so kill ↔ spawn can't race: spawn won't claim a
13
+ // stale pid file while we're tearing it down; we won't try to kill a
14
+ // worker whose pid file is mid-creation.
15
+ return withLock(workerLockPath(channelName, opts.as, ref.project), () => killLocked(channelName, opts, ref.project), { maxWaitMs: KILL_GRACE_MS + 2000 });
16
+ }
17
+ async function killLocked(channelName, opts, project) {
18
+ const pidPath = workerFile(channelName, opts.as, "pid", project);
19
+ if (!fs.existsSync(pidPath)) {
20
+ throw new Error(`Worker '${opts.as}' not running in channel '${channelName}'`);
21
+ }
22
+ const supervisorPid = Number(fs.readFileSync(pidPath, "utf-8").trim());
23
+ if (!supervisorPid || !alive(supervisorPid)) {
24
+ await appendEvent(channelName, {
25
+ kind: "error",
26
+ by: `cli:kill`,
27
+ message: `supervisor lost (pid ${supervisorPid})`,
28
+ worker: opts.as,
29
+ }, project);
30
+ cleanupFiles(channelName, opts.as, project);
31
+ return;
32
+ }
33
+ if (opts.force) {
34
+ // Also kill the inner worker so it doesn't become an orphan.
35
+ const workerPidPath = workerFile(channelName, opts.as, "worker-pid", project);
36
+ if (fs.existsSync(workerPidPath)) {
37
+ const wpid = Number(fs.readFileSync(workerPidPath, "utf-8").trim());
38
+ if (wpid && alive(wpid)) {
39
+ try {
40
+ process.kill(wpid, "SIGKILL");
41
+ }
42
+ catch {
43
+ // already dead
44
+ }
45
+ }
46
+ }
47
+ try {
48
+ process.kill(supervisorPid, "SIGKILL");
49
+ }
50
+ catch {
51
+ // already dead
52
+ }
53
+ // SIGKILL skips supervisor's onShutdown handler, so the `killed`
54
+ // event would never make it into events.jsonl. Write it from here
55
+ // so forensic readers see the kill happened.
56
+ await appendEvent(channelName, {
57
+ kind: "killed",
58
+ by: "cli:kill",
59
+ worker: opts.as,
60
+ reason: "explicit-kill",
61
+ signal: "SIGKILL",
62
+ }, project);
63
+ }
64
+ else {
65
+ try {
66
+ process.kill(supervisorPid, "SIGTERM");
67
+ }
68
+ catch {
69
+ // already dead
70
+ }
71
+ }
72
+ // Wait for supervisor to actually exit
73
+ const deadline = Date.now() + KILL_GRACE_MS;
74
+ while (alive(supervisorPid) && Date.now() < deadline) {
75
+ await sleep(POLL_INTERVAL_MS);
76
+ }
77
+ if (alive(supervisorPid)) {
78
+ // Grace expired — force kill. Supervisor's onShutdown handler never
79
+ // got to fire (or it deadlocked), so we write the `killed` event from
80
+ // the CLI side to keep the channel log truthful.
81
+ try {
82
+ process.kill(supervisorPid, "SIGKILL");
83
+ }
84
+ catch {
85
+ // already dead
86
+ }
87
+ await appendEvent(channelName, {
88
+ kind: "killed",
89
+ by: "cli:kill",
90
+ worker: opts.as,
91
+ reason: "explicit-kill",
92
+ signal: "SIGKILL",
93
+ detail: "grace expired, supervisor SIGKILL'd by CLI",
94
+ }, project);
95
+ }
96
+ cleanupFiles(channelName, opts.as, project);
97
+ }
98
+ function alive(pid) {
99
+ try {
100
+ process.kill(pid, 0);
101
+ return true;
102
+ }
103
+ catch {
104
+ return false;
105
+ }
106
+ }
107
+ function cleanupFiles(channelName, worker, project) {
108
+ // Keep `log` (forensic), `session-id` / `thread-id` (resume).
109
+ for (const suffix of ["pid", "worker-pid", "config", "spawnlock"]) {
110
+ try {
111
+ fs.unlinkSync(workerFile(channelName, worker, suffix, project));
112
+ }
113
+ catch {
114
+ // already gone
115
+ }
116
+ }
117
+ }
118
+ function sleep(ms) {
119
+ return new Promise((r) => setTimeout(r, ms));
120
+ }
121
+ //# sourceMappingURL=kill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kill.js","sourceRoot":"","sources":["../../../src/commands/channel/kill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EACL,yBAAyB,EACzB,UAAU,EACV,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAQtD,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,CAAC,0CAA0C;AAEtE,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,WAAmB,EACnB,IAAiB;IAEjB,MAAM,GAAG,GAAG,yBAAyB,CAAC,WAAW,EAAE;QACjD,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;KACrC,CAAC,CAAC;IACH,uEAAuE;IACvE,qEAAqE;IACrE,yCAAyC;IACzC,OAAO,QAAQ,CACb,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,EACjD,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,EAChD,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI,EAAE,CACpC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,WAAmB,EACnB,IAAiB,EACjB,OAAe;IAEf,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACjE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,WAAW,IAAI,CAAC,EAAE,6BAA6B,WAAW,GAAG,CAC9D,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvE,IAAI,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;QAC5C,MAAM,WAAW,CACf,WAAW,EACX;YACE,IAAI,EAAE,OAAO;YACb,EAAE,EAAE,UAAU;YACd,OAAO,EAAE,wBAAwB,aAAa,GAAG;YACjD,MAAM,EAAE,IAAI,CAAC,EAAE;SAChB,EACD,OAAO,CACR,CAAC;QACF,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,6DAA6D;QAC7D,MAAM,aAAa,GAAG,UAAU,CAC9B,WAAW,EACX,IAAI,CAAC,EAAE,EACP,YAAY,EACZ,OAAO,CACR,CAAC;QACF,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACpE,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAChC,CAAC;gBAAC,MAAM,CAAC;oBACP,eAAe;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;QACD,iEAAiE;QACjE,kEAAkE;QAClE,6CAA6C;QAC7C,MAAM,WAAW,CACf,WAAW,EACX;YACE,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,UAAU;YACd,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,MAAM,EAAE,eAAe;YACvB,MAAM,EAAE,SAAS;SAClB,EACD,OAAO,CACR,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC;IAC5C,OAAO,KAAK,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QACrD,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;QACzB,oEAAoE;QACpE,sEAAsE;QACtE,iDAAiD;QACjD,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;QACD,MAAM,WAAW,CACf,WAAW,EACX;YACE,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,UAAU;YACd,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,MAAM,EAAE,eAAe;YACvB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,4CAA4C;SACrD,EACD,OAAO,CACR,CAAC;IACJ,CAAC;IAED,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,KAAK,CAAC,GAAW;IACxB,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CACnB,WAAmB,EACnB,MAAc,EACd,OAAe;IAEf,8DAA8D;IAC9D,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAClE,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `trellis channel list` — table summary of all channels in `~/.trellis/channels/`.
3
+ *
4
+ * Columns: name, created (ts), workers (alive/total), last activity, task.
5
+ * Sorted by most recent activity first.
6
+ */
7
+ export interface ListOptions {
8
+ json?: boolean;
9
+ project?: string;
10
+ /** Include ephemeral channels in the output (default: hide them). */
11
+ all?: boolean;
12
+ /** Scan every project bucket, not just the current cwd's. */
13
+ allProjects?: boolean;
14
+ scope?: string;
15
+ }
16
+ export declare function channelList(opts?: ListOptions): Promise<void>;
17
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/list.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuCH,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,WAAW,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8EvE"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * `trellis channel list` — table summary of all channels in `~/.trellis/channels/`.
3
+ *
4
+ * Columns: name, created (ts), workers (alive/total), last activity, task.
5
+ * Sorted by most recent activity first.
6
+ */
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import chalk from "chalk";
10
+ import { isCreateEvent, reduceChannelMetadata, } from "./store/events.js";
11
+ import { channelDir, currentProjectKey, listProjects, migrateLegacyChannels, projectDir, } from "./store/paths.js";
12
+ import { GLOBAL_PROJECT_KEY, parseChannelScope } from "./store/schema.js";
13
+ export async function channelList(opts = {}) {
14
+ // Move any pre-bucket flat channels into `_legacy/` before listing,
15
+ // so the new layout is the authoritative view.
16
+ migrateLegacyChannels();
17
+ const scope = parseChannelScope(opts.scope);
18
+ const projects = scope === "global"
19
+ ? [GLOBAL_PROJECT_KEY]
20
+ : opts.allProjects
21
+ ? listProjects()
22
+ : [currentProjectKey()];
23
+ const summaries = [];
24
+ for (const project of projects) {
25
+ const dir = projectDir(project);
26
+ if (!fs.existsSync(dir))
27
+ continue;
28
+ let names;
29
+ try {
30
+ names = fs.readdirSync(dir).filter((n) => {
31
+ if (n.startsWith("."))
32
+ return false; // skip .bucket marker etc.
33
+ try {
34
+ return fs.statSync(path.join(dir, n)).isDirectory();
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ });
40
+ }
41
+ catch {
42
+ continue;
43
+ }
44
+ for (const name of names) {
45
+ const s = summarize(name, project);
46
+ if (s)
47
+ summaries.push(s);
48
+ }
49
+ }
50
+ // Filter by project (matches task substring for now)
51
+ const projectFilter = opts.project;
52
+ let filtered = projectFilter
53
+ ? summaries.filter((s) => s.task?.includes(projectFilter))
54
+ : summaries;
55
+ // Hide ephemeral channels unless --all (keeps the default `list`
56
+ // uncluttered after lots of one-shot CR / brainstorm sessions).
57
+ const ephemeralHidden = opts.all
58
+ ? 0
59
+ : filtered.filter((s) => s.ephemeral).length;
60
+ if (!opts.all) {
61
+ filtered = filtered.filter((s) => !s.ephemeral);
62
+ }
63
+ // Sort by last activity desc; channels without activity bubble to bottom
64
+ filtered.sort((a, b) => {
65
+ const ta = a.lastEventTs ?? "";
66
+ const tb = b.lastEventTs ?? "";
67
+ return tb.localeCompare(ta);
68
+ });
69
+ if (opts.json) {
70
+ console.log(JSON.stringify(filtered, null, 2));
71
+ return;
72
+ }
73
+ if (filtered.length === 0) {
74
+ console.log("(no channels match)");
75
+ if (ephemeralHidden > 0) {
76
+ console.log(`(${ephemeralHidden} ephemeral channel${ephemeralHidden === 1 ? "" : "s"} hidden — use --all to show)`);
77
+ }
78
+ return;
79
+ }
80
+ printTable(filtered);
81
+ if (ephemeralHidden > 0) {
82
+ console.log(`\n(${ephemeralHidden} ephemeral channel${ephemeralHidden === 1 ? "" : "s"} hidden — use --all to show)`);
83
+ }
84
+ }
85
+ function summarize(name, project) {
86
+ const dir = channelDir(name, project);
87
+ const eventsFile = path.join(dir, "events.jsonl");
88
+ if (!fs.existsSync(eventsFile))
89
+ return null;
90
+ // Read events to find: createdAt + task, last event ts/kind, total
91
+ // count. Channels stay small (no auto-rotation; ~few MB at worst), so
92
+ // a single full readFile per `list` invocation is fine.
93
+ let firstEvent = null;
94
+ let lastEvent = null;
95
+ let totalEvents = 0;
96
+ const events = [];
97
+ try {
98
+ const allText = fs.readFileSync(eventsFile, "utf-8");
99
+ const lines = allText.split("\n").filter((l) => l.trim());
100
+ totalEvents = lines.length;
101
+ for (const line of lines) {
102
+ try {
103
+ events.push(JSON.parse(line));
104
+ }
105
+ catch {
106
+ // skip corrupted lines
107
+ }
108
+ }
109
+ if (events.length > 0) {
110
+ const first = events[0];
111
+ firstEvent = isCreateEvent(first) ? first : null;
112
+ lastEvent = events[events.length - 1];
113
+ }
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ // Worker counts: scan *.pid files in dir, probe each pid.
119
+ let workersAlive = 0;
120
+ let workersTotal = 0;
121
+ try {
122
+ const entries = fs.readdirSync(dir);
123
+ for (const e of entries) {
124
+ if (!e.endsWith(".pid"))
125
+ continue;
126
+ workersTotal++;
127
+ const pidFile = path.join(dir, e);
128
+ const pid = Number(fs.readFileSync(pidFile, "utf-8").trim());
129
+ if (pid && pidAlive(pid))
130
+ workersAlive++;
131
+ }
132
+ }
133
+ catch {
134
+ // ignore
135
+ }
136
+ // Use the full event-stream reducer so projected metadata reflects
137
+ // title set/clear, context add/delete, and legacy linkedContext.
138
+ const metadata = reduceChannelMetadata(events);
139
+ return {
140
+ name,
141
+ project,
142
+ createdAt: firstEvent?.ts,
143
+ task: firstEvent?.task,
144
+ type: metadata.type,
145
+ description: metadata.title ?? metadata.description,
146
+ workersAlive,
147
+ workersTotal,
148
+ lastEventTs: lastEvent?.ts,
149
+ lastEventKind: lastEvent?.kind,
150
+ totalEvents,
151
+ ephemeral: firstEvent?.ephemeral === true,
152
+ };
153
+ }
154
+ function pidAlive(pid) {
155
+ try {
156
+ process.kill(pid, 0);
157
+ return true;
158
+ }
159
+ catch {
160
+ return false;
161
+ }
162
+ }
163
+ function printTable(rows) {
164
+ const cols = [
165
+ { key: "name", label: "NAME", width: 24 },
166
+ { key: "workers", label: "WORKERS", width: 9 },
167
+ { key: "events", label: "EVENTS", width: 7 },
168
+ { key: "last", label: "LAST", width: 19 },
169
+ { key: "kind", label: "KIND", width: 9 },
170
+ { key: "type", label: "TYPE", width: 7 },
171
+ { key: "task", label: "TASK", width: 0 }, // last column, no truncate
172
+ ];
173
+ // Header
174
+ console.log(chalk.bold(cols.map((c) => (c.width ? c.label.padEnd(c.width) : c.label)).join(" ")));
175
+ // Rows
176
+ for (const r of rows) {
177
+ const displayName = r.ephemeral ? `${r.name} *` : r.name;
178
+ const name = trunc(displayName, cols[0].width);
179
+ const workers = r.workersAlive > 0
180
+ ? chalk.green(`${r.workersAlive}/${r.workersTotal}`)
181
+ : r.workersTotal > 0
182
+ ? chalk.gray(`0/${r.workersTotal}`)
183
+ : chalk.gray("-");
184
+ const events = String(r.totalEvents);
185
+ const last = r.lastEventTs
186
+ ? r.lastEventTs.slice(0, 19).replace("T", " ")
187
+ : "-";
188
+ const kind = colorKind(r.lastEventKind);
189
+ const task = r.task ?? r.description ?? "-";
190
+ console.log([
191
+ name.padEnd(cols[0].width),
192
+ // workers cell needs visible-width padding (chalk adds ANSI bytes)
193
+ padVisible(workers, cols[1].width),
194
+ events.padEnd(cols[2].width),
195
+ last.padEnd(cols[3].width),
196
+ padVisible(kind, cols[4].width),
197
+ r.type.padEnd(cols[5].width),
198
+ task,
199
+ ].join(" "));
200
+ }
201
+ }
202
+ function trunc(s, w) {
203
+ if (s.length <= w)
204
+ return s;
205
+ return s.slice(0, w - 1) + "…";
206
+ }
207
+ /** Pad a string accounting for ANSI escape codes which take 0 visible width. */
208
+ function padVisible(s, w) {
209
+ // eslint-disable-next-line no-control-regex
210
+ const visible = s.replace(/\x1b\[[0-9;]*m/g, "");
211
+ const pad = Math.max(0, w - visible.length);
212
+ return s + " ".repeat(pad);
213
+ }
214
+ function colorKind(k) {
215
+ if (!k)
216
+ return chalk.gray("-");
217
+ switch (k) {
218
+ case "done":
219
+ return chalk.green(k);
220
+ case "error":
221
+ case "killed":
222
+ return chalk.red(k);
223
+ case "spawned":
224
+ return chalk.cyan(k);
225
+ case "message":
226
+ return chalk.yellow(k);
227
+ case "progress":
228
+ return chalk.gray(k);
229
+ default:
230
+ return k;
231
+ }
232
+ }
233
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/channel/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface MessagesOptions {
2
+ raw?: boolean;
3
+ follow?: boolean;
4
+ last?: number;
5
+ since?: number;
6
+ kind?: string;
7
+ from?: string;
8
+ to?: string;
9
+ noProgress?: boolean;
10
+ scope?: string;
11
+ thread?: string;
12
+ action?: string;
13
+ }
14
+ export declare function channelMessages(channelName: string, opts: MessagesOptions): Promise<void>;
15
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/messages.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC,CAsEf"}
@@ -0,0 +1,245 @@
1
+ import fs from "node:fs";
2
+ import chalk from "chalk";
3
+ import { parseChannelKind, readChannelEvents, readChannelMetadata, } from "./store/events.js";
4
+ import { matchesEventFilter } from "./store/filter.js";
5
+ import { eventsPath, resolveExistingChannelRef } from "./store/paths.js";
6
+ import { normalizeThreadKey, parseCsv, parseChannelScope, parseThreadAction, } from "./store/schema.js";
7
+ import { formatThreadBoard, reduceThreads } from "./store/thread-state.js";
8
+ import { watchEvents } from "./store/watch.js";
9
+ export async function channelMessages(channelName, opts) {
10
+ const ref = resolveExistingChannelRef(channelName, {
11
+ scope: parseChannelScope(opts.scope),
12
+ });
13
+ const file = eventsPath(channelName, ref.project);
14
+ if (!fs.existsSync(file)) {
15
+ throw new Error(`Channel '${channelName}' not found at ${file}`);
16
+ }
17
+ const all = await readChannelEvents(channelName, ref.project);
18
+ const fromList = parseCsv(opts.from);
19
+ // Validate --kind against whitelist up front so typos fail fast.
20
+ const kindFilter = parseChannelKind(opts.kind);
21
+ const threadFilter = opts.thread
22
+ ? normalizeThreadKey(opts.thread)
23
+ : undefined;
24
+ const actionFilter = opts.action
25
+ ? parseThreadAction(opts.action)
26
+ : undefined;
27
+ const metadata = await readChannelMetadata(channelName, ref.project);
28
+ if (metadata.type === "chat" && (threadFilter || actionFilter)) {
29
+ throw new Error(`Channel '${channelName}' is type 'chat'. --thread/--action require a forum channel.`);
30
+ }
31
+ const filter = {
32
+ kind: kindFilter,
33
+ from: fromList,
34
+ to: opts.to,
35
+ thread: threadFilter,
36
+ action: actionFilter,
37
+ includeProgress: !opts.noProgress,
38
+ includeNonMeaningful: true,
39
+ };
40
+ const filtered = all.filter((ev) => {
41
+ if (opts.since !== undefined && ev.seq <= opts.since)
42
+ return false;
43
+ return matchesEventFilter(ev, filter);
44
+ });
45
+ const view = opts.last ? filtered.slice(-opts.last) : filtered;
46
+ const threadBoardView = !opts.raw &&
47
+ metadata.type === "forum" &&
48
+ !threadFilter &&
49
+ !kindFilter &&
50
+ !actionFilter &&
51
+ !opts.from &&
52
+ !opts.to;
53
+ if (threadBoardView) {
54
+ console.log("Forum channel: showing threads. Use --thread <key> for timeline, --raw for event log.");
55
+ printThreadBoard(view);
56
+ }
57
+ else {
58
+ for (const ev of view)
59
+ printEvent(ev, opts.raw ?? false);
60
+ }
61
+ if (opts.follow) {
62
+ const abort = new AbortController();
63
+ process.on("SIGINT", () => abort.abort());
64
+ for await (const ev of watchEvents(channelName, filter, {
65
+ signal: abort.signal,
66
+ project: ref.project,
67
+ })) {
68
+ printEvent(ev, opts.raw ?? false);
69
+ }
70
+ }
71
+ }
72
+ function printEvent(ev, raw) {
73
+ if (raw) {
74
+ console.log(JSON.stringify(ev));
75
+ return;
76
+ }
77
+ const ts = (ev.ts || "").slice(11, 19);
78
+ const by = colorBy(ev.by);
79
+ switch (ev.kind) {
80
+ case "create": {
81
+ const cwd = ev.cwd ?? "";
82
+ const task = ev.task ?? "";
83
+ printLine(`${kindTag("create")} by=${by} cwd=${cwd}${task ? " task=" + task : ""}`, ts);
84
+ if (ev.description)
85
+ console.log(` ${chalk.dim("description:")} ${ev.description}`);
86
+ printContext(ev.context ?? ev.linkedContext);
87
+ break;
88
+ }
89
+ case "spawned": {
90
+ const as = ev.as ?? "?";
91
+ const provider = ev.provider ?? "?";
92
+ const pid = ev.pid ?? "?";
93
+ const agent = ev.agent;
94
+ const files = ev.files;
95
+ const manifests = ev.manifests;
96
+ const agentStr = agent ? ` agent=${chalk.magenta(agent)}` : "";
97
+ printLine(`${kindTag("spawned")} by=${by} worker=${colorTo(as)} provider=${provider}${agentStr} pid=${pid}`, ts);
98
+ if (files && files.length > 0) {
99
+ console.log(` ${chalk.dim("files:")} ${files.join(", ")}`);
100
+ }
101
+ if (manifests && manifests.length > 0) {
102
+ console.log(` ${chalk.dim("manifests:")} ${manifests.join(", ")}`);
103
+ }
104
+ break;
105
+ }
106
+ case "killed": {
107
+ const reason = ev.reason ?? "?";
108
+ const sig = ev.signal ?? "?";
109
+ printLine(`${kindTag("killed")} by=${by} reason=${reason} signal=${sig}`, ts);
110
+ break;
111
+ }
112
+ case "message": {
113
+ const text = (ev.text ?? "").replace(/\n/g, "\n ");
114
+ const to = ev.to;
115
+ const toStr = to
116
+ ? ` to=${colorTo(Array.isArray(to) ? to.join(",") : to)}`
117
+ : "";
118
+ printLine(`${kindTag("message")} by=${by}${toStr}`, ts);
119
+ console.log(` ${text}`);
120
+ break;
121
+ }
122
+ case "thread": {
123
+ const action = ev.action ?? "?";
124
+ const text = (ev.text ?? "").replace(/\n/g, "\n ");
125
+ printLine(`${kindTag("thread")} by=${by} ${action} ${ev.thread}`, ts);
126
+ if (ev.description)
127
+ console.log(` ${chalk.dim("description:")} ${ev.description}`);
128
+ printContext(ev.context ?? ev.linkedContext);
129
+ if (text)
130
+ console.log(` ${text}`);
131
+ break;
132
+ }
133
+ case "done": {
134
+ const dur = ev.duration_ms;
135
+ printLine(`${kindTag("done")} by=${by}${dur !== undefined ? " duration=" + dur + "ms" : ""}`, ts);
136
+ break;
137
+ }
138
+ case "error": {
139
+ const msg = ev.message ?? "";
140
+ printLine(`${kindTag("error")} by=${by} ${msg}`, ts);
141
+ break;
142
+ }
143
+ case "progress": {
144
+ const detail = ev.detail ?? {};
145
+ const summary = summarizeProgress(detail);
146
+ printLine(`${kindTag("progress")} by=${by} ${summary}`, ts);
147
+ break;
148
+ }
149
+ case "supervisor_warning": {
150
+ const worker = typeof ev.worker === "string" ? ev.worker : "?";
151
+ const reason = typeof ev.reason === "string" ? ev.reason : "?";
152
+ const remaining = typeof ev.remaining_ms === "number" ? ev.remaining_ms : undefined;
153
+ const timeout = typeof ev.timeout_ms === "number" ? ev.timeout_ms : undefined;
154
+ const remainingStr = remaining !== undefined ? ` remaining=${remaining}ms` : "";
155
+ const timeoutStr = timeout !== undefined ? ` timeout=${timeout}ms` : "";
156
+ printLine(`${kindTag("supervisor_warning")} by=${by} worker=${colorTo(worker)} reason=${reason}${remainingStr}${timeoutStr}`, ts);
157
+ break;
158
+ }
159
+ default: {
160
+ printLine(`${kindTag(ev.kind)} by=${by}`, ts);
161
+ }
162
+ }
163
+ }
164
+ function printContext(context) {
165
+ if (!context || context.length === 0)
166
+ return;
167
+ for (const entry of context) {
168
+ const detail = entry.type === "file" ? entry.path : summarizeContextText(entry.text);
169
+ console.log(` ${chalk.dim(`context:${entry.type}:`)} ${detail}`);
170
+ }
171
+ }
172
+ function summarizeContextText(text) {
173
+ const oneLine = text.replace(/\s+/g, " ").trim();
174
+ return oneLine.length > 100 ? `${oneLine.slice(0, 100)}...` : oneLine;
175
+ }
176
+ function printThreadBoard(events) {
177
+ for (const line of formatThreadBoard(reduceThreads(events))) {
178
+ console.log(line);
179
+ }
180
+ }
181
+ /**
182
+ * Print `body` right-padded with `ts` at the terminal's right edge. The ANSI
183
+ * escape codes don't count toward visible width, so we strip them before
184
+ * computing the pad amount.
185
+ */
186
+ function printLine(body, ts) {
187
+ const width = process.stdout.columns || 100;
188
+ // eslint-disable-next-line no-control-regex
189
+ const visible = body.replace(/\x1b\[[0-9;]*m/g, "").length;
190
+ const tsCols = ts.length; // "HH:MM:SS" = 8
191
+ const gap = Math.max(2, width - visible - tsCols);
192
+ console.log(body + " ".repeat(gap) + chalk.dim(ts));
193
+ }
194
+ function colorBy(name) {
195
+ if (name === "main")
196
+ return chalk.magenta(name);
197
+ if (name.startsWith("supervisor:") || name.startsWith("cli:")) {
198
+ return chalk.gray(name);
199
+ }
200
+ return chalk.cyan(name);
201
+ }
202
+ function colorTo(name) {
203
+ return chalk.greenBright(name);
204
+ }
205
+ function kindTag(k) {
206
+ const padded = `[${k}]`.padEnd(10);
207
+ switch (k) {
208
+ case "done":
209
+ return chalk.green(padded);
210
+ case "error":
211
+ case "killed":
212
+ return chalk.red(padded);
213
+ case "spawned":
214
+ return chalk.cyan(padded);
215
+ case "respawned":
216
+ return chalk.cyan(padded);
217
+ case "message":
218
+ return chalk.yellow(padded);
219
+ case "thread":
220
+ return chalk.blue(padded);
221
+ case "progress":
222
+ return chalk.gray(padded);
223
+ case "create":
224
+ return chalk.blueBright(padded);
225
+ case "supervisor_warning":
226
+ return chalk.yellow(padded);
227
+ default:
228
+ return padded;
229
+ }
230
+ }
231
+ function summarizeProgress(detail) {
232
+ const parts = [];
233
+ for (const key of ["kind", "tool", "tool_name", "server", "status", "cmd"]) {
234
+ if (detail[key] !== undefined) {
235
+ const v = String(detail[key]);
236
+ parts.push(`${key}=${v.length > 60 ? v.slice(0, 60) + "…" : v}`);
237
+ }
238
+ }
239
+ if (detail.text_delta) {
240
+ const t = String(detail.text_delta);
241
+ parts.push(`delta="${t.length > 40 ? t.slice(0, 40) + "…" : t}"`);
242
+ }
243
+ return parts.join(" ");
244
+ }
245
+ //# sourceMappingURL=messages.js.map