@lumenflow/cli 3.18.1 → 3.19.0

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 (159) hide show
  1. package/dist/docs-sync.js +123 -6
  2. package/dist/docs-sync.js.map +1 -1
  3. package/dist/gate-co-change.js +23 -4
  4. package/dist/gate-co-change.js.map +1 -1
  5. package/dist/gates-runners.js +108 -12
  6. package/dist/gates-runners.js.map +1 -1
  7. package/dist/lumenflow-upgrade.js +1 -0
  8. package/dist/lumenflow-upgrade.js.map +1 -1
  9. package/dist/public-manifest.js +1 -1
  10. package/dist/public-manifest.js.map +1 -1
  11. package/dist/sync-templates.js +13 -0
  12. package/dist/sync-templates.js.map +1 -1
  13. package/dist/wu-block.js +10 -0
  14. package/dist/wu-block.js.map +1 -1
  15. package/dist/wu-claim-validation.js +3 -1
  16. package/dist/wu-claim-validation.js.map +1 -1
  17. package/dist/wu-claim.js +3 -1
  18. package/dist/wu-claim.js.map +1 -1
  19. package/dist/wu-done-memory-telemetry.js +5 -1
  20. package/dist/wu-done-memory-telemetry.js.map +1 -1
  21. package/dist/wu-done-ownership.js +6 -0
  22. package/dist/wu-done-ownership.js.map +1 -1
  23. package/dist/wu-edit-operations.js +4 -4
  24. package/dist/wu-edit-operations.js.map +1 -1
  25. package/dist/wu-prep.js +88 -13
  26. package/dist/wu-prep.js.map +1 -1
  27. package/dist/wu-recover.js +15 -0
  28. package/dist/wu-recover.js.map +1 -1
  29. package/dist/wu-release.js +10 -1
  30. package/dist/wu-release.js.map +1 -1
  31. package/dist/wu-spawn-prompt-builders.js +27 -2
  32. package/dist/wu-spawn-prompt-builders.js.map +1 -1
  33. package/dist/wu-state-mutation-ownership.js +136 -0
  34. package/dist/wu-state-mutation-ownership.js.map +1 -0
  35. package/dist/wu-unblock.js +10 -0
  36. package/dist/wu-unblock.js.map +1 -1
  37. package/package.json +111 -110
  38. package/packs/agent-runtime/.turbo/turbo-build.log +1 -1
  39. package/packs/agent-runtime/package.json +1 -1
  40. package/packs/sidekick/.turbo/turbo-build.log +1 -1
  41. package/packs/sidekick/package.json +1 -1
  42. package/packs/software-delivery/.turbo/turbo-build.log +1 -1
  43. package/packs/software-delivery/package.json +1 -1
  44. package/templates/core/AGENTS.md.template +157 -32
  45. package/templates/core/LUMENFLOW.md.template +44 -29
  46. package/templates/core/_frameworks/lumenflow/wu-sizing-guide.md.template +644 -0
  47. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +5 -5
  48. package/templates/core/ai/onboarding/agent-safety-card.md.template +1 -0
  49. package/templates/core/ai/onboarding/docs-generation.md.template +94 -4
  50. package/templates/core/ai/onboarding/first-15-mins.md.template +1 -1
  51. package/templates/core/ai/onboarding/first-wu-mistakes.md.template +2 -1
  52. package/templates/core/ai/onboarding/initiative-orchestration.md.template +21 -21
  53. package/templates/core/ai/onboarding/quick-ref-commands.md.template +102 -95
  54. package/templates/core/ai/onboarding/release-process.md.template +12 -12
  55. package/templates/core/ai/onboarding/starting-prompt.md.template +31 -31
  56. package/templates/vendors/claude/.claude/skills/initiative-management/SKILL.md.template +2 -2
  57. package/templates/vendors/claude/.claude/skills/multi-agent-coordination/SKILL.md.template +2 -2
  58. package/templates/vendors/claude/.claude/skills/orchestration/SKILL.md.template +3 -3
  59. package/dist/chunk-2D2VOCA4.js +0 -37
  60. package/dist/chunk-2D5KFYGX.js +0 -284
  61. package/dist/chunk-2GXVIN57.js +0 -14072
  62. package/dist/chunk-2MQ7HZWZ.js +0 -26
  63. package/dist/chunk-2UFQ3A3C.js +0 -643
  64. package/dist/chunk-3RG5ZIWI.js +0 -10
  65. package/dist/chunk-4N74J3UT.js +0 -15
  66. package/dist/chunk-5GTOXFYR.js +0 -392
  67. package/dist/chunk-5VY6MQMC.js +0 -240
  68. package/dist/chunk-67XVPMRY.js +0 -1297
  69. package/dist/chunk-6HO4GWJE.js +0 -164
  70. package/dist/chunk-6W5XHWYV.js +0 -1890
  71. package/dist/chunk-6X4EMYJQ.js +0 -64
  72. package/dist/chunk-6XYXI2NQ.js +0 -772
  73. package/dist/chunk-7ANSOV6Q.js +0 -285
  74. package/dist/chunk-A624LFLB.js +0 -1380
  75. package/dist/chunk-ADN5NHG4.js +0 -126
  76. package/dist/chunk-B7YJYJKG.js +0 -33
  77. package/dist/chunk-CCLHCPKG.js +0 -210
  78. package/dist/chunk-CK36VROC.js +0 -1584
  79. package/dist/chunk-D3UOFRSB.js +0 -81
  80. package/dist/chunk-DFR4DJBM.js +0 -230
  81. package/dist/chunk-DSYBDHYH.js +0 -79
  82. package/dist/chunk-DWMLTXKQ.js +0 -1176
  83. package/dist/chunk-E3REJTAJ.js +0 -28
  84. package/dist/chunk-EA3IVO64.js +0 -633
  85. package/dist/chunk-EK2AKZKD.js +0 -55
  86. package/dist/chunk-ELD7JTTT.js +0 -343
  87. package/dist/chunk-EX6TT2XI.js +0 -195
  88. package/dist/chunk-EXINSFZE.js +0 -82
  89. package/dist/chunk-EZ6ZBYBM.js +0 -510
  90. package/dist/chunk-FBKAPTJ2.js +0 -16
  91. package/dist/chunk-FVLV5RYH.js +0 -1118
  92. package/dist/chunk-GDNSBQVK.js +0 -2485
  93. package/dist/chunk-GPQHMBNN.js +0 -278
  94. package/dist/chunk-GTFJB67L.js +0 -68
  95. package/dist/chunk-HANJXVKW.js +0 -1127
  96. package/dist/chunk-HEVS5YLD.js +0 -269
  97. package/dist/chunk-HMEVZKPQ.js +0 -9
  98. package/dist/chunk-HRGSYNLM.js +0 -3511
  99. package/dist/chunk-ISZR5N4K.js +0 -60
  100. package/dist/chunk-J6SUPR2C.js +0 -226
  101. package/dist/chunk-JERYVEIZ.js +0 -244
  102. package/dist/chunk-JHHWGL2N.js +0 -87
  103. package/dist/chunk-JONWQUB5.js +0 -775
  104. package/dist/chunk-K2DIWWDM.js +0 -1766
  105. package/dist/chunk-KY4PGL5V.js +0 -969
  106. package/dist/chunk-L737LQ4C.js +0 -1285
  107. package/dist/chunk-LFTWYIB2.js +0 -497
  108. package/dist/chunk-LV47RFNJ.js +0 -41
  109. package/dist/chunk-MKSAITI7.js +0 -15
  110. package/dist/chunk-MZ7RKIX4.js +0 -212
  111. package/dist/chunk-NAP6CFSO.js +0 -84
  112. package/dist/chunk-ND6MY37M.js +0 -16
  113. package/dist/chunk-NMG736UR.js +0 -683
  114. package/dist/chunk-NRAXROED.js +0 -32
  115. package/dist/chunk-NRIZR3A7.js +0 -690
  116. package/dist/chunk-NX43BG3M.js +0 -233
  117. package/dist/chunk-O645XLSI.js +0 -297
  118. package/dist/chunk-OMJD6A3S.js +0 -235
  119. package/dist/chunk-QB6SJD4T.js +0 -430
  120. package/dist/chunk-QFSTL4J3.js +0 -276
  121. package/dist/chunk-QLGDFMFX.js +0 -212
  122. package/dist/chunk-RIAAGL2E.js +0 -13
  123. package/dist/chunk-RWO5XMZ6.js +0 -86
  124. package/dist/chunk-RXRKBBSM.js +0 -149
  125. package/dist/chunk-RZOZMML6.js +0 -363
  126. package/dist/chunk-U7I7FS7T.js +0 -113
  127. package/dist/chunk-UI42RODY.js +0 -717
  128. package/dist/chunk-UTVMVSCO.js +0 -519
  129. package/dist/chunk-V6OJGLBA.js +0 -1746
  130. package/dist/chunk-W2JHVH7D.js +0 -152
  131. package/dist/chunk-WD3Y7VQN.js +0 -280
  132. package/dist/chunk-WOCTQ5MS.js +0 -303
  133. package/dist/chunk-WZR3ZUNN.js +0 -696
  134. package/dist/chunk-XGI665H7.js +0 -150
  135. package/dist/chunk-XKY65P2T.js +0 -304
  136. package/dist/chunk-Y4CQZY65.js +0 -57
  137. package/dist/chunk-YFEXKLVE.js +0 -194
  138. package/dist/chunk-YHO3HS5X.js +0 -287
  139. package/dist/chunk-YLS7AZSX.js +0 -738
  140. package/dist/chunk-ZE473AO6.js +0 -49
  141. package/dist/chunk-ZF747T3O.js +0 -644
  142. package/dist/chunk-ZHCZHZH3.js +0 -43
  143. package/dist/chunk-ZZNZX2XY.js +0 -87
  144. package/dist/constants-7QAP3VQ4.js +0 -23
  145. package/dist/dist-IY3UUMWK.js +0 -33
  146. package/dist/invariants-runner-W5RGHCSU.js +0 -27
  147. package/dist/lane-lock-6J36HD5O.js +0 -35
  148. package/dist/mem-checkpoint-core-EANG2GVN.js +0 -14
  149. package/dist/mem-signal-core-2LZ2WYHW.js +0 -19
  150. package/dist/memory-store-OLB5FO7K.js +0 -18
  151. package/dist/service-6BYCOCO5.js +0 -13
  152. package/dist/spawn-policy-resolver-NTSZYQ6R.js +0 -17
  153. package/dist/spawn-task-builder-R4E2BHSW.js +0 -22
  154. package/dist/wu-done-pr-WLFFFEPJ.js +0 -25
  155. package/dist/wu-done-validation-3J5E36FE.js +0 -30
  156. package/dist/wu-duplicate-id-detector-5S7JHELK.js +0 -232
  157. package/packs/sidekick/.turbo/turbo-test.log +0 -12
  158. package/packs/sidekick/.turbo/turbo-typecheck.log +0 -4
  159. package/packs/software-delivery/.turbo/turbo-typecheck.log +0 -4
