@lumenflow/cli 3.1.1 → 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 +244 -61
- 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 -230
- 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 -1964
- 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
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',
|
package/dist/validate.js
CHANGED
package/dist/workspace-init.js
CHANGED
|
@@ -17,11 +17,41 @@
|
|
|
17
17
|
import * as readline from 'node:readline';
|
|
18
18
|
import * as path from 'node:path';
|
|
19
19
|
import YAML from 'yaml';
|
|
20
|
-
import { createWUParser } from '@lumenflow/core';
|
|
21
20
|
import { createFile } from './init-scaffolding.js';
|
|
22
21
|
import { runCLI } from './cli-entry-point.js';
|
|
23
22
|
export const LOG_PREFIX = '[workspace:init]';
|
|
24
|
-
const WORKSPACE_FILENAME = 'workspace.yaml';
|
|
23
|
+
export const WORKSPACE_FILENAME = 'workspace.yaml';
|
|
24
|
+
export const DEFAULT_WORKSPACE_ID = 'default';
|
|
25
|
+
export const DEFAULT_WORKSPACE_NAME = 'My Project';
|
|
26
|
+
export const DEFAULT_PROJECT_NAME = 'my-project';
|
|
27
|
+
export const DEFAULT_LANE_TITLE = 'Default';
|
|
28
|
+
export const DEFAULT_NAMESPACE = DEFAULT_WORKSPACE_ID;
|
|
29
|
+
export const CANONICAL_BOOTSTRAP_COMMAND = 'npx lumenflow';
|
|
30
|
+
const LEGACY_WORKSPACE_INIT_ENTRYPOINT = 'workspace-init';
|
|
31
|
+
const LEGACY_ENTRYPOINT_MARKER = 'legacy';
|
|
32
|
+
const LEGACY_ENTRYPOINT_MESSAGE_PREFIX = `${LOG_PREFIX} ${LEGACY_ENTRYPOINT_MARKER} entrypoint`;
|
|
33
|
+
export const DEFAULT_DENY_OVERLAYS = ['~/.ssh', '~/.aws', '~/.gnupg', '.env'];
|
|
34
|
+
export const DEFAULT_DENY_OVERLAYS_PROMPT = DEFAULT_DENY_OVERLAYS.join(', ');
|
|
35
|
+
export const SANDBOX_NETWORK_PROFILE = {
|
|
36
|
+
OFF: 'off',
|
|
37
|
+
FULL: 'full',
|
|
38
|
+
};
|
|
39
|
+
export const DEFAULT_SANDBOX_NETWORK_PROFILE = SANDBOX_NETWORK_PROFILE.OFF;
|
|
40
|
+
export const CLOUD_CONNECT_RESPONSE = {
|
|
41
|
+
YES: 'yes',
|
|
42
|
+
NO: 'no',
|
|
43
|
+
SHORT_YES: 'y',
|
|
44
|
+
BOOLEAN_TRUE: 'true',
|
|
45
|
+
};
|
|
46
|
+
const CLOUD_CONNECT_TRUTHY = new Set([
|
|
47
|
+
CLOUD_CONNECT_RESPONSE.YES,
|
|
48
|
+
CLOUD_CONNECT_RESPONSE.SHORT_YES,
|
|
49
|
+
CLOUD_CONNECT_RESPONSE.BOOLEAN_TRUE,
|
|
50
|
+
]);
|
|
51
|
+
const EMPTY_SOFTWARE_DELIVERY_CONFIG = Object.freeze({});
|
|
52
|
+
function createEmptySoftwareDeliveryConfig() {
|
|
53
|
+
return { ...EMPTY_SOFTWARE_DELIVERY_CONFIG };
|
|
54
|
+
}
|
|
25
55
|
/**
|
|
26
56
|
* AC1: 5 interactive questions for workspace configuration
|
|
27
57
|
*/
|
|
@@ -29,29 +59,33 @@ export const WORKSPACE_QUESTIONS = [
|
|
|
29
59
|
{
|
|
30
60
|
name: 'projectName',
|
|
31
61
|
prompt: 'Project name',
|
|
32
|
-
defaultValue:
|
|
62
|
+
defaultValue: DEFAULT_PROJECT_NAME,
|
|
33
63
|
},
|
|
34
64
|
{
|
|
35
65
|
name: 'lanes',
|
|
36
66
|
prompt: 'Work lanes (comma-separated, e.g., Backend, Frontend, DevOps)',
|
|
37
|
-
defaultValue:
|
|
67
|
+
defaultValue: DEFAULT_LANE_TITLE,
|
|
38
68
|
},
|
|
39
69
|
{
|
|
40
70
|
name: 'sandboxProfile',
|
|
41
71
|
prompt: 'Sandbox network profile (off | full)',
|
|
42
|
-
defaultValue:
|
|
72
|
+
defaultValue: DEFAULT_SANDBOX_NETWORK_PROFILE,
|
|
43
73
|
},
|
|
44
74
|
{
|
|
45
75
|
name: 'deniedPaths',
|
|
46
76
|
prompt: 'Denied paths (comma-separated, e.g., ~/.ssh, ~/.aws, .env)',
|
|
47
|
-
defaultValue:
|
|
77
|
+
defaultValue: DEFAULT_DENY_OVERLAYS_PROMPT,
|
|
48
78
|
},
|
|
49
79
|
{
|
|
50
80
|
name: 'cloudConnect',
|
|
51
81
|
prompt: 'Enable cloud agent support? (yes | no)',
|
|
52
|
-
defaultValue:
|
|
82
|
+
defaultValue: CLOUD_CONNECT_RESPONSE.NO,
|
|
53
83
|
},
|
|
54
84
|
];
|
|
85
|
+
export function buildLegacyWorkspaceInitGuidance(entrypoint = LEGACY_WORKSPACE_INIT_ENTRYPOINT) {
|
|
86
|
+
return (`${LEGACY_ENTRYPOINT_MESSAGE_PREFIX} "${entrypoint}" is retired. ` +
|
|
87
|
+
`Use "${CANONICAL_BOOTSTRAP_COMMAND}" for bootstrap-all onboarding.`);
|
|
88
|
+
}
|
|
55
89
|
/**
|
|
56
90
|
* Parse raw string answers from interactive prompts into typed config inputs.
|
|
57
91
|
*/
|
|
@@ -66,10 +100,10 @@ export function parseAnswers(answers) {
|
|
|
66
100
|
.map((p) => p.trim())
|
|
67
101
|
.filter(Boolean)
|
|
68
102
|
: [];
|
|
69
|
-
const cloudConnect = answers.cloudConnect.toLowerCase()
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
103
|
+
const cloudConnect = CLOUD_CONNECT_TRUTHY.has(answers.cloudConnect.toLowerCase());
|
|
104
|
+
const sandboxProfile = answers.sandboxProfile === SANDBOX_NETWORK_PROFILE.FULL
|
|
105
|
+
? SANDBOX_NETWORK_PROFILE.FULL
|
|
106
|
+
: SANDBOX_NETWORK_PROFILE.OFF;
|
|
73
107
|
return {
|
|
74
108
|
projectName: answers.projectName,
|
|
75
109
|
lanes,
|
|
@@ -94,24 +128,25 @@ function toKebabCase(title) {
|
|
|
94
128
|
*/
|
|
95
129
|
export function getDefaultWorkspaceConfig() {
|
|
96
130
|
return {
|
|
97
|
-
id:
|
|
98
|
-
name:
|
|
131
|
+
id: DEFAULT_WORKSPACE_ID,
|
|
132
|
+
name: DEFAULT_WORKSPACE_NAME,
|
|
99
133
|
packs: [],
|
|
100
134
|
lanes: [
|
|
101
135
|
{
|
|
102
|
-
id:
|
|
103
|
-
title:
|
|
136
|
+
id: DEFAULT_WORKSPACE_ID,
|
|
137
|
+
title: DEFAULT_LANE_TITLE,
|
|
104
138
|
allowed_scopes: [],
|
|
105
139
|
},
|
|
106
140
|
],
|
|
107
141
|
policies: {},
|
|
108
142
|
security: {
|
|
109
143
|
allowed_scopes: [],
|
|
110
|
-
network_default:
|
|
111
|
-
deny_overlays: [
|
|
144
|
+
network_default: DEFAULT_SANDBOX_NETWORK_PROFILE,
|
|
145
|
+
deny_overlays: [...DEFAULT_DENY_OVERLAYS],
|
|
112
146
|
},
|
|
113
|
-
|
|
114
|
-
|
|
147
|
+
software_delivery: createEmptySoftwareDeliveryConfig(),
|
|
148
|
+
memory_namespace: DEFAULT_NAMESPACE,
|
|
149
|
+
event_namespace: DEFAULT_NAMESPACE,
|
|
115
150
|
};
|
|
116
151
|
}
|
|
117
152
|
/**
|
|
@@ -134,6 +169,7 @@ export function buildWorkspaceConfig(input) {
|
|
|
134
169
|
network_default: input.sandboxProfile,
|
|
135
170
|
deny_overlays: input.deniedPaths,
|
|
136
171
|
},
|
|
172
|
+
software_delivery: createEmptySoftwareDeliveryConfig(),
|
|
137
173
|
memory_namespace: toKebabCase(input.projectName),
|
|
138
174
|
event_namespace: toKebabCase(input.projectName),
|
|
139
175
|
};
|
|
@@ -172,7 +208,7 @@ export function generateWorkspaceYaml(config) {
|
|
|
172
208
|
lines.push('security:');
|
|
173
209
|
lines.push(' # Workspace-level scope restrictions');
|
|
174
210
|
lines.push(` allowed_scopes: ${YAML.stringify(config.security.allowed_scopes).trim()}`);
|
|
175
|
-
lines.push(
|
|
211
|
+
lines.push(` # Network access default for sandbox (${SANDBOX_NETWORK_PROFILE.OFF} = no network, ${SANDBOX_NETWORK_PROFILE.FULL} = unrestricted)`);
|
|
176
212
|
lines.push(` network_default: ${config.security.network_default}`);
|
|
177
213
|
lines.push(' # Paths denied to agent sandbox via deny overlays');
|
|
178
214
|
lines.push(' deny_overlays:');
|
|
@@ -186,6 +222,9 @@ export function generateWorkspaceYaml(config) {
|
|
|
186
222
|
}
|
|
187
223
|
}
|
|
188
224
|
lines.push('');
|
|
225
|
+
lines.push('# Software delivery config extensions (required workspace v2 block)');
|
|
226
|
+
lines.push(`software_delivery: ${YAML.stringify(config.software_delivery).trim()}`);
|
|
227
|
+
lines.push('');
|
|
189
228
|
lines.push('# Memory namespace for session tracking and context recovery');
|
|
190
229
|
lines.push(`memory_namespace: ${YAML.stringify(config.memory_namespace).trim()}`);
|
|
191
230
|
lines.push('');
|
|
@@ -270,51 +309,12 @@ export async function runInteractive(targetDir, force = false) {
|
|
|
270
309
|
}
|
|
271
310
|
}
|
|
272
311
|
// --- CLI entry point ---
|
|
273
|
-
const WORKSPACE_INIT_OPTIONS = {
|
|
274
|
-
yes: {
|
|
275
|
-
name: 'yes',
|
|
276
|
-
flags: '--yes, -y',
|
|
277
|
-
description: 'Accept all defaults non-interactively',
|
|
278
|
-
},
|
|
279
|
-
output: {
|
|
280
|
-
name: 'output',
|
|
281
|
-
flags: '--output, -o <dir>',
|
|
282
|
-
description: 'Output directory (default: current directory)',
|
|
283
|
-
},
|
|
284
|
-
force: {
|
|
285
|
-
name: 'force',
|
|
286
|
-
flags: '--force, -f',
|
|
287
|
-
description: 'Overwrite existing workspace.yaml',
|
|
288
|
-
},
|
|
289
|
-
};
|
|
290
312
|
/**
|
|
291
313
|
* CLI main entry point for workspace:init
|
|
292
314
|
*/
|
|
293
315
|
export async function main() {
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
description: 'Initialize a LumenFlow workspace configuration (workspace.yaml)',
|
|
297
|
-
options: [
|
|
298
|
-
WORKSPACE_INIT_OPTIONS.yes,
|
|
299
|
-
WORKSPACE_INIT_OPTIONS.output,
|
|
300
|
-
WORKSPACE_INIT_OPTIONS.force,
|
|
301
|
-
],
|
|
302
|
-
});
|
|
303
|
-
const targetDir = opts.output ?? process.cwd();
|
|
304
|
-
const force = Boolean(opts.force);
|
|
305
|
-
const useDefaults = Boolean(opts.yes);
|
|
306
|
-
if (useDefaults) {
|
|
307
|
-
const result = await runNonInteractive(targetDir, force);
|
|
308
|
-
if (result.created.length > 0) {
|
|
309
|
-
console.log(`${LOG_PREFIX} Created ${WORKSPACE_FILENAME} with default settings`);
|
|
310
|
-
}
|
|
311
|
-
else if (result.skipped.length > 0) {
|
|
312
|
-
console.log(`${LOG_PREFIX} ${WORKSPACE_FILENAME} already exists. Use --force to overwrite.`);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
await runInteractive(targetDir, force);
|
|
317
|
-
}
|
|
316
|
+
const invokedEntryPoint = path.basename(process.argv[1] ?? LEGACY_WORKSPACE_INIT_ENTRYPOINT, '.js');
|
|
317
|
+
console.warn(buildLegacyWorkspaceInitGuidance(invokedEntryPoint));
|
|
318
318
|
}
|
|
319
319
|
// Run if executed directly
|
|
320
320
|
if (import.meta.main) {
|
package/dist/wu-block.js
CHANGED
|
@@ -178,7 +178,7 @@ async function handleWorktreeRemoval(args, doc) {
|
|
|
178
178
|
console.warn(`${LOG_PREFIX.BLOCK} No worktree path specified; skipping removal`);
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
async function main() {
|
|
181
|
+
export async function main() {
|
|
182
182
|
const args = createWUParser({
|
|
183
183
|
name: 'wu-block',
|
|
184
184
|
description: 'Block a work unit and move it from in-progress to blocked status',
|
package/dist/wu-brief.js
CHANGED
package/dist/wu-claim.js
CHANGED
|
@@ -127,7 +127,7 @@ export async function maybeLaunchClaimSandboxSession(input, deps = {}) {
|
|
|
127
127
|
// Main orchestrator
|
|
128
128
|
// ============================================================================
|
|
129
129
|
// eslint-disable-next-line sonarjs/cognitive-complexity -- main() orchestrates multi-step claim workflow
|
|
130
|
-
async function main() {
|
|
130
|
+
export async function main() {
|
|
131
131
|
const args = createWUParser({
|
|
132
132
|
name: 'wu-claim',
|
|
133
133
|
description: 'Claim a work unit by creating a worktree/branch and updating status',
|
package/dist/wu-cleanup.js
CHANGED
|
@@ -180,7 +180,7 @@ function hasStampFile(wuId) {
|
|
|
180
180
|
const stampPath = path.join(process.cwd(), WU_PATHS.STAMP(wuId));
|
|
181
181
|
return existsSync(stampPath);
|
|
182
182
|
}
|
|
183
|
-
async function main() {
|
|
183
|
+
export async function main() {
|
|
184
184
|
const args = createWUParser({
|
|
185
185
|
name: 'wu-cleanup',
|
|
186
186
|
description: 'Clean up worktree and branch after PR merge (PR-based completion workflow)',
|
package/dist/wu-create.js
CHANGED
|
@@ -124,7 +124,7 @@ export function warnIfBetterLaneExists(providedLane, codePathsArray, title, desc
|
|
|
124
124
|
* Resolve lane lifecycle classification for wu:create without mutating config.
|
|
125
125
|
*
|
|
126
126
|
* WU-1751: wu:create must not persist lifecycle migration side effects to
|
|
127
|
-
* .
|
|
127
|
+
* workspace.yaml on main.
|
|
128
128
|
*/
|
|
129
129
|
export function resolveLaneLifecycleForWuCreate(projectRoot) {
|
|
130
130
|
return ensureLaneLifecycleForProject(projectRoot, { persist: false });
|
|
@@ -182,7 +182,7 @@ async function getDefaultAssignedTo() {
|
|
|
182
182
|
return '';
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
async function main() {
|
|
185
|
+
export async function main() {
|
|
186
186
|
const args = createWUParser({
|
|
187
187
|
name: 'wu-create',
|
|
188
188
|
description: 'Create a new Work Unit with micro-worktree isolation (race-safe)',
|
|
@@ -267,7 +267,7 @@ async function main() {
|
|
|
267
267
|
` - Single colon with EXACTLY one space after (e.g., "Parent: Subdomain")\n` +
|
|
268
268
|
` - No spaces before colon\n` +
|
|
269
269
|
` - No multiple colons\n\n` +
|
|
270
|
-
`See .
|
|
270
|
+
`See workspace.yaml software_delivery.lanes.definitions for valid parent lanes.`);
|
|
271
271
|
}
|
|
272
272
|
// WU-2330: Warn if a more specific sub-lane matches code_paths or description
|
|
273
273
|
warnIfBetterLaneExists(args.lane, args.codePaths, args.title, args.description);
|
package/dist/wu-delegate.js
CHANGED
package/dist/wu-deps.js
CHANGED
|
@@ -18,7 +18,7 @@ import { buildDependencyGraphAsync, renderASCII, renderMermaid, validateGraph, }
|
|
|
18
18
|
import { OUTPUT_FORMATS } from '@lumenflow/initiatives/constants';
|
|
19
19
|
import { PATTERNS } from '@lumenflow/core/wu-constants';
|
|
20
20
|
import { getConfig } from '@lumenflow/core/config';
|
|
21
|
-
async function main() {
|
|
21
|
+
export async function main() {
|
|
22
22
|
const args = createWUParser({
|
|
23
23
|
name: 'wu-deps',
|
|
24
24
|
description: 'Visualize WU dependency graph',
|