@lumenflow/cli 2.1.1 → 2.2.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/__tests__/guard-main-branch.test.js +79 -0
- package/dist/agent-issues-query.d.ts +16 -0
- package/dist/agent-log-issue.d.ts +10 -0
- package/dist/agent-session-end.d.ts +10 -0
- package/dist/agent-session.d.ts +10 -0
- package/dist/backlog-prune.d.ts +84 -0
- package/dist/cli-entry-point.d.ts +8 -0
- package/dist/deps-add.d.ts +91 -0
- package/dist/deps-remove.d.ts +17 -0
- package/dist/docs-sync.d.ts +50 -0
- package/dist/file-delete.d.ts +84 -0
- package/dist/file-edit.d.ts +82 -0
- package/dist/file-read.d.ts +92 -0
- package/dist/file-write.d.ts +90 -0
- package/dist/flow-bottlenecks.d.ts +16 -0
- package/dist/flow-report.d.ts +16 -0
- package/dist/gates.d.ts +94 -0
- package/dist/git-branch.d.ts +65 -0
- package/dist/git-diff.d.ts +58 -0
- package/dist/git-log.d.ts +69 -0
- package/dist/git-status.d.ts +58 -0
- package/dist/guard-locked.d.ts +62 -0
- package/dist/guard-main-branch.d.ts +50 -0
- package/dist/guard-main-branch.js +11 -0
- package/dist/guard-worktree-commit.d.ts +59 -0
- package/dist/index.d.ts +10 -0
- package/dist/init-plan.d.ts +80 -0
- package/dist/init.d.ts +46 -0
- package/dist/initiative-add-wu.d.ts +22 -0
- package/dist/initiative-bulk-assign-wus.d.ts +16 -0
- package/dist/initiative-create.d.ts +28 -0
- package/dist/initiative-edit.d.ts +34 -0
- package/dist/initiative-list.d.ts +12 -0
- package/dist/initiative-status.d.ts +11 -0
- package/dist/lumenflow-upgrade.d.ts +103 -0
- package/dist/mem-checkpoint.d.ts +16 -0
- package/dist/mem-cleanup.d.ts +29 -0
- package/dist/mem-create.d.ts +17 -0
- package/dist/mem-export.d.ts +10 -0
- package/dist/mem-export.js +138 -0
- package/dist/mem-inbox.d.ts +35 -0
- package/dist/mem-init.d.ts +15 -0
- package/dist/mem-ready.d.ts +16 -0
- package/dist/mem-signal.d.ts +16 -0
- package/dist/mem-start.d.ts +16 -0
- package/dist/mem-summarize.d.ts +22 -0
- package/dist/mem-triage.d.ts +22 -0
- package/dist/metrics-cli.d.ts +90 -0
- package/dist/metrics-snapshot.d.ts +18 -0
- package/dist/orchestrate-init-status.d.ts +11 -0
- package/dist/orchestrate-initiative.d.ts +12 -0
- package/dist/orchestrate-monitor.d.ts +11 -0
- package/dist/release.d.ts +117 -0
- package/dist/rotate-progress.d.ts +48 -0
- package/dist/session-coordinator.d.ts +74 -0
- package/dist/spawn-list.d.ts +16 -0
- package/dist/state-bootstrap.d.ts +92 -0
- package/dist/sync-templates.d.ts +52 -0
- package/dist/trace-gen.d.ts +84 -0
- package/dist/validate-agent-skills.d.ts +50 -0
- package/dist/validate-agent-sync.d.ts +36 -0
- package/dist/validate-backlog-sync.d.ts +37 -0
- package/dist/validate-skills-spec.d.ts +40 -0
- package/dist/validate.d.ts +60 -0
- package/dist/wu-block.d.ts +16 -0
- package/dist/wu-claim.d.ts +74 -0
- package/dist/wu-cleanup.d.ts +35 -0
- package/dist/wu-cleanup.js +11 -2
- package/dist/wu-create.d.ts +69 -0
- package/dist/wu-delete.d.ts +21 -0
- package/dist/wu-deps.d.ts +13 -0
- package/dist/wu-done.d.ts +225 -0
- package/dist/wu-done.js +9 -3
- package/dist/wu-edit.d.ts +63 -0
- package/dist/wu-edit.js +76 -9
- package/dist/wu-infer-lane.d.ts +17 -0
- package/dist/wu-preflight.d.ts +47 -0
- package/dist/wu-prune.d.ts +16 -0
- package/dist/wu-recover.d.ts +37 -0
- package/dist/wu-release.d.ts +19 -0
- package/dist/wu-repair.d.ts +60 -0
- package/dist/wu-spawn-completion.d.ts +10 -0
- package/dist/wu-spawn.d.ts +192 -0
- package/dist/wu-spawn.js +176 -12
- package/dist/wu-status.d.ts +25 -0
- package/dist/wu-unblock.d.ts +16 -0
- package/dist/wu-unlock-lane.d.ts +19 -0
- package/dist/wu-validate.d.ts +16 -0
- package/package.json +7 -6
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WU Done Helper
|
|
4
|
+
*
|
|
5
|
+
* Canonical sequence (Worktree mode - DEFAULT):
|
|
6
|
+
* 1) Run gates in lane worktree (validates the change, not just main)
|
|
7
|
+
* 2) Pre-flight validation: run ALL pre-commit hooks before merge (prevents partial completion)
|
|
8
|
+
* 3) cd into worktree
|
|
9
|
+
* 4) Auto-update WU YAML/backlog/status to Done in worktree (unless --no-auto)
|
|
10
|
+
* 5) Create `.lumenflow/stamps/WU-{id}.done` in worktree
|
|
11
|
+
* 6) Validate staged files against whitelist
|
|
12
|
+
* 7) Commit metadata changes in worktree (on lane branch)
|
|
13
|
+
* 8) cd back to main
|
|
14
|
+
* 9) Merge lane branch to main with --ff-only (metadata + code merged atomically)
|
|
15
|
+
* 10) Push to `main`
|
|
16
|
+
* 11) Remove the associated worktree (unless --no-remove)
|
|
17
|
+
* 12) Optionally delete the lane branch (with --delete-branch)
|
|
18
|
+
* 13) Emit telemetry to .lumenflow/flow.log
|
|
19
|
+
*
|
|
20
|
+
* Canonical sequence (Branch-Only mode - LEGACY):
|
|
21
|
+
* 1) Run gates on lane branch (in main checkout)
|
|
22
|
+
* 2) Pre-flight validation
|
|
23
|
+
* 3) Merge lane branch to main
|
|
24
|
+
* 4) Update metadata on main
|
|
25
|
+
* 5) Commit and push
|
|
26
|
+
* 6) Delete lane branch
|
|
27
|
+
*
|
|
28
|
+
* Usage:
|
|
29
|
+
* pnpm wu:done --id WU-334 [--worktree worktrees/intelligence-wu-334] [--no-auto] [--no-remove] [--no-merge] [--delete-branch]
|
|
30
|
+
*
|
|
31
|
+
* WU-2542: This script imports utilities from @lumenflow/core package.
|
|
32
|
+
* Full migration to thin shim pending @lumenflow/core CLI export implementation.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* WU-1999: Print exposure validation warnings.
|
|
36
|
+
*
|
|
37
|
+
* Validates exposure field and UI pairing for user-facing WUs.
|
|
38
|
+
* Non-blocking - logs warnings but doesn't prevent completion.
|
|
39
|
+
*
|
|
40
|
+
* Checks:
|
|
41
|
+
* - exposure field is present (warn if missing)
|
|
42
|
+
* - If exposure=api, warns if no ui_pairing_wus specified
|
|
43
|
+
* - If exposure=api, checks acceptance criteria for UI verification mention
|
|
44
|
+
* - If exposure=ui, recommends user_journey field if not present
|
|
45
|
+
*
|
|
46
|
+
* @param {object} wu - WU YAML document
|
|
47
|
+
* @param {object} options - Validation options
|
|
48
|
+
* @param {boolean} [options.skipExposureCheck=false] - Skip all exposure validation
|
|
49
|
+
* @returns {void}
|
|
50
|
+
*/
|
|
51
|
+
interface ExposureOptions {
|
|
52
|
+
skipExposureCheck?: boolean;
|
|
53
|
+
}
|
|
54
|
+
export declare function printExposureWarnings(wu: Record<string, unknown>, options?: ExposureOptions): void;
|
|
55
|
+
/**
|
|
56
|
+
* WU-2022: Validate feature accessibility for UI-exposed WUs.
|
|
57
|
+
*
|
|
58
|
+
* BLOCKING validation - prevents wu:done if exposure=ui but feature is not accessible.
|
|
59
|
+
* This prevents "orphaned code" where UI features exist but users cannot navigate to them.
|
|
60
|
+
*
|
|
61
|
+
* Accessibility is verified by ANY of:
|
|
62
|
+
* 1. navigation_path field is specified (explicit route)
|
|
63
|
+
* 2. code_paths includes a page.tsx file (Next.js page)
|
|
64
|
+
* 3. tests.manual includes navigation/accessibility verification
|
|
65
|
+
*
|
|
66
|
+
* @param {object} wu - WU YAML document
|
|
67
|
+
* @param {object} options - Validation options
|
|
68
|
+
* @param {boolean} [options.skipAccessibilityCheck=false] - Skip accessibility validation
|
|
69
|
+
* @returns {void} Calls die() if validation fails
|
|
70
|
+
*/
|
|
71
|
+
interface AccessibilityOptions {
|
|
72
|
+
skipAccessibilityCheck?: boolean;
|
|
73
|
+
}
|
|
74
|
+
export declare function validateAccessibilityOrDie(wu: Record<string, unknown>, options?: AccessibilityOptions): void;
|
|
75
|
+
/**
|
|
76
|
+
* WU-1012: Validate --docs-only flag usage.
|
|
77
|
+
*
|
|
78
|
+
* The --docs-only flag can only be used when the WU is documentation-focused:
|
|
79
|
+
* 1. exposure field is 'documentation'
|
|
80
|
+
* 2. OR all code_paths are documentation paths (docs/, ai/, .claude/, *.md)
|
|
81
|
+
* 3. OR type is 'documentation'
|
|
82
|
+
*
|
|
83
|
+
* @param {object} wu - WU YAML document
|
|
84
|
+
* @param {object} args - Parsed CLI arguments
|
|
85
|
+
* @param {boolean} args.docsOnly - Whether --docs-only flag was passed
|
|
86
|
+
* @returns {{ valid: boolean, errors: string[] }} Validation result
|
|
87
|
+
*/
|
|
88
|
+
interface DocsOnlyArgs {
|
|
89
|
+
docsOnly?: boolean;
|
|
90
|
+
}
|
|
91
|
+
export declare function validateDocsOnlyFlag(wu: Record<string, unknown>, args: DocsOnlyArgs): {
|
|
92
|
+
valid: boolean;
|
|
93
|
+
errors: string[];
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* WU-1012: Build gates command with --docs-only flag support.
|
|
97
|
+
*
|
|
98
|
+
* Returns the appropriate gates command based on:
|
|
99
|
+
* - Explicit --docs-only flag from CLI
|
|
100
|
+
* - Auto-detected isDocsOnly from code_paths analysis
|
|
101
|
+
*
|
|
102
|
+
* @param {object} options - Build options
|
|
103
|
+
* @param {boolean} options.docsOnly - Explicit --docs-only flag from CLI
|
|
104
|
+
* @param {boolean} options.isDocsOnly - Auto-detected docs-only from code_paths
|
|
105
|
+
* @returns {string} Gates command string
|
|
106
|
+
*/
|
|
107
|
+
interface BuildGatesOptions {
|
|
108
|
+
docsOnly?: boolean;
|
|
109
|
+
isDocsOnly?: boolean;
|
|
110
|
+
}
|
|
111
|
+
export declare function buildGatesCommand(options: BuildGatesOptions): string;
|
|
112
|
+
/**
|
|
113
|
+
* WU-1946: Update spawn registry on WU completion.
|
|
114
|
+
* Non-blocking wrapper - failures logged as warnings.
|
|
115
|
+
*
|
|
116
|
+
* When a WU is completed via wu:done, this function updates the spawn registry
|
|
117
|
+
* to mark the spawned entry as completed (if one exists). This allows orchestrators
|
|
118
|
+
* to track sub-agent spawn completion status.
|
|
119
|
+
*
|
|
120
|
+
* Gracefully skips if:
|
|
121
|
+
* - No spawn entry found for this WU (legacy WU created before registry)
|
|
122
|
+
* - Registry file doesn't exist
|
|
123
|
+
* - Any error during update
|
|
124
|
+
*
|
|
125
|
+
* @param {string} id - WU ID being completed
|
|
126
|
+
* @param {string} baseDir - Base directory containing .lumenflow/state/
|
|
127
|
+
* @returns {Promise<void>}
|
|
128
|
+
*/
|
|
129
|
+
export declare function updateSpawnRegistryOnCompletion(id: any, baseDir?: string): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* WU-1234: Normalize username for ownership comparison
|
|
132
|
+
* Extracts username from email address for comparison.
|
|
133
|
+
* This allows tom@hellm.ai to match 'tom' assigned_to field.
|
|
134
|
+
*
|
|
135
|
+
* @param {string|null|undefined} value - Email address or username
|
|
136
|
+
* @returns {string} Normalized username (lowercase)
|
|
137
|
+
*/
|
|
138
|
+
export declare function normalizeUsername(value: any): string;
|
|
139
|
+
/**
|
|
140
|
+
* WU-1234: Detect if branch is already merged to main
|
|
141
|
+
* Checks if branch tip is an ancestor of main HEAD (i.e., already merged).
|
|
142
|
+
* This prevents merge loops when code was merged via emergency fix or manual merge.
|
|
143
|
+
*
|
|
144
|
+
* @param {string} branch - Lane branch name
|
|
145
|
+
* @returns {Promise<boolean>} True if branch is already merged to main
|
|
146
|
+
*/
|
|
147
|
+
export declare function isBranchAlreadyMerged(branch: any): Promise<boolean>;
|
|
148
|
+
export { shouldSkipWebTests as isDocsOnlyByPaths } from '@lumenflow/core/dist/path-classifiers.js';
|
|
149
|
+
/**
|
|
150
|
+
* WU-1234: Pre-flight check for backlog state consistency
|
|
151
|
+
* Fails fast if the WU appears in both Done and In Progress sections.
|
|
152
|
+
*
|
|
153
|
+
* @param {string} id - WU ID to check
|
|
154
|
+
* @param {string} backlogPath - Path to backlog.md
|
|
155
|
+
* @returns {{ valid: boolean, error: string|null }}
|
|
156
|
+
*/
|
|
157
|
+
export declare function checkBacklogConsistencyForWU(id: any, backlogPath: any): {
|
|
158
|
+
valid: boolean;
|
|
159
|
+
error: string;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* WU-1084: Check for uncommitted changes on main after merge completes.
|
|
163
|
+
*
|
|
164
|
+
* This catches cases where pnpm format (or other tooling) touched files
|
|
165
|
+
* outside the WU's code_paths during worktree work. These changes survive
|
|
166
|
+
* the merge and would be silently left behind when the worktree is removed.
|
|
167
|
+
*
|
|
168
|
+
* @param gitStatus - Output from git status (porcelain format)
|
|
169
|
+
* @param wuId - The WU ID for error messaging
|
|
170
|
+
* @returns Object with isDirty flag and optional error message
|
|
171
|
+
*/
|
|
172
|
+
export declare function checkPostMergeDirtyState(gitStatus: string, wuId: string): {
|
|
173
|
+
isDirty: boolean;
|
|
174
|
+
error?: string;
|
|
175
|
+
};
|
|
176
|
+
export declare function emitTelemetry(event: any): void;
|
|
177
|
+
/**
|
|
178
|
+
* Print State HUD for visibility
|
|
179
|
+
* Extracted from main() to reduce complexity (WU-1215 Phase 2 Extraction #4)
|
|
180
|
+
* @param {object} params - Parameters
|
|
181
|
+
* @param {string} params.id - WU ID
|
|
182
|
+
* @param {object} params.docMain - Main WU YAML document
|
|
183
|
+
* @param {boolean} params.isBranchOnly - Whether in branch-only mode
|
|
184
|
+
* @param {boolean} params.isDocsOnly - Whether this is a docs-only WU
|
|
185
|
+
* @param {string|null} params.derivedWorktree - Derived worktree path
|
|
186
|
+
* @param {string} params.STAMPS_DIR - Stamps directory path
|
|
187
|
+
*/
|
|
188
|
+
export declare function computeBranchOnlyFallback({ isBranchOnly, branchOnlyRequested, worktreeExists, derivedWorktree, }: {
|
|
189
|
+
isBranchOnly: boolean;
|
|
190
|
+
branchOnlyRequested: boolean | undefined;
|
|
191
|
+
worktreeExists: boolean;
|
|
192
|
+
derivedWorktree: string | null;
|
|
193
|
+
}): {
|
|
194
|
+
allowFallback: boolean;
|
|
195
|
+
effectiveBranchOnly: boolean;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* WU-1983: Print migration deployment nudge when WU includes supabase changes.
|
|
199
|
+
* Notifies agent to deploy new migrations to production via MCP tools.
|
|
200
|
+
* Conditional output - only prints when migrations are in scope and new migrations exist.
|
|
201
|
+
*
|
|
202
|
+
* @param {string[]} codePaths - WU code_paths array
|
|
203
|
+
* @param {string} baseDir - Base directory for migration discovery
|
|
204
|
+
* @returns {Promise<void>}
|
|
205
|
+
*/
|
|
206
|
+
export declare function printMigrationDeploymentNudge(codePaths: any, baseDir: any): Promise<void>;
|
|
207
|
+
/**
|
|
208
|
+
* WU-1763: Print discovery summary nudge when discoveries exist for this WU.
|
|
209
|
+
* Conditional output - only prints when discoveryCount > 0.
|
|
210
|
+
* Non-blocking, single-line output to avoid flooding the console.
|
|
211
|
+
*
|
|
212
|
+
* @param {string} id - WU ID being completed
|
|
213
|
+
* @param {number} discoveryCount - Number of open discoveries for this WU
|
|
214
|
+
* @param {string[]} discoveryIds - List of discovery IDs (limited to 5 in output)
|
|
215
|
+
*/
|
|
216
|
+
export declare function printDiscoveryNudge(id: any, discoveryCount: any, discoveryIds: any): void;
|
|
217
|
+
/**
|
|
218
|
+
* WU-1763: Print documentation validation nudge when docs changed.
|
|
219
|
+
* Conditional output - only prints when changedDocPaths.length > 0.
|
|
220
|
+
* Non-blocking, single-line output to avoid flooding the console.
|
|
221
|
+
*
|
|
222
|
+
* @param {string} id - WU ID being completed
|
|
223
|
+
* @param {string[]} changedDocPaths - List of documentation paths that changed
|
|
224
|
+
*/
|
|
225
|
+
export declare function printDocValidationNudge(id: any, changedDocPaths: any): void;
|
package/dist/wu-done.js
CHANGED
|
@@ -1975,9 +1975,15 @@ async function main() {
|
|
|
1975
1975
|
// This prevents partial completion states where merge succeeds but commit fails
|
|
1976
1976
|
// Validates all 8 gates: secrets, file size, ESLint, Prettier, TypeScript, audit, architecture, tasks
|
|
1977
1977
|
// WU-2308: Pass worktreePath to run audit from worktree (checks fixed deps, not stale main deps)
|
|
1978
|
-
|
|
1979
|
-
if (!
|
|
1980
|
-
|
|
1978
|
+
// WU-1145: Skip pre-flight when skipGates is true (pre-flight runs gates which was already skipped)
|
|
1979
|
+
if (!args.skipGates) {
|
|
1980
|
+
const hookResult = validateAllPreCommitHooks(id, worktreePath);
|
|
1981
|
+
if (!hookResult.valid) {
|
|
1982
|
+
die('Pre-flight validation failed. Fix hook issues and try again.');
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
else {
|
|
1986
|
+
console.log(`${LOG_PREFIX.DONE} Skipping pre-flight hook validation (--skip-gates)`);
|
|
1981
1987
|
}
|
|
1982
1988
|
// Step 0.6: WU-1781 - Run tasks:validate preflight BEFORE any merge/push operations
|
|
1983
1989
|
// This prevents deadlocks where validation fails after merge, leaving local main ahead of origin
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WU Edit Helper
|
|
4
|
+
*
|
|
5
|
+
* Race-safe WU spec editing using micro-worktree isolation (WU-1274).
|
|
6
|
+
*
|
|
7
|
+
* Enables editing WU YAML files without claiming the WU, perfect for:
|
|
8
|
+
* - Filling in placeholder content after wu:create
|
|
9
|
+
* - Updating description/acceptance criteria
|
|
10
|
+
* - Adding code_paths, notes, or other spec fields
|
|
11
|
+
*
|
|
12
|
+
* Uses the same micro-worktree pattern as wu:create (WU-1262):
|
|
13
|
+
* 1) Validate inputs (WU exists, status is ready)
|
|
14
|
+
* 2) Ensure main is clean and up-to-date with origin
|
|
15
|
+
* 3) Create temp branch WITHOUT switching (main checkout stays on main)
|
|
16
|
+
* 4) Create micro-worktree in /tmp pointing to temp branch
|
|
17
|
+
* 5) Apply edits in micro-worktree
|
|
18
|
+
* 6) Commit, ff-only merge, push
|
|
19
|
+
* 7) Cleanup temp branch and micro-worktree
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* pnpm wu:edit --id WU-123 --spec-file /path/to/spec.yaml
|
|
23
|
+
* pnpm wu:edit --id WU-123 --description "New description text"
|
|
24
|
+
* pnpm wu:edit --id WU-123 --acceptance "Criterion 1" --acceptance "Criterion 2"
|
|
25
|
+
*
|
|
26
|
+
* Part of WU-1274: Add wu:edit command for spec-only changes
|
|
27
|
+
* @see {@link tools/lib/micro-worktree.mjs} - Shared micro-worktree logic
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* WU-1039: Validate which edits are allowed on done WUs
|
|
31
|
+
*
|
|
32
|
+
* Done WUs only allow metadata reassignment: initiative, phase, and exposure.
|
|
33
|
+
* All other edits are blocked to preserve WU immutability after completion.
|
|
34
|
+
*
|
|
35
|
+
* @param opts - Parsed CLI options
|
|
36
|
+
* @returns { valid: boolean, disallowedEdits: string[] }
|
|
37
|
+
*/
|
|
38
|
+
export declare function validateDoneWUEdits(opts: Record<string, unknown>): {
|
|
39
|
+
valid: boolean;
|
|
40
|
+
disallowedEdits: string[];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* WU-1039: Validate exposure value against schema
|
|
44
|
+
*
|
|
45
|
+
* Uses WU_EXPOSURE_VALUES from core constants (Library-First, no magic strings).
|
|
46
|
+
*
|
|
47
|
+
* @param exposure - Exposure value to validate
|
|
48
|
+
* @returns { valid: boolean, error?: string }
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateExposureValue(exposure: string): {
|
|
51
|
+
valid: boolean;
|
|
52
|
+
error?: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* WU-1039: Apply exposure edit to WU object
|
|
56
|
+
*
|
|
57
|
+
* Returns a new WU object with updated exposure (immutable pattern).
|
|
58
|
+
*
|
|
59
|
+
* @param wu - Original WU object
|
|
60
|
+
* @param exposure - New exposure value
|
|
61
|
+
* @returns Updated WU object (does not mutate original)
|
|
62
|
+
*/
|
|
63
|
+
export declare function applyExposureEdit(wu: Record<string, unknown>, exposure: string): Record<string, unknown>;
|
package/dist/wu-edit.js
CHANGED
|
@@ -84,6 +84,9 @@ export function validateDoneWUEdits(opts) {
|
|
|
84
84
|
if (opts.codePaths && Array.isArray(opts.codePaths) && opts.codePaths.length > 0) {
|
|
85
85
|
disallowedEdits.push('--code-paths');
|
|
86
86
|
}
|
|
87
|
+
if (opts.risks && Array.isArray(opts.risks) && opts.risks.length > 0) {
|
|
88
|
+
disallowedEdits.push('--risks');
|
|
89
|
+
}
|
|
87
90
|
if (opts.lane)
|
|
88
91
|
disallowedEdits.push('--lane');
|
|
89
92
|
if (opts.type)
|
|
@@ -157,13 +160,24 @@ const EDIT_OPTIONS = {
|
|
|
157
160
|
acceptance: {
|
|
158
161
|
name: 'acceptance',
|
|
159
162
|
flags: '--acceptance <criterion>',
|
|
160
|
-
description: 'Acceptance criterion (repeatable,
|
|
163
|
+
description: 'Acceptance criterion (repeatable, appends to existing; use --replace-acceptance to overwrite)',
|
|
161
164
|
isRepeatable: true,
|
|
162
165
|
},
|
|
163
166
|
notes: {
|
|
164
167
|
name: 'notes',
|
|
165
168
|
flags: '--notes <text>',
|
|
166
|
-
description: '
|
|
169
|
+
description: 'Notes text (appends to existing; use --replace-notes to overwrite)',
|
|
170
|
+
},
|
|
171
|
+
// WU-1144: Add explicit replace flags for notes and acceptance
|
|
172
|
+
replaceNotes: {
|
|
173
|
+
name: 'replaceNotes',
|
|
174
|
+
flags: '--replace-notes',
|
|
175
|
+
description: 'Replace existing notes instead of appending',
|
|
176
|
+
},
|
|
177
|
+
replaceAcceptance: {
|
|
178
|
+
name: 'replaceAcceptance',
|
|
179
|
+
flags: '--replace-acceptance',
|
|
180
|
+
description: 'Replace existing acceptance criteria instead of appending',
|
|
167
181
|
},
|
|
168
182
|
codePaths: {
|
|
169
183
|
name: 'codePaths',
|
|
@@ -171,10 +185,16 @@ const EDIT_OPTIONS = {
|
|
|
171
185
|
description: 'Code path (repeatable, replaces existing; use --append to add)',
|
|
172
186
|
isRepeatable: true,
|
|
173
187
|
},
|
|
188
|
+
risks: {
|
|
189
|
+
name: 'risks',
|
|
190
|
+
flags: '--risks <risk>',
|
|
191
|
+
description: 'Risk entry (repeatable, replaces existing; use --append to add)',
|
|
192
|
+
isRepeatable: true,
|
|
193
|
+
},
|
|
174
194
|
append: {
|
|
175
195
|
name: 'append',
|
|
176
196
|
flags: '--append',
|
|
177
|
-
description: 'Append to existing array values instead of replacing (for --
|
|
197
|
+
description: 'Append to existing array values instead of replacing (for --code-paths, --test-paths-*, --blocked-by, --add-dep)',
|
|
178
198
|
},
|
|
179
199
|
// WU-1456: Add lane reassignment support
|
|
180
200
|
lane: {
|
|
@@ -310,7 +330,11 @@ function parseArgs() {
|
|
|
310
330
|
EDIT_OPTIONS.description,
|
|
311
331
|
EDIT_OPTIONS.acceptance,
|
|
312
332
|
EDIT_OPTIONS.notes,
|
|
333
|
+
// WU-1144: Add explicit replace flags for notes and acceptance
|
|
334
|
+
EDIT_OPTIONS.replaceNotes,
|
|
335
|
+
EDIT_OPTIONS.replaceAcceptance,
|
|
313
336
|
EDIT_OPTIONS.codePaths,
|
|
337
|
+
EDIT_OPTIONS.risks,
|
|
314
338
|
EDIT_OPTIONS.append,
|
|
315
339
|
// WU-1390: Add test path flags
|
|
316
340
|
WU_OPTIONS.testPathsManual,
|
|
@@ -581,6 +605,25 @@ function mergeArrayField(existing, newValues, shouldAppend) {
|
|
|
581
605
|
const existingArray = Array.isArray(existing) ? existing : [];
|
|
582
606
|
return [...existingArray, ...newValues];
|
|
583
607
|
}
|
|
608
|
+
/**
|
|
609
|
+
* WU-1144: Merge string field values with append-by-default behavior
|
|
610
|
+
*
|
|
611
|
+
* Notes and acceptance criteria should append by default (preserving original),
|
|
612
|
+
* with explicit --replace-notes and --replace-acceptance flags for overwrite.
|
|
613
|
+
*
|
|
614
|
+
* @param {string | undefined} existing - Current string value from WU
|
|
615
|
+
* @param {string} newValue - New value from CLI
|
|
616
|
+
* @param {boolean} shouldReplace - Whether to replace instead of append
|
|
617
|
+
* @returns {string} Merged string value
|
|
618
|
+
*/
|
|
619
|
+
export function mergeStringField(existing, newValue, shouldReplace) {
|
|
620
|
+
// If replace mode or no existing value, just use new value
|
|
621
|
+
if (shouldReplace || !existing || existing.trim() === '') {
|
|
622
|
+
return newValue;
|
|
623
|
+
}
|
|
624
|
+
// Append with double newline separator
|
|
625
|
+
return `${existing}\n\n${newValue}`;
|
|
626
|
+
}
|
|
584
627
|
/**
|
|
585
628
|
* Load spec file and merge with original WU (preserving id and status)
|
|
586
629
|
* @param {string} specPath - Path to spec file
|
|
@@ -610,7 +653,7 @@ function loadSpecFile(specPath, originalWU) {
|
|
|
610
653
|
* Returns the updated WU object
|
|
611
654
|
*/
|
|
612
655
|
// eslint-disable-next-line sonarjs/cognitive-complexity -- Pre-existing complexity, refactor tracked separately
|
|
613
|
-
function applyEdits(wu, opts) {
|
|
656
|
+
export function applyEdits(wu, opts) {
|
|
614
657
|
// Full spec replacement from file
|
|
615
658
|
if (opts.specFile) {
|
|
616
659
|
return loadSpecFile(opts.specFile, wu);
|
|
@@ -620,12 +663,17 @@ function applyEdits(wu, opts) {
|
|
|
620
663
|
if (opts.description) {
|
|
621
664
|
updated.description = opts.description;
|
|
622
665
|
}
|
|
623
|
-
// Handle
|
|
666
|
+
// WU-1144: Handle --acceptance with append-by-default behavior
|
|
667
|
+
// Appends to existing acceptance criteria unless --replace-acceptance is set
|
|
624
668
|
if (opts.acceptance && opts.acceptance.length > 0) {
|
|
625
|
-
|
|
669
|
+
// Invert the logic: append by default, replace with --replace-acceptance
|
|
670
|
+
const shouldAppend = !opts.replaceAcceptance;
|
|
671
|
+
updated.acceptance = mergeArrayField(wu.acceptance, opts.acceptance, shouldAppend);
|
|
626
672
|
}
|
|
673
|
+
// WU-1144: Handle --notes with append-by-default behavior
|
|
674
|
+
// Appends to existing notes unless --replace-notes is set
|
|
627
675
|
if (opts.notes) {
|
|
628
|
-
updated.notes = opts.notes;
|
|
676
|
+
updated.notes = mergeStringField(wu.notes, opts.notes, opts.replaceNotes ?? false);
|
|
629
677
|
}
|
|
630
678
|
// WU-1456: Handle lane reassignment
|
|
631
679
|
if (opts.lane) {
|
|
@@ -670,6 +718,21 @@ function applyEdits(wu, opts) {
|
|
|
670
718
|
.filter(Boolean);
|
|
671
719
|
updated.code_paths = mergeArrayField(wu.code_paths, codePaths, opts.append);
|
|
672
720
|
}
|
|
721
|
+
// WU-1073: Handle repeatable --risks flags (replace by default, append with --append)
|
|
722
|
+
// Split comma-separated values within each entry for consistency with other list fields
|
|
723
|
+
if (opts.risks && opts.risks.length > 0) {
|
|
724
|
+
const rawRisks = opts.risks;
|
|
725
|
+
const risks = Array.isArray(rawRisks)
|
|
726
|
+
? rawRisks
|
|
727
|
+
.flatMap((risk) => risk.split(','))
|
|
728
|
+
.map((risk) => risk.trim())
|
|
729
|
+
.filter(Boolean)
|
|
730
|
+
: rawRisks
|
|
731
|
+
.split(',')
|
|
732
|
+
.map((risk) => risk.trim())
|
|
733
|
+
.filter(Boolean);
|
|
734
|
+
updated.risks = mergeArrayField(wu.risks, risks, opts.append);
|
|
735
|
+
}
|
|
673
736
|
// WU-1390: Handle test path flags (DRY refactor)
|
|
674
737
|
const testPathMappings = [
|
|
675
738
|
{ optKey: 'testPathsManual', field: 'manual' },
|
|
@@ -757,6 +820,7 @@ async function main() {
|
|
|
757
820
|
(opts.acceptance && opts.acceptance.length > 0) ||
|
|
758
821
|
opts.notes ||
|
|
759
822
|
(opts.codePaths && opts.codePaths.length > 0) ||
|
|
823
|
+
(opts.risks && opts.risks.length > 0) ||
|
|
760
824
|
// WU-1390: Add test path flags to hasEdits check
|
|
761
825
|
(opts.testPathsManual && opts.testPathsManual.length > 0) ||
|
|
762
826
|
(opts.testPathsUnit && opts.testPathsUnit.length > 0) ||
|
|
@@ -779,9 +843,12 @@ async function main() {
|
|
|
779
843
|
'Provide one of:\n' +
|
|
780
844
|
' --spec-file <path> Replace full spec from YAML file\n' +
|
|
781
845
|
' --description <text> Update description field\n' +
|
|
782
|
-
' --acceptance <text>
|
|
783
|
-
' --notes <text>
|
|
846
|
+
' --acceptance <text> Append acceptance criteria (repeatable; use --replace-acceptance to overwrite)\n' +
|
|
847
|
+
' --notes <text> Append to notes (use --replace-notes to overwrite)\n' +
|
|
848
|
+
' --replace-notes Replace existing notes instead of appending\n' +
|
|
849
|
+
' --replace-acceptance Replace existing acceptance instead of appending\n' +
|
|
784
850
|
' --code-paths <paths> Replace code paths (repeatable; use --append to add)\n' +
|
|
851
|
+
' --risks <risk> Replace risks (repeatable; use --append to add)\n' +
|
|
785
852
|
' --lane <lane> Update lane assignment (e.g., "Operations: Tooling")\n' +
|
|
786
853
|
' --type <type> Update WU type (feature, bug, refactor, documentation)\n' +
|
|
787
854
|
' --priority <priority> Update priority (P0, P1, P2, P3)\n' +
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WU Lane Inference CLI (WU-908)
|
|
4
|
+
*
|
|
5
|
+
* Suggests sub-lane for a WU based on code paths and description.
|
|
6
|
+
* Wrapper around lib/lane-inference.mjs for standalone CLI usage.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* # Infer from existing WU
|
|
10
|
+
* node tools/wu-infer-lane.mjs --id WU-123
|
|
11
|
+
*
|
|
12
|
+
* # Infer from manual inputs
|
|
13
|
+
* node tools/wu-infer-lane.mjs --paths "tools/**" "docs/**" --desc "Tooling improvements"
|
|
14
|
+
*
|
|
15
|
+
* Returns suggested lane and confidence score (0-100).
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WU Preflight Validation
|
|
4
|
+
*
|
|
5
|
+
* WU-1803: Fast validation of code_paths and test paths before gates run.
|
|
6
|
+
* Completes in under 5 seconds vs 2+ minutes for full gates.
|
|
7
|
+
*
|
|
8
|
+
* This catches YAML mismatches early, preventing wasted time running full
|
|
9
|
+
* gates only to fail on code_paths validation at the end of wu:done.
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* pnpm wu:preflight --id WU-1803 # Validate from main checkout
|
|
13
|
+
* pnpm wu:preflight --id WU-1803 --worktree worktrees/operations-gates-wu-1803
|
|
14
|
+
*
|
|
15
|
+
* Validates:
|
|
16
|
+
* - code_paths files exist
|
|
17
|
+
* - test file paths exist (unit, e2e, integration)
|
|
18
|
+
* - WU YAML schema is valid
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Parse command-line arguments
|
|
22
|
+
* @param {string[]} argv - Process arguments
|
|
23
|
+
* @returns {object} Parsed arguments
|
|
24
|
+
*/
|
|
25
|
+
declare function parseArgs(argv: any): {
|
|
26
|
+
help: boolean;
|
|
27
|
+
error?: undefined;
|
|
28
|
+
id?: undefined;
|
|
29
|
+
worktree?: undefined;
|
|
30
|
+
} | {
|
|
31
|
+
error: string;
|
|
32
|
+
help?: undefined;
|
|
33
|
+
id?: undefined;
|
|
34
|
+
worktree?: undefined;
|
|
35
|
+
} | {
|
|
36
|
+
id: any;
|
|
37
|
+
worktree: any;
|
|
38
|
+
help: boolean;
|
|
39
|
+
error?: undefined;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Detect worktree path from WU YAML or calculate from lane
|
|
43
|
+
* @param {string} id - WU ID
|
|
44
|
+
* @returns {string|null} Worktree path or null if not found
|
|
45
|
+
*/
|
|
46
|
+
declare function detectWorktreePath(id: any): string;
|
|
47
|
+
export { parseArgs, detectWorktreePath };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WU Prune Utility
|
|
4
|
+
*
|
|
5
|
+
* Maintains worktree hygiene by:
|
|
6
|
+
* - Running git worktree prune to clean stale metadata
|
|
7
|
+
* - Validating worktree ↔ WU ↔ lane mappings
|
|
8
|
+
* - Warning on orphaned worktrees (no matching WU YAML)
|
|
9
|
+
* - Warning on stale worktrees (WU status is done/blocked)
|
|
10
|
+
* - Warning on invalid branch naming conventions
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* pnpm wu:prune # Dry-run mode (shows what would be done)
|
|
14
|
+
* pnpm wu:prune --execute # Actually run cleanup
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WU Recovery Command
|
|
4
|
+
*
|
|
5
|
+
* WU-1090: Context-aware state machine for WU lifecycle commands
|
|
6
|
+
*
|
|
7
|
+
* Analyzes WU state inconsistencies and offers recovery actions:
|
|
8
|
+
* - resume: Reconcile state and continue working (preserves work)
|
|
9
|
+
* - reset: Discard worktree and reset WU to ready
|
|
10
|
+
* - nuke: Remove all artifacts completely (requires --force)
|
|
11
|
+
* - cleanup: Remove leftover worktree for done WUs
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* pnpm wu:recover --id WU-123 # Analyze issues
|
|
15
|
+
* pnpm wu:recover --id WU-123 --action resume # Apply fix
|
|
16
|
+
* pnpm wu:recover --id WU-123 --action nuke --force # Destructive
|
|
17
|
+
*/
|
|
18
|
+
import { type RecoveryAnalysis } from '@lumenflow/core/dist/recovery/recovery-analyzer.js';
|
|
19
|
+
/**
|
|
20
|
+
* Check if action requires --force flag
|
|
21
|
+
*/
|
|
22
|
+
export declare function requiresForceFlag(action: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Validate recovery action
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateRecoveryAction(action: string): {
|
|
27
|
+
valid: boolean;
|
|
28
|
+
error?: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Format recovery analysis output
|
|
32
|
+
*/
|
|
33
|
+
export declare function formatRecoveryOutput(analysis: RecoveryAnalysis): string;
|
|
34
|
+
/**
|
|
35
|
+
* Get exit code for recovery command
|
|
36
|
+
*/
|
|
37
|
+
export declare function getRecoveryExitCode(analysis: RecoveryAnalysis, actionFailed: boolean): number;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WU Release Command (WU-1080)
|
|
4
|
+
*
|
|
5
|
+
* Releases an orphaned WU from in_progress back to ready state.
|
|
6
|
+
* Use when an agent is interrupted mid-WU and the WU needs to be reclaimed.
|
|
7
|
+
*
|
|
8
|
+
* Sequence (micro-worktree pattern):
|
|
9
|
+
* 1) Validate WU is in_progress
|
|
10
|
+
* 2) Create micro-worktree from main
|
|
11
|
+
* 3) Append release event to state store
|
|
12
|
+
* 4) Regenerate backlog.md and status.md
|
|
13
|
+
* 5) Commit in micro-worktree, push directly to origin/main
|
|
14
|
+
* 6) Optionally remove the work worktree
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* pnpm wu:release --id WU-1080 --reason "Agent interrupted"
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WU State Repair Tool (Unified - WU-1826, WU-2240)
|
|
4
|
+
*
|
|
5
|
+
* Layer 2 defense-in-depth: detect and repair WU state inconsistencies.
|
|
6
|
+
*
|
|
7
|
+
* This unified tool consolidates four repair modes:
|
|
8
|
+
* - Consistency mode (default): detect/repair state inconsistencies
|
|
9
|
+
* - Claim mode (--claim): repair missing claim metadata in worktrees
|
|
10
|
+
* - Admin mode (--admin): administrative fixes for done WUs
|
|
11
|
+
* - State mode (--repair-state): repair corrupted wu-events.jsonl (WU-2240)
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* # Consistency mode (default)
|
|
15
|
+
* pnpm wu:repair --id WU-123 # Repair single WU
|
|
16
|
+
* pnpm wu:repair --id WU-123 --check # Audit only, no changes
|
|
17
|
+
* pnpm wu:repair --all # Batch repair all WUs
|
|
18
|
+
* pnpm wu:repair --all --check # Audit all WUs
|
|
19
|
+
*
|
|
20
|
+
* # Claim mode
|
|
21
|
+
* pnpm wu:repair --claim --id WU-123 # Repair claim metadata
|
|
22
|
+
* pnpm wu:repair --claim --id WU-123 --check # Check only
|
|
23
|
+
* pnpm wu:repair --claim --id WU-123 --worktree /path/to/worktree
|
|
24
|
+
*
|
|
25
|
+
* # Admin mode
|
|
26
|
+
* pnpm wu:repair --admin --id WU-123 --lane "Operations: Tooling"
|
|
27
|
+
* pnpm wu:repair --admin --id WU-123 --status cancelled
|
|
28
|
+
* pnpm wu:repair --admin --id WU-123 --notes "Administrative fix"
|
|
29
|
+
* pnpm wu:repair --admin --id WU-123 --initiative INIT-001
|
|
30
|
+
*
|
|
31
|
+
* # State mode (WU-2240)
|
|
32
|
+
* pnpm wu:repair --repair-state # Repair default state file
|
|
33
|
+
* pnpm wu:repair --repair-state --path /path/to/wu-events.jsonl # Repair specific file
|
|
34
|
+
*
|
|
35
|
+
* Exit codes:
|
|
36
|
+
* 0: Success (no issues or all repaired)
|
|
37
|
+
* 1: Issues detected (--check mode)
|
|
38
|
+
* 2: Repair failed
|
|
39
|
+
*
|
|
40
|
+
* DEPRECATION NOTICE:
|
|
41
|
+
* - pnpm wu:repair-claim is deprecated. Use: pnpm wu:repair --claim
|
|
42
|
+
* - pnpm wu:admin-repair is deprecated. Use: pnpm wu:repair --admin
|
|
43
|
+
*
|
|
44
|
+
* @see {@link tools/lib/wu-repair-core.mjs} - Core repair logic
|
|
45
|
+
* @see {@link tools/lib/wu-consistency-checker.mjs} - Consistency detection/repair
|
|
46
|
+
* @see {@link tools/lib/wu-state-store.mjs} - State file repair (repairStateFile)
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* Normalise WU ID to uppercase with WU- prefix
|
|
50
|
+
* @param {string} id - Raw WU ID
|
|
51
|
+
* @returns {string} Normalised WU ID
|
|
52
|
+
*/
|
|
53
|
+
declare function normaliseWUId(id: any): any;
|
|
54
|
+
/**
|
|
55
|
+
* Validate WU ID format
|
|
56
|
+
* @param {string} id - WU ID to validate
|
|
57
|
+
* @returns {boolean} True if valid
|
|
58
|
+
*/
|
|
59
|
+
declare function isValidWUId(id: any): boolean;
|
|
60
|
+
export { normaliseWUId, isValidWUId };
|