@lumenflow/cli 3.1.2 → 3.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -35
- package/dist/agent-issues-query.js +13 -8
- package/dist/agent-log-issue.js +15 -4
- package/dist/agent-session-end.js +15 -4
- package/dist/agent-session.js +18 -6
- package/dist/backlog-prune.js +1 -1
- package/dist/commands/integrate.js +32 -18
- package/dist/config-get.js +27 -15
- package/dist/config-set.js +104 -37
- package/dist/delegation-list.js +1 -1
- package/dist/doctor.js +19 -13
- package/dist/file-delete.js +1 -1
- package/dist/file-edit.js +1 -1
- package/dist/file-read.js +1 -1
- package/dist/file-write.js +1 -1
- package/dist/flow-bottlenecks.js +1 -1
- package/dist/flow-report.js +10 -9
- package/dist/gates.js +3 -2
- package/dist/git-branch.js +1 -1
- package/dist/git-diff.js +1 -1
- package/dist/git-log.js +1 -1
- package/dist/init.js +238 -42
- package/dist/initiative-add-wu.js +1 -1
- package/dist/initiative-bulk-assign-wus.js +1 -1
- package/dist/initiative-create.js +2 -2
- package/dist/initiative-edit.js +1 -1
- package/dist/initiative-list.js +1 -1
- package/dist/initiative-plan.js +1 -3
- package/dist/initiative-status.js +47 -6
- package/dist/lane-edit.js +19 -10
- package/dist/lane-health.js +13 -24
- package/dist/lane-lock.js +4 -5
- package/dist/lane-setup.js +5 -5
- package/dist/lane-status.js +4 -5
- package/dist/lane-suggest.js +9 -7
- package/dist/lane-validate.js +4 -5
- package/dist/lumenflow-upgrade.js +17 -11
- package/dist/mem-checkpoint.js +1 -1
- package/dist/mem-cleanup.js +6 -23
- package/dist/mem-context.js +1 -1
- package/dist/mem-create.js +1 -1
- package/dist/mem-delete.js +1 -1
- package/dist/mem-export.js +1 -1
- package/dist/mem-inbox.js +1 -1
- package/dist/mem-init.js +1 -1
- package/dist/mem-ready.js +1 -1
- package/dist/mem-recover.js +1 -1
- package/dist/mem-signal.js +1 -1
- package/dist/mem-start.js +1 -1
- package/dist/mem-summarize.js +8 -7
- package/dist/mem-triage.js +7 -5
- package/dist/metrics-cli.js +1 -1
- package/dist/metrics-snapshot.js +1 -1
- package/dist/onboard.js +295 -120
- package/dist/orchestrate-init-status.js +12 -7
- package/dist/orchestrate-initiative.js +23 -12
- package/dist/orchestrate-monitor.js +20 -8
- package/dist/pack-scaffold.js +1 -1
- package/dist/plan-create.js +1 -3
- package/dist/plan-edit.js +1 -3
- package/dist/plan-link.js +1 -3
- package/dist/plan-promote.js +1 -3
- package/dist/release.js +1 -3
- package/dist/signal-cleanup.js +4 -18
- package/dist/state-bootstrap.js +11 -8
- package/dist/state-cleanup.js +5 -19
- package/dist/state-doctor.js +213 -9
- package/dist/task-claim.js +1 -1
- package/dist/validate.js +1 -1
- package/dist/workspace-init.js +61 -61
- package/dist/wu-block.js +1 -1
- package/dist/wu-brief.js +1 -1
- package/dist/wu-claim.js +1 -1
- package/dist/wu-cleanup.js +1 -1
- package/dist/wu-create.js +3 -3
- package/dist/wu-delegate.js +1 -1
- package/dist/wu-deps.js +1 -1
- package/dist/wu-done.js +66 -34
- package/dist/wu-edit.js +1 -1
- package/dist/wu-infer-lane.js +1 -1
- package/dist/wu-preflight.js +1 -1
- package/dist/wu-prep.js +1 -1
- package/dist/wu-proto.js +1 -1
- package/dist/wu-prune.js +1 -1
- package/dist/wu-recover.js +1 -1
- package/dist/wu-release.js +1 -1
- package/dist/wu-repair.js +1 -1
- package/dist/wu-sandbox.js +40 -27
- package/dist/wu-status.js +1 -1
- package/dist/wu-unblock.js +1 -1
- package/dist/wu-unlock-lane.js +1 -1
- package/dist/wu-validate.js +1 -1
- package/package.json +12 -8
- package/packs/software-delivery/constants.ts +10 -0
- package/packs/software-delivery/extensions.ts +140 -0
- package/packs/software-delivery/gate-policies.ts +134 -0
- package/packs/software-delivery/index.ts +8 -0
- package/packs/software-delivery/manifest-schema.ts +236 -0
- package/packs/software-delivery/manifest.ts +417 -0
- package/packs/software-delivery/manifest.yaml +711 -0
- package/packs/software-delivery/pack-registration.ts +113 -0
- package/packs/software-delivery/tool-impl/agent-tools.ts +263 -0
- package/packs/software-delivery/tool-impl/delegation-tools.ts +66 -0
- package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +219 -0
- package/packs/software-delivery/tool-impl/git-runner.ts +113 -0
- package/packs/software-delivery/tool-impl/git-tools.ts +316 -0
- package/packs/software-delivery/tool-impl/index.ts +15 -0
- package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +720 -0
- package/packs/software-delivery/tool-impl/lane-lock.ts +246 -0
- package/packs/software-delivery/tool-impl/memory-tools.ts +415 -0
- package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +21 -0
- package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +328 -0
- package/packs/software-delivery/tool-impl/runtime-native-tools.ts +687 -0
- package/packs/software-delivery/tool-impl/worker-loader.ts +52 -0
- package/packs/software-delivery/tool-impl/worktree-tools.ts +46 -0
- package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +759 -0
- package/packs/software-delivery/tools/delegation-tools.ts +23 -0
- package/packs/software-delivery/tools/git-tools.ts +55 -0
- package/packs/software-delivery/tools/index.ts +8 -0
- package/packs/software-delivery/tools/lane-lock-tool.ts +37 -0
- package/packs/software-delivery/tools/types.ts +71 -0
- package/packs/software-delivery/tools/worktree-tools.ts +49 -0
- package/templates/core/LUMENFLOW.md.template +3 -3
- package/templates/core/ai/onboarding/agent-invocation-guide.md.template +1 -1
- package/templates/core/ai/onboarding/lumenflow-force-usage.md.template +1 -1
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +5 -5
- package/templates/core/ai/onboarding/starting-prompt.md.template +3 -3
- package/templates/core/ai/onboarding/vendor-support.md.template +1 -1
- package/templates/core/ai/onboarding/wu-create-checklist.md.template +1 -1
- package/dist/agent-issues-query.js.map +0 -1
- package/dist/agent-log-issue.js.map +0 -1
- package/dist/agent-session-end.js.map +0 -1
- package/dist/agent-session.js.map +0 -1
- package/dist/backlog-prune.js.map +0 -1
- package/dist/cli-entry-point.js +0 -149
- package/dist/cli-entry-point.js.map +0 -1
- package/dist/commands/integrate.js.map +0 -1
- package/dist/commands.js.map +0 -1
- package/dist/config-get.js.map +0 -1
- package/dist/config-set.js.map +0 -1
- package/dist/delegation-list.js.map +0 -1
- package/dist/deps-add.js +0 -259
- package/dist/deps-add.js.map +0 -1
- package/dist/deps-remove.js +0 -105
- package/dist/deps-remove.js.map +0 -1
- package/dist/docs-sync.js.map +0 -1
- package/dist/doctor.js.map +0 -1
- package/dist/file-delete.js.map +0 -1
- package/dist/file-edit.js.map +0 -1
- package/dist/file-read.js.map +0 -1
- package/dist/file-write.js.map +0 -1
- package/dist/flow-bottlenecks.js.map +0 -1
- package/dist/flow-report.js.map +0 -1
- package/dist/formatters.js +0 -151
- package/dist/formatters.js.map +0 -1
- package/dist/gate-defaults.js +0 -131
- package/dist/gate-defaults.js.map +0 -1
- package/dist/gate-registry.js +0 -73
- package/dist/gate-registry.js.map +0 -1
- package/dist/gates-graceful-degradation.js +0 -153
- package/dist/gates-graceful-degradation.js.map +0 -1
- package/dist/gates-plan-resolvers.js +0 -152
- package/dist/gates-plan-resolvers.js.map +0 -1
- package/dist/gates-runners.js +0 -509
- package/dist/gates-runners.js.map +0 -1
- package/dist/gates-types.js +0 -4
- package/dist/gates-types.js.map +0 -1
- package/dist/gates-utils.js +0 -323
- package/dist/gates-utils.js.map +0 -1
- package/dist/gates.js.map +0 -1
- package/dist/git-branch.js.map +0 -1
- package/dist/git-diff.js.map +0 -1
- package/dist/git-log.js.map +0 -1
- package/dist/git-status.js.map +0 -1
- package/dist/guard-locked.js +0 -172
- package/dist/guard-locked.js.map +0 -1
- package/dist/guard-main-branch.js +0 -217
- package/dist/guard-main-branch.js.map +0 -1
- package/dist/guard-worktree-commit.js +0 -163
- package/dist/guard-worktree-commit.js.map +0 -1
- package/dist/hooks/auto-checkpoint-utils.js +0 -54
- package/dist/hooks/auto-checkpoint-utils.js.map +0 -1
- package/dist/hooks/enforcement-checks.js +0 -399
- package/dist/hooks/enforcement-checks.js.map +0 -1
- package/dist/hooks/enforcement-generator.js +0 -139
- package/dist/hooks/enforcement-generator.js.map +0 -1
- package/dist/hooks/enforcement-sync.js +0 -385
- package/dist/hooks/enforcement-sync.js.map +0 -1
- package/dist/hooks/generators/auto-checkpoint.js +0 -125
- package/dist/hooks/generators/auto-checkpoint.js.map +0 -1
- package/dist/hooks/generators/enforce-worktree.js +0 -190
- package/dist/hooks/generators/enforce-worktree.js.map +0 -1
- package/dist/hooks/generators/index.js +0 -18
- package/dist/hooks/generators/index.js.map +0 -1
- package/dist/hooks/generators/pre-compact-checkpoint.js +0 -136
- package/dist/hooks/generators/pre-compact-checkpoint.js.map +0 -1
- package/dist/hooks/generators/require-wu.js +0 -117
- package/dist/hooks/generators/require-wu.js.map +0 -1
- package/dist/hooks/generators/session-start-recovery.js +0 -103
- package/dist/hooks/generators/session-start-recovery.js.map +0 -1
- package/dist/hooks/generators/signal-utils.js +0 -54
- package/dist/hooks/generators/signal-utils.js.map +0 -1
- package/dist/hooks/generators/warn-incomplete.js +0 -67
- package/dist/hooks/generators/warn-incomplete.js.map +0 -1
- package/dist/hooks/index.js +0 -10
- package/dist/hooks/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init-detection.js +0 -232
- package/dist/init-detection.js.map +0 -1
- package/dist/init-lane-validation.js +0 -143
- package/dist/init-lane-validation.js.map +0 -1
- package/dist/init-scaffolding.js +0 -158
- package/dist/init-scaffolding.js.map +0 -1
- package/dist/init-templates.js +0 -1982
- package/dist/init-templates.js.map +0 -1
- package/dist/init.js.map +0 -1
- package/dist/initiative-add-wu.js.map +0 -1
- package/dist/initiative-bulk-assign-wus.js.map +0 -1
- package/dist/initiative-create.js.map +0 -1
- package/dist/initiative-edit.js.map +0 -1
- package/dist/initiative-list.js.map +0 -1
- package/dist/initiative-plan.js.map +0 -1
- package/dist/initiative-remove-wu.js.map +0 -1
- package/dist/initiative-status.js.map +0 -1
- package/dist/lane-edit.js.map +0 -1
- package/dist/lane-health.js.map +0 -1
- package/dist/lane-lifecycle-process.js +0 -366
- package/dist/lane-lifecycle-process.js.map +0 -1
- package/dist/lane-lock.js.map +0 -1
- package/dist/lane-setup.js.map +0 -1
- package/dist/lane-status.js.map +0 -1
- package/dist/lane-suggest.js.map +0 -1
- package/dist/lane-validate.js.map +0 -1
- package/dist/lifecycle-regression-harness.js +0 -181
- package/dist/lifecycle-regression-harness.js.map +0 -1
- package/dist/lumenflow-upgrade.js.map +0 -1
- package/dist/mem-checkpoint.js.map +0 -1
- package/dist/mem-cleanup.js.map +0 -1
- package/dist/mem-context.js.map +0 -1
- package/dist/mem-create.js.map +0 -1
- package/dist/mem-delete.js.map +0 -1
- package/dist/mem-export.js.map +0 -1
- package/dist/mem-inbox.js.map +0 -1
- package/dist/mem-index.js +0 -214
- package/dist/mem-index.js.map +0 -1
- package/dist/mem-init.js.map +0 -1
- package/dist/mem-profile.js +0 -210
- package/dist/mem-profile.js.map +0 -1
- package/dist/mem-promote.js +0 -257
- package/dist/mem-promote.js.map +0 -1
- package/dist/mem-ready.js.map +0 -1
- package/dist/mem-recover.js.map +0 -1
- package/dist/mem-signal.js.map +0 -1
- package/dist/mem-start.js.map +0 -1
- package/dist/mem-summarize.js.map +0 -1
- package/dist/mem-triage.js.map +0 -1
- package/dist/merge-block.js +0 -225
- package/dist/merge-block.js.map +0 -1
- package/dist/metrics-cli.js.map +0 -1
- package/dist/metrics-snapshot.js.map +0 -1
- package/dist/onboard.js.map +0 -1
- package/dist/onboarding-smoke-test.js +0 -418
- package/dist/onboarding-smoke-test.js.map +0 -1
- package/dist/orchestrate-init-status.js.map +0 -1
- package/dist/orchestrate-initiative.js.map +0 -1
- package/dist/orchestrate-monitor.js.map +0 -1
- package/dist/pack-author.js.map +0 -1
- package/dist/pack-hash.js.map +0 -1
- package/dist/pack-install.js.map +0 -1
- package/dist/pack-publish.js.map +0 -1
- package/dist/pack-scaffold.js.map +0 -1
- package/dist/pack-search.js.map +0 -1
- package/dist/pack-validate.js.map +0 -1
- package/dist/plan-create.js.map +0 -1
- package/dist/plan-edit.js.map +0 -1
- package/dist/plan-link.js.map +0 -1
- package/dist/plan-promote.js.map +0 -1
- package/dist/public-manifest.js +0 -920
- package/dist/public-manifest.js.map +0 -1
- package/dist/release.js.map +0 -1
- package/dist/rotate-progress.js +0 -253
- package/dist/rotate-progress.js.map +0 -1
- package/dist/session-coordinator.js +0 -303
- package/dist/session-coordinator.js.map +0 -1
- package/dist/shared-validators.js +0 -81
- package/dist/shared-validators.js.map +0 -1
- package/dist/signal-cleanup.js.map +0 -1
- package/dist/state-bootstrap.js.map +0 -1
- package/dist/state-cleanup.js.map +0 -1
- package/dist/state-doctor-fix.js +0 -226
- package/dist/state-doctor-fix.js.map +0 -1
- package/dist/state-doctor-stamps.js +0 -23
- package/dist/state-doctor-stamps.js.map +0 -1
- package/dist/state-doctor.js.map +0 -1
- package/dist/strict-progress.js +0 -255
- package/dist/strict-progress.js.map +0 -1
- package/dist/sync-templates.js.map +0 -1
- package/dist/task-claim.js.map +0 -1
- package/dist/trace-gen.js +0 -401
- package/dist/trace-gen.js.map +0 -1
- package/dist/validate-agent-skills.js +0 -223
- package/dist/validate-agent-skills.js.map +0 -1
- package/dist/validate-agent-sync.js +0 -151
- package/dist/validate-agent-sync.js.map +0 -1
- package/dist/validate-backlog-sync.js +0 -77
- package/dist/validate-backlog-sync.js.map +0 -1
- package/dist/validate-skills-spec.js +0 -211
- package/dist/validate-skills-spec.js.map +0 -1
- package/dist/validate.js.map +0 -1
- package/dist/validator-defaults.js +0 -107
- package/dist/validator-defaults.js.map +0 -1
- package/dist/validator-registry.js +0 -71
- package/dist/validator-registry.js.map +0 -1
- package/dist/workspace-init.js.map +0 -1
- package/dist/wu-block.js.map +0 -1
- package/dist/wu-brief.js.map +0 -1
- package/dist/wu-claim-branch.js +0 -123
- package/dist/wu-claim-branch.js.map +0 -1
- package/dist/wu-claim-cloud.js +0 -79
- package/dist/wu-claim-cloud.js.map +0 -1
- package/dist/wu-claim-mode.js +0 -82
- package/dist/wu-claim-mode.js.map +0 -1
- package/dist/wu-claim-output.js +0 -85
- package/dist/wu-claim-output.js.map +0 -1
- package/dist/wu-claim-repair-guidance.js +0 -12
- package/dist/wu-claim-repair-guidance.js.map +0 -1
- package/dist/wu-claim-resume-handler.js +0 -87
- package/dist/wu-claim-resume-handler.js.map +0 -1
- package/dist/wu-claim-state.js +0 -581
- package/dist/wu-claim-state.js.map +0 -1
- package/dist/wu-claim-validation.js +0 -457
- package/dist/wu-claim-validation.js.map +0 -1
- package/dist/wu-claim-worktree.js +0 -223
- package/dist/wu-claim-worktree.js.map +0 -1
- package/dist/wu-claim.js.map +0 -1
- package/dist/wu-cleanup-cloud.js +0 -78
- package/dist/wu-cleanup-cloud.js.map +0 -1
- package/dist/wu-cleanup.js.map +0 -1
- package/dist/wu-code-path-coverage.js +0 -83
- package/dist/wu-code-path-coverage.js.map +0 -1
- package/dist/wu-create-cloud.js +0 -30
- package/dist/wu-create-cloud.js.map +0 -1
- package/dist/wu-create-content.js +0 -264
- package/dist/wu-create-content.js.map +0 -1
- package/dist/wu-create-readiness.js +0 -59
- package/dist/wu-create-readiness.js.map +0 -1
- package/dist/wu-create-validation.js +0 -128
- package/dist/wu-create-validation.js.map +0 -1
- package/dist/wu-create.js.map +0 -1
- package/dist/wu-delegate.js.map +0 -1
- package/dist/wu-delete.js.map +0 -1
- package/dist/wu-deps.js.map +0 -1
- package/dist/wu-done-auto-cleanup.js +0 -203
- package/dist/wu-done-auto-cleanup.js.map +0 -1
- package/dist/wu-done-check.js +0 -38
- package/dist/wu-done-check.js.map +0 -1
- package/dist/wu-done-cloud.js +0 -48
- package/dist/wu-done-cloud.js.map +0 -1
- package/dist/wu-done-decay.js +0 -86
- package/dist/wu-done-decay.js.map +0 -1
- package/dist/wu-done.js.map +0 -1
- package/dist/wu-edit-operations.js +0 -399
- package/dist/wu-edit-operations.js.map +0 -1
- package/dist/wu-edit-validators.js +0 -282
- package/dist/wu-edit-validators.js.map +0 -1
- package/dist/wu-edit.js.map +0 -1
- package/dist/wu-infer-lane.js.map +0 -1
- package/dist/wu-preflight.js.map +0 -1
- package/dist/wu-prep.js.map +0 -1
- package/dist/wu-proto.js.map +0 -1
- package/dist/wu-prune.js.map +0 -1
- package/dist/wu-recover.js.map +0 -1
- package/dist/wu-release.js.map +0 -1
- package/dist/wu-repair.js.map +0 -1
- package/dist/wu-sandbox.js.map +0 -1
- package/dist/wu-spawn-completion.js +0 -33
- package/dist/wu-spawn-completion.js.map +0 -1
- package/dist/wu-spawn-prompt-builders.js +0 -1197
- package/dist/wu-spawn-prompt-builders.js.map +0 -1
- package/dist/wu-spawn-strategy-resolver.js +0 -322
- package/dist/wu-spawn-strategy-resolver.js.map +0 -1
- package/dist/wu-spawn.js +0 -59
- package/dist/wu-spawn.js.map +0 -1
- package/dist/wu-state-cloud.js +0 -41
- package/dist/wu-state-cloud.js.map +0 -1
- package/dist/wu-status.js.map +0 -1
- package/dist/wu-unblock.js.map +0 -1
- package/dist/wu-unlock-lane.js.map +0 -1
- package/dist/wu-validate.js.map +0 -1
|
@@ -25,8 +25,10 @@ import { Command } from 'commander';
|
|
|
25
25
|
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
26
26
|
import { join } from 'node:path';
|
|
27
27
|
import { EXIT_CODES, LUMENFLOW_PATHS, DelegationRegistryStore, analyzeDelegations, detectStuckDelegations, checkZombieLocks, generateSuggestions, formatMonitorOutput, formatRecoveryResults, runRecovery, processDelegationFailureSignals, formatSignalHandlerOutput, DEFAULT_THRESHOLD_MINUTES, calculateBackoff, } from '@lumenflow/core';
|
|
28
|
+
import { ProcessExitError } from '@lumenflow/core/error-handler';
|
|
28
29
|
import chalk from 'chalk';
|
|
29
30
|
import ms, {} from 'ms';
|
|
31
|
+
import { runCLI } from './cli-entry-point.js';
|
|
30
32
|
// ============================================================================
|
|
31
33
|
// WU-1242: Watch Mode Constants
|
|
32
34
|
// ============================================================================
|
|
@@ -187,8 +189,9 @@ async function runDelegationMonitoring(opts) {
|
|
|
187
189
|
const baseDir = process.cwd();
|
|
188
190
|
const thresholdMinutes = parseInt(opts.threshold, 10);
|
|
189
191
|
if (isNaN(thresholdMinutes) || thresholdMinutes <= 0) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
+
const message = `${LOG_PREFIX} Invalid threshold: ${opts.threshold}`;
|
|
193
|
+
console.error(chalk.red(message));
|
|
194
|
+
throw new ProcessExitError(message, EXIT_CODES.FAILURE);
|
|
192
195
|
}
|
|
193
196
|
console.log(chalk.cyan(`${LOG_PREFIX} Analyzing delegation health...`));
|
|
194
197
|
console.log(chalk.gray(` Threshold: ${thresholdMinutes} minutes`));
|
|
@@ -209,7 +212,7 @@ async function runDelegationMonitoring(opts) {
|
|
|
209
212
|
console.log(formatSignalHandlerOutput(signalResult));
|
|
210
213
|
}
|
|
211
214
|
if (result.stuckDelegations.length > 0 || result.zombieLocks.length > 0) {
|
|
212
|
-
|
|
215
|
+
throw new ProcessExitError(`${LOG_PREFIX} Delegation monitor detected stuck delegations or zombie locks.`, EXIT_CODES.ERROR);
|
|
213
216
|
}
|
|
214
217
|
}
|
|
215
218
|
/**
|
|
@@ -378,8 +381,9 @@ async function runWatchMode(opts) {
|
|
|
378
381
|
const baseDir = process.cwd();
|
|
379
382
|
const thresholdMinutes = parseInt(opts.threshold, 10);
|
|
380
383
|
if (isNaN(thresholdMinutes) || thresholdMinutes <= 0) {
|
|
381
|
-
|
|
382
|
-
|
|
384
|
+
const message = `${LOG_PREFIX} Invalid threshold: ${opts.threshold}`;
|
|
385
|
+
console.error(chalk.red(message));
|
|
386
|
+
throw new ProcessExitError(message, EXIT_CODES.FAILURE);
|
|
383
387
|
}
|
|
384
388
|
const watchOptions = parseWatchOptions(opts);
|
|
385
389
|
console.log(chalk.cyan(`${LOG_PREFIX} Starting continuous patrol mode...`));
|
|
@@ -403,7 +407,7 @@ async function runWatchMode(opts) {
|
|
|
403
407
|
// Handle graceful shutdown
|
|
404
408
|
const shutdown = () => {
|
|
405
409
|
runner.stop();
|
|
406
|
-
process.
|
|
410
|
+
process.exitCode = EXIT_CODES.SUCCESS;
|
|
407
411
|
};
|
|
408
412
|
process.on('SIGINT', shutdown);
|
|
409
413
|
process.on('SIGTERM', shutdown);
|
|
@@ -438,10 +442,18 @@ const program = new Command()
|
|
|
438
442
|
await runDelegationMonitoring(opts);
|
|
439
443
|
}
|
|
440
444
|
catch (err) {
|
|
445
|
+
if (err instanceof ProcessExitError) {
|
|
446
|
+
throw err;
|
|
447
|
+
}
|
|
441
448
|
const message = err instanceof Error ? err.message : String(err);
|
|
442
449
|
console.error(chalk.red(`${LOG_PREFIX} Error: ${message}`));
|
|
443
|
-
|
|
450
|
+
throw new ProcessExitError(message, EXIT_CODES.ERROR);
|
|
444
451
|
}
|
|
445
452
|
});
|
|
446
|
-
|
|
453
|
+
export async function main() {
|
|
454
|
+
await program.parseAsync(process.argv);
|
|
455
|
+
}
|
|
456
|
+
if (import.meta.main) {
|
|
457
|
+
void runCLI(main);
|
|
458
|
+
}
|
|
447
459
|
//# sourceMappingURL=orchestrate-monitor.js.map
|
package/dist/pack-scaffold.js
CHANGED
|
@@ -112,7 +112,7 @@ LumenFlow domain pack - version ${version}
|
|
|
112
112
|
|
|
113
113
|
## Overview
|
|
114
114
|
|
|
115
|
-
This pack provides
|
|
115
|
+
This pack provides pack-specific tools and policies for the LumenFlow kernel.
|
|
116
116
|
|
|
117
117
|
## Structure
|
|
118
118
|
|
package/dist/plan-create.js
CHANGED
|
@@ -139,7 +139,7 @@ export function getCommitMessage(id, title) {
|
|
|
139
139
|
const idLower = id.toLowerCase();
|
|
140
140
|
return `docs: create plan for ${idLower} - ${title}`;
|
|
141
141
|
}
|
|
142
|
-
async function main() {
|
|
142
|
+
export async function main() {
|
|
143
143
|
const args = createWUParser({
|
|
144
144
|
name: 'plan-create',
|
|
145
145
|
description: 'Create a new plan file in repo plansDir',
|
|
@@ -195,6 +195,4 @@ import { runCLI } from './cli-entry-point.js';
|
|
|
195
195
|
if (import.meta.main) {
|
|
196
196
|
void runCLI(main);
|
|
197
197
|
}
|
|
198
|
-
// Export for testing
|
|
199
|
-
export { main };
|
|
200
198
|
//# sourceMappingURL=plan-create.js.map
|
package/dist/plan-edit.js
CHANGED
|
@@ -164,7 +164,7 @@ export function getCommitMessage(id, section) {
|
|
|
164
164
|
const idLower = id.toLowerCase();
|
|
165
165
|
return `docs: update ${section} section in ${idLower} plan`;
|
|
166
166
|
}
|
|
167
|
-
async function main() {
|
|
167
|
+
export async function main() {
|
|
168
168
|
const SECTION_OPTION = {
|
|
169
169
|
name: 'section',
|
|
170
170
|
flags: '--section <name>',
|
|
@@ -257,6 +257,4 @@ import { runCLI } from './cli-entry-point.js';
|
|
|
257
257
|
if (import.meta.main) {
|
|
258
258
|
void runCLI(main);
|
|
259
259
|
}
|
|
260
|
-
// Export for testing
|
|
261
|
-
export { main };
|
|
262
260
|
//# sourceMappingURL=plan-edit.js.map
|
package/dist/plan-link.js
CHANGED
|
@@ -200,7 +200,7 @@ export function getCommitMessage(id, planUri) {
|
|
|
200
200
|
const filename = planUri.replace(PLAN_URI_SCHEME, '');
|
|
201
201
|
return `docs: link plan ${filename} to ${idLower}`;
|
|
202
202
|
}
|
|
203
|
-
async function main() {
|
|
203
|
+
export async function main() {
|
|
204
204
|
const PLAN_OPTION = {
|
|
205
205
|
name: 'plan',
|
|
206
206
|
flags: '--plan <uri>',
|
|
@@ -269,6 +269,4 @@ import { runCLI } from './cli-entry-point.js';
|
|
|
269
269
|
if (import.meta.main) {
|
|
270
270
|
void runCLI(main);
|
|
271
271
|
}
|
|
272
|
-
// Export for testing
|
|
273
|
-
export { main };
|
|
274
272
|
//# sourceMappingURL=plan-link.js.map
|
package/dist/plan-promote.js
CHANGED
|
@@ -154,7 +154,7 @@ export function getCommitMessage(id) {
|
|
|
154
154
|
const idLower = id.toLowerCase();
|
|
155
155
|
return `docs: promote ${idLower} plan to approved`;
|
|
156
156
|
}
|
|
157
|
-
async function main() {
|
|
157
|
+
export async function main() {
|
|
158
158
|
const FORCE_OPTION = {
|
|
159
159
|
name: 'force',
|
|
160
160
|
flags: '-f, --force',
|
|
@@ -227,6 +227,4 @@ import { runCLI } from './cli-entry-point.js';
|
|
|
227
227
|
if (import.meta.main) {
|
|
228
228
|
void runCLI(main);
|
|
229
229
|
}
|
|
230
|
-
// Export for testing
|
|
231
|
-
export { main };
|
|
232
230
|
//# sourceMappingURL=plan-promote.js.map
|
package/dist/release.js
CHANGED
|
@@ -317,7 +317,7 @@ export async function pushTagWithForce(git, tagName, reason = 'release: tag push
|
|
|
317
317
|
* Main release function
|
|
318
318
|
* WU-1085: Renamed --version to --release-version to avoid conflict with CLI --version flag
|
|
319
319
|
*/
|
|
320
|
-
async function main() {
|
|
320
|
+
export async function main() {
|
|
321
321
|
const program = new Command()
|
|
322
322
|
.name('lumenflow-release')
|
|
323
323
|
.description('Release @lumenflow/* packages to npm with version bump, tag, and publish')
|
|
@@ -468,8 +468,6 @@ async function main() {
|
|
|
468
468
|
console.log(` - Verify packages: npm view @lumenflow/cli version`);
|
|
469
469
|
}
|
|
470
470
|
}
|
|
471
|
-
// Export for testing
|
|
472
|
-
export { main };
|
|
473
471
|
// Guard main() for testability
|
|
474
472
|
if (import.meta.main) {
|
|
475
473
|
void runCLI(main);
|
package/dist/signal-cleanup.js
CHANGED
|
@@ -29,6 +29,7 @@ import { cleanupSignals } from '@lumenflow/memory/signal-cleanup-core';
|
|
|
29
29
|
import { createWUParser } from '@lumenflow/core/arg-parser';
|
|
30
30
|
import { EXIT_CODES, LUMENFLOW_PATHS, PROTECTED_WU_STATUSES } from '@lumenflow/core/wu-constants';
|
|
31
31
|
import { getConfig } from '@lumenflow/core/config';
|
|
32
|
+
import { formatBytes } from './constants.js';
|
|
32
33
|
import { runCLI } from './cli-entry-point.js';
|
|
33
34
|
/**
|
|
34
35
|
* Log prefix for signal:cleanup output
|
|
@@ -38,10 +39,7 @@ const LOG_PREFIX = '[signal:cleanup]';
|
|
|
38
39
|
* Tool name for audit logging
|
|
39
40
|
*/
|
|
40
41
|
const TOOL_NAME = 'signal:cleanup';
|
|
41
|
-
|
|
42
|
-
* Bytes per KB for formatting
|
|
43
|
-
*/
|
|
44
|
-
const BYTES_PER_KB = 1024;
|
|
42
|
+
// WU-2044: BYTES_PER_KB imported from ./constants.js
|
|
45
43
|
/**
|
|
46
44
|
* CLI argument options specific to signal:cleanup
|
|
47
45
|
*/
|
|
@@ -100,19 +98,7 @@ async function writeAuditLog(baseDir, entry) {
|
|
|
100
98
|
// Audit logging is non-fatal - silently ignore errors
|
|
101
99
|
}
|
|
102
100
|
}
|
|
103
|
-
|
|
104
|
-
* Format bytes as human-readable string
|
|
105
|
-
*
|
|
106
|
-
* @param bytes - Number of bytes
|
|
107
|
-
* @returns Formatted string (e.g., "1.5 KB")
|
|
108
|
-
*/
|
|
109
|
-
function formatBytes(bytes) {
|
|
110
|
-
if (bytes < BYTES_PER_KB) {
|
|
111
|
-
return `${bytes} B`;
|
|
112
|
-
}
|
|
113
|
-
const kb = (bytes / BYTES_PER_KB).toFixed(1);
|
|
114
|
-
return `${kb} KB`;
|
|
115
|
-
}
|
|
101
|
+
// WU-2044: formatBytes imported from ./constants.js
|
|
116
102
|
/**
|
|
117
103
|
* Format compaction ratio as percentage
|
|
118
104
|
*
|
|
@@ -227,7 +213,7 @@ function printResult(result, quiet) {
|
|
|
227
213
|
/**
|
|
228
214
|
* Main CLI entry point
|
|
229
215
|
*/
|
|
230
|
-
async function main() {
|
|
216
|
+
export async function main() {
|
|
231
217
|
const args = parseArguments();
|
|
232
218
|
const baseDir = args.baseDir || process.cwd();
|
|
233
219
|
const startedAt = new Date().toISOString();
|
package/dist/state-bootstrap.js
CHANGED
|
@@ -18,7 +18,8 @@ import path from 'node:path';
|
|
|
18
18
|
import { parse as parseYaml } from 'yaml';
|
|
19
19
|
import { readFileSync } from 'node:fs';
|
|
20
20
|
import { WU_PATHS } from '@lumenflow/core/wu-paths';
|
|
21
|
-
import { CLI_FLAGS, EXIT_CODES, EMOJI, STRING_LITERALS } from '@lumenflow/core/wu-constants';
|
|
21
|
+
import { CLI_FLAGS, EXIT_CODES, EMOJI, STRING_LITERALS, WU_STATUS, } from '@lumenflow/core/wu-constants';
|
|
22
|
+
import { WU_EVENT_TYPE } from '@lumenflow/core/wu-state-schema';
|
|
22
23
|
/** Log prefix for consistent output */
|
|
23
24
|
const LOG_PREFIX = '[state-bootstrap]';
|
|
24
25
|
/**
|
|
@@ -99,36 +100,38 @@ function toTimestamp(dateStr, fallback) {
|
|
|
99
100
|
export function inferEventsFromWu(wu) {
|
|
100
101
|
const events = [];
|
|
101
102
|
// Ready WUs have no events (not yet in the lifecycle)
|
|
102
|
-
if (wu.status ===
|
|
103
|
+
if (wu.status === WU_STATUS.READY ||
|
|
104
|
+
wu.status === WU_STATUS.BACKLOG ||
|
|
105
|
+
wu.status === WU_STATUS.TODO) {
|
|
103
106
|
return events;
|
|
104
107
|
}
|
|
105
108
|
// All other states start with a claim event
|
|
106
109
|
const claimTimestamp = toTimestamp(wu.claimed_at, wu.created);
|
|
107
110
|
events.push({
|
|
108
|
-
type:
|
|
111
|
+
type: WU_EVENT_TYPE.CLAIM,
|
|
109
112
|
wuId: wu.id,
|
|
110
113
|
lane: wu.lane,
|
|
111
114
|
title: wu.title,
|
|
112
115
|
timestamp: claimTimestamp,
|
|
113
116
|
});
|
|
114
117
|
// Handle completed/done status
|
|
115
|
-
if (wu.status ===
|
|
118
|
+
if (wu.status === WU_STATUS.DONE || wu.status === WU_STATUS.COMPLETED) {
|
|
116
119
|
const completeTimestamp = toTimestamp(wu.completed_at, wu.created);
|
|
117
120
|
events.push({
|
|
118
|
-
type:
|
|
121
|
+
type: WU_EVENT_TYPE.COMPLETE,
|
|
119
122
|
wuId: wu.id,
|
|
120
123
|
timestamp: completeTimestamp,
|
|
121
124
|
});
|
|
122
125
|
return events;
|
|
123
126
|
}
|
|
124
127
|
// Handle blocked status
|
|
125
|
-
if (wu.status ===
|
|
128
|
+
if (wu.status === WU_STATUS.BLOCKED) {
|
|
126
129
|
// Block event timestamp should be after claim
|
|
127
130
|
// We don't have exact block time, so use claim time + 1 second
|
|
128
131
|
const claimDate = new Date(claimTimestamp);
|
|
129
132
|
claimDate.setSeconds(claimDate.getSeconds() + 1);
|
|
130
133
|
events.push({
|
|
131
|
-
type:
|
|
134
|
+
type: WU_EVENT_TYPE.BLOCK,
|
|
132
135
|
wuId: wu.id,
|
|
133
136
|
timestamp: claimDate.toISOString(),
|
|
134
137
|
reason: 'Bootstrapped from WU YAML (original reason unknown)',
|
|
@@ -266,7 +269,7 @@ Supported WU statuses:
|
|
|
266
269
|
/**
|
|
267
270
|
* Main function
|
|
268
271
|
*/
|
|
269
|
-
async function main() {
|
|
272
|
+
export async function main() {
|
|
270
273
|
const args = parseStateBootstrapArgs(process.argv);
|
|
271
274
|
if (args.help) {
|
|
272
275
|
printHelp();
|
package/dist/state-cleanup.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Cleanup order: signals -> memory -> events (dependency order)
|
|
13
13
|
*
|
|
14
14
|
* Features:
|
|
15
|
-
* - Respects config from .
|
|
15
|
+
* - Respects config from workspace.yaml
|
|
16
16
|
* - Supports --dry-run for preview
|
|
17
17
|
* - Supports --signals-only, --memory-only, --events-only for selective cleanup
|
|
18
18
|
* - Non-fatal: warns on errors but continues with other cleanups
|
|
@@ -40,6 +40,7 @@ import { EXIT_CODES, LUMENFLOW_PATHS, PROTECTED_WU_STATUSES } from '@lumenflow/c
|
|
|
40
40
|
import { getConfig } from '@lumenflow/core/config';
|
|
41
41
|
import fg from 'fast-glob';
|
|
42
42
|
import { parse as parseYaml } from 'yaml';
|
|
43
|
+
import { formatBytes } from './constants.js';
|
|
43
44
|
import { runCLI } from './cli-entry-point.js';
|
|
44
45
|
/**
|
|
45
46
|
* Log prefix for state:cleanup output
|
|
@@ -49,10 +50,7 @@ const LOG_PREFIX = '[state:cleanup]';
|
|
|
49
50
|
* Tool name for audit logging
|
|
50
51
|
*/
|
|
51
52
|
const TOOL_NAME = 'state:cleanup';
|
|
52
|
-
|
|
53
|
-
* Bytes per KB for formatting
|
|
54
|
-
*/
|
|
55
|
-
const BYTES_PER_KB = 1024;
|
|
53
|
+
// WU-2044: BYTES_PER_KB imported from ./constants.js
|
|
56
54
|
/**
|
|
57
55
|
* Labels for output formatting
|
|
58
56
|
*/
|
|
@@ -117,19 +115,7 @@ async function writeAuditLog(baseDir, entry) {
|
|
|
117
115
|
// Audit logging is non-fatal - silently ignore errors
|
|
118
116
|
}
|
|
119
117
|
}
|
|
120
|
-
|
|
121
|
-
* Format bytes as human-readable string
|
|
122
|
-
*
|
|
123
|
-
* @param bytes - Number of bytes
|
|
124
|
-
* @returns Formatted string (e.g., "1.5 KB")
|
|
125
|
-
*/
|
|
126
|
-
function formatBytes(bytes) {
|
|
127
|
-
if (bytes < BYTES_PER_KB) {
|
|
128
|
-
return `${bytes} B`;
|
|
129
|
-
}
|
|
130
|
-
const kb = (bytes / BYTES_PER_KB).toFixed(1);
|
|
131
|
-
return `${kb} KB`;
|
|
132
|
-
}
|
|
118
|
+
// WU-2044: formatBytes imported from ./constants.js
|
|
133
119
|
/**
|
|
134
120
|
* Get active WU IDs (in_progress or blocked) by scanning WU YAML files.
|
|
135
121
|
*
|
|
@@ -264,7 +250,7 @@ function printResult(result, quiet) {
|
|
|
264
250
|
/**
|
|
265
251
|
* Main CLI entry point
|
|
266
252
|
*/
|
|
267
|
-
async function main() {
|
|
253
|
+
export async function main() {
|
|
268
254
|
const args = parseArguments();
|
|
269
255
|
const baseDir = args.baseDir || process.cwd();
|
|
270
256
|
const startedAt = new Date().toISOString();
|
package/dist/state-doctor.js
CHANGED
|
@@ -30,20 +30,28 @@
|
|
|
30
30
|
import fs from 'node:fs/promises';
|
|
31
31
|
import path from 'node:path';
|
|
32
32
|
import fg from 'fast-glob';
|
|
33
|
-
import { parse as parseYaml } from 'yaml';
|
|
33
|
+
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
34
34
|
import { diagnoseState, ISSUE_TYPES, ISSUE_SEVERITY, } from '@lumenflow/core/state-doctor-core';
|
|
35
35
|
import { createWUParser } from '@lumenflow/core/arg-parser';
|
|
36
|
-
import { EXIT_CODES, LUMENFLOW_PATHS } from '@lumenflow/core/wu-constants';
|
|
37
|
-
import { getConfig, getResolvedPaths } from '@lumenflow/core/config';
|
|
36
|
+
import { EXIT_CODES, LUMENFLOW_PATHS, WU_STATUS } from '@lumenflow/core/wu-constants';
|
|
37
|
+
import { getConfig, getResolvedPaths, getConfigFilePresence, WORKSPACE_CONFIG_FILE_NAME, } from '@lumenflow/core/config';
|
|
38
38
|
import { existsSync } from 'node:fs';
|
|
39
39
|
import { createStamp } from '@lumenflow/core/stamp-utils';
|
|
40
|
+
import { withMicroWorktree } from '@lumenflow/core/micro-worktree';
|
|
40
41
|
import { createStateDoctorFixDeps } from './state-doctor-fix.js';
|
|
41
42
|
import { runCLI } from './cli-entry-point.js';
|
|
42
43
|
import { resolveStateDoctorStampIds } from './state-doctor-stamps.js';
|
|
44
|
+
import { deriveInitiativeLifecycleStatus } from './initiative-status.js';
|
|
43
45
|
/**
|
|
44
46
|
* Log prefix for state:doctor output
|
|
45
47
|
*/
|
|
46
48
|
const LOG_PREFIX = '[state:doctor]';
|
|
49
|
+
const WORKSPACE_INIT_COMMAND = 'pnpm workspace-init --yes';
|
|
50
|
+
const INITIATIVE_FILE_GLOB = 'INIT-*.yaml';
|
|
51
|
+
const WU_FILE_GLOB = 'WU-*.yaml';
|
|
52
|
+
const STATUS_RECONCILIATION_OPERATION_ID = 'reconcile-initiative-status';
|
|
53
|
+
const STATUS_RECONCILIATION_COMMIT_MESSAGE = 'fix(state-doctor): reconcile stale initiative lifecycle statuses';
|
|
54
|
+
const INITIATIVE_STATUS_RECONCILIATION_SUGGESTION = 'Run with --fix to reconcile initiative status';
|
|
47
55
|
// WU-1539/WU-1548: Use centralized LUMENFLOW_PATHS.MEMORY_SIGNALS and LUMENFLOW_PATHS.WU_EVENTS
|
|
48
56
|
/**
|
|
49
57
|
* Tool name for audit logging
|
|
@@ -89,6 +97,161 @@ const CLI_OPTIONS = {
|
|
|
89
97
|
description: 'Base directory (defaults to current directory)',
|
|
90
98
|
},
|
|
91
99
|
};
|
|
100
|
+
function normalizeLifecycleStatus(value) {
|
|
101
|
+
return typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
102
|
+
}
|
|
103
|
+
function toInitiativePhases(value) {
|
|
104
|
+
if (!Array.isArray(value)) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
return value
|
|
108
|
+
.filter((phase) => phase != null && typeof phase === 'object')
|
|
109
|
+
.flatMap((phase) => {
|
|
110
|
+
if (typeof phase.id !== 'number') {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
const status = typeof phase.status === 'string' ? phase.status : undefined;
|
|
114
|
+
return [{ id: phase.id, status }];
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function createInitiativeStatusMismatchIssue(mismatch) {
|
|
118
|
+
return {
|
|
119
|
+
type: ISSUE_TYPES.STATUS_MISMATCH,
|
|
120
|
+
severity: ISSUE_SEVERITY.WARNING,
|
|
121
|
+
wuId: mismatch.initiativeId,
|
|
122
|
+
description: `Initiative ${mismatch.initiativeId} metadata status is '${mismatch.currentStatus}' but linked WUs derive '${mismatch.derivedStatus}'`,
|
|
123
|
+
suggestion: INITIATIVE_STATUS_RECONCILIATION_SUGGESTION,
|
|
124
|
+
canAutoFix: true,
|
|
125
|
+
statusMismatch: {
|
|
126
|
+
yamlStatus: mismatch.currentStatus,
|
|
127
|
+
derivedStatus: mismatch.derivedStatus,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export async function collectInitiativeLifecycleStatusMismatches(baseDir) {
|
|
132
|
+
const config = getConfig({ projectRoot: baseDir, strictWorkspace: true });
|
|
133
|
+
const initiativesDir = path.join(baseDir, config.directories.initiativesDir);
|
|
134
|
+
const wuDir = path.join(baseDir, config.directories.wuDir);
|
|
135
|
+
const [initiativeFiles, wuFiles] = await Promise.all([
|
|
136
|
+
fg(INITIATIVE_FILE_GLOB, { cwd: initiativesDir }),
|
|
137
|
+
fg(WU_FILE_GLOB, { cwd: wuDir }),
|
|
138
|
+
]);
|
|
139
|
+
if (initiativeFiles.length === 0) {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
const initiatives = [];
|
|
143
|
+
const initiativeIdByReference = new Map();
|
|
144
|
+
const progressByInitiativeId = new Map();
|
|
145
|
+
for (const file of initiativeFiles) {
|
|
146
|
+
const relativePath = path.join(config.directories.initiativesDir, file);
|
|
147
|
+
const fullPath = path.join(initiativesDir, file);
|
|
148
|
+
try {
|
|
149
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
150
|
+
const doc = parseYaml(content);
|
|
151
|
+
const initiativeId = typeof doc.id === 'string' && doc.id.length > 0 ? doc.id : '';
|
|
152
|
+
if (!initiativeId) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const slug = typeof doc.slug === 'string' ? doc.slug : '';
|
|
156
|
+
const status = normalizeLifecycleStatus(doc.status);
|
|
157
|
+
const phases = toInitiativePhases(doc.phases);
|
|
158
|
+
initiatives.push({
|
|
159
|
+
id: initiativeId,
|
|
160
|
+
slug,
|
|
161
|
+
status,
|
|
162
|
+
phases,
|
|
163
|
+
relativePath,
|
|
164
|
+
});
|
|
165
|
+
initiativeIdByReference.set(initiativeId, initiativeId);
|
|
166
|
+
if (slug.length > 0) {
|
|
167
|
+
initiativeIdByReference.set(slug, initiativeId);
|
|
168
|
+
}
|
|
169
|
+
progressByInitiativeId.set(initiativeId, { done: 0, total: 0 });
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Skip malformed initiative YAML files during diagnosis.
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
for (const file of wuFiles) {
|
|
176
|
+
const fullPath = path.join(wuDir, file);
|
|
177
|
+
try {
|
|
178
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
179
|
+
const doc = parseYaml(content);
|
|
180
|
+
const initiativeRef = typeof doc.initiative === 'string' ? doc.initiative : '';
|
|
181
|
+
if (!initiativeRef) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const initiativeId = initiativeIdByReference.get(initiativeRef);
|
|
185
|
+
if (!initiativeId) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const current = progressByInitiativeId.get(initiativeId) || { done: 0, total: 0 };
|
|
189
|
+
current.total += 1;
|
|
190
|
+
if (normalizeLifecycleStatus(doc.status) === WU_STATUS.DONE) {
|
|
191
|
+
current.done += 1;
|
|
192
|
+
}
|
|
193
|
+
progressByInitiativeId.set(initiativeId, current);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// Skip malformed WU YAML files during diagnosis.
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const mismatches = [];
|
|
200
|
+
for (const initiative of initiatives) {
|
|
201
|
+
if (![WU_STATUS.IN_PROGRESS, WU_STATUS.DONE].includes(initiative.status)) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const progress = progressByInitiativeId.get(initiative.id);
|
|
205
|
+
const derivedStatus = deriveInitiativeLifecycleStatus(initiative.status, initiative.phases, progress);
|
|
206
|
+
if (derivedStatus !== initiative.status) {
|
|
207
|
+
mismatches.push({
|
|
208
|
+
initiativeId: initiative.id,
|
|
209
|
+
relativePath: initiative.relativePath,
|
|
210
|
+
currentStatus: initiative.status,
|
|
211
|
+
derivedStatus,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return mismatches;
|
|
216
|
+
}
|
|
217
|
+
export async function applyInitiativeLifecycleStatusFixes(baseDir, mismatches) {
|
|
218
|
+
if (mismatches.length === 0) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const uniqueMismatches = Array.from(new Map(mismatches.map((mismatch) => [mismatch.relativePath, mismatch])).values());
|
|
222
|
+
await withMicroWorktree({
|
|
223
|
+
operation: TOOL_NAME,
|
|
224
|
+
id: STATUS_RECONCILIATION_OPERATION_ID,
|
|
225
|
+
logPrefix: LOG_PREFIX,
|
|
226
|
+
pushOnly: true,
|
|
227
|
+
execute: async ({ worktreePath }) => {
|
|
228
|
+
const modifiedFiles = [];
|
|
229
|
+
for (const mismatch of uniqueMismatches) {
|
|
230
|
+
const initiativePath = path.join(worktreePath, mismatch.relativePath);
|
|
231
|
+
const content = await fs.readFile(initiativePath, 'utf-8');
|
|
232
|
+
const doc = parseYaml(content);
|
|
233
|
+
doc.status = mismatch.derivedStatus;
|
|
234
|
+
await fs.writeFile(initiativePath, stringifyYaml(doc), 'utf-8');
|
|
235
|
+
modifiedFiles.push(mismatch.relativePath);
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
commitMessage: STATUS_RECONCILIATION_COMMIT_MESSAGE,
|
|
239
|
+
files: modifiedFiles,
|
|
240
|
+
};
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
function appendInitiativeStatusMismatchIssues(result, mismatches) {
|
|
245
|
+
if (mismatches.length === 0) {
|
|
246
|
+
return [];
|
|
247
|
+
}
|
|
248
|
+
const issues = mismatches.map((mismatch) => createInitiativeStatusMismatchIssue(mismatch));
|
|
249
|
+
result.issues.push(...issues);
|
|
250
|
+
result.summary.statusMismatches += issues.length;
|
|
251
|
+
result.summary.totalIssues += issues.length;
|
|
252
|
+
result.healthy = false;
|
|
253
|
+
return issues;
|
|
254
|
+
}
|
|
92
255
|
/**
|
|
93
256
|
* Write audit log entry for tool execution
|
|
94
257
|
*/
|
|
@@ -126,7 +289,7 @@ function parseArguments() {
|
|
|
126
289
|
* Create dependencies for state doctor from filesystem
|
|
127
290
|
*/
|
|
128
291
|
async function createDeps(baseDir) {
|
|
129
|
-
const config = getConfig({ projectRoot: baseDir });
|
|
292
|
+
const config = getConfig({ projectRoot: baseDir, strictWorkspace: true });
|
|
130
293
|
return {
|
|
131
294
|
/**
|
|
132
295
|
* List all WU YAML files
|
|
@@ -289,6 +452,19 @@ async function createDeps(baseDir) {
|
|
|
289
452
|
},
|
|
290
453
|
};
|
|
291
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Enforce canonical workspace config before running state-doctor checks.
|
|
457
|
+
*
|
|
458
|
+
* @param baseDir - Target repository directory
|
|
459
|
+
* @throws Error when workspace.yaml is missing
|
|
460
|
+
*/
|
|
461
|
+
function assertCanonicalWorkspace(baseDir) {
|
|
462
|
+
const { workspaceConfigExists } = getConfigFilePresence(baseDir);
|
|
463
|
+
if (workspaceConfigExists) {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
throw new Error(`${LOG_PREFIX} Missing ${WORKSPACE_CONFIG_FILE_NAME}. Run \`${WORKSPACE_INIT_COMMAND}\`.`);
|
|
467
|
+
}
|
|
292
468
|
/**
|
|
293
469
|
* Get emoji for issue severity
|
|
294
470
|
*/
|
|
@@ -433,7 +609,7 @@ function buildAuditOutput(result) {
|
|
|
433
609
|
function warnMissingPaths(baseDir, quiet) {
|
|
434
610
|
if (quiet)
|
|
435
611
|
return;
|
|
436
|
-
const paths = getResolvedPaths({ projectRoot: baseDir });
|
|
612
|
+
const paths = getResolvedPaths({ projectRoot: baseDir, strictWorkspace: true });
|
|
437
613
|
const missing = [];
|
|
438
614
|
if (!existsSync(paths.wuDir)) {
|
|
439
615
|
missing.push(`WU directory: ${paths.wuDir}`);
|
|
@@ -449,22 +625,24 @@ function warnMissingPaths(baseDir, quiet) {
|
|
|
449
625
|
for (const p of missing) {
|
|
450
626
|
console.warn(` - ${p}`);
|
|
451
627
|
}
|
|
452
|
-
console.warn(
|
|
628
|
+
console.warn(` Tip: Run \`${WORKSPACE_INIT_COMMAND}\` and verify ${WORKSPACE_CONFIG_FILE_NAME}`);
|
|
453
629
|
}
|
|
454
630
|
}
|
|
455
631
|
/**
|
|
456
632
|
* Main CLI entry point
|
|
457
633
|
*/
|
|
458
|
-
async function main() {
|
|
634
|
+
export async function main() {
|
|
459
635
|
const args = parseArguments();
|
|
460
636
|
const baseDir = args.baseDir || process.cwd();
|
|
461
637
|
const startedAt = new Date().toISOString();
|
|
462
638
|
const startTime = Date.now();
|
|
463
|
-
// WU-1301: Warn about missing configured paths
|
|
464
|
-
warnMissingPaths(baseDir, args.quiet ?? false);
|
|
465
639
|
let result = null;
|
|
466
640
|
let error = null;
|
|
467
641
|
try {
|
|
642
|
+
// Hard-cut enforcement: require canonical workspace configuration.
|
|
643
|
+
assertCanonicalWorkspace(baseDir);
|
|
644
|
+
// WU-1301: Warn about missing configured paths
|
|
645
|
+
warnMissingPaths(baseDir, args.quiet ?? false);
|
|
468
646
|
// Create base deps for read operations
|
|
469
647
|
const baseDeps = await createDeps(baseDir);
|
|
470
648
|
// WU-1230: When --fix is enabled, use micro-worktree isolation for all
|
|
@@ -480,6 +658,32 @@ async function main() {
|
|
|
480
658
|
fix: args.fix,
|
|
481
659
|
dryRun: args.dryRun,
|
|
482
660
|
});
|
|
661
|
+
const initiativeMismatches = await collectInitiativeLifecycleStatusMismatches(baseDir);
|
|
662
|
+
const initiativeIssues = appendInitiativeStatusMismatchIssues(result, initiativeMismatches);
|
|
663
|
+
if (initiativeIssues.length > 0) {
|
|
664
|
+
if (args.fix && args.dryRun) {
|
|
665
|
+
result.dryRun = true;
|
|
666
|
+
const existingWouldFix = result.wouldFix || [];
|
|
667
|
+
result.wouldFix = [...existingWouldFix, ...initiativeIssues];
|
|
668
|
+
}
|
|
669
|
+
else if (args.fix) {
|
|
670
|
+
try {
|
|
671
|
+
await applyInitiativeLifecycleStatusFixes(baseDir, initiativeMismatches);
|
|
672
|
+
result.fixed.push(...initiativeIssues);
|
|
673
|
+
}
|
|
674
|
+
catch (fixErr) {
|
|
675
|
+
const message = fixErr instanceof Error ? fixErr.message : String(fixErr);
|
|
676
|
+
for (const issue of initiativeIssues) {
|
|
677
|
+
result.fixErrors.push({
|
|
678
|
+
type: issue.type,
|
|
679
|
+
wuId: issue.wuId,
|
|
680
|
+
signalId: issue.signalId,
|
|
681
|
+
error: message,
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
483
687
|
}
|
|
484
688
|
catch (err) {
|
|
485
689
|
error = err.message;
|
package/dist/task-claim.js
CHANGED
|
@@ -57,7 +57,7 @@ const TASK_CLAIM_OPTIONS = {
|
|
|
57
57
|
domainData: {
|
|
58
58
|
name: 'domainData',
|
|
59
59
|
flags: '--domain-data <json>',
|
|
60
|
-
description: 'Optional JSON object payload for
|
|
60
|
+
description: 'Optional JSON object payload for task-scoped metadata',
|
|
61
61
|
},
|
|
62
62
|
workspaceRoot: {
|
|
63
63
|
name: 'workspaceRoot',
|