@@ -124,6 +124,7 @@ cat {{DOCS_TASKS_PATH}}/wu/WU-XXXX.yaml
124
124
 
125
125
  # 2. Claim the WU (creates isolated worktree)
126
126
  pnpm wu:claim --id WU-XXXX --lane "Lane Name"
127
+ pnpm wu:brief --id WU-XXXX --client <client>
127
128
 
128
129
  # 3. IMMEDIATELY cd to worktree (CRITICAL!)
129
130
  cd worktrees/<lane>-wu-xxxx
@@ -152,6 +153,7 @@ cat {{DOCS_TASKS_PATH}}/wu/WU-XXXX.yaml
152
153
  # 2. Claim in cloud mode (no worktree, sets claimed_mode: branch-pr)
153
154
  pnpm wu:claim --id WU-XXXX --lane "Lane Name" --cloud
154
155
  # Or: LUMENFLOW_CLOUD=1 pnpm wu:claim --id WU-XXXX --lane "Lane Name"
156
+ pnpm wu:brief --id WU-XXXX --client <client>
155
157
 
156
158
  # 3. Work on the lane branch (lane/<lane>/wu-xxxx)
157
159
 
@@ -476,6 +478,8 @@ pnpm wu:done --id WU-XXX
476
478
 
477
479
  Use `wu:brief` to create parallel sub-agent handoff prompts for complex WUs. Use `wu:delegate` when you also need explicit lineage recording.
