@lumenflow/cli 3.1.2 → 3.1.3

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 (389) hide show
  1. package/README.md +36 -35
  2. package/dist/agent-issues-query.js +13 -8
  3. package/dist/agent-log-issue.js +15 -4
  4. package/dist/agent-session-end.js +15 -4
  5. package/dist/agent-session.js +18 -6
  6. package/dist/backlog-prune.js +1 -1
  7. package/dist/commands/integrate.js +32 -18
  8. package/dist/config-get.js +27 -15
  9. package/dist/config-set.js +104 -37
  10. package/dist/delegation-list.js +1 -1
  11. package/dist/doctor.js +19 -13
  12. package/dist/file-delete.js +1 -1
  13. package/dist/file-edit.js +1 -1
  14. package/dist/file-read.js +1 -1
  15. package/dist/file-write.js +1 -1
  16. package/dist/flow-bottlenecks.js +1 -1
  17. package/dist/flow-report.js +10 -9
  18. package/dist/gates.js +3 -2
  19. package/dist/git-branch.js +1 -1
  20. package/dist/git-diff.js +1 -1
  21. package/dist/git-log.js +1 -1
  22. package/dist/init.js +238 -42
  23. package/dist/initiative-add-wu.js +1 -1
  24. package/dist/initiative-bulk-assign-wus.js +1 -1
  25. package/dist/initiative-create.js +2 -2
  26. package/dist/initiative-edit.js +1 -1
  27. package/dist/initiative-list.js +1 -1
  28. package/dist/initiative-plan.js +1 -3
  29. package/dist/initiative-status.js +47 -6
  30. package/dist/lane-edit.js +19 -10
  31. package/dist/lane-health.js +13 -24
  32. package/dist/lane-lock.js +4 -5
  33. package/dist/lane-setup.js +5 -5
  34. package/dist/lane-status.js +4 -5
  35. package/dist/lane-suggest.js +9 -7
  36. package/dist/lane-validate.js +4 -5
  37. package/dist/lumenflow-upgrade.js +17 -11
  38. package/dist/mem-checkpoint.js +1 -1
  39. package/dist/mem-cleanup.js +6 -23
  40. package/dist/mem-context.js +1 -1
  41. package/dist/mem-create.js +1 -1
  42. package/dist/mem-delete.js +1 -1
  43. package/dist/mem-export.js +1 -1
  44. package/dist/mem-inbox.js +1 -1
  45. package/dist/mem-init.js +1 -1
  46. package/dist/mem-ready.js +1 -1
  47. package/dist/mem-recover.js +1 -1
  48. package/dist/mem-signal.js +1 -1
  49. package/dist/mem-start.js +1 -1
  50. package/dist/mem-summarize.js +8 -7
  51. package/dist/mem-triage.js +7 -5
  52. package/dist/metrics-cli.js +1 -1
  53. package/dist/metrics-snapshot.js +1 -1
  54. package/dist/onboard.js +295 -120
  55. package/dist/orchestrate-init-status.js +12 -7
  56. package/dist/orchestrate-initiative.js +23 -12
  57. package/dist/orchestrate-monitor.js +20 -8
  58. package/dist/pack-scaffold.js +1 -1
  59. package/dist/plan-create.js +1 -3
  60. package/dist/plan-edit.js +1 -3
  61. package/dist/plan-link.js +1 -3
  62. package/dist/plan-promote.js +1 -3
  63. package/dist/release.js +1 -3
  64. package/dist/signal-cleanup.js +4 -18
  65. package/dist/state-bootstrap.js +11 -8
  66. package/dist/state-cleanup.js +5 -19
  67. package/dist/state-doctor.js +213 -9
  68. package/dist/task-claim.js +1 -1
  69. package/dist/validate.js +1 -1
  70. package/dist/workspace-init.js +61 -61
  71. package/dist/wu-block.js +1 -1
  72. package/dist/wu-brief.js +1 -1
  73. package/dist/wu-claim.js +1 -1
  74. package/dist/wu-cleanup.js +1 -1
  75. package/dist/wu-create.js +3 -3
  76. package/dist/wu-delegate.js +1 -1
  77. package/dist/wu-deps.js +1 -1
  78. package/dist/wu-done.js +66 -34
  79. package/dist/wu-edit.js +1 -1
  80. package/dist/wu-infer-lane.js +1 -1
  81. package/dist/wu-preflight.js +1 -1
  82. package/dist/wu-prep.js +1 -1
  83. package/dist/wu-proto.js +1 -1
  84. package/dist/wu-prune.js +1 -1
  85. package/dist/wu-recover.js +1 -1
  86. package/dist/wu-release.js +1 -1
  87. package/dist/wu-repair.js +1 -1
  88. package/dist/wu-sandbox.js +40 -27
  89. package/dist/wu-status.js +1 -1
  90. package/dist/wu-unblock.js +1 -1
  91. package/dist/wu-unlock-lane.js +1 -1
  92. package/dist/wu-validate.js +1 -1
  93. package/package.json +12 -8
  94. package/packs/software-delivery/constants.ts +10 -0
  95. package/packs/software-delivery/extensions.ts +140 -0
  96. package/packs/software-delivery/gate-policies.ts +134 -0
  97. package/packs/software-delivery/index.ts +8 -0
  98. package/packs/software-delivery/manifest-schema.ts +236 -0
  99. package/packs/software-delivery/manifest.ts +417 -0
  100. package/packs/software-delivery/manifest.yaml +711 -0
  101. package/packs/software-delivery/pack-registration.ts +113 -0
  102. package/packs/software-delivery/tool-impl/agent-tools.ts +263 -0
  103. package/packs/software-delivery/tool-impl/delegation-tools.ts +66 -0
  104. package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +219 -0
  105. package/packs/software-delivery/tool-impl/git-runner.ts +113 -0
  106. package/packs/software-delivery/tool-impl/git-tools.ts +316 -0
  107. package/packs/software-delivery/tool-impl/index.ts +15 -0
  108. package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +720 -0
  109. package/packs/software-delivery/tool-impl/lane-lock.ts +246 -0
  110. package/packs/software-delivery/tool-impl/memory-tools.ts +415 -0
  111. package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +21 -0
  112. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +328 -0
  113. package/packs/software-delivery/tool-impl/runtime-native-tools.ts +687 -0
  114. package/packs/software-delivery/tool-impl/worker-loader.ts +52 -0
  115. package/packs/software-delivery/tool-impl/worktree-tools.ts +46 -0
  116. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +759 -0
  117. package/packs/software-delivery/tools/delegation-tools.ts +23 -0
  118. package/packs/software-delivery/tools/git-tools.ts +55 -0
  119. package/packs/software-delivery/tools/index.ts +8 -0
  120. package/packs/software-delivery/tools/lane-lock-tool.ts +37 -0
  121. package/packs/software-delivery/tools/types.ts +71 -0
  122. package/packs/software-delivery/tools/worktree-tools.ts +49 -0
  123. package/templates/core/LUMENFLOW.md.template +3 -3
  124. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +1 -1
  125. package/templates/core/ai/onboarding/lumenflow-force-usage.md.template +1 -1
  126. package/templates/core/ai/onboarding/quick-ref-commands.md.template +5 -5
  127. package/templates/core/ai/onboarding/starting-prompt.md.template +3 -3
  128. package/templates/core/ai/onboarding/vendor-support.md.template +1 -1
  129. package/templates/core/ai/onboarding/wu-create-checklist.md.template +1 -1
  130. package/dist/agent-issues-query.js.map +0 -1
  131. package/dist/agent-log-issue.js.map +0 -1
  132. package/dist/agent-session-end.js.map +0 -1
  133. package/dist/agent-session.js.map +0 -1
  134. package/dist/backlog-prune.js.map +0 -1
  135. package/dist/cli-entry-point.js +0 -149
  136. package/dist/cli-entry-point.js.map +0 -1
  137. package/dist/commands/integrate.js.map +0 -1
  138. package/dist/commands.js.map +0 -1
  139. package/dist/config-get.js.map +0 -1
  140. package/dist/config-set.js.map +0 -1
  141. package/dist/delegation-list.js.map +0 -1
  142. package/dist/deps-add.js +0 -259
  143. package/dist/deps-add.js.map +0 -1
  144. package/dist/deps-remove.js +0 -105
  145. package/dist/deps-remove.js.map +0 -1
  146. package/dist/docs-sync.js.map +0 -1
  147. package/dist/doctor.js.map +0 -1
  148. package/dist/file-delete.js.map +0 -1
  149. package/dist/file-edit.js.map +0 -1
  150. package/dist/file-read.js.map +0 -1
  151. package/dist/file-write.js.map +0 -1
  152. package/dist/flow-bottlenecks.js.map +0 -1
  153. package/dist/flow-report.js.map +0 -1
  154. package/dist/formatters.js +0 -151
  155. package/dist/formatters.js.map +0 -1
  156. package/dist/gate-defaults.js +0 -131
  157. package/dist/gate-defaults.js.map +0 -1
  158. package/dist/gate-registry.js +0 -73
  159. package/dist/gate-registry.js.map +0 -1
  160. package/dist/gates-graceful-degradation.js +0 -153
  161. package/dist/gates-graceful-degradation.js.map +0 -1
  162. package/dist/gates-plan-resolvers.js +0 -152
  163. package/dist/gates-plan-resolvers.js.map +0 -1
  164. package/dist/gates-runners.js +0 -509
  165. package/dist/gates-runners.js.map +0 -1
  166. package/dist/gates-types.js +0 -4
  167. package/dist/gates-types.js.map +0 -1
  168. package/dist/gates-utils.js +0 -323
  169. package/dist/gates-utils.js.map +0 -1
  170. package/dist/gates.js.map +0 -1
  171. package/dist/git-branch.js.map +0 -1
  172. package/dist/git-diff.js.map +0 -1
  173. package/dist/git-log.js.map +0 -1
  174. package/dist/git-status.js.map +0 -1
  175. package/dist/guard-locked.js +0 -172
  176. package/dist/guard-locked.js.map +0 -1
  177. package/dist/guard-main-branch.js +0 -217
  178. package/dist/guard-main-branch.js.map +0 -1
  179. package/dist/guard-worktree-commit.js +0 -163
  180. package/dist/guard-worktree-commit.js.map +0 -1
  181. package/dist/hooks/auto-checkpoint-utils.js +0 -54
  182. package/dist/hooks/auto-checkpoint-utils.js.map +0 -1
  183. package/dist/hooks/enforcement-checks.js +0 -399
  184. package/dist/hooks/enforcement-checks.js.map +0 -1
  185. package/dist/hooks/enforcement-generator.js +0 -139
  186. package/dist/hooks/enforcement-generator.js.map +0 -1
  187. package/dist/hooks/enforcement-sync.js +0 -385
  188. package/dist/hooks/enforcement-sync.js.map +0 -1
  189. package/dist/hooks/generators/auto-checkpoint.js +0 -125
  190. package/dist/hooks/generators/auto-checkpoint.js.map +0 -1
  191. package/dist/hooks/generators/enforce-worktree.js +0 -190
  192. package/dist/hooks/generators/enforce-worktree.js.map +0 -1
  193. package/dist/hooks/generators/index.js +0 -18
  194. package/dist/hooks/generators/index.js.map +0 -1
  195. package/dist/hooks/generators/pre-compact-checkpoint.js +0 -136
  196. package/dist/hooks/generators/pre-compact-checkpoint.js.map +0 -1
  197. package/dist/hooks/generators/require-wu.js +0 -117
  198. package/dist/hooks/generators/require-wu.js.map +0 -1
  199. package/dist/hooks/generators/session-start-recovery.js +0 -103
  200. package/dist/hooks/generators/session-start-recovery.js.map +0 -1
  201. package/dist/hooks/generators/signal-utils.js +0 -54
  202. package/dist/hooks/generators/signal-utils.js.map +0 -1
  203. package/dist/hooks/generators/warn-incomplete.js +0 -67
  204. package/dist/hooks/generators/warn-incomplete.js.map +0 -1
  205. package/dist/hooks/index.js +0 -10
  206. package/dist/hooks/index.js.map +0 -1
  207. package/dist/index.js.map +0 -1
  208. package/dist/init-detection.js +0 -232
  209. package/dist/init-detection.js.map +0 -1
  210. package/dist/init-lane-validation.js +0 -143
  211. package/dist/init-lane-validation.js.map +0 -1
  212. package/dist/init-scaffolding.js +0 -158
  213. package/dist/init-scaffolding.js.map +0 -1
  214. package/dist/init-templates.js +0 -1982
  215. package/dist/init-templates.js.map +0 -1
  216. package/dist/init.js.map +0 -1
  217. package/dist/initiative-add-wu.js.map +0 -1
  218. package/dist/initiative-bulk-assign-wus.js.map +0 -1
  219. package/dist/initiative-create.js.map +0 -1
  220. package/dist/initiative-edit.js.map +0 -1
  221. package/dist/initiative-list.js.map +0 -1
  222. package/dist/initiative-plan.js.map +0 -1
  223. package/dist/initiative-remove-wu.js.map +0 -1
  224. package/dist/initiative-status.js.map +0 -1
  225. package/dist/lane-edit.js.map +0 -1
  226. package/dist/lane-health.js.map +0 -1
  227. package/dist/lane-lifecycle-process.js +0 -366
  228. package/dist/lane-lifecycle-process.js.map +0 -1
  229. package/dist/lane-lock.js.map +0 -1
  230. package/dist/lane-setup.js.map +0 -1
  231. package/dist/lane-status.js.map +0 -1
  232. package/dist/lane-suggest.js.map +0 -1
  233. package/dist/lane-validate.js.map +0 -1
  234. package/dist/lifecycle-regression-harness.js +0 -181
  235. package/dist/lifecycle-regression-harness.js.map +0 -1
  236. package/dist/lumenflow-upgrade.js.map +0 -1
  237. package/dist/mem-checkpoint.js.map +0 -1
  238. package/dist/mem-cleanup.js.map +0 -1
  239. package/dist/mem-context.js.map +0 -1
  240. package/dist/mem-create.js.map +0 -1
  241. package/dist/mem-delete.js.map +0 -1
  242. package/dist/mem-export.js.map +0 -1
  243. package/dist/mem-inbox.js.map +0 -1
  244. package/dist/mem-index.js +0 -214
  245. package/dist/mem-index.js.map +0 -1
  246. package/dist/mem-init.js.map +0 -1
  247. package/dist/mem-profile.js +0 -210
  248. package/dist/mem-profile.js.map +0 -1
  249. package/dist/mem-promote.js +0 -257
  250. package/dist/mem-promote.js.map +0 -1
  251. package/dist/mem-ready.js.map +0 -1
  252. package/dist/mem-recover.js.map +0 -1
  253. package/dist/mem-signal.js.map +0 -1
  254. package/dist/mem-start.js.map +0 -1
  255. package/dist/mem-summarize.js.map +0 -1
  256. package/dist/mem-triage.js.map +0 -1
  257. package/dist/merge-block.js +0 -225
  258. package/dist/merge-block.js.map +0 -1
  259. package/dist/metrics-cli.js.map +0 -1
  260. package/dist/metrics-snapshot.js.map +0 -1
  261. package/dist/onboard.js.map +0 -1
  262. package/dist/onboarding-smoke-test.js +0 -418
  263. package/dist/onboarding-smoke-test.js.map +0 -1
  264. package/dist/orchestrate-init-status.js.map +0 -1
  265. package/dist/orchestrate-initiative.js.map +0 -1
  266. package/dist/orchestrate-monitor.js.map +0 -1
  267. package/dist/pack-author.js.map +0 -1
  268. package/dist/pack-hash.js.map +0 -1
  269. package/dist/pack-install.js.map +0 -1
  270. package/dist/pack-publish.js.map +0 -1
  271. package/dist/pack-scaffold.js.map +0 -1
  272. package/dist/pack-search.js.map +0 -1
  273. package/dist/pack-validate.js.map +0 -1
  274. package/dist/plan-create.js.map +0 -1
  275. package/dist/plan-edit.js.map +0 -1
  276. package/dist/plan-link.js.map +0 -1
  277. package/dist/plan-promote.js.map +0 -1
  278. package/dist/public-manifest.js +0 -920
  279. package/dist/public-manifest.js.map +0 -1
  280. package/dist/release.js.map +0 -1
  281. package/dist/rotate-progress.js +0 -253
  282. package/dist/rotate-progress.js.map +0 -1
  283. package/dist/session-coordinator.js +0 -303
  284. package/dist/session-coordinator.js.map +0 -1
  285. package/dist/shared-validators.js +0 -81
  286. package/dist/shared-validators.js.map +0 -1
  287. package/dist/signal-cleanup.js.map +0 -1
  288. package/dist/state-bootstrap.js.map +0 -1
  289. package/dist/state-cleanup.js.map +0 -1
  290. package/dist/state-doctor-fix.js +0 -226
  291. package/dist/state-doctor-fix.js.map +0 -1
  292. package/dist/state-doctor-stamps.js +0 -23
  293. package/dist/state-doctor-stamps.js.map +0 -1
  294. package/dist/state-doctor.js.map +0 -1
  295. package/dist/strict-progress.js +0 -255
  296. package/dist/strict-progress.js.map +0 -1
  297. package/dist/sync-templates.js.map +0 -1
  298. package/dist/task-claim.js.map +0 -1
  299. package/dist/trace-gen.js +0 -401
  300. package/dist/trace-gen.js.map +0 -1
  301. package/dist/validate-agent-skills.js +0 -223
  302. package/dist/validate-agent-skills.js.map +0 -1
  303. package/dist/validate-agent-sync.js +0 -151
  304. package/dist/validate-agent-sync.js.map +0 -1
  305. package/dist/validate-backlog-sync.js +0 -77
  306. package/dist/validate-backlog-sync.js.map +0 -1
  307. package/dist/validate-skills-spec.js +0 -211
  308. package/dist/validate-skills-spec.js.map +0 -1
  309. package/dist/validate.js.map +0 -1
  310. package/dist/validator-defaults.js +0 -107
  311. package/dist/validator-defaults.js.map +0 -1
  312. package/dist/validator-registry.js +0 -71
  313. package/dist/validator-registry.js.map +0 -1
  314. package/dist/workspace-init.js.map +0 -1
  315. package/dist/wu-block.js.map +0 -1
  316. package/dist/wu-brief.js.map +0 -1
  317. package/dist/wu-claim-branch.js +0 -123
  318. package/dist/wu-claim-branch.js.map +0 -1
  319. package/dist/wu-claim-cloud.js +0 -79
  320. package/dist/wu-claim-cloud.js.map +0 -1
  321. package/dist/wu-claim-mode.js +0 -82
  322. package/dist/wu-claim-mode.js.map +0 -1
  323. package/dist/wu-claim-output.js +0 -85
  324. package/dist/wu-claim-output.js.map +0 -1
  325. package/dist/wu-claim-repair-guidance.js +0 -12
  326. package/dist/wu-claim-repair-guidance.js.map +0 -1
  327. package/dist/wu-claim-resume-handler.js +0 -87
  328. package/dist/wu-claim-resume-handler.js.map +0 -1
  329. package/dist/wu-claim-state.js +0 -581
  330. package/dist/wu-claim-state.js.map +0 -1
  331. package/dist/wu-claim-validation.js +0 -457
  332. package/dist/wu-claim-validation.js.map +0 -1
  333. package/dist/wu-claim-worktree.js +0 -223
  334. package/dist/wu-claim-worktree.js.map +0 -1
  335. package/dist/wu-claim.js.map +0 -1
  336. package/dist/wu-cleanup-cloud.js +0 -78
  337. package/dist/wu-cleanup-cloud.js.map +0 -1
  338. package/dist/wu-cleanup.js.map +0 -1
  339. package/dist/wu-code-path-coverage.js +0 -83
  340. package/dist/wu-code-path-coverage.js.map +0 -1
  341. package/dist/wu-create-cloud.js +0 -30
  342. package/dist/wu-create-cloud.js.map +0 -1
  343. package/dist/wu-create-content.js +0 -264
  344. package/dist/wu-create-content.js.map +0 -1
  345. package/dist/wu-create-readiness.js +0 -59
  346. package/dist/wu-create-readiness.js.map +0 -1
  347. package/dist/wu-create-validation.js +0 -128
  348. package/dist/wu-create-validation.js.map +0 -1
  349. package/dist/wu-create.js.map +0 -1
  350. package/dist/wu-delegate.js.map +0 -1
  351. package/dist/wu-delete.js.map +0 -1
  352. package/dist/wu-deps.js.map +0 -1
  353. package/dist/wu-done-auto-cleanup.js +0 -203
  354. package/dist/wu-done-auto-cleanup.js.map +0 -1
  355. package/dist/wu-done-check.js +0 -38
  356. package/dist/wu-done-check.js.map +0 -1
  357. package/dist/wu-done-cloud.js +0 -48
  358. package/dist/wu-done-cloud.js.map +0 -1
  359. package/dist/wu-done-decay.js +0 -86
  360. package/dist/wu-done-decay.js.map +0 -1
  361. package/dist/wu-done.js.map +0 -1
  362. package/dist/wu-edit-operations.js +0 -399
  363. package/dist/wu-edit-operations.js.map +0 -1
  364. package/dist/wu-edit-validators.js +0 -282
  365. package/dist/wu-edit-validators.js.map +0 -1
  366. package/dist/wu-edit.js.map +0 -1
  367. package/dist/wu-infer-lane.js.map +0 -1
  368. package/dist/wu-preflight.js.map +0 -1
  369. package/dist/wu-prep.js.map +0 -1
  370. package/dist/wu-proto.js.map +0 -1
  371. package/dist/wu-prune.js.map +0 -1
  372. package/dist/wu-recover.js.map +0 -1
  373. package/dist/wu-release.js.map +0 -1
  374. package/dist/wu-repair.js.map +0 -1
  375. package/dist/wu-sandbox.js.map +0 -1
  376. package/dist/wu-spawn-completion.js +0 -33
  377. package/dist/wu-spawn-completion.js.map +0 -1
  378. package/dist/wu-spawn-prompt-builders.js +0 -1197
  379. package/dist/wu-spawn-prompt-builders.js.map +0 -1
  380. package/dist/wu-spawn-strategy-resolver.js +0 -322
  381. package/dist/wu-spawn-strategy-resolver.js.map +0 -1
  382. package/dist/wu-spawn.js +0 -59
  383. package/dist/wu-spawn.js.map +0 -1
  384. package/dist/wu-state-cloud.js +0 -41
  385. package/dist/wu-state-cloud.js.map +0 -1
  386. package/dist/wu-status.js.map +0 -1
  387. package/dist/wu-unblock.js.map +0 -1
  388. package/dist/wu-unlock-lane.js.map +0 -1
  389. package/dist/wu-validate.js.map +0 -1
