@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.
- package/dist/docs-sync.js +123 -6
- package/dist/docs-sync.js.map +1 -1
- package/dist/gate-co-change.js +23 -4
- package/dist/gate-co-change.js.map +1 -1
- package/dist/gates-runners.js +108 -12
- package/dist/gates-runners.js.map +1 -1
- package/dist/lumenflow-upgrade.js +1 -0
- package/dist/lumenflow-upgrade.js.map +1 -1
- package/dist/public-manifest.js +1 -1
- package/dist/public-manifest.js.map +1 -1
- package/dist/sync-templates.js +13 -0
- package/dist/sync-templates.js.map +1 -1
- package/dist/wu-block.js +10 -0
- package/dist/wu-block.js.map +1 -1
- package/dist/wu-claim-validation.js +3 -1
- package/dist/wu-claim-validation.js.map +1 -1
- package/dist/wu-claim.js +3 -1
- package/dist/wu-claim.js.map +1 -1
- package/dist/wu-done-memory-telemetry.js +5 -1
- package/dist/wu-done-memory-telemetry.js.map +1 -1
- package/dist/wu-done-ownership.js +6 -0
- package/dist/wu-done-ownership.js.map +1 -1
- package/dist/wu-edit-operations.js +4 -4
- package/dist/wu-edit-operations.js.map +1 -1
- package/dist/wu-prep.js +88 -13
- package/dist/wu-prep.js.map +1 -1
- package/dist/wu-recover.js +15 -0
- package/dist/wu-recover.js.map +1 -1
- package/dist/wu-release.js +10 -1
- package/dist/wu-release.js.map +1 -1
- package/dist/wu-spawn-prompt-builders.js +27 -2
- package/dist/wu-spawn-prompt-builders.js.map +1 -1
- package/dist/wu-state-mutation-ownership.js +136 -0
- package/dist/wu-state-mutation-ownership.js.map +1 -0
- package/dist/wu-unblock.js +10 -0
- package/dist/wu-unblock.js.map +1 -1
- package/package.json +111 -110
- package/packs/agent-runtime/.turbo/turbo-build.log +1 -1
- package/packs/agent-runtime/package.json +1 -1
- package/packs/sidekick/.turbo/turbo-build.log +1 -1
- package/packs/sidekick/package.json +1 -1
- package/packs/software-delivery/.turbo/turbo-build.log +1 -1
- package/packs/software-delivery/package.json +1 -1
- package/templates/core/AGENTS.md.template +157 -32
- package/templates/core/LUMENFLOW.md.template +44 -29
- package/templates/core/_frameworks/lumenflow/wu-sizing-guide.md.template +644 -0
- package/templates/core/ai/onboarding/agent-invocation-guide.md.template +5 -5
- package/templates/core/ai/onboarding/agent-safety-card.md.template +1 -0
- package/templates/core/ai/onboarding/docs-generation.md.template +94 -4
- package/templates/core/ai/onboarding/first-15-mins.md.template +1 -1
- package/templates/core/ai/onboarding/first-wu-mistakes.md.template +2 -1
- package/templates/core/ai/onboarding/initiative-orchestration.md.template +21 -21
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +102 -95
- package/templates/core/ai/onboarding/release-process.md.template +12 -12
- package/templates/core/ai/onboarding/starting-prompt.md.template +31 -31
- package/templates/vendors/claude/.claude/skills/initiative-management/SKILL.md.template +2 -2
- package/templates/vendors/claude/.claude/skills/multi-agent-coordination/SKILL.md.template +2 -2
- package/templates/vendors/claude/.claude/skills/orchestration/SKILL.md.template +3 -3
- package/dist/chunk-2D2VOCA4.js +0 -37
- package/dist/chunk-2D5KFYGX.js +0 -284
- package/dist/chunk-2GXVIN57.js +0 -14072
- package/dist/chunk-2MQ7HZWZ.js +0 -26
- package/dist/chunk-2UFQ3A3C.js +0 -643
- package/dist/chunk-3RG5ZIWI.js +0 -10
- package/dist/chunk-4N74J3UT.js +0 -15
- package/dist/chunk-5GTOXFYR.js +0 -392
- package/dist/chunk-5VY6MQMC.js +0 -240
- package/dist/chunk-67XVPMRY.js +0 -1297
- package/dist/chunk-6HO4GWJE.js +0 -164
- package/dist/chunk-6W5XHWYV.js +0 -1890
- package/dist/chunk-6X4EMYJQ.js +0 -64
- package/dist/chunk-6XYXI2NQ.js +0 -772
- package/dist/chunk-7ANSOV6Q.js +0 -285
- package/dist/chunk-A624LFLB.js +0 -1380
- package/dist/chunk-ADN5NHG4.js +0 -126
- package/dist/chunk-B7YJYJKG.js +0 -33
- package/dist/chunk-CCLHCPKG.js +0 -210
- package/dist/chunk-CK36VROC.js +0 -1584
- package/dist/chunk-D3UOFRSB.js +0 -81
- package/dist/chunk-DFR4DJBM.js +0 -230
- package/dist/chunk-DSYBDHYH.js +0 -79
- package/dist/chunk-DWMLTXKQ.js +0 -1176
- package/dist/chunk-E3REJTAJ.js +0 -28
- package/dist/chunk-EA3IVO64.js +0 -633
- package/dist/chunk-EK2AKZKD.js +0 -55
- package/dist/chunk-ELD7JTTT.js +0 -343
- package/dist/chunk-EX6TT2XI.js +0 -195
- package/dist/chunk-EXINSFZE.js +0 -82
- package/dist/chunk-EZ6ZBYBM.js +0 -510
- package/dist/chunk-FBKAPTJ2.js +0 -16
- package/dist/chunk-FVLV5RYH.js +0 -1118
- package/dist/chunk-GDNSBQVK.js +0 -2485
- package/dist/chunk-GPQHMBNN.js +0 -278
- package/dist/chunk-GTFJB67L.js +0 -68
- package/dist/chunk-HANJXVKW.js +0 -1127
- package/dist/chunk-HEVS5YLD.js +0 -269
- package/dist/chunk-HMEVZKPQ.js +0 -9
- package/dist/chunk-HRGSYNLM.js +0 -3511
- package/dist/chunk-ISZR5N4K.js +0 -60
- package/dist/chunk-J6SUPR2C.js +0 -226
- package/dist/chunk-JERYVEIZ.js +0 -244
- package/dist/chunk-JHHWGL2N.js +0 -87
- package/dist/chunk-JONWQUB5.js +0 -775
- package/dist/chunk-K2DIWWDM.js +0 -1766
- package/dist/chunk-KY4PGL5V.js +0 -969
- package/dist/chunk-L737LQ4C.js +0 -1285
- package/dist/chunk-LFTWYIB2.js +0 -497
- package/dist/chunk-LV47RFNJ.js +0 -41
- package/dist/chunk-MKSAITI7.js +0 -15
- package/dist/chunk-MZ7RKIX4.js +0 -212
- package/dist/chunk-NAP6CFSO.js +0 -84
- package/dist/chunk-ND6MY37M.js +0 -16
- package/dist/chunk-NMG736UR.js +0 -683
- package/dist/chunk-NRAXROED.js +0 -32
- package/dist/chunk-NRIZR3A7.js +0 -690
- package/dist/chunk-NX43BG3M.js +0 -233
- package/dist/chunk-O645XLSI.js +0 -297
- package/dist/chunk-OMJD6A3S.js +0 -235
- package/dist/chunk-QB6SJD4T.js +0 -430
- package/dist/chunk-QFSTL4J3.js +0 -276
- package/dist/chunk-QLGDFMFX.js +0 -212
- package/dist/chunk-RIAAGL2E.js +0 -13
- package/dist/chunk-RWO5XMZ6.js +0 -86
- package/dist/chunk-RXRKBBSM.js +0 -149
- package/dist/chunk-RZOZMML6.js +0 -363
- package/dist/chunk-U7I7FS7T.js +0 -113
- package/dist/chunk-UI42RODY.js +0 -717
- package/dist/chunk-UTVMVSCO.js +0 -519
- package/dist/chunk-V6OJGLBA.js +0 -1746
- package/dist/chunk-W2JHVH7D.js +0 -152
- package/dist/chunk-WD3Y7VQN.js +0 -280
- package/dist/chunk-WOCTQ5MS.js +0 -303
- package/dist/chunk-WZR3ZUNN.js +0 -696
- package/dist/chunk-XGI665H7.js +0 -150
- package/dist/chunk-XKY65P2T.js +0 -304
- package/dist/chunk-Y4CQZY65.js +0 -57
- package/dist/chunk-YFEXKLVE.js +0 -194
- package/dist/chunk-YHO3HS5X.js +0 -287
- package/dist/chunk-YLS7AZSX.js +0 -738
- package/dist/chunk-ZE473AO6.js +0 -49
- package/dist/chunk-ZF747T3O.js +0 -644
- package/dist/chunk-ZHCZHZH3.js +0 -43
- package/dist/chunk-ZZNZX2XY.js +0 -87
- package/dist/constants-7QAP3VQ4.js +0 -23
- package/dist/dist-IY3UUMWK.js +0 -33
- package/dist/invariants-runner-W5RGHCSU.js +0 -27
- package/dist/lane-lock-6J36HD5O.js +0 -35
- package/dist/mem-checkpoint-core-EANG2GVN.js +0 -14
- package/dist/mem-signal-core-2LZ2WYHW.js +0 -19
- package/dist/memory-store-OLB5FO7K.js +0 -18
- package/dist/service-6BYCOCO5.js +0 -13
- package/dist/spawn-policy-resolver-NTSZYQ6R.js +0 -17
- package/dist/spawn-task-builder-R4E2BHSW.js +0 -22
- package/dist/wu-done-pr-WLFFFEPJ.js +0 -25
- package/dist/wu-done-validation-3J5E36FE.js +0 -30
- package/dist/wu-duplicate-id-detector-5S7JHELK.js +0 -232
- package/packs/sidekick/.turbo/turbo-test.log +0 -12
- package/packs/sidekick/.turbo/turbo-typecheck.log +0 -4
- 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
|
|
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
|
-
- `
|
|
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
|
|
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
|
|
673
|
+
pnpm lumenflow
|
|
674
674
|
|
|
675
675
|
# Claude-specific setup
|
|
676
|
-
pnpm
|
|
676
|
+
pnpm lumenflow --client claude
|
|
677
677
|
|
|
678
678
|
# Cursor-specific setup
|
|
679
|
-
pnpm
|
|
679
|
+
pnpm lumenflow --client cursor
|
|
680
680
|
|
|
681
681
|
# Windsurf-specific setup
|
|
682
|
-
pnpm
|
|
682
|
+
pnpm lumenflow --client windsurf
|
|
683
683
|
|
|
684
684
|
# All clients
|
|
685
|
-
pnpm
|
|
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
|
|
697
|
+
pnpm lumenflow --merge
|
|
698
698
|
|
|
699
699
|
# Merge with client overlay
|
|
700
|
-
pnpm
|
|
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
|
|
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](
|
|
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
|
|
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
|
-
**
|
|
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
|
|
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
|
|
37
|
-
pnpm wu:brief --id WU-XXX --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
|
|
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
|
|
package/dist/chunk-2D2VOCA4.js
DELETED
|
@@ -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
|
-
};
|
package/dist/chunk-2D5KFYGX.js
DELETED
|
@@ -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
|
-
};
|