478
480
 
481
+ **MANDATORY:** You **must** run `wu:brief` explicitly after `wu:claim`. While `wu:claim` auto-records a stub event (`claim-auto`), this stub does **not** satisfy the `wu:done` evidence gate (WU-2379). Only an explicit `wu:brief` run generates the handoff prompt, checks lane occupation, validates sizing, and records proper evidence. Without it, `wu:done` will block.
482
+
479
483
  **Evidence recording:** `wu:brief` writes a checkpoint event to `.lumenflow/state/wu-events.jsonl` when run in a claimed workspace (worktree mode) or on the claimed lane branch (branch-pr/branch-only mode). This evidence is **required** — `wu:done` blocks feature/bug WUs without it (WU-2132). Running from an unrelated checkout/branch is side-effect-free (WU-2144). **Never delete or revert `wu-events.jsonl` entries** written by lifecycle commands — if evidence is accidentally lost, rerun `wu:brief` to recreate it.
480
484
 
481
485
  ### When to Use wu:brief
@@ -488,7 +492,7 @@ Use `wu:brief` to create parallel sub-agent handoff prompts for complex WUs. Use
488
492
  ### Choose the Correct Flow
489
493
 
490
494
  - **Delegating to a sub-agent:** Run `wu:brief` (or `wu:delegate` for lineage), then pass the generated prompt to Task tool.
491
- - **Implementing in current session:** Run `wu:brief --client <client>` to record evidence, then do the WU yourself. `wu:brief` always outputs full context AND records evidence.
495
+ - **Implementing in current session:** Run `wu:brief --client <client>` to satisfy evidence policy. It outputs full WU context and records evidence in a single step.
492
496
 
493
497
  ### How to Use wu:brief / wu:delegate
494
498
 
@@ -496,9 +500,6 @@ Use `wu:brief` to create parallel sub-agent handoff prompts for complex WUs. Use
496
500
  # Generate a handoff prompt + evidence (no lineage side effect)
497
501
  pnpm wu:brief --id WU-XXXX --client <client-type>
498
502
 
499
- # Self-implementation: wu:brief always outputs full context AND records evidence
500
- pnpm wu:brief --id WU-XXXX --client <client>
501
-
502
503
  # Generate + record explicit delegation lineage