@@ -14,18 +14,16 @@
14
14
  * pnpm lane:health --json # Output as JSON
15
15
  * pnpm lane:health --verbose # Show all checked files
16
16
  */
17
- import { readFileSync, existsSync } from 'node:fs';
18
- import path from 'node:path';
19
17
  import fg from 'fast-glob';
20
18
  import { minimatch } from 'minimatch';
21
- import { parse as parseYAML } from 'yaml';
22
19
  import chalk from 'chalk';
23
20
  import { createWUParser } from '@lumenflow/core/arg-parser';
24
- import { findProjectRoot } from '@lumenflow/core/config';
21
+ import { findProjectRoot, getConfig, WORKSPACE_CONFIG_FILE_NAME } from '@lumenflow/core/config';
25
22
  import { runCLI } from './cli-entry-point.js';
23
+ import { asRecord } from './object-guards.js';
26
24
  /** Constants */
27
25
  const LOG_PREFIX = '[lane:health]';
28
- const CONFIG_FILE_NAME = '.lumenflow.config.yaml';
26
+ const CONFIG_FILE_NAME = WORKSPACE_CONFIG_FILE_NAME;
29
27
  const MAX_DISPLAY_FILES = 5;
30
28
  const MAX_DISPLAY_GAPS = 10;
31
29
  /** Default exclude patterns for coverage gap detection */
