@lumenflow/cli 2.2.2 → 2.3.2
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/README.md +147 -57
- package/dist/__tests__/agent-log-issue.test.js +56 -0
- package/dist/__tests__/cli-entry-point.test.js +66 -17
- package/dist/__tests__/cli-subprocess.test.js +25 -0
- package/dist/__tests__/init.test.js +298 -0
- package/dist/__tests__/initiative-plan.test.js +340 -0
- package/dist/__tests__/mem-cleanup-execution.test.js +19 -0
- package/dist/__tests__/merge-block.test.js +220 -0
- package/dist/__tests__/release.test.js +61 -0
- package/dist/__tests__/safe-git.test.js +191 -0
- package/dist/__tests__/state-doctor.test.js +274 -0
- package/dist/__tests__/wu-done.test.js +36 -0
- package/dist/__tests__/wu-edit.test.js +119 -0
- package/dist/__tests__/wu-prep.test.js +108 -0
- package/dist/agent-issues-query.js +4 -3
- package/dist/agent-log-issue.js +25 -4
- package/dist/backlog-prune.js +5 -4
- package/dist/cli-entry-point.js +11 -1
- package/dist/doctor.js +368 -0
- package/dist/flow-bottlenecks.js +6 -5
- package/dist/flow-report.js +4 -3
- package/dist/gates.js +356 -101
- package/dist/guard-locked.js +4 -3
- package/dist/guard-worktree-commit.js +4 -3
- package/dist/init.js +517 -86
- package/dist/initiative-add-wu.js +4 -3
- package/dist/initiative-bulk-assign-wus.js +8 -5
- package/dist/initiative-create.js +73 -37
- package/dist/initiative-edit.js +37 -21
- package/dist/initiative-list.js +4 -3
- package/dist/initiative-plan.js +337 -0
- package/dist/initiative-status.js +4 -3
- package/dist/lane-health.js +377 -0
- package/dist/lane-suggest.js +382 -0
- package/dist/mem-checkpoint.js +2 -2
- package/dist/mem-cleanup.js +2 -2
- package/dist/mem-context.js +306 -0
- package/dist/mem-create.js +2 -2
- package/dist/mem-delete.js +293 -0
- package/dist/mem-inbox.js +2 -2
- package/dist/mem-index.js +211 -0
- package/dist/mem-init.js +1 -1
- package/dist/mem-profile.js +207 -0
- package/dist/mem-promote.js +254 -0
- package/dist/mem-ready.js +2 -2
- package/dist/mem-signal.js +2 -2
- package/dist/mem-start.js +2 -2
- package/dist/mem-summarize.js +2 -2
- package/dist/mem-triage.js +2 -2
- package/dist/merge-block.js +222 -0
- package/dist/metrics-cli.js +7 -4
- package/dist/metrics-snapshot.js +4 -3
- package/dist/orchestrate-initiative.js +10 -4
- package/dist/orchestrate-monitor.js +379 -31
- package/dist/release.js +69 -29
- package/dist/signal-cleanup.js +296 -0
- package/dist/spawn-list.js +6 -5
- package/dist/state-bootstrap.js +5 -4
- package/dist/state-cleanup.js +360 -0
- package/dist/state-doctor-fix.js +196 -0
- package/dist/state-doctor.js +501 -0
- package/dist/validate-agent-skills.js +4 -3
- package/dist/validate-agent-sync.js +4 -3
- package/dist/validate-backlog-sync.js +4 -3
- package/dist/validate-skills-spec.js +4 -3
- package/dist/validate.js +4 -3
- package/dist/wu-block.js +3 -3
- package/dist/wu-claim.js +208 -98
- package/dist/wu-cleanup.js +5 -4
- package/dist/wu-create.js +71 -46
- package/dist/wu-delete.js +88 -60
- package/dist/wu-deps.js +6 -5
- package/dist/wu-done-check.js +34 -0
- package/dist/wu-done.js +39 -12
- package/dist/wu-edit.js +63 -28
- package/dist/wu-infer-lane.js +7 -6
- package/dist/wu-preflight.js +23 -81
- package/dist/wu-prep.js +125 -0
- package/dist/wu-prune.js +4 -3
- package/dist/wu-recover.js +88 -22
- package/dist/wu-repair.js +7 -6
- package/dist/wu-spawn.js +226 -270
- package/dist/wu-status.js +4 -3
- package/dist/wu-unblock.js +5 -5
- package/dist/wu-unlock-lane.js +4 -3
- package/dist/wu-validate.js +5 -4
- package/package.json +16 -7
- package/templates/core/.lumenflow/constraints.md.template +192 -0
- package/templates/core/.lumenflow/rules/git-safety.md.template +27 -0
- package/templates/core/.lumenflow/rules/wu-workflow.md.template +48 -0
- package/templates/core/AGENTS.md.template +60 -0
- package/templates/core/LUMENFLOW.md.template +255 -0
- package/templates/core/UPGRADING.md.template +121 -0
- package/templates/core/ai/onboarding/agent-safety-card.md.template +106 -0
- package/templates/core/ai/onboarding/first-wu-mistakes.md.template +198 -0
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +186 -0
- package/templates/core/ai/onboarding/release-process.md.template +362 -0
- package/templates/core/ai/onboarding/troubleshooting-wu-done.md.template +159 -0
- package/templates/core/ai/onboarding/wu-create-checklist.md.template +117 -0
- package/templates/vendors/aider/.aider.conf.yml.template +27 -0
- package/templates/vendors/claude/.claude/CLAUDE.md.template +52 -0
- package/templates/vendors/claude/.claude/settings.json.template +49 -0
- package/templates/vendors/claude/.claude/skills/bug-classification/SKILL.md.template +192 -0
- package/templates/vendors/claude/.claude/skills/code-quality/SKILL.md.template +152 -0
- package/templates/vendors/claude/.claude/skills/context-management/SKILL.md.template +155 -0
- package/templates/vendors/claude/.claude/skills/execution-memory/SKILL.md.template +304 -0
- package/templates/vendors/claude/.claude/skills/frontend-design/SKILL.md.template +131 -0
- package/templates/vendors/claude/.claude/skills/initiative-management/SKILL.md.template +164 -0
- package/templates/vendors/claude/.claude/skills/library-first/SKILL.md.template +98 -0
- package/templates/vendors/claude/.claude/skills/lumenflow-gates/SKILL.md.template +87 -0
- package/templates/vendors/claude/.claude/skills/multi-agent-coordination/SKILL.md.template +84 -0
- package/templates/vendors/claude/.claude/skills/ops-maintenance/SKILL.md.template +254 -0
- package/templates/vendors/claude/.claude/skills/orchestration/SKILL.md.template +189 -0
- package/templates/vendors/claude/.claude/skills/tdd-workflow/SKILL.md.template +139 -0
- package/templates/vendors/claude/.claude/skills/worktree-discipline/SKILL.md.template +138 -0
- package/templates/vendors/claude/.claude/skills/wu-lifecycle/SKILL.md.template +106 -0
- package/templates/vendors/cline/.clinerules.template +53 -0
- package/templates/vendors/cursor/.cursor/rules/lumenflow.md.template +34 -0
- package/templates/vendors/cursor/.cursor/rules.md.template +28 -0
- package/templates/vendors/windsurf/.windsurf/rules/lumenflow.md.template +34 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console -- CLI tool requires console output */
|
|
3
|
+
/**
|
|
4
|
+
* Signal Cleanup CLI (WU-1204)
|
|
5
|
+
*
|
|
6
|
+
* Prune old signals based on TTL policy to prevent unbounded growth.
|
|
7
|
+
* Implements configurable retention:
|
|
8
|
+
* - Read signals: 7 days default TTL
|
|
9
|
+
* - Unread signals: 30 days default TTL
|
|
10
|
+
* - Max entries: 500 default
|
|
11
|
+
* - Active WU protection: signals linked to in_progress/blocked WUs are never removed
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* pnpm signal:cleanup # Cleanup based on TTL policy
|
|
15
|
+
* pnpm signal:cleanup --dry-run # Preview without changes
|
|
16
|
+
* pnpm signal:cleanup --ttl 3d # Override read signal TTL
|
|
17
|
+
* pnpm signal:cleanup --max-entries 100 # Override max entries
|
|
18
|
+
* pnpm signal:cleanup --json # Output as JSON
|
|
19
|
+
*
|
|
20
|
+
* @see {@link packages/@lumenflow/memory/src/signal-cleanup-core.ts} - Core logic
|
|
21
|
+
* @see {@link packages/@lumenflow/memory/__tests__/signal-cleanup-core.test.ts} - Tests
|
|
22
|
+
*/
|
|
23
|
+
import fs from 'node:fs/promises';
|
|
24
|
+
import path from 'node:path';
|
|
25
|
+
import fg from 'fast-glob';
|
|
26
|
+
import { parse as parseYaml } from 'yaml';
|
|
27
|
+
import { cleanupSignals } from '@lumenflow/memory/dist/signal-cleanup-core.js';
|
|
28
|
+
import { createWUParser } from '@lumenflow/core/dist/arg-parser.js';
|
|
29
|
+
import { EXIT_CODES, LUMENFLOW_PATHS } from '@lumenflow/core/dist/wu-constants.js';
|
|
30
|
+
import { getConfig } from '@lumenflow/core/dist/lumenflow-config.js';
|
|
31
|
+
/**
|
|
32
|
+
* Log prefix for signal:cleanup output
|
|
33
|
+
*/
|
|
34
|
+
const LOG_PREFIX = '[signal:cleanup]';
|
|
35
|
+
/**
|
|
36
|
+
* Tool name for audit logging
|
|
37
|
+
*/
|
|
38
|
+
const TOOL_NAME = 'signal:cleanup';
|
|
39
|
+
/**
|
|
40
|
+
* Bytes per KB for formatting
|
|
41
|
+
*/
|
|
42
|
+
const BYTES_PER_KB = 1024;
|
|
43
|
+
/**
|
|
44
|
+
* Active WU statuses that should protect signals
|
|
45
|
+
*/
|
|
46
|
+
const ACTIVE_WU_STATUSES = ['in_progress', 'blocked'];
|
|
47
|
+
/**
|
|
48
|
+
* CLI argument options specific to signal:cleanup
|
|
49
|
+
*/
|
|
50
|
+
const CLI_OPTIONS = {
|
|
51
|
+
dryRun: {
|
|
52
|
+
name: 'dryRun',
|
|
53
|
+
flags: '--dry-run',
|
|
54
|
+
description: 'Preview cleanup without making changes',
|
|
55
|
+
},
|
|
56
|
+
ttl: {
|
|
57
|
+
name: 'ttl',
|
|
58
|
+
flags: '--ttl <duration>',
|
|
59
|
+
description: 'TTL for read signals (e.g., 7d, 24h). Default: 7d',
|
|
60
|
+
},
|
|
61
|
+
unreadTtl: {
|
|
62
|
+
name: 'unreadTtl',
|
|
63
|
+
flags: '--unread-ttl <duration>',
|
|
64
|
+
description: 'TTL for unread signals (e.g., 30d). Default: 30d',
|
|
65
|
+
},
|
|
66
|
+
maxEntries: {
|
|
67
|
+
name: 'maxEntries',
|
|
68
|
+
flags: '--max-entries <count>',
|
|
69
|
+
description: 'Maximum signals to retain. Default: 500',
|
|
70
|
+
},
|
|
71
|
+
json: {
|
|
72
|
+
name: 'json',
|
|
73
|
+
flags: '--json',
|
|
74
|
+
description: 'Output as JSON',
|
|
75
|
+
},
|
|
76
|
+
quiet: {
|
|
77
|
+
name: 'quiet',
|
|
78
|
+
flags: '-q, --quiet',
|
|
79
|
+
description: 'Suppress output except errors',
|
|
80
|
+
},
|
|
81
|
+
baseDir: {
|
|
82
|
+
name: 'baseDir',
|
|
83
|
+
flags: '-b, --base-dir <path>',
|
|
84
|
+
description: 'Base directory (defaults to current directory)',
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Write audit log entry for tool execution
|
|
89
|
+
*
|
|
90
|
+
* @param baseDir - Base directory
|
|
91
|
+
* @param entry - Audit log entry
|
|
92
|
+
*/
|
|
93
|
+
async function writeAuditLog(baseDir, entry) {
|
|
94
|
+
try {
|
|
95
|
+
const logPath = path.join(baseDir, LUMENFLOW_PATHS.AUDIT_LOG);
|
|
96
|
+
const logDir = path.dirname(logPath);
|
|
97
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- CLI tool creates known directory
|
|
98
|
+
await fs.mkdir(logDir, { recursive: true });
|
|
99
|
+
const line = `${JSON.stringify(entry)}\n`;
|
|
100
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- CLI tool writes audit log
|
|
101
|
+
await fs.appendFile(logPath, line, 'utf-8');
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Audit logging is non-fatal - silently ignore errors
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Format bytes as human-readable string
|
|
109
|
+
*
|
|
110
|
+
* @param bytes - Number of bytes
|
|
111
|
+
* @returns Formatted string (e.g., "1.5 KB")
|
|
112
|
+
*/
|
|
113
|
+
function formatBytes(bytes) {
|
|
114
|
+
if (bytes < BYTES_PER_KB) {
|
|
115
|
+
return `${bytes} B`;
|
|
116
|
+
}
|
|
117
|
+
const kb = (bytes / BYTES_PER_KB).toFixed(1);
|
|
118
|
+
return `${kb} KB`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Format compaction ratio as percentage
|
|
122
|
+
*
|
|
123
|
+
* @param ratio - Compaction ratio (0-1)
|
|
124
|
+
* @returns Formatted percentage
|
|
125
|
+
*/
|
|
126
|
+
function formatRatio(ratio) {
|
|
127
|
+
return `${(ratio * 100).toFixed(1)}%`;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get active WU IDs (in_progress or blocked) by scanning WU YAML files.
|
|
131
|
+
*
|
|
132
|
+
* @param baseDir - Base directory
|
|
133
|
+
* @returns Set of active WU IDs
|
|
134
|
+
*/
|
|
135
|
+
async function getActiveWuIds(baseDir) {
|
|
136
|
+
const activeIds = new Set();
|
|
137
|
+
try {
|
|
138
|
+
const config = getConfig({ projectRoot: baseDir });
|
|
139
|
+
const wuDir = path.join(baseDir, config.directories.wuDir);
|
|
140
|
+
// Find all WU YAML files
|
|
141
|
+
const wuFiles = await fg('WU-*.yaml', { cwd: wuDir });
|
|
142
|
+
for (const file of wuFiles) {
|
|
143
|
+
try {
|
|
144
|
+
const filePath = path.join(wuDir, file);
|
|
145
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- CLI tool reads known path
|
|
146
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
147
|
+
const wu = parseYaml(content);
|
|
148
|
+
if (wu.id && wu.status && ACTIVE_WU_STATUSES.includes(wu.status)) {
|
|
149
|
+
activeIds.add(wu.id);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Skip files that fail to parse
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// If we can't read WU files, return empty set (safer to remove nothing)
|
|
160
|
+
}
|
|
161
|
+
return activeIds;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Parse CLI arguments
|
|
165
|
+
*
|
|
166
|
+
* @returns Parsed arguments
|
|
167
|
+
*/
|
|
168
|
+
function parseArguments() {
|
|
169
|
+
return createWUParser({
|
|
170
|
+
name: 'signal-cleanup',
|
|
171
|
+
description: 'Prune old signals based on TTL policy to prevent unbounded growth',
|
|
172
|
+
options: [
|
|
173
|
+
CLI_OPTIONS.dryRun,
|
|
174
|
+
CLI_OPTIONS.ttl,
|
|
175
|
+
CLI_OPTIONS.unreadTtl,
|
|
176
|
+
CLI_OPTIONS.maxEntries,
|
|
177
|
+
CLI_OPTIONS.json,
|
|
178
|
+
CLI_OPTIONS.quiet,
|
|
179
|
+
CLI_OPTIONS.baseDir,
|
|
180
|
+
],
|
|
181
|
+
required: [],
|
|
182
|
+
allowPositionalId: false,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Print cleanup result to console
|
|
187
|
+
*
|
|
188
|
+
* @param result - Cleanup result
|
|
189
|
+
* @param quiet - Suppress verbose output
|
|
190
|
+
*/
|
|
191
|
+
function printResult(result, quiet) {
|
|
192
|
+
if (result.dryRun) {
|
|
193
|
+
console.log(`${LOG_PREFIX} Dry-run: Would remove ${result.removedIds.length} signal(s)`);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.log(`${LOG_PREFIX} Cleanup complete`);
|
|
197
|
+
}
|
|
198
|
+
if (quiet) {
|
|
199
|
+
console.log(`${result.removedIds.length} removed, ${result.retainedIds.length} retained`);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
console.log('');
|
|
203
|
+
console.log('Summary:');
|
|
204
|
+
console.log(` Removed: ${result.removedIds.length} signal(s)`);
|
|
205
|
+
console.log(` Retained: ${result.retainedIds.length} signal(s)`);
|
|
206
|
+
console.log(` Bytes Freed: ${formatBytes(result.bytesFreed)}`);
|
|
207
|
+
console.log(` Compaction Ratio: ${formatRatio(result.compactionRatio)}`);
|
|
208
|
+
console.log('');
|
|
209
|
+
console.log('Breakdown:');
|
|
210
|
+
console.log(` TTL Expired (read): ${result.breakdown.ttlExpired} removed`);
|
|
211
|
+
console.log(` TTL Expired (unread): ${result.breakdown.unreadTtlExpired} removed`);
|
|
212
|
+
console.log(` Count Limit Exceeded: ${result.breakdown.countLimitExceeded} removed`);
|
|
213
|
+
console.log(` Active WU Protected: ${result.breakdown.activeWuProtected} retained`);
|
|
214
|
+
if (result.removedIds.length > 0 && !result.dryRun) {
|
|
215
|
+
console.log('');
|
|
216
|
+
console.log('Removed Signal IDs:');
|
|
217
|
+
// Show first 10, then "and X more" if needed
|
|
218
|
+
const displayLimit = 10;
|
|
219
|
+
const displayIds = result.removedIds.slice(0, displayLimit);
|
|
220
|
+
for (const id of displayIds) {
|
|
221
|
+
console.log(` - ${id}`);
|
|
222
|
+
}
|
|
223
|
+
if (result.removedIds.length > displayLimit) {
|
|
224
|
+
console.log(` ... and ${result.removedIds.length - displayLimit} more`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (result.dryRun) {
|
|
228
|
+
console.log('');
|
|
229
|
+
console.log('To execute, run without --dry-run');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Main CLI entry point
|
|
234
|
+
*/
|
|
235
|
+
async function main() {
|
|
236
|
+
const args = parseArguments();
|
|
237
|
+
const baseDir = args.baseDir || process.cwd();
|
|
238
|
+
const startedAt = new Date().toISOString();
|
|
239
|
+
const startTime = Date.now();
|
|
240
|
+
let result = null;
|
|
241
|
+
let error = null;
|
|
242
|
+
try {
|
|
243
|
+
result = await cleanupSignals(baseDir, {
|
|
244
|
+
dryRun: args.dryRun,
|
|
245
|
+
ttl: args.ttl,
|
|
246
|
+
unreadTtl: args.unreadTtl,
|
|
247
|
+
maxEntries: args.maxEntries ? parseInt(args.maxEntries, 10) : undefined,
|
|
248
|
+
getActiveWuIds: () => getActiveWuIds(baseDir),
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
error = err.message;
|
|
253
|
+
}
|
|
254
|
+
const durationMs = Date.now() - startTime;
|
|
255
|
+
await writeAuditLog(baseDir, {
|
|
256
|
+
tool: TOOL_NAME,
|
|
257
|
+
status: error ? 'failed' : 'success',
|
|
258
|
+
startedAt,
|
|
259
|
+
completedAt: new Date().toISOString(),
|
|
260
|
+
durationMs,
|
|
261
|
+
input: {
|
|
262
|
+
baseDir,
|
|
263
|
+
dryRun: args.dryRun,
|
|
264
|
+
ttl: args.ttl,
|
|
265
|
+
unreadTtl: args.unreadTtl,
|
|
266
|
+
maxEntries: args.maxEntries,
|
|
267
|
+
},
|
|
268
|
+
output: result
|
|
269
|
+
? {
|
|
270
|
+
success: result.success,
|
|
271
|
+
removedCount: result.removedIds.length,
|
|
272
|
+
retainedCount: result.retainedIds.length,
|
|
273
|
+
bytesFreed: result.bytesFreed,
|
|
274
|
+
compactionRatio: result.compactionRatio,
|
|
275
|
+
breakdown: result.breakdown,
|
|
276
|
+
dryRun: result.dryRun,
|
|
277
|
+
}
|
|
278
|
+
: null,
|
|
279
|
+
error: error ? { message: error } : null,
|
|
280
|
+
});
|
|
281
|
+
if (error) {
|
|
282
|
+
console.error(`${LOG_PREFIX} Error: ${error}`);
|
|
283
|
+
process.exit(EXIT_CODES.ERROR);
|
|
284
|
+
}
|
|
285
|
+
if (args.json) {
|
|
286
|
+
console.log(JSON.stringify(result, null, 2));
|
|
287
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
288
|
+
}
|
|
289
|
+
if (result) {
|
|
290
|
+
printResult(result, args.quiet ?? false);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
main().catch((e) => {
|
|
294
|
+
console.error(`${LOG_PREFIX} ${e.message}`);
|
|
295
|
+
process.exit(EXIT_CODES.ERROR);
|
|
296
|
+
});
|
package/dist/spawn-list.js
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* pnpm spawn:list --initiative INIT-XXX # All spawns in an initiative
|
|
11
11
|
* pnpm spawn:list --json # JSON output
|
|
12
12
|
*
|
|
13
|
-
* @see {@link
|
|
14
|
-
* @see {@link
|
|
13
|
+
* @see {@link packages/@lumenflow/cli/src/lib/spawn-tree.ts} - Tree builder
|
|
14
|
+
* @see {@link packages/@lumenflow/cli/src/__tests__/spawn-list.test.ts} - Tests
|
|
15
15
|
*/
|
|
16
16
|
import { createWUParser, WU_OPTIONS } from '@lumenflow/core/dist/arg-parser.js';
|
|
17
17
|
import { die } from '@lumenflow/core/dist/error-handler.js';
|
|
@@ -130,9 +130,10 @@ async function main() {
|
|
|
130
130
|
console.log(`\nTotal: ${spawns.length} spawn(s) across ${rootWuIds.length} root WU(s)`);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
// WU-1181: Use import.meta.main instead of process.argv[1] comparison
|
|
134
|
+
// The old pattern fails with pnpm symlinks because process.argv[1] is the symlink
|
|
135
|
+
// path but import.meta.url resolves to the real path - they never match
|
|
136
|
+
if (import.meta.main) {
|
|
136
137
|
main().catch((err) => {
|
|
137
138
|
console.error(`${LOG_PREFIX} ${EMOJI.ERROR} ${err.message}`);
|
|
138
139
|
process.exit(1);
|
package/dist/state-bootstrap.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* One-time migration utility from WU YAMLs to event-sourced state store.
|
|
6
6
|
* Reads all WU YAML files and generates corresponding events in the state store.
|
|
7
7
|
*
|
|
8
|
-
* WU-1107: INIT-003 Phase 3c - Migrate state-bootstrap.
|
|
8
|
+
* WU-1107: INIT-003 Phase 3c - Migrate state-bootstrap.ts from PatientPath
|
|
9
9
|
*
|
|
10
10
|
* Usage:
|
|
11
11
|
* pnpm state:bootstrap # Dry-run mode (shows what would be done)
|
|
@@ -299,9 +299,10 @@ async function main() {
|
|
|
299
299
|
}
|
|
300
300
|
process.exit(EXIT_CODES.SUCCESS);
|
|
301
301
|
}
|
|
302
|
-
//
|
|
303
|
-
|
|
302
|
+
// WU-1181: Use import.meta.main instead of process.argv[1] comparison
|
|
303
|
+
// The old pattern fails with pnpm symlinks because process.argv[1] is the symlink
|
|
304
|
+
// path but import.meta.url resolves to the real path - they never match
|
|
304
305
|
import { runCLI } from './cli-entry-point.js';
|
|
305
|
-
if (
|
|
306
|
+
if (import.meta.main) {
|
|
306
307
|
runCLI(main);
|
|
307
308
|
}
|