503
504
  pnpm wu:delegate --id WU-XXXX --parent-wu WU-YYYY --client <client-type>
504
505
 
@@ -520,8 +521,7 @@ extra project commands, or client-specific overrides.
520
521
 
521
522
  - New installs get the current defaults automatically.
522
523
  - Existing installs get the runtime defaults after `pnpm lumenflow:upgrade --latest`.
523
- - `pnpm lumenflow:upgrade --latest` already refreshes managed docs, onboarding docs, and configured
524
- vendor assets. Use `pnpm docs:sync --vendor <type>` only for an extra targeted refresh.
524
+ - `lumenflow:upgrade` automatically syncs onboarding docs and vendor assets (no separate `docs:sync` step needed).
525
525
 
526
526
  Default profiles:
527
527
 
@@ -550,22 +550,22 @@ Domain-specific commands must come from local configuration, not core framework
550
550
 
551
551
  ## WU Lifecycle Commands
552
552
 
553
- | Command | Description | When to Use |
554
- | ---------------------------------------------- | ------------------------------------------------ | --------------------------- |
555
- | `pnpm wu:status --id WU-XXX` | Show WU state and valid commands | Check current state |
556
- | `pnpm wu:claim --id WU-XXX --lane "Lane"` | Claim WU and create worktree (default) | Start working (local) |
557
- | `pnpm wu:claim --id WU-XXX --lane "L" --cloud` | Claim WU in branch-pr mode (no worktree) | Start working (cloud) |
558
- | `pnpm wu:edit --id WU-XXX --field value` | Edit WU spec fields | Update notes/desc |
559
- | `pnpm wu:brief --id WU-XXX --client <client>` | **MANDATORY after wu:claim.** Generate prompt + evidence | Delegation or self-impl |
560
- | `pnpm wu:delegate --id WU-XXX --parent-wu P` | Generate prompt + record delegation | Auditable delegation flows |
561
- | `pnpm wu:prep --id WU-XXX` | Run gates in claimed workspace, prep completion | Before wu:done |
562
- | `pnpm wu:done --id WU-XXX` | Complete WU (merge or PR, cleanup) | After gates pass |
563
- | `pnpm wu:cleanup --id WU-XXX` | Post-merge cleanup (branch-pr) | After PR merge (cloud only) |
564
- | `pnpm wu:escalate --id WU-XXX` | Show or resolve escalation status | Escalation-triggered WUs |
565
- | `pnpm wu:escalate --resolve --id WU-XXX` | Resolve human escalation | Before wu:done (escalation) |
566
- | `pnpm wu:verify --id WU-XXX` | Verify WU completion (stamp, commit, clean tree) | After wu:done |
567
- | `pnpm wu:delete --id WU-XXX` | Delete WU spec and cleanup | Cancel stale/throwaway WUs |
568
- | `pnpm wu:recover --id WU-XXX` | Fix inconsistent WU state | When state is broken |
553
+ | Command | Description | When to Use |
554
+ | ---------------------------------------------- | ------------------------------------------------ | --------------------------------- |
555
+ | `pnpm wu:status --id WU-XXX` | Show WU state and valid commands | Check current state |
556
+ | `pnpm wu:claim --id WU-XXX --lane "Lane"` | Claim WU and create worktree (default) | Start working (local) |
557
+ | `pnpm wu:claim --id WU-XXX --lane "L" --cloud` | Claim WU in branch-pr mode (no worktree) | Start working (cloud) |
558
+ | `pnpm wu:edit --id WU-XXX --field value` | Edit WU spec fields | Update notes/desc |
559
+ | `pnpm wu:brief --id WU-XXX --client X` | Generate handoff prompt + record evidence | Delegation or self-implementation |
560
+ | `pnpm wu:delegate --id WU-XXX --parent-wu P` | Generate prompt + record delegation | Auditable delegation flows |
561
+ | `pnpm wu:prep --id WU-XXX` | Run gates in claimed workspace, prep completion | Before wu:done |
562
+ | `pnpm wu:done --id WU-XXX` | Complete WU (merge or PR, cleanup) | After gates pass |
563
+ | `pnpm wu:cleanup --id WU-XXX` | Post-merge cleanup (branch-pr) | After PR merge (cloud only) |
564
+ | `pnpm wu:escalate --id WU-XXX` | Show or resolve escalation status | Escalation-triggered WUs |
565
+ | `pnpm wu:escalate --resolve --id WU-XXX` | Resolve human escalation | Before wu:done (escalation) |
566
+ | `pnpm wu:verify --id WU-XXX` | Verify WU completion (stamp, commit, clean tree) | After wu:done |
567
+ | `pnpm wu:delete --id WU-XXX` | Delete WU spec and cleanup | Cancel stale/throwaway WUs |
568
+ | `pnpm wu:recover --id WU-XXX` | Fix inconsistent WU state | When state is broken |
569
569
 
570
570
  ---
571
571
 