@@ -74,10 +72,10 @@ const CODE_FILE_EXTENSIONS = [
74
72
  * Parse lane definition from raw object
75
73
  */
76
74
  function parseLaneDefinition(lane) {
77
- if (typeof lane !== 'object' || lane === null) {
75
+ const laneObj = asRecord(lane);
76
+ if (!laneObj) {
78
77
  return null;
79
78
  }
80
- const laneObj = lane;
81
79
  if (typeof laneObj.name !== 'string' || !Array.isArray(laneObj.code_paths)) {
82
80
  return null;
83
81
  }
@@ -88,28 +86,19 @@ function parseLaneDefinition(lane) {
88
86
  };
89
87
  }
90
88
  /**
91
- * Load lane definitions from .lumenflow.config.yaml
89
+ * Load lane definitions from workspace.yaml software_delivery.lanes.definitions
92
90
  *
93
91
  * @param projectRoot - Project root directory
94
92
  * @returns Array of lane definitions
95
93
  */
96
94
  export function loadLaneDefinitions(projectRoot) {
97
- const configPath = path.join(projectRoot, CONFIG_FILE_NAME);
98
- if (!existsSync(configPath)) {
99
- return [];
100
- }
101
95
  try {
102
- const content = readFileSync(configPath, 'utf8');
103
- const config = parseYAML(content);
104
- const lanesConfig = config.lanes;
105
- if (!lanesConfig) {
106
- return [];
107
- }
108
- const definitions = (lanesConfig.definitions || lanesConfig);
109
- if (!Array.isArray(definitions)) {
110
- return [];
111
- }
112
- return definitions
96
+ const config = getConfig({
97
+ projectRoot,
98
+ reload: true,
99
+ strictWorkspace: true,
100
+ });
101
+ return (config.lanes?.definitions ?? [])
113
102
  .map(parseLaneDefinition)
114
103
  .filter((lane) => lane !== null);
115
104
  }
@@ -333,7 +322,7 @@ export function runLaneHealthCheck(options) {
333
322
  /**
334
323
  * Main entry point
335
324
  */
336
- async function main() {
325
+ export async function main() {
337
326
  const args = createWUParser({
338
327
  name: 'lane-health',
339
328
  description: 'Check lane configuration health (WU-1188)',
package/dist/lane-lock.js CHANGED
@@ -3,17 +3,16 @@
3
3
  // SPDX-License-Identifier: AGPL-3.0-only
4
4
  import path from 'node:path';
5
5
  import { existsSync } from 'node:fs';
6
- import { findProjectRoot } from '@lumenflow/core/config';
6
+ import { findProjectRoot, WORKSPACE_CONFIG_FILE_NAME } from '@lumenflow/core/config';
7
7
  import { die } from '@lumenflow/core/error-handler';
8
- import { CONFIG_FILES } from '@lumenflow/core/wu-constants';
9
8
  import { LANE_LIFECYCLE_STATUS, recommendLaneLifecycleNextStep, setLaneLifecycleStatus, validateLaneArtifacts, } from './lane-lifecycle-process.js';
10
9
  import { runCLI } from './cli-entry-point.js';
11
10
  const LOG_PREFIX = '[lane:lock]';
12
11
  function ensureLumenflowInit(projectRoot) {
13
- const configPath = path.join(projectRoot, CONFIG_FILES.LUMENFLOW_CONFIG);
12
+ const configPath = path.join(projectRoot, WORKSPACE_CONFIG_FILE_NAME);
14
13
  if (!existsSync(configPath)) {
15
- die(`${LOG_PREFIX} Missing ${CONFIG_FILES.LUMENFLOW_CONFIG}.\n\n` +
16
- 'Run `pnpm exec lumenflow init` first, then configure lane lifecycle.');
14
+ die(`${LOG_PREFIX} Missing ${WORKSPACE_CONFIG_FILE_NAME}.\n\n` +
15
+ 'Run `pnpm workspace-init --yes` first, then configure lane lifecycle.');
17
16
  }
18
17
  }
19
18
  async function main() {
@@ -3,7 +3,7 @@
3
3
  // SPDX-License-Identifier: AGPL-3.0-only
4
4
  import path from 'node:path';
5
5
  import { existsSync } from 'node:fs';
6
- import { findProjectRoot } from '@lumenflow/core/config';
6
+ import { findProjectRoot, WORKSPACE_CONFIG_FILE_NAME } from '@lumenflow/core/config';
7
7
  import { die } from '@lumenflow/core/error-handler';
8
8
  import { CONFIG_FILES } from '@lumenflow/core/wu-constants';
9
9
  import { ensureDraftLaneArtifacts, LANE_LIFECYCLE_STATUS, recommendLaneLifecycleNextStep, validateLaneArtifacts, setLaneLifecycleStatus, } from './lane-lifecycle-process.js';
@@ -11,10 +11,10 @@ import { runCLI } from './cli-entry-point.js';
11
11
  const LOG_PREFIX = '[lane:setup]';
12
12
  const LANE_VALIDATE_COMMAND = 'pnpm lane:validate';
13
13
  function ensureLumenflowInit(projectRoot) {
14
- const configPath = path.join(projectRoot, CONFIG_FILES.LUMENFLOW_CONFIG);
14
+ const configPath = path.join(projectRoot, WORKSPACE_CONFIG_FILE_NAME);
15
15
  if (!existsSync(configPath)) {
16
- die(`${LOG_PREFIX} Missing ${CONFIG_FILES.LUMENFLOW_CONFIG}.\n\n` +
17
- 'Run `pnpm exec lumenflow init` first, then configure lane lifecycle.');
16
+ die(`${LOG_PREFIX} Missing ${WORKSPACE_CONFIG_FILE_NAME}.\n\n` +
17
+ 'Run `pnpm workspace-init --yes` first, then configure lane lifecycle.');
18
18
  }
19
19
  }
20
20
  async function main() {
@@ -26,7 +26,7 @@ async function main() {
26
26
  console.log(`${LOG_PREFIX} Lane lifecycle status: ${result.status}`);
27
27
  if (result.createdDefinitions || result.createdInference) {
28
28
  console.log(`${LOG_PREFIX} Draft artifacts prepared:`);
29
- console.log(` - ${CONFIG_FILES.LUMENFLOW_CONFIG}: ${result.createdDefinitions ? 'created/updated lane definitions' : 'existing definitions preserved'}`);
29
+ console.log(` - ${WORKSPACE_CONFIG_FILE_NAME}: ${result.createdDefinitions ? 'created/updated lane definitions' : 'existing definitions preserved'}`);
30
30
  console.log(` - ${CONFIG_FILES.LANE_INFERENCE}: ${result.createdInference ? 'created draft taxonomy' : 'existing taxonomy preserved'}`);
31
31
  }
32
32
  else {
@@ -3,17 +3,16 @@
3
3
  // SPDX-License-Identifier: AGPL-3.0-only
4
4
  import path from 'node:path';
5
5
  import { existsSync } from 'node:fs';
6
- import { findProjectRoot } from '@lumenflow/core/config';
6
+ import { findProjectRoot, WORKSPACE_CONFIG_FILE_NAME } from '@lumenflow/core/config';
7
7
  import { die } from '@lumenflow/core/error-handler';
8
- import { CONFIG_FILES } from '@lumenflow/core/wu-constants';
9
8
  import { ensureLaneLifecycleForProject, recommendLaneLifecycleNextStep, } from './lane-lifecycle-process.js';
10
9
  import { runCLI } from './cli-entry-point.js';
11
10
  const LOG_PREFIX = '[lane:status]';
12
11
  function ensureLumenflowInit(projectRoot) {
13
- const configPath = path.join(projectRoot, CONFIG_FILES.LUMENFLOW_CONFIG);
12
+ const configPath = path.join(projectRoot, WORKSPACE_CONFIG_FILE_NAME);
14
13
  if (!existsSync(configPath)) {
15
- die(`${LOG_PREFIX} Missing ${CONFIG_FILES.LUMENFLOW_CONFIG}.\n\n` +
16
- 'Run `pnpm exec lumenflow init` first, then re-run lane lifecycle commands.');
14
+ die(`${LOG_PREFIX} Missing ${WORKSPACE_CONFIG_FILE_NAME}.\n\n` +
15
+ 'Run `pnpm workspace-init --yes` first, then re-run lane lifecycle commands.');
17
16
  }
18
17
  }
19
18
  /**
@@ -23,6 +23,7 @@ import { findProjectRoot, createWUParser } from '@lumenflow/core';
23
23
  import { gatherProjectContext, generateSystemPrompt, generateUserPrompt, getDefaultSuggestions, isValidLaneFormat, } from '@lumenflow/core/lane-suggest-prompt';
24
24
  import { extractGitContext, summarizeGitContext, } from '@lumenflow/core/git-context-extractor';
25
25
  import { runCLI } from './cli-entry-point.js';
26
+ import { GIT_SUMMARY_PREVIEW_LENGTH, GIT_CONTEXT_MAX_TOKENS, SYSTEM_PROMPT_PREVIEW_LENGTH, USER_PROMPT_PREVIEW_LENGTH, JSON_INDENT, } from './constants.js';
26
27
  /**
27
28
  * CLI option definitions
28
29
  */
@@ -216,12 +217,13 @@ function displayDryRun(context, systemPrompt, userPrompt, gitContext, gitSummary
216
217
  console.log(chalk.gray(` - Churn hotspots: ${gitContext.churn.length} files identified`));
217
218
  }
218
219
  console.log(chalk.bold('\nGit Summary (for LLM):'));
219
- console.log(chalk.gray(gitSummary.slice(0, 500) + (gitSummary.length > 500 ? '...' : '')));
220
+ console.log(chalk.gray(gitSummary.slice(0, GIT_SUMMARY_PREVIEW_LENGTH) +
221
+ (gitSummary.length > GIT_SUMMARY_PREVIEW_LENGTH ? '...' : '')));
220
222
  }
221
223
  console.log(chalk.bold('\nSystem Prompt Preview:'));
222
- console.log(chalk.gray(systemPrompt.slice(0, 500) + '...'));
224
+ console.log(chalk.gray(systemPrompt.slice(0, SYSTEM_PROMPT_PREVIEW_LENGTH) + '...'));
223
225
  console.log(chalk.bold('\nUser Prompt Preview:'));
224
- console.log(chalk.gray(userPrompt.slice(0, 1000) + '...'));
226
+ console.log(chalk.gray(userPrompt.slice(0, USER_PROMPT_PREVIEW_LENGTH) + '...'));
225
227
  console.log(chalk.bold('\nDefault Suggestions (without LLM):'));
226
228
  const defaults = getDefaultSuggestions(context);
227
229
  for (let i = 0; i < defaults.length; i++) {
@@ -258,7 +260,7 @@ function outputAsJson(suggestions, context) {
258
260
  },
259
261
  };
260
262
  console.log(chalk.bold('\nJSON Output:'));
261
- console.log(JSON.stringify(result, null, 2));
263
+ console.log(JSON.stringify(result, null, JSON_INDENT));
262
264
  }
263
265
  /**
264
266
  * Write suggestions to YAML file
@@ -319,7 +321,7 @@ ${gitSummary}
319
321
  /**
320
322
  * Main entry point
321
323
  */
322
- async function main() {
324
+ export async function main() {
323
325
  const opts = parseOptions();
324
326
  const projectRoot = findProjectRoot();
325
327
  console.log(chalk.bold('[lane:suggest] Analyzing project structure...'));
@@ -340,7 +342,7 @@ async function main() {
340
342
  console.log(chalk.gray(` - ${gitContext.churn.length} churn hotspots`));
341
343
  }
342
344
  // Summarize for LLM prompt (respecting token limits)
343
- gitSummary = summarizeGitContext(gitContext, { maxTokens: 500 });
345
+ gitSummary = summarizeGitContext(gitContext, { maxTokens: GIT_CONTEXT_MAX_TOKENS });
344
346
  }
345
347
  if (opts.dryRun) {
346
348
  const userPrompt = generateEnrichedUserPrompt(context, gitSummary);
@@ -380,5 +382,5 @@ if (import.meta.main) {
380
382
  void runCLI(main);
381
383
  }
382
384
  // Export for testing
383
- export { main, parseOptions, formatSuggestion, interactiveMode, generateLaneInferenceYAML };
385
+ export { parseOptions, formatSuggestion, interactiveMode, generateLaneInferenceYAML };
384
386
  //# sourceMappingURL=lane-suggest.js.map
@@ -3,18 +3,17 @@
3
3
  // SPDX-License-Identifier: AGPL-3.0-only
4
4
  import path from 'node:path';
5
5
  import { existsSync } from 'node:fs';
6
- import { findProjectRoot } from '@lumenflow/core/config';
6
+ import { findProjectRoot, WORKSPACE_CONFIG_FILE_NAME } from '@lumenflow/core/config';
7
7
  import { die } from '@lumenflow/core/error-handler';
8
- import { CONFIG_FILES } from '@lumenflow/core/wu-constants';
9
8
  import { LANE_LIFECYCLE_STATUS, recommendLaneLifecycleNextStep, setLaneLifecycleStatus, validateLaneArtifacts, } from './lane-lifecycle-process.js';
10
9
  import { runCLI } from './cli-entry-point.js';
11
10
  const LOG_PREFIX = '[lane:validate]';
12
11
  const PASS_SENTINEL = 'Lane lifecycle validation passed.';
13
12
  function ensureLumenflowInit(projectRoot) {
14
- const configPath = path.join(projectRoot, CONFIG_FILES.LUMENFLOW_CONFIG);
13
+ const configPath = path.join(projectRoot, WORKSPACE_CONFIG_FILE_NAME);
15
14
  if (!existsSync(configPath)) {
16
- die(`${LOG_PREFIX} Missing ${CONFIG_FILES.LUMENFLOW_CONFIG}.\n\n` +
17
- 'Run `pnpm exec lumenflow init` first, then configure lane lifecycle.');
15
+ die(`${LOG_PREFIX} Missing ${WORKSPACE_CONFIG_FILE_NAME}.\n\n` +
16
+ 'Run `pnpm workspace-init --yes` first, then configure lane lifecycle.');
18
17
  }
19
18
  }
20
19
  async function main() {
@@ -30,6 +30,15 @@ import { runCLI } from './cli-entry-point.js';
30
30
  const LOG_PREFIX = '[lumenflow:upgrade]';
31
31
  /** Operation name for micro-worktree */
32
32
  const OPERATION_NAME = 'lumenflow-upgrade';
33
+ /** CLI argument names */
34
+ const ARG_HELP = '--help';
35
+ const ARG_HELP_SHORT = '-h';
36
+ const ARG_VERSION = '--version';
37
+ const ARG_VERSION_SHORT = '-v';
38
+ const ARG_LATEST = '--latest';
39
+ const ARG_LATEST_SHORT = '-l';
40
+ const ARG_DRY_RUN = '--dry-run';
41
+ const ARG_DRY_RUN_SHORT = '-n';
33
42
  /**
34
43
  * All @lumenflow/* packages that should be upgraded together
35
44
  *
@@ -57,16 +66,16 @@ export function parseUpgradeArgs(argv) {
57
66
  const cliArgs = argv.slice(2);
58
67
  for (let i = 0; i < cliArgs.length; i++) {
59
68
  const arg = cliArgs[i];
60
- if (arg === '--help' || arg === '-h') {
69
+ if (arg === ARG_HELP || arg === ARG_HELP_SHORT) {
61
70
  args.help = true;
62
71
  }
63
- else if (arg === '--version' || arg === '-v') {
72
+ else if (arg === ARG_VERSION || arg === ARG_VERSION_SHORT) {
64
73
  args.version = cliArgs[++i];
65
74
  }
66
- else if (arg === '--latest' || arg === '-l') {
75
+ else if (arg === ARG_LATEST || arg === ARG_LATEST_SHORT) {
67
76
  args.latest = true;
68
77
  }
69
- else if (arg === '--dry-run' || arg === '-n') {
78
+ else if (arg === ARG_DRY_RUN || arg === ARG_DRY_RUN_SHORT) {
70
79
  args.dryRun = true;
71
80
  }
72
81
  }
@@ -211,13 +220,10 @@ function printHelp() {
211
220
  console.log(`
212
221
  Usage: lumenflow-upgrade [options]
213
222
 
214
- Upgrade all @lumenflow/* packages to a specified version.
215
- Uses micro-worktree isolation to atomically update packages from main checkout.
216
-
217
223
  Options:
218
- -v, --version <ver> Upgrade to specific version (e.g., 1.5.0)
219
- -l, --latest Upgrade to latest version
220
- -n, --dry-run Show commands without executing
224
+ -v, --version <ver> Upgrade to specific version (e.g., 1.5.0)
225
+ -l, --latest Upgrade to latest version
226
+ -n, --dry-run Show commands without executing
221
227
  -h, --help Show this help message
222
228
 
223
229
  Packages upgraded (all 7):
@@ -241,7 +247,7 @@ Micro-Worktree Pattern (WU-1127):
241
247
  * Main entry point for lumenflow-upgrade command
242
248
  */
243
249
  /* istanbul ignore next -- CLI entry point */
244
- async function main() {
250
+ export async function main() {
245
251
  const args = parseUpgradeArgs(process.argv);
246
252
  if (args.help) {
247
253
  printHelp();
@@ -225,7 +225,7 @@ function printMetadata(metadata) {
225
225
  /**
226
226
  * Main CLI entry point
227
227
  */
228
- async function main() {
228
+ export async function main() {
229
229
  const { args, note } = parseArguments();
230
230
  if (!note) {
231
231
  console.error(`${LOG_PREFIX} Error: note is required`);
@@ -39,6 +39,7 @@ import { archiveByDecay } from '@lumenflow/memory/decay/archival';
39
39
  import { getConfig } from '@lumenflow/core/config';
40
40
  import { createWUParser } from '@lumenflow/core/arg-parser';
41
41
  import { EXIT_CODES, LUMENFLOW_PATHS } from '@lumenflow/core/wu-constants';
42
+ import { formatBytes, MS_PER_DAY } from './constants.js';
42
43
  import { runCLI } from './cli-entry-point.js';
43
44
  /**
44
45
  * Log prefix for mem:cleanup output
@@ -48,10 +49,7 @@ const LOG_PREFIX = '[mem:cleanup]';
48
49
  * Tool name for audit logging
49
50
  */
50
51
  const TOOL_NAME = 'mem:cleanup';
51
- /**
52
- * Bytes per KB for formatting
53
- */
54
- const BYTES_PER_KB = 1024;
52
+ // WU-2044: BYTES_PER_KB imported from ./constants.js
55
53
  /**
56
54
  * CLI argument options specific to mem:cleanup
57
55
  */
@@ -89,7 +87,7 @@ const CLI_OPTIONS = {
89
87
  decay: {
90
88
  name: 'decay',
91
89
  flags: '--decay',
92
- description: 'Run decay-based archival (archive stale nodes below threshold). Uses config from .lumenflow.config.yaml or defaults.',
90
+ description: 'Run decay-based archival (archive stale nodes below threshold). Uses config from workspace.yaml software_delivery or defaults.',
93
91
  },
94
92
  };
95
93
  /**
@@ -110,19 +108,7 @@ async function writeAuditLog(baseDir, entry) {
110
108
  // Audit logging is non-fatal - silently ignore errors
111
109
  }
112
110
  }
113
- /**
114
- * Format bytes as human-readable string
115
- *
116
- * @param {number} bytes - Number of bytes
117
- * @returns {string} Formatted string (e.g., "1.5 KB")
118
- */
119
- function formatBytes(bytes) {
120
- if (bytes < BYTES_PER_KB) {
121
- return `${bytes} B`;
122
- }
123
- const kb = (bytes / BYTES_PER_KB).toFixed(1);
124
- return `${kb} KB`;
125
- }
111
+ // WU-2044: formatBytes imported from ./constants.js
126
112
  /**
127
113
  * Format compaction ratio as percentage
128
114
  *
@@ -213,10 +199,7 @@ function printResult(result, quiet, ttl) {
213
199
  console.log('To execute, run without --dry-run');
214
200
  }
215
201
  }
216
- /**
217
- * WU-1474: Milliseconds per day for converting half_life_days to halfLifeMs
218
- */
219
- const MS_PER_DAY = 24 * 60 * 60 * 1000;
202
+ // WU-2044: MS_PER_DAY imported from ./constants.js (local to avoid cross-package subpath export)
220
203
  // WU-1548: Using LUMENFLOW_PATHS.MEMORY_DIR from wu-constants (consolidated)
221
204
  /**
222
205
  * WU-1474: Print decay archival result to console
@@ -308,7 +291,7 @@ async function runDecayMode(baseDir, dryRun, json, quiet) {
308
291
  /**
309
292
  * Main CLI entry point
310
293
  */
311
- async function main() {
294
+ export async function main() {
312
295
  const args = parseArguments();
313
296
  const baseDir = args.baseDir || process.cwd();
314
297
  // WU-1474: Decay mode - separate execution path
@@ -207,7 +207,7 @@ function printJsonFormat(result, wuId) {
207
207
  /**
208
208
  * Main CLI entry point
209
209
  */
210
- async function main() {
210
+ export async function main() {
211
211
  const args = createWUParser({
212
212
  name: 'mem-context',
213
213
  description: 'Generate context injection block for delegation prompts',
@@ -181,7 +181,7 @@ function printMetadata(metadata) {
181
181
  /**
182
182
  * Main CLI entry point
183
183
  */
184
- async function main() {
184
+ export async function main() {
185
185
  const { args, title } = parseArguments();
186
186
  if (!title) {
187
187
  console.error(`${LOG_PREFIX} Error: title is required`);
@@ -235,7 +235,7 @@ function printUsageAndExit() {
235
235
  /**
236
236
  * Main CLI entry point
237
237
  */
238
- async function main() {
238
+ export async function main() {
239
239
  const { args, nodeIds } = parseArguments();
240
240
  const baseDir = args.baseDir || process.cwd();
241
241
  const startedAt = new Date().toISOString();
@@ -62,7 +62,7 @@ function validateFormat(format) {
62
62
  function validateLifecycle(lifecycle) {
63
63
  return ['ephemeral', 'session', 'wu', 'project'].includes(lifecycle);
64
64
  }
65
- async function main() {
65
+ export async function main() {
66
66
  const args = createWUParser({
67
67
  name: 'mem-export',
68
68
  description: 'Export memory nodes as markdown or JSON',
package/dist/mem-inbox.js CHANGED
@@ -314,7 +314,7 @@ async function runStandardMode(baseDir, filterOptions, markAsRead, quiet) {
314
314
  /**
315
315
  * Main CLI entry point
316
316
  */
317
- async function main() {
317
+ export async function main() {
318
318
  // WU-2202: Validate dependencies BEFORE UnsafeAny other operation
319
319
  const depResult = await validateInboxDependencies();
320
320
  if (!depResult.valid) {
package/dist/mem-init.js CHANGED
@@ -66,7 +66,7 @@ const CLI_OPTIONS = {
66
66
  /**
67
67
  * Main CLI entry point
68
68
  */
69
- async function main() {
69
+ export async function main() {
70
70
  const args = createWUParser({
71
71
  name: 'mem-init',
72
72
  description: 'Initialize memory layer in repository',
package/dist/mem-ready.js CHANGED
@@ -143,7 +143,7 @@ function printJsonFormat(nodes, opts) {
143
143
  /**
144
144
  * Main CLI entry point
145
145
  */
146
- async function main() {
146
+ export async function main() {
147
147
  const args = createWUParser({
148
148
  name: 'mem-ready',
149
149
  description: 'Query ready nodes for a WU (deterministic ordering)',
@@ -136,7 +136,7 @@ function printJsonFormat(result, wuId) {
136
136
  /**
137
137
  * Main CLI entry point
138
138
  */
139
- async function main() {
139
+ export async function main() {
140
140
  const args = createWUParser({
141
141
  name: 'mem-recover',
142
142
  description: 'Generate post-compaction recovery context for agents',
@@ -138,7 +138,7 @@ function printSignalDetails(result) {
138
138
  /**
139
139
  * Main CLI entry point
140
140
  */
141
- async function main() {
141
+ export async function main() {
142
142
  const { args, message } = parseArguments();
143
143
  if (!message) {
144
144
  console.error(`${LOG_PREFIX} Error: message is required`);
package/dist/mem-start.js CHANGED
@@ -77,7 +77,7 @@ const CLI_OPTIONS = {
77
77
  /**
78
78
  * Main CLI entry point
79
79
  */
80
- async function main() {
80
+ export async function main() {
81
81
  const args = createWUParser({
82
82
  name: 'mem-start',
83
83
  description: 'Create a session node linked to a WU',
@@ -27,6 +27,7 @@ import { summarizeWu } from '@lumenflow/memory/summarize';
27
27
  import { createWUParser } from '@lumenflow/core/arg-parser';
28
28
  import { EXIT_CODES, LUMENFLOW_PATHS } from '@lumenflow/core/wu-constants';
29
29
  import { runCLI } from './cli-entry-point.js';
30
+ import { CLEANUP_LIST_DISPLAY_LIMIT, CONTENT_PREVIEW_LENGTH, JSON_INDENT } from './constants.js';
30
31
  /**
31
32
  * Log prefix for mem:summarize output
32
33
  */
@@ -135,17 +136,17 @@ function printResult(result, quiet) {
135
136
  if (result.markedForCleanup.length > 0) {
136
137
  console.log('');
137
138
  console.log('Marked for Cleanup:');
138
- for (const nodeId of result.markedForCleanup.slice(0, 10)) {
139
+ for (const nodeId of result.markedForCleanup.slice(0, CLEANUP_LIST_DISPLAY_LIMIT)) {
139
140
  console.log(` - ${nodeId}`);
140
141
  }
141
- if (result.markedForCleanup.length > 10) {
142
- console.log(` ... and ${result.markedForCleanup.length - 10} more`);
142
+ if (result.markedForCleanup.length > CLEANUP_LIST_DISPLAY_LIMIT) {
143
+ console.log(` ... and ${result.markedForCleanup.length - CLEANUP_LIST_DISPLAY_LIMIT} more`);
143
144
  }
144
145
  }
145
146
  console.log('');
146
147
  console.log('Content Preview:');
147
- const preview = result.summary.content.slice(0, 200);
148
- console.log(` ${preview}${result.summary.content.length > 200 ? '...' : ''}`);
148
+ const preview = result.summary.content.slice(0, CONTENT_PREVIEW_LENGTH);
149
+ console.log(` ${preview}${result.summary.content.length > CONTENT_PREVIEW_LENGTH ? '...' : ''}`);
149
150
  if (result.dryRun) {
150
151
  console.log('');
151
152
  console.log('To execute, run without --dry-run');
@@ -154,7 +155,7 @@ function printResult(result, quiet) {
154
155
  /**
155
156
  * Main CLI entry point
156
157
  */
157
- async function main() {
158
+ export async function main() {
158
159
  const args = parseArguments();
159
160
  const baseDir = args.baseDir || process.cwd();
160
161
  const startedAt = new Date().toISOString();
@@ -199,7 +200,7 @@ async function main() {
199
200
  process.exit(EXIT_CODES.ERROR);
200
201
  }
201
202
  if (args.json) {
202
- console.log(JSON.stringify(result, null, 2));
203
+ console.log(JSON.stringify(result, null, JSON_INDENT));
203
204
  process.exit(EXIT_CODES.SUCCESS);
204
205
  }
205
206
  printResult(result, args.quiet);
@@ -27,6 +27,7 @@ import { listOpenDiscoveries, promoteDiscovery, archiveDiscovery } from '@lumenf
27
27
  import { createWUParser } from '@lumenflow/core/arg-parser';
28
28
  import { EXIT_CODES, LUMENFLOW_PATHS } from '@lumenflow/core/wu-constants';
29
29
  import { runCLI } from './cli-entry-point.js';
30
+ import { DISCOVERY_CONTENT_TRUNCATION_LENGTH, JSON_INDENT } from './constants.js';
30
31
  /**
31
32
  * Log prefix for mem:triage output
32
33
  */
@@ -134,7 +135,8 @@ function formatDiscovery(node) {
134
135
  parts.push(`(${node.wu_id})`);
135
136
  }
136
137
  parts.push('-');
137
- parts.push(node.content.substring(0, 60) + (node.content.length > 60 ? '...' : ''));
138
+ parts.push(node.content.substring(0, DISCOVERY_CONTENT_TRUNCATION_LENGTH) +
139
+ (node.content.length > DISCOVERY_CONTENT_TRUNCATION_LENGTH ? '...' : ''));
138
140
  return parts.join(' ');
139
141
  }
140
142
  async function handleList(baseDir, args) {
@@ -147,7 +149,7 @@ async function handleList(baseDir, args) {
147
149
  }
148
150
  const discoveries = await listOpenDiscoveries(baseDir, options);
149
151
  if (args.json) {
150
- console.log(JSON.stringify(discoveries, null, 2));
152
+ console.log(JSON.stringify(discoveries, null, JSON_INDENT));
151
153
  return { success: true, count: discoveries.length };
152
154
  }
153
155
  if (discoveries.length === 0) {
@@ -188,7 +190,7 @@ async function handlePromote(baseDir, args) {
188
190
  dryRun: args.dryRun,
189
191
  });
190
192
  if (args.json) {
191
- console.log(JSON.stringify(result, null, 2));
193
+ console.log(JSON.stringify(result, null, JSON_INDENT));
192
194
  return result;
193
195
  }
194
196
  if (args.dryRun) {
@@ -232,7 +234,7 @@ async function handleArchive(baseDir, args) {
232
234
  reason: args.reason,
233
235
  });
234
236
  if (args.json) {
235
- console.log(JSON.stringify(result, null, 2));
237
+ console.log(JSON.stringify(result, null, JSON_INDENT));
236
238
  return result;
237
239
  }
238
240
  if (!args.quiet) {
@@ -271,7 +273,7 @@ function parseArguments() {
271
273
  /**
272
274
  * Main CLI entry point
273
275
  */
274
- async function main() {
276
+ export async function main() {
275
277
  const args = parseArguments();
276
278
  const baseDir = process.cwd();
277
279
  const startedAt = new Date().toISOString();
@@ -410,7 +410,7 @@ async function writeOutput(baseDir, outputPath, data) {
410
410
  /**
411
411
  * Main entry point
412
412
  */
413
- async function main() {
413
+ export async function main() {
414
414
  const opts = parseCommand(process.argv);
415
415
  switch (opts.subcommand) {
416
416
  case 'lanes':
@@ -248,7 +248,7 @@ function formatSnapshot(snapshot, type) {
248
248
  /**
249
249
  * Main function
250
250
  */
251
- async function main() {
251
+ export async function main() {
252
252
  const opts = parseArgs();
253
253
  const baseDir = process.cwd();
254
254
  const type = opts.type;