@@ -670,19 +670,19 @@ When initializing LumenFlow, use the `--client` flag to generate client-specific
670
670
  pnpm add -D @lumenflow/cli
671
671
 
672
672
  # Universal setup (AGENTS.md only)
673
- pnpm exec lumenflow
673
+ pnpm lumenflow
674
674
 
675
675
  # Claude-specific setup
676
- pnpm exec lumenflow --client claude
676
+ pnpm lumenflow --client claude
677
677
 
678
678
  # Cursor-specific setup
679
- pnpm exec lumenflow --client cursor
679
+ pnpm lumenflow --client cursor
680
680
 
681
681
  # Windsurf-specific setup
682
- pnpm exec lumenflow --client windsurf
682
+ pnpm lumenflow --client windsurf
683
683
 
684
684
  # All clients
685
- pnpm exec lumenflow --client all
685
+ pnpm lumenflow --client all
686
686
  ```
687
687
 
688
688
  ### Adding LumenFlow to Existing Projects
@@ -694,10 +694,10 @@ Use `--merge` mode to safely add LumenFlow configuration to existing files witho
694
694
  pnpm add -D @lumenflow/cli
695
695
 
696
696
  # Merge into existing AGENTS.md (preserves your content)
697
- pnpm exec lumenflow --merge
697
+ pnpm lumenflow --merge
698
698
 
699
699
  # Merge with client overlay
700
- pnpm exec lumenflow --merge --client claude
700
+ pnpm lumenflow --merge --client claude
701
701
  ```
702
702
 
703
703
  The merge mode uses bounded markers (`<!-- LUMENFLOW:START -->` and `<!-- LUMENFLOW:END -->`) to safely insert and update the LumenFlow block while preserving everything else.
@@ -717,7 +717,7 @@ cp -rn /tmp/nextjs-scaffold/.* . 2>/dev/null || true
717
717
  # 3. Install and initialize LumenFlow
718
718
  pnpm install
719
719
  pnpm add -D @lumenflow/cli
720
- pnpm exec lumenflow --client claude --full
720
+ pnpm lumenflow --client claude --full
721
721
 
722
722
  # 4. Clean up
723
723
  rm -rf /tmp/nextjs-scaffold
@@ -733,5 +733,5 @@ rm -rf /tmp/nextjs-scaffold
733
733
  - [troubleshooting-wu-done.md](troubleshooting-wu-done.md) - Why agents forget wu:done
734
734
  - [first-wu-mistakes.md](first-wu-mistakes.md) - Common mistakes to avoid
735
735
  - [quick-ref-commands.md](quick-ref-commands.md) - Command reference
736
- - [wu-sizing-guide.md](../../wu-sizing-guide.md) - Context safety and WU sizing
736
+ - [wu-sizing-guide.md](wu-sizing-guide.md) - Context safety and WU sizing
737
737
  - [initiative-orchestration.md](initiative-orchestration.md) - Initiative orchestration, delegation, recovery
@@ -134,8 +134,8 @@ pnpm wu:brief --id WU-1501 --client claude-code # Prompt generation only
134
134
  pnpm wu:delegate --id WU-1502 --parent-wu WU-1500 # Prompt + lineage recording
135
135
  pnpm wu:delegate --id WU-1503 --parent-wu WU-1500
136
136
 
137
- # For WUs implemented in current session:
138
- pnpm wu:brief --id WU-1504 --client <client> # Full context + evidence (self-implementation)
137
+ # For WUs implemented in current session (full context + evidence):
138
+ pnpm wu:brief --id WU-1504 --client claude-code # Always gives context + records evidence
139
139
  ```
140
140
 
141
141
  ### Orchestration Pattern
@@ -35,10 +35,10 @@ pnpm wu:brief --id WU-XXX --client claude-code # Generate prompt only
35
35
  pnpm wu:delegate --id WU-XXX --parent-wu WU-YYY # Generate prompt + record lineage
36
36
  ```
37
37
 
38
- **Use wu:brief** when you are implementing the WU yourself (it always outputs full context AND records evidence):
38
+ **Self-implementation**: `wu:brief` always gives full context AND records evidence use it even when implementing yourself:
39
39
 
40
40
  ```bash
41
- pnpm wu:brief --id WU-XXX --client <client> # Full context + evidence recording
41
+ pnpm wu:brief --id WU-XXX --client claude-code # Full context + evidence (always)
42
42
  ```
43
43
 
44
44
  **DON'T use wu:brief/wu:delegate** for helper agents (code-reviewer, test-engineer) on YOUR WU.
@@ -33,8 +33,8 @@ pnpm wu:brief --id WU-XXX --client claude-code
33
33
  # ✅ CORRECT: Use wu:delegate for lineage-tracked delegation
34
34
  pnpm wu:delegate --id WU-XXX --parent-wu WU-YYY
35
35
 
36
- # ✅ CORRECT: wu:brief always outputs full context AND records evidence
37
- pnpm wu:brief --id WU-XXX --client <client>
36
+ # ✅ CORRECT: Use wu:brief for self-implementation (gives context + records evidence)
37
+ pnpm wu:brief --id WU-XXX --client claude-code
38
38
  ```
39
39
 
40
40
  **❌ NEVER do this:**
@@ -46,7 +46,7 @@ pnpm wu:brief --id WU-XXX --client <client>
46
46
  **Why this matters:**
47
47
 
48
48
  1. `wu:brief` generates prompts with context loading preamble, TDD directives, and constraints block
49
- 2. `wu:brief` always records evidence AND outputs full context (no separate evidence-only mode)
49
+ 2. `wu:brief` always records evidence AND provides full WU context (no silent mode)
50
50
  3. Sub-agents need `wu:claim` (inside generated prompts) to create proper lane locks and event tracking
51
51
  4. Direct Task spawns bypass all safety mechanisms, coordination signals, and spawn registry tracking
52
52
 
@@ -1,37 +0,0 @@
1
- import {
2
- TEST_TYPES,
3
- WU_TYPES
4
- } from "./chunk-V6OJGLBA.js";
5
-
6
- // ../core/dist/wu-type-helpers.js
7
- function isNonEmptyArray(value) {
8
- return Array.isArray(value) && value.length > 0;
9
- }
10
- function isDocumentationType(type) {
11
- return typeof type === "string" && type === WU_TYPES.DOCUMENTATION;
12
- }
13
- function isProcessType(type) {
14
- return typeof type === "string" && type === WU_TYPES.PROCESS;
15
- }
16
- function isDocsOrProcessType(type) {
17
- return isDocumentationType(type) || isProcessType(type);
18
- }
19
- function hasAnyTests(tests) {
20
- if (!tests || typeof tests !== "object")
21
- return false;
22
- const t = tests;
23
- return isNonEmptyArray(t[TEST_TYPES.MANUAL]) || isNonEmptyArray(t[TEST_TYPES.UNIT]) || isNonEmptyArray(t[TEST_TYPES.E2E]) || isNonEmptyArray(t[TEST_TYPES.INTEGRATION]);
24
- }
25
- function hasManualTests(tests) {
26
- if (!tests || typeof tests !== "object")
27
- return false;
28
- const t = tests;
29
- return isNonEmptyArray(t[TEST_TYPES.MANUAL]);
30
- }
31
-
32
- export {
33
- isDocumentationType,
34
- isDocsOrProcessType,
35
- hasAnyTests,
36
- hasManualTests
37
- };
@@ -1,284 +0,0 @@
1
- import {
2
- DomainPackManifestSchema,
3
- PACK_MANIFEST_FILE_NAME,
4
- UTF8_ENCODING,
5
- computeDeterministicPackHash,
6
- isBroadWildcardScopePattern,
7
- resolvePackToolEntryPath,
8
- validateDomainPackToolSafety,
9
- validatePackImportBoundaries
10
- } from "./chunk-HANJXVKW.js";
11
- import {
12
- WU_OPTIONS,
13
- createWUParser,
14
- runCLI
15
- } from "./chunk-2GXVIN57.js";
16
-
17
- // src/pack-validate.ts
18
- import { readFile } from "fs/promises";
19
- import { join, resolve } from "path";
20
- import YAML from "yaml";
21
- var LOG_PREFIX = "[pack:validate]";
22
- var DEFAULT_PACKS_ROOT = "packages/@lumenflow/packs";
23
- var HTTPS_PROTOCOL = "https:";
24
- var NETWORK_URL_PROPERTY = "url";
25
- var SECURITY_LINT_ERROR = {
26
- PERMISSION_SCOPE_READ_WRITE: "permission/scope mismatch: read-permission tool cannot request write path access.",
27
- PERMISSION_SCOPE_WRITE_MISSING: "permission/scope mismatch: write-permission tool must include at least one write path scope.",
28
- WILDCARD_WRITE: "forbidden wildcard write scope. Replace with constrained path pattern (for example reports/**/*.md).",
29
- NETWORK_URL_REQUIRED: "network-scoped tools must constrain input_schema.properties.url via const/enum https URL allow-list.",
30
- NETWORK_URL_INVALID: "network-scoped tool has invalid URL in input_schema.properties.url.",
31
- NETWORK_URL_SCHEME: "network-scoped tool URL must use https:// in input_schema.properties.url."
32
- };
33
- async function validatePack(options) {
34
- const { packRoot, hashExclusions } = options;
35
- const absolutePackRoot = resolve(packRoot);
36
- let manifest;
37
- const manifestResult = await validateManifest(absolutePackRoot);
38
- if (manifestResult.status === "pass" && manifestResult.manifest) {
39
- manifest = manifestResult.manifest;
40
- }
41
- const toolEntriesResult = manifest ? validateToolEntries(absolutePackRoot, manifest) : { status: "skip", error: "Skipped: manifest validation failed" };
42
- const importBoundariesResult = await checkImportBoundaries(absolutePackRoot, hashExclusions);
43
- const securityLintResult = manifest ? runSecurityLint(manifest) : { status: "skip", error: "Skipped: manifest validation failed" };
44
- const integrityResult = await computeIntegrity(absolutePackRoot, hashExclusions);
45
- const allPassed = manifestResult.status === "pass" && toolEntriesResult.status === "pass" && importBoundariesResult.status === "pass" && securityLintResult.status === "pass" && integrityResult.status === "pass";
46
- return {
47
- manifest: manifestResult,
48
- importBoundaries: importBoundariesResult,
49
- toolEntries: toolEntriesResult,
50
- securityLint: securityLintResult,
51
- integrity: integrityResult,
52
- allPassed
53
- };
54
- }
55
- async function validateManifest(packRoot) {
56
- try {
57
- const manifestPath = join(packRoot, PACK_MANIFEST_FILE_NAME);
58
- const manifestRaw = await readFile(manifestPath, UTF8_ENCODING);
59
- const parsed = YAML.parse(manifestRaw);
60
- const manifest = DomainPackManifestSchema.parse(parsed);
61
- return { status: "pass", manifest };
62
- } catch (err) {
63
- const message = err instanceof Error ? err.message : String(err);
64
- return { status: "fail", error: message };
65
- }
66
- }
67
- function validateToolEntries(packRoot, manifest) {
68
- try {
69
- for (const tool of manifest.tools) {
70
- resolvePackToolEntryPath(packRoot, tool.entry);
71
- }
72
- return { status: "pass" };
73
- } catch (err) {
74
- const message = err instanceof Error ? err.message : String(err);
75
- return { status: "fail", error: message };
76
- }
77
- }
78
- async function checkImportBoundaries(packRoot, hashExclusions) {
79
- try {
80
- await validatePackImportBoundaries(packRoot, hashExclusions);
81
- return { status: "pass" };
82
- } catch (err) {
83
- const message = err instanceof Error ? err.message : String(err);
84
- return { status: "fail", error: message };
85
- }
86
- }
87
- async function computeIntegrity(packRoot, hashExclusions) {
88
- try {
89
- const hash = await computeDeterministicPackHash({
90
- packRoot,
91
- exclusions: hashExclusions
92
- });
93
- return { status: "pass", hash };
94
- } catch (err) {
95
- const message = err instanceof Error ? err.message : String(err);
96
- return { status: "fail", error: message };
97
- }
98
- }
99
- function isObjectRecord(value) {
100
- return typeof value === "object" && value !== null;
101
- }
102
- function extractNetworkUrls(tool) {
103
- const inputSchema = tool.input_schema;
104
- if (!isObjectRecord(inputSchema)) {
105
- return [];
106
- }
107
- const properties = inputSchema.properties;
108
- if (!isObjectRecord(properties)) {
109
- return [];
110
- }
111
- const urlSchema = properties[NETWORK_URL_PROPERTY];
112
- if (!isObjectRecord(urlSchema)) {
113
- return [];
114
- }
115
- if (typeof urlSchema.const === "string") {
116
- return [urlSchema.const];
117
- }
118
- if (!Array.isArray(urlSchema.enum)) {
119
- return [];
120
- }
121
- return urlSchema.enum.filter((candidate) => typeof candidate === "string");
122
- }
123
- function lintPermissionScopeConsistency(tool) {
124
- const pathScopes = tool.required_scopes.filter(
125
- (scope) => scope.type === "path"
126
- );
127
- const hasWritePathScope = pathScopes.some((scope) => scope.access === "write");
128
- const issues = [];
129
- if (tool.permission === "read" && hasWritePathScope) {
130
- issues.push(SECURITY_LINT_ERROR.PERMISSION_SCOPE_READ_WRITE);
131
- }
132
- if (tool.permission === "write" && pathScopes.length > 0 && !hasWritePathScope) {
133
- issues.push(SECURITY_LINT_ERROR.PERMISSION_SCOPE_WRITE_MISSING);
134
- }
135
- return issues;
136
- }
137
- function runSecurityLint(manifest) {
138
- const issues = /* @__PURE__ */ new Set();
139
- for (const tool of manifest.tools) {
140
- for (const issue of lintPermissionScopeConsistency(tool)) {
141
- issues.add(`Tool "${tool.name}": ${issue}`);
142
- }
143
- for (const issue of validateDomainPackToolSafety(tool)) {
144
- issues.add(`Tool "${tool.name}": ${issue}`);
145
- }
146
- const hasNetworkScope = tool.required_scopes.some((scope) => scope.type === "network");
147
- for (const scope of tool.required_scopes) {
148
- if (scope.type !== "path") {
149
- continue;
150
- }
151
- if ((tool.permission === "write" || tool.permission === "admin") && scope.access === "write" && isBroadWildcardScopePattern(scope.pattern)) {
152
- issues.add(`Tool "${tool.name}": ${SECURITY_LINT_ERROR.WILDCARD_WRITE}`);
153
- }
154
- }
155
- if (!hasNetworkScope) {
156
- continue;
157
- }
158
- const allowedUrls = extractNetworkUrls(tool);
159
- if (allowedUrls.length === 0) {
160
- issues.add(`Tool "${tool.name}": ${SECURITY_LINT_ERROR.NETWORK_URL_REQUIRED}`);
161
- continue;
162
- }
163
- for (const allowedUrl of allowedUrls) {
164
- let parsedUrl;
165
- try {
166
- parsedUrl = new URL(allowedUrl);
167
- } catch {
168
- issues.add(
169
- `Tool "${tool.name}" URL "${allowedUrl}": ${SECURITY_LINT_ERROR.NETWORK_URL_INVALID}`
170
- );
171
- continue;
172
- }
173
- if (parsedUrl.protocol !== HTTPS_PROTOCOL) {
174
- issues.add(
175
- `Tool "${tool.name}" URL "${allowedUrl}": ${SECURITY_LINT_ERROR.NETWORK_URL_SCHEME}`
176
- );
177
- }
178
- }
179
- }
180
- if (issues.size > 0) {
181
- return {
182
- status: "fail",
183
- error: [...issues].join("\n")
184
- };
185
- }
186
- return { status: "pass" };
187
- }
188
- var CHECK_LABELS = {
189
- manifest: "Manifest schema",
190
- importBoundaries: "Import boundaries",
191
- toolEntries: "Tool entry resolution",
192
- securityLint: "Security lint",
193
- integrity: "Integrity hash"
194
- };
195
- var STATUS_INDICATORS = {
196
- pass: "PASS",
197
- fail: "FAIL",
198
- skip: "SKIP"
199
- };
200
- function formatValidationReport(result) {
201
- const lines = [];
202
- lines.push("Pack Validation Report");
203
- lines.push("=====================");
204
- lines.push("");
205
- const checks = [
206
- ["manifest", result.manifest],
207
- ["importBoundaries", result.importBoundaries],
208
- ["toolEntries", result.toolEntries],
209
- ["securityLint", result.securityLint],
210
- ["integrity", result.integrity]
211
- ];
212
- for (const [key, check] of checks) {
213
- const label = CHECK_LABELS[key];
214
- const indicator = STATUS_INDICATORS[check.status];
215
- lines.push(` [${indicator}] ${label}`);
216
- if (check.status === "fail" && check.error) {
217
- lines.push(` Error: ${check.error}`);
218
- }
219
- if (key === "integrity" && "hash" in check && check.hash) {
220
- lines.push(` Hash: sha256:${check.hash}`);
221
- }
222
- }
223
- lines.push("");
224
- lines.push(`Result: ${result.allPassed ? "ALL CHECKS PASSED" : "VALIDATION FAILED"}`);
225
- return lines.join("\n");
226
- }
227
- var PACK_VALIDATE_OPTIONS = {
228
- packId: {
229
- name: "id",
230
- flags: "--id <packId>",
231
- description: "Pack ID to validate (resolves under --packs-root)"
232
- },
233
- packsRoot: {
234
- name: "packsRoot",
235
- flags: "--packs-root <dir>",
236
- description: `Root directory containing packs (default: "${DEFAULT_PACKS_ROOT}")`
237
- },
238
- packRoot: {
239
- name: "packRoot",
240
- flags: "--pack-root <dir>",
241
- description: "Direct path to pack directory (overrides --id and --packs-root)"
242
- }
243
- };
244
- async function main() {
245
- const opts = createWUParser({
246
- name: "pack-validate",
247
- description: "Validate a LumenFlow domain pack for integrity",
248
- options: [
249
- PACK_VALIDATE_OPTIONS.packId,
250
- PACK_VALIDATE_OPTIONS.packsRoot,
251
- PACK_VALIDATE_OPTIONS.packRoot,
252
- WU_OPTIONS.force
253
- ]
254
- });
255
- const packId = opts.id;
256
- const packsRoot = opts.packsRoot ?? DEFAULT_PACKS_ROOT;
257
- const directPackRoot = opts.packRoot;
258
- let resolvedPackRoot;
259
- if (directPackRoot) {
260
- resolvedPackRoot = resolve(directPackRoot);
261
- } else if (packId) {
262
- resolvedPackRoot = resolve(packsRoot, packId);
263
- } else {
264
- console.error(`${LOG_PREFIX} Error: Provide --id <packId> or --pack-root <dir>`);
265
- process.exit(1);
266
- }
267
- console.log(`${LOG_PREFIX} Validating pack at: ${resolvedPackRoot}`);
268
- const result = await validatePack({ packRoot: resolvedPackRoot });
269
- const report = formatValidationReport(result);
270
- console.log(report);
271
- if (!result.allPassed) {
272
- process.exit(1);
273
- }
274
- }
275
- if (import.meta.main) {
276
- void runCLI(main);
277
- }
278
-
279
- export {
280
- LOG_PREFIX,
281
- validatePack,
282
- formatValidationReport,
283
- main
284
- };