@lumenflow/core 3.1.2 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -16
- package/dist/cli/is-agent-branch.js +31 -10
- package/dist/index.js +3 -0
- package/package.json +5 -2
- package/dist/active-wu-detector.d.ts +0 -25
- package/dist/active-wu-detector.d.ts.map +0 -1
- package/dist/active-wu-detector.js +0 -109
- package/dist/active-wu-detector.js.map +0 -1
- package/dist/adapters/context-adapters.d.ts +0 -101
- package/dist/adapters/context-adapters.d.ts.map +0 -1
- package/dist/adapters/context-adapters.js +0 -98
- package/dist/adapters/context-adapters.js.map +0 -1
- package/dist/adapters/filesystem-metrics.adapter.d.ts +0 -91
- package/dist/adapters/filesystem-metrics.adapter.d.ts.map +0 -1
- package/dist/adapters/filesystem-metrics.adapter.js +0 -530
- package/dist/adapters/filesystem-metrics.adapter.js.map +0 -1
- package/dist/adapters/index.d.ts +0 -15
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js +0 -21
- package/dist/adapters/index.js.map +0 -1
- package/dist/adapters/mock-dashboard-renderer.adapter.d.ts +0 -86
- package/dist/adapters/mock-dashboard-renderer.adapter.d.ts.map +0 -1
- package/dist/adapters/mock-dashboard-renderer.adapter.js +0 -93
- package/dist/adapters/mock-dashboard-renderer.adapter.js.map +0 -1
- package/dist/adapters/recovery-adapters.d.ts +0 -41
- package/dist/adapters/recovery-adapters.d.ts.map +0 -1
- package/dist/adapters/recovery-adapters.js +0 -32
- package/dist/adapters/recovery-adapters.js.map +0 -1
- package/dist/adapters/terminal-renderer.adapter.d.ts +0 -86
- package/dist/adapters/terminal-renderer.adapter.d.ts.map +0 -1
- package/dist/adapters/terminal-renderer.adapter.js +0 -342
- package/dist/adapters/terminal-renderer.adapter.js.map +0 -1
- package/dist/adapters/validation-adapters.d.ts +0 -53
- package/dist/adapters/validation-adapters.d.ts.map +0 -1
- package/dist/adapters/validation-adapters.js +0 -48
- package/dist/adapters/validation-adapters.js.map +0 -1
- package/dist/agent-patterns-registry.d.ts +0 -141
- package/dist/agent-patterns-registry.d.ts.map +0 -1
- package/dist/agent-patterns-registry.js +0 -319
- package/dist/agent-patterns-registry.js.map +0 -1
- package/dist/arg-parser.d.ts +0 -94
- package/dist/arg-parser.d.ts.map +0 -1
- package/dist/arg-parser.js +0 -774
- package/dist/arg-parser.js.map +0 -1
- package/dist/atomic-merge.d.ts +0 -21
- package/dist/atomic-merge.d.ts.map +0 -1
- package/dist/atomic-merge.js +0 -87
- package/dist/atomic-merge.js.map +0 -1
- package/dist/backlog-editor.d.ts +0 -103
- package/dist/backlog-editor.d.ts.map +0 -1
- package/dist/backlog-editor.js +0 -158
- package/dist/backlog-editor.js.map +0 -1
- package/dist/backlog-generator.d.ts +0 -90
- package/dist/backlog-generator.d.ts.map +0 -1
- package/dist/backlog-generator.js +0 -536
- package/dist/backlog-generator.js.map +0 -1
- package/dist/backlog-parser.d.ts +0 -46
- package/dist/backlog-parser.d.ts.map +0 -1
- package/dist/backlog-parser.js +0 -105
- package/dist/backlog-parser.js.map +0 -1
- package/dist/backlog-sync-validator.d.ts +0 -88
- package/dist/backlog-sync-validator.d.ts.map +0 -1
- package/dist/backlog-sync-validator.js +0 -324
- package/dist/backlog-sync-validator.js.map +0 -1
- package/dist/beacon-migration.d.ts +0 -56
- package/dist/beacon-migration.js +0 -101
- package/dist/branch-check.d.ts +0 -63
- package/dist/branch-check.d.ts.map +0 -1
- package/dist/branch-check.js +0 -197
- package/dist/branch-check.js.map +0 -1
- package/dist/branch-drift.d.ts +0 -24
- package/dist/branch-drift.d.ts.map +0 -1
- package/dist/branch-drift.js +0 -54
- package/dist/branch-drift.js.map +0 -1
- package/dist/cleanup-install-config.d.ts +0 -24
- package/dist/cleanup-install-config.d.ts.map +0 -1
- package/dist/cleanup-install-config.js +0 -40
- package/dist/cleanup-install-config.js.map +0 -1
- package/dist/cleanup-lock.d.ts +0 -125
- package/dist/cleanup-lock.d.ts.map +0 -1
- package/dist/cleanup-lock.js +0 -325
- package/dist/cleanup-lock.js.map +0 -1
- package/dist/cli/is-agent-branch.d.ts +0 -15
- package/dist/cli/is-agent-branch.d.ts.map +0 -1
- package/dist/cli/is-agent-branch.js.map +0 -1
- package/dist/cloud-detect.d.ts +0 -145
- package/dist/cloud-detect.d.ts.map +0 -1
- package/dist/cloud-detect.js +0 -116
- package/dist/cloud-detect.js.map +0 -1
- package/dist/code-path-validator.d.ts +0 -147
- package/dist/code-path-validator.d.ts.map +0 -1
- package/dist/code-path-validator.js +0 -551
- package/dist/code-path-validator.js.map +0 -1
- package/dist/code-paths-overlap.d.ts +0 -50
- package/dist/code-paths-overlap.d.ts.map +0 -1
- package/dist/code-paths-overlap.js +0 -248
- package/dist/code-paths-overlap.js.map +0 -1
- package/dist/color-support.d.ts +0 -21
- package/dist/color-support.d.ts.map +0 -1
- package/dist/color-support.js +0 -67
- package/dist/color-support.js.map +0 -1
- package/dist/commands-logger.d.ts +0 -71
- package/dist/commands-logger.d.ts.map +0 -1
- package/dist/commands-logger.js +0 -256
- package/dist/commands-logger.js.map +0 -1
- package/dist/commit-message-utils.d.ts +0 -26
- package/dist/commit-message-utils.d.ts.map +0 -1
- package/dist/commit-message-utils.js +0 -44
- package/dist/commit-message-utils.js.map +0 -1
- package/dist/compliance-parser.d.ts +0 -125
- package/dist/compliance-parser.d.ts.map +0 -1
- package/dist/compliance-parser.js +0 -457
- package/dist/compliance-parser.js.map +0 -1
- package/dist/constants/backlog-patterns.d.ts +0 -21
- package/dist/constants/backlog-patterns.d.ts.map +0 -1
- package/dist/constants/backlog-patterns.js +0 -26
- package/dist/constants/backlog-patterns.js.map +0 -1
- package/dist/constants/dora-constants.d.ts +0 -50
- package/dist/constants/dora-constants.d.ts.map +0 -1
- package/dist/constants/dora-constants.js +0 -56
- package/dist/constants/dora-constants.js.map +0 -1
- package/dist/constants/gate-constants.d.ts +0 -16
- package/dist/constants/gate-constants.d.ts.map +0 -1
- package/dist/constants/gate-constants.js +0 -18
- package/dist/constants/gate-constants.js.map +0 -1
- package/dist/constants/linter-constants.d.ts +0 -17
- package/dist/constants/linter-constants.d.ts.map +0 -1
- package/dist/constants/linter-constants.js +0 -19
- package/dist/constants/linter-constants.js.map +0 -1
- package/dist/constants/tokenizer-constants.d.ts +0 -16
- package/dist/constants/tokenizer-constants.d.ts.map +0 -1
- package/dist/constants/tokenizer-constants.js +0 -18
- package/dist/constants/tokenizer-constants.js.map +0 -1
- package/dist/context/context-computer.d.ts +0 -36
- package/dist/context/context-computer.d.ts.map +0 -1
- package/dist/context/context-computer.js +0 -128
- package/dist/context/context-computer.js.map +0 -1
- package/dist/context/git-state-reader.d.ts +0 -37
- package/dist/context/git-state-reader.d.ts.map +0 -1
- package/dist/context/git-state-reader.js +0 -64
- package/dist/context/git-state-reader.js.map +0 -1
- package/dist/context/index.d.ts +0 -18
- package/dist/context/index.d.ts.map +0 -1
- package/dist/context/index.js +0 -20
- package/dist/context/index.js.map +0 -1
- package/dist/context/location-resolver.d.ts +0 -34
- package/dist/context/location-resolver.d.ts.map +0 -1
- package/dist/context/location-resolver.js +0 -179
- package/dist/context/location-resolver.js.map +0 -1
- package/dist/context/wu-state-reader.d.ts +0 -30
- package/dist/context/wu-state-reader.d.ts.map +0 -1
- package/dist/context/wu-state-reader.js +0 -126
- package/dist/context/wu-state-reader.js.map +0 -1
- package/dist/context-di.d.ts +0 -185
- package/dist/context-di.d.ts.map +0 -1
- package/dist/context-di.js +0 -165
- package/dist/context-di.js.map +0 -1
- package/dist/context-validation-integration.d.ts +0 -69
- package/dist/context-validation-integration.d.ts.map +0 -1
- package/dist/context-validation-integration.js +0 -161
- package/dist/context-validation-integration.js.map +0 -1
- package/dist/core/scope-checker.d.ts +0 -80
- package/dist/core/scope-checker.d.ts.map +0 -1
- package/dist/core/scope-checker.js +0 -166
- package/dist/core/scope-checker.js.map +0 -1
- package/dist/core/tool-runner.d.ts +0 -136
- package/dist/core/tool-runner.d.ts.map +0 -1
- package/dist/core/tool-runner.js +0 -396
- package/dist/core/tool-runner.js.map +0 -1
- package/dist/core/tool.constants.d.ts +0 -106
- package/dist/core/tool.constants.d.ts.map +0 -1
- package/dist/core/tool.constants.js +0 -104
- package/dist/core/tool.constants.js.map +0 -1
- package/dist/core/tool.schemas.d.ts +0 -227
- package/dist/core/tool.schemas.d.ts.map +0 -1
- package/dist/core/tool.schemas.js +0 -229
- package/dist/core/tool.schemas.js.map +0 -1
- package/dist/core/worktree-guard.d.ts +0 -115
- package/dist/core/worktree-guard.d.ts.map +0 -1
- package/dist/core/worktree-guard.js +0 -245
- package/dist/core/worktree-guard.js.map +0 -1
- package/dist/coverage-gate.d.ts +0 -126
- package/dist/coverage-gate.d.ts.map +0 -1
- package/dist/coverage-gate.js +0 -209
- package/dist/coverage-gate.js.map +0 -1
- package/dist/cycle-detector.d.ts +0 -52
- package/dist/cycle-detector.d.ts.map +0 -1
- package/dist/cycle-detector.js +0 -84
- package/dist/cycle-detector.js.map +0 -1
- package/dist/date-utils.d.ts +0 -66
- package/dist/date-utils.d.ts.map +0 -1
- package/dist/date-utils.js +0 -143
- package/dist/date-utils.js.map +0 -1
- package/dist/delegation-escalation.d.ts +0 -71
- package/dist/delegation-escalation.d.ts.map +0 -1
- package/dist/delegation-escalation.js +0 -264
- package/dist/delegation-escalation.js.map +0 -1
- package/dist/delegation-monitor.d.ts +0 -262
- package/dist/delegation-monitor.d.ts.map +0 -1
- package/dist/delegation-monitor.js +0 -678
- package/dist/delegation-monitor.js.map +0 -1
- package/dist/delegation-recovery.d.ts +0 -62
- package/dist/delegation-recovery.d.ts.map +0 -1
- package/dist/delegation-recovery.js +0 -304
- package/dist/delegation-recovery.js.map +0 -1
- package/dist/delegation-registry-schema.d.ts +0 -75
- package/dist/delegation-registry-schema.d.ts.map +0 -1
- package/dist/delegation-registry-schema.js +0 -93
- package/dist/delegation-registry-schema.js.map +0 -1
- package/dist/delegation-registry-store.d.ts +0 -145
- package/dist/delegation-registry-store.d.ts.map +0 -1
- package/dist/delegation-registry-store.js +0 -308
- package/dist/delegation-registry-store.js.map +0 -1
- package/dist/delegation-tree.d.ts +0 -52
- package/dist/delegation-tree.d.ts.map +0 -1
- package/dist/delegation-tree.js +0 -205
- package/dist/delegation-tree.js.map +0 -1
- package/dist/dependency-graph.d.ts +0 -169
- package/dist/dependency-graph.d.ts.map +0 -1
- package/dist/dependency-graph.js +0 -612
- package/dist/dependency-graph.js.map +0 -1
- package/dist/dependency-guard.d.ts +0 -41
- package/dist/dependency-guard.d.ts.map +0 -1
- package/dist/dependency-guard.js +0 -145
- package/dist/dependency-guard.js.map +0 -1
- package/dist/dependency-validator.d.ts +0 -89
- package/dist/dependency-validator.d.ts.map +0 -1
- package/dist/dependency-validator.js +0 -155
- package/dist/dependency-validator.js.map +0 -1
- package/dist/docs-path-validator.d.ts +0 -16
- package/dist/docs-path-validator.d.ts.map +0 -1
- package/dist/docs-path-validator.js +0 -98
- package/dist/docs-path-validator.js.map +0 -1
- package/dist/domain/context.schemas.d.ts +0 -170
- package/dist/domain/context.schemas.d.ts.map +0 -1
- package/dist/domain/context.schemas.js +0 -151
- package/dist/domain/context.schemas.js.map +0 -1
- package/dist/domain/index.d.ts +0 -15
- package/dist/domain/index.d.ts.map +0 -1
- package/dist/domain/index.js +0 -23
- package/dist/domain/index.js.map +0 -1
- package/dist/domain/orchestration.constants.d.ts +0 -111
- package/dist/domain/orchestration.constants.d.ts.map +0 -1
- package/dist/domain/orchestration.constants.js +0 -130
- package/dist/domain/orchestration.constants.js.map +0 -1
- package/dist/domain/orchestration.schemas.d.ts +0 -307
- package/dist/domain/orchestration.schemas.d.ts.map +0 -1
- package/dist/domain/orchestration.schemas.js +0 -214
- package/dist/domain/orchestration.schemas.js.map +0 -1
- package/dist/domain/orchestration.types.d.ts +0 -134
- package/dist/domain/orchestration.types.d.ts.map +0 -1
- package/dist/domain/orchestration.types.js +0 -5
- package/dist/domain/orchestration.types.js.map +0 -1
- package/dist/domain/recovery.schemas.d.ts +0 -164
- package/dist/domain/recovery.schemas.d.ts.map +0 -1
- package/dist/domain/recovery.schemas.js +0 -134
- package/dist/domain/recovery.schemas.js.map +0 -1
- package/dist/domain/validation.schemas.d.ts +0 -147
- package/dist/domain/validation.schemas.d.ts.map +0 -1
- package/dist/domain/validation.schemas.js +0 -117
- package/dist/domain/validation.schemas.js.map +0 -1
- package/dist/error-handler.d.ts +0 -144
- package/dist/error-handler.d.ts.map +0 -1
- package/dist/error-handler.js +0 -214
- package/dist/error-handler.js.map +0 -1
- package/dist/file-classifiers.d.ts +0 -63
- package/dist/file-classifiers.d.ts.map +0 -1
- package/dist/file-classifiers.js +0 -111
- package/dist/file-classifiers.js.map +0 -1
- package/dist/force-bypass-audit.d.ts +0 -47
- package/dist/force-bypass-audit.d.ts.map +0 -1
- package/dist/force-bypass-audit.js +0 -146
- package/dist/force-bypass-audit.js.map +0 -1
- package/dist/gates-agent-mode.d.ts +0 -107
- package/dist/gates-agent-mode.d.ts.map +0 -1
- package/dist/gates-agent-mode.js +0 -138
- package/dist/gates-agent-mode.js.map +0 -1
- package/dist/gates-config.d.ts +0 -268
- package/dist/gates-config.d.ts.map +0 -1
- package/dist/gates-config.js +0 -644
- package/dist/gates-config.js.map +0 -1
- package/dist/generate-traceability.d.ts +0 -106
- package/dist/generate-traceability.d.ts.map +0 -1
- package/dist/generate-traceability.js +0 -387
- package/dist/generate-traceability.js.map +0 -1
- package/dist/git-adapter.d.ts +0 -406
- package/dist/git-adapter.d.ts.map +0 -1
- package/dist/git-adapter.js +0 -686
- package/dist/git-adapter.js.map +0 -1
- package/dist/git-context-extractor.d.ts +0 -102
- package/dist/git-context-extractor.d.ts.map +0 -1
- package/dist/git-context-extractor.js +0 -571
- package/dist/git-context-extractor.js.map +0 -1
- package/dist/git-staged-validator.d.ts +0 -33
- package/dist/git-staged-validator.d.ts.map +0 -1
- package/dist/git-staged-validator.js +0 -52
- package/dist/git-staged-validator.js.map +0 -1
- package/dist/hardcoded-strings.d.ts +0 -67
- package/dist/hardcoded-strings.d.ts.map +0 -1
- package/dist/hardcoded-strings.js +0 -276
- package/dist/hardcoded-strings.js.map +0 -1
- package/dist/incremental-lint.d.ts +0 -71
- package/dist/incremental-lint.d.ts.map +0 -1
- package/dist/incremental-lint.js +0 -132
- package/dist/incremental-lint.js.map +0 -1
- package/dist/incremental-test.d.ts +0 -33
- package/dist/incremental-test.d.ts.map +0 -1
- package/dist/incremental-test.js +0 -64
- package/dist/incremental-test.js.map +0 -1
- package/dist/index.d.ts +0 -104
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invariants/check-automated-tests.d.ts +0 -42
- package/dist/invariants/check-automated-tests.d.ts.map +0 -1
- package/dist/invariants/check-automated-tests.js +0 -171
- package/dist/invariants/check-automated-tests.js.map +0 -1
- package/dist/invariants-runner.d.ts +0 -108
- package/dist/invariants-runner.d.ts.map +0 -1
- package/dist/invariants-runner.js +0 -547
- package/dist/invariants-runner.js.map +0 -1
- package/dist/lane-checker.d.ts +0 -132
- package/dist/lane-checker.d.ts.map +0 -1
- package/dist/lane-checker.js +0 -743
- package/dist/lane-checker.js.map +0 -1
- package/dist/lane-inference.d.ts +0 -29
- package/dist/lane-inference.d.ts.map +0 -1
- package/dist/lane-inference.js +0 -210
- package/dist/lane-inference.js.map +0 -1
- package/dist/lane-lock.d.ts +0 -220
- package/dist/lane-lock.d.ts.map +0 -1
- package/dist/lane-lock.js +0 -499
- package/dist/lane-lock.js.map +0 -1
- package/dist/lane-suggest-prompt.d.ts +0 -97
- package/dist/lane-suggest-prompt.d.ts.map +0 -1
- package/dist/lane-suggest-prompt.js +0 -362
- package/dist/lane-suggest-prompt.js.map +0 -1
- package/dist/lane-validator.d.ts +0 -49
- package/dist/lane-validator.d.ts.map +0 -1
- package/dist/lane-validator.js +0 -117
- package/dist/lane-validator.js.map +0 -1
- package/dist/logs-lib.d.ts +0 -89
- package/dist/logs-lib.d.ts.map +0 -1
- package/dist/logs-lib.js +0 -214
- package/dist/logs-lib.js.map +0 -1
- package/dist/lumenflow-config-schema.d.ts +0 -1428
- package/dist/lumenflow-config-schema.d.ts.map +0 -1
- package/dist/lumenflow-config-schema.js +0 -1255
- package/dist/lumenflow-config-schema.js.map +0 -1
- package/dist/lumenflow-config.d.ts +0 -94
- package/dist/lumenflow-config.d.ts.map +0 -1
- package/dist/lumenflow-config.js +0 -253
- package/dist/lumenflow-config.js.map +0 -1
- package/dist/lumenflow-home.d.ts +0 -118
- package/dist/lumenflow-home.d.ts.map +0 -1
- package/dist/lumenflow-home.js +0 -214
- package/dist/lumenflow-home.js.map +0 -1
- package/dist/manual-test-validator.d.ts +0 -84
- package/dist/manual-test-validator.d.ts.map +0 -1
- package/dist/manual-test-validator.js +0 -206
- package/dist/manual-test-validator.js.map +0 -1
- package/dist/merge-lock.d.ts +0 -107
- package/dist/merge-lock.d.ts.map +0 -1
- package/dist/merge-lock.js +0 -263
- package/dist/merge-lock.js.map +0 -1
- package/dist/micro-worktree-shared.d.ts +0 -128
- package/dist/micro-worktree-shared.d.ts.map +0 -1
- package/dist/micro-worktree-shared.js +0 -352
- package/dist/micro-worktree-shared.js.map +0 -1
- package/dist/micro-worktree.d.ts +0 -165
- package/dist/micro-worktree.d.ts.map +0 -1
- package/dist/micro-worktree.js +0 -463
- package/dist/micro-worktree.js.map +0 -1
- package/dist/migration-deployer.d.ts +0 -70
- package/dist/migration-deployer.d.ts.map +0 -1
- package/dist/migration-deployer.js +0 -152
- package/dist/migration-deployer.js.map +0 -1
- package/dist/normalize-config-keys.d.ts +0 -10
- package/dist/normalize-config-keys.d.ts.map +0 -1
- package/dist/normalize-config-keys.js +0 -70
- package/dist/normalize-config-keys.js.map +0 -1
- package/dist/orchestration-advisory-loader.d.ts +0 -19
- package/dist/orchestration-advisory-loader.d.ts.map +0 -1
- package/dist/orchestration-advisory-loader.js +0 -94
- package/dist/orchestration-advisory-loader.js.map +0 -1
- package/dist/orchestration-advisory.d.ts +0 -49
- package/dist/orchestration-advisory.d.ts.map +0 -1
- package/dist/orchestration-advisory.js +0 -97
- package/dist/orchestration-advisory.js.map +0 -1
- package/dist/orchestration-di.d.ts +0 -36
- package/dist/orchestration-di.d.ts.map +0 -1
- package/dist/orchestration-di.js +0 -60
- package/dist/orchestration-di.js.map +0 -1
- package/dist/orchestration-rules.d.ts +0 -60
- package/dist/orchestration-rules.d.ts.map +0 -1
- package/dist/orchestration-rules.js +0 -212
- package/dist/orchestration-rules.js.map +0 -1
- package/dist/orphan-detector.d.ts +0 -148
- package/dist/orphan-detector.d.ts.map +0 -1
- package/dist/orphan-detector.js +0 -253
- package/dist/orphan-detector.js.map +0 -1
- package/dist/pack-authoring-template-engine.d.ts +0 -54
- package/dist/pack-authoring-template-engine.d.ts.map +0 -1
- package/dist/pack-authoring-template-engine.js +0 -510
- package/dist/pack-authoring-template-engine.js.map +0 -1
- package/dist/path-classifiers.d.ts +0 -58
- package/dist/path-classifiers.d.ts.map +0 -1
- package/dist/path-classifiers.js +0 -96
- package/dist/path-classifiers.js.map +0 -1
- package/dist/patrol-loop.d.ts +0 -171
- package/dist/patrol-loop.d.ts.map +0 -1
- package/dist/patrol-loop.js +0 -197
- package/dist/patrol-loop.js.map +0 -1
- package/dist/piped-command-detector.d.ts +0 -25
- package/dist/piped-command-detector.d.ts.map +0 -1
- package/dist/piped-command-detector.js +0 -67
- package/dist/piped-command-detector.js.map +0 -1
- package/dist/ports/context.ports.d.ts +0 -136
- package/dist/ports/context.ports.d.ts.map +0 -1
- package/dist/ports/context.ports.js +0 -4
- package/dist/ports/context.ports.js.map +0 -1
- package/dist/ports/core-tools.ports.d.ts +0 -282
- package/dist/ports/core-tools.ports.d.ts.map +0 -1
- package/dist/ports/core-tools.ports.js +0 -4
- package/dist/ports/core-tools.ports.js.map +0 -1
- package/dist/ports/dashboard-renderer.port.d.ts +0 -113
- package/dist/ports/dashboard-renderer.port.d.ts.map +0 -1
- package/dist/ports/dashboard-renderer.port.js +0 -4
- package/dist/ports/dashboard-renderer.port.js.map +0 -1
- package/dist/ports/git-validator.ports.d.ts +0 -114
- package/dist/ports/git-validator.ports.d.ts.map +0 -1
- package/dist/ports/git-validator.ports.js +0 -4
- package/dist/ports/git-validator.ports.js.map +0 -1
- package/dist/ports/index.d.ts +0 -21
- package/dist/ports/index.d.ts.map +0 -1
- package/dist/ports/index.js +0 -23
- package/dist/ports/index.js.map +0 -1
- package/dist/ports/metrics-collector.port.d.ts +0 -133
- package/dist/ports/metrics-collector.port.d.ts.map +0 -1
- package/dist/ports/metrics-collector.port.js +0 -4
- package/dist/ports/metrics-collector.port.js.map +0 -1
- package/dist/ports/recovery.ports.d.ts +0 -59
- package/dist/ports/recovery.ports.d.ts.map +0 -1
- package/dist/ports/recovery.ports.js +0 -4
- package/dist/ports/recovery.ports.js.map +0 -1
- package/dist/ports/validation.ports.d.ts +0 -75
- package/dist/ports/validation.ports.d.ts.map +0 -1
- package/dist/ports/validation.ports.js +0 -4
- package/dist/ports/validation.ports.js.map +0 -1
- package/dist/ports/wu-helpers.ports.d.ts +0 -227
- package/dist/ports/wu-helpers.ports.d.ts.map +0 -1
- package/dist/ports/wu-helpers.ports.js +0 -4
- package/dist/ports/wu-helpers.ports.js.map +0 -1
- package/dist/process-detector.d.ts +0 -69
- package/dist/process-detector.d.ts.map +0 -1
- package/dist/process-detector.js +0 -175
- package/dist/process-detector.js.map +0 -1
- package/dist/prompt-linter.d.ts +0 -66
- package/dist/prompt-linter.d.ts.map +0 -1
- package/dist/prompt-linter.js +0 -323
- package/dist/prompt-linter.js.map +0 -1
- package/dist/prompt-monitor.d.ts +0 -6
- package/dist/prompt-monitor.d.ts.map +0 -1
- package/dist/prompt-monitor.js +0 -218
- package/dist/prompt-monitor.js.map +0 -1
- package/dist/rebase-artifact-cleanup.d.ts +0 -156
- package/dist/rebase-artifact-cleanup.d.ts.map +0 -1
- package/dist/rebase-artifact-cleanup.js +0 -475
- package/dist/rebase-artifact-cleanup.js.map +0 -1
- package/dist/recovery/index.d.ts +0 -12
- package/dist/recovery/index.d.ts.map +0 -1
- package/dist/recovery/index.js +0 -14
- package/dist/recovery/index.js.map +0 -1
- package/dist/recovery/recovery-analyzer.d.ts +0 -49
- package/dist/recovery/recovery-analyzer.d.ts.map +0 -1
- package/dist/recovery/recovery-analyzer.js +0 -149
- package/dist/recovery/recovery-analyzer.js.map +0 -1
- package/dist/resolve-policy.d.ts +0 -257
- package/dist/resolve-policy.d.ts.map +0 -1
- package/dist/resolve-policy.js +0 -269
- package/dist/resolve-policy.js.map +0 -1
- package/dist/retry-strategy.d.ts +0 -191
- package/dist/retry-strategy.d.ts.map +0 -1
- package/dist/retry-strategy.js +0 -286
- package/dist/retry-strategy.js.map +0 -1
- package/dist/risk-detector.d.ts +0 -109
- package/dist/risk-detector.d.ts.map +0 -1
- package/dist/risk-detector.js +0 -253
- package/dist/risk-detector.js.map +0 -1
- package/dist/rollback-utils.d.ts +0 -129
- package/dist/rollback-utils.d.ts.map +0 -1
- package/dist/rollback-utils.js +0 -217
- package/dist/rollback-utils.js.map +0 -1
- package/dist/sandbox-allowlist.d.ts +0 -16
- package/dist/sandbox-allowlist.d.ts.map +0 -1
- package/dist/sandbox-allowlist.js +0 -77
- package/dist/sandbox-allowlist.js.map +0 -1
- package/dist/sandbox-backend-linux.d.ts +0 -6
- package/dist/sandbox-backend-linux.d.ts.map +0 -1
- package/dist/sandbox-backend-linux.js +0 -67
- package/dist/sandbox-backend-linux.js.map +0 -1
- package/dist/sandbox-backend-macos.d.ts +0 -6
- package/dist/sandbox-backend-macos.d.ts.map +0 -1
- package/dist/sandbox-backend-macos.js +0 -66
- package/dist/sandbox-backend-macos.js.map +0 -1
- package/dist/sandbox-backend-windows.d.ts +0 -6
- package/dist/sandbox-backend-windows.d.ts.map +0 -1
- package/dist/sandbox-backend-windows.js +0 -30
- package/dist/sandbox-backend-windows.js.map +0 -1
- package/dist/sandbox-profile.d.ts +0 -53
- package/dist/sandbox-profile.d.ts.map +0 -1
- package/dist/sandbox-profile.js +0 -64
- package/dist/sandbox-profile.js.map +0 -1
- package/dist/schemas/arg-validators.d.ts +0 -58
- package/dist/schemas/arg-validators.d.ts.map +0 -1
- package/dist/schemas/arg-validators.js +0 -193
- package/dist/schemas/arg-validators.js.map +0 -1
- package/dist/schemas/command-schemas.d.ts +0 -171
- package/dist/schemas/command-schemas.d.ts.map +0 -1
- package/dist/schemas/command-schemas.js +0 -145
- package/dist/schemas/command-schemas.js.map +0 -1
- package/dist/schemas/flow-arg-validators.d.ts +0 -32
- package/dist/schemas/flow-arg-validators.d.ts.map +0 -1
- package/dist/schemas/flow-arg-validators.js +0 -57
- package/dist/schemas/flow-arg-validators.js.map +0 -1
- package/dist/schemas/flow-schemas.d.ts +0 -152
- package/dist/schemas/flow-schemas.d.ts.map +0 -1
- package/dist/schemas/flow-schemas.js +0 -105
- package/dist/schemas/flow-schemas.js.map +0 -1
- package/dist/schemas/index.d.ts +0 -33
- package/dist/schemas/index.d.ts.map +0 -1
- package/dist/schemas/index.js +0 -96
- package/dist/schemas/index.js.map +0 -1
- package/dist/schemas/initiative-arg-validators.d.ts +0 -64
- package/dist/schemas/initiative-arg-validators.d.ts.map +0 -1
- package/dist/schemas/initiative-arg-validators.js +0 -65
- package/dist/schemas/initiative-arg-validators.js.map +0 -1
- package/dist/schemas/initiative-schemas.d.ts +0 -256
- package/dist/schemas/initiative-schemas.d.ts.map +0 -1
- package/dist/schemas/initiative-schemas.js +0 -186
- package/dist/schemas/initiative-schemas.js.map +0 -1
- package/dist/schemas/memory-arg-validators.d.ts +0 -91
- package/dist/schemas/memory-arg-validators.d.ts.map +0 -1
- package/dist/schemas/memory-arg-validators.js +0 -75
- package/dist/schemas/memory-arg-validators.js.map +0 -1
- package/dist/schemas/memory-schemas.d.ts +0 -287
- package/dist/schemas/memory-schemas.d.ts.map +0 -1
- package/dist/schemas/memory-schemas.js +0 -242
- package/dist/schemas/memory-schemas.js.map +0 -1
- package/dist/schemas/schema-utils.d.ts +0 -87
- package/dist/schemas/schema-utils.d.ts.map +0 -1
- package/dist/schemas/schema-utils.js +0 -320
- package/dist/schemas/schema-utils.js.map +0 -1
- package/dist/schemas/setup-arg-validators.d.ts +0 -91
- package/dist/schemas/setup-arg-validators.d.ts.map +0 -1
- package/dist/schemas/setup-arg-validators.js +0 -98
- package/dist/schemas/setup-arg-validators.js.map +0 -1
- package/dist/schemas/setup-schemas.d.ts +0 -335
- package/dist/schemas/setup-schemas.d.ts.map +0 -1
- package/dist/schemas/setup-schemas.js +0 -260
- package/dist/schemas/setup-schemas.js.map +0 -1
- package/dist/schemas/validation-arg-validators.d.ts +0 -18
- package/dist/schemas/validation-arg-validators.d.ts.map +0 -1
- package/dist/schemas/validation-arg-validators.js +0 -59
- package/dist/schemas/validation-arg-validators.js.map +0 -1
- package/dist/schemas/validation-schemas.d.ts +0 -80
- package/dist/schemas/validation-schemas.d.ts.map +0 -1
- package/dist/schemas/validation-schemas.js +0 -88
- package/dist/schemas/validation-schemas.js.map +0 -1
- package/dist/schemas/wu-lifecycle-arg-validators.d.ts +0 -118
- package/dist/schemas/wu-lifecycle-arg-validators.d.ts.map +0 -1
- package/dist/schemas/wu-lifecycle-arg-validators.js +0 -82
- package/dist/schemas/wu-lifecycle-arg-validators.js.map +0 -1
- package/dist/schemas/wu-lifecycle-schemas.d.ts +0 -362
- package/dist/schemas/wu-lifecycle-schemas.d.ts.map +0 -1
- package/dist/schemas/wu-lifecycle-schemas.js +0 -284
- package/dist/schemas/wu-lifecycle-schemas.js.map +0 -1
- package/dist/section-headings.d.ts +0 -35
- package/dist/section-headings.d.ts.map +0 -1
- package/dist/section-headings.js +0 -54
- package/dist/section-headings.js.map +0 -1
- package/dist/spawn-escalation.d.ts +0 -91
- package/dist/spawn-escalation.d.ts.map +0 -1
- package/dist/spawn-escalation.js +0 -258
- package/dist/spawn-escalation.js.map +0 -1
- package/dist/spawn-monitor.d.ts +0 -230
- package/dist/spawn-monitor.d.ts.map +0 -1
- package/dist/spawn-monitor.js +0 -675
- package/dist/spawn-monitor.js.map +0 -1
- package/dist/spawn-prompt-schema.d.ts +0 -107
- package/dist/spawn-prompt-schema.d.ts.map +0 -1
- package/dist/spawn-prompt-schema.js +0 -163
- package/dist/spawn-prompt-schema.js.map +0 -1
- package/dist/spawn-recovery.d.ts +0 -83
- package/dist/spawn-recovery.d.ts.map +0 -1
- package/dist/spawn-recovery.js +0 -299
- package/dist/spawn-recovery.js.map +0 -1
- package/dist/spawn-registry-schema.d.ts +0 -122
- package/dist/spawn-registry-schema.d.ts.map +0 -1
- package/dist/spawn-registry-schema.js +0 -129
- package/dist/spawn-registry-schema.js.map +0 -1
- package/dist/spawn-registry-store.d.ts +0 -161
- package/dist/spawn-registry-store.d.ts.map +0 -1
- package/dist/spawn-registry-store.js +0 -301
- package/dist/spawn-registry-store.js.map +0 -1
- package/dist/spawn-strategy.d.ts +0 -60
- package/dist/spawn-strategy.d.ts.map +0 -1
- package/dist/spawn-strategy.js +0 -112
- package/dist/spawn-strategy.js.map +0 -1
- package/dist/spawn-tree.d.ts +0 -125
- package/dist/spawn-tree.d.ts.map +0 -1
- package/dist/spawn-tree.js +0 -286
- package/dist/spawn-tree.js.map +0 -1
- package/dist/stamp-status-validator.d.ts +0 -77
- package/dist/stamp-status-validator.d.ts.map +0 -1
- package/dist/stamp-status-validator.js +0 -138
- package/dist/stamp-status-validator.js.map +0 -1
- package/dist/stamp-tracking.d.ts +0 -12
- package/dist/stamp-tracking.d.ts.map +0 -1
- package/dist/stamp-tracking.js +0 -43
- package/dist/stamp-tracking.js.map +0 -1
- package/dist/stamp-utils.d.ts +0 -94
- package/dist/stamp-utils.d.ts.map +0 -1
- package/dist/stamp-utils.js +0 -245
- package/dist/stamp-utils.js.map +0 -1
- package/dist/state-cleanup-core.d.ts +0 -206
- package/dist/state-cleanup-core.d.ts.map +0 -1
- package/dist/state-cleanup-core.js +0 -225
- package/dist/state-cleanup-core.js.map +0 -1
- package/dist/state-doctor-core.d.ts +0 -177
- package/dist/state-doctor-core.d.ts.map +0 -1
- package/dist/state-doctor-core.js +0 -395
- package/dist/state-doctor-core.js.map +0 -1
- package/dist/state-machine.d.ts +0 -10
- package/dist/state-machine.d.ts.map +0 -1
- package/dist/state-machine.js +0 -89
- package/dist/state-machine.js.map +0 -1
- package/dist/stream-error-handler.d.ts +0 -68
- package/dist/stream-error-handler.d.ts.map +0 -1
- package/dist/stream-error-handler.js +0 -77
- package/dist/stream-error-handler.js.map +0 -1
- package/dist/system-map-validator.d.ts +0 -111
- package/dist/system-map-validator.d.ts.map +0 -1
- package/dist/system-map-validator.js +0 -383
- package/dist/system-map-validator.js.map +0 -1
- package/dist/telemetry.d.ts +0 -81
- package/dist/telemetry.d.ts.map +0 -1
- package/dist/telemetry.js +0 -219
- package/dist/telemetry.js.map +0 -1
- package/dist/template-loader.d.ts +0 -151
- package/dist/template-loader.d.ts.map +0 -1
- package/dist/template-loader.js +0 -400
- package/dist/template-loader.js.map +0 -1
- package/dist/test-baseline.d.ts +0 -177
- package/dist/test-baseline.d.ts.map +0 -1
- package/dist/test-baseline.js +0 -286
- package/dist/test-baseline.js.map +0 -1
- package/dist/token-counter.d.ts +0 -50
- package/dist/token-counter.d.ts.map +0 -1
- package/dist/token-counter.js +0 -144
- package/dist/token-counter.js.map +0 -1
- package/dist/usecases/analyze-recovery.usecase.d.ts +0 -43
- package/dist/usecases/analyze-recovery.usecase.d.ts.map +0 -1
- package/dist/usecases/analyze-recovery.usecase.js +0 -34
- package/dist/usecases/analyze-recovery.usecase.js.map +0 -1
- package/dist/usecases/compute-context.usecase.d.ts +0 -63
- package/dist/usecases/compute-context.usecase.d.ts.map +0 -1
- package/dist/usecases/compute-context.usecase.js +0 -91
- package/dist/usecases/compute-context.usecase.js.map +0 -1
- package/dist/usecases/get-dashboard-data.usecase.d.ts +0 -53
- package/dist/usecases/get-dashboard-data.usecase.d.ts.map +0 -1
- package/dist/usecases/get-dashboard-data.usecase.js +0 -54
- package/dist/usecases/get-dashboard-data.usecase.js.map +0 -1
- package/dist/usecases/get-suggestions.usecase.d.ts +0 -101
- package/dist/usecases/get-suggestions.usecase.d.ts.map +0 -1
- package/dist/usecases/get-suggestions.usecase.js +0 -148
- package/dist/usecases/get-suggestions.usecase.js.map +0 -1
- package/dist/usecases/index.d.ts +0 -15
- package/dist/usecases/index.d.ts.map +0 -1
- package/dist/usecases/index.js +0 -21
- package/dist/usecases/index.js.map +0 -1
- package/dist/usecases/validate-command.usecase.d.ts +0 -56
- package/dist/usecases/validate-command.usecase.d.ts.map +0 -1
- package/dist/usecases/validate-command.usecase.js +0 -143
- package/dist/usecases/validate-command.usecase.js.map +0 -1
- package/dist/user-normalizer.d.ts +0 -36
- package/dist/user-normalizer.d.ts.map +0 -1
- package/dist/user-normalizer.js +0 -149
- package/dist/user-normalizer.js.map +0 -1
- package/dist/validation/command-registry.d.ts +0 -26
- package/dist/validation/command-registry.d.ts.map +0 -1
- package/dist/validation/command-registry.js +0 -269
- package/dist/validation/command-registry.js.map +0 -1
- package/dist/validation/index.d.ts +0 -16
- package/dist/validation/index.d.ts.map +0 -1
- package/dist/validation/index.js +0 -18
- package/dist/validation/index.js.map +0 -1
- package/dist/validation/types.d.ts +0 -140
- package/dist/validation/types.d.ts.map +0 -1
- package/dist/validation/types.js +0 -4
- package/dist/validation/types.js.map +0 -1
- package/dist/validation/validate-command.d.ts +0 -16
- package/dist/validation/validate-command.d.ts.map +0 -1
- package/dist/validation/validate-command.js +0 -163
- package/dist/validation/validate-command.js.map +0 -1
- package/dist/validators/backlog-sync.d.ts +0 -11
- package/dist/validators/backlog-sync.d.ts.map +0 -1
- package/dist/validators/backlog-sync.js +0 -65
- package/dist/validators/backlog-sync.js.map +0 -1
- package/dist/validators/phi-constants.d.ts +0 -98
- package/dist/validators/phi-constants.d.ts.map +0 -1
- package/dist/validators/phi-constants.js +0 -153
- package/dist/validators/phi-constants.js.map +0 -1
- package/dist/validators/phi-scanner.d.ts +0 -59
- package/dist/validators/phi-scanner.d.ts.map +0 -1
- package/dist/validators/phi-scanner.js +0 -222
- package/dist/validators/phi-scanner.js.map +0 -1
- package/dist/validators/supabase-docs-linter.d.ts +0 -15
- package/dist/validators/supabase-docs-linter.d.ts.map +0 -1
- package/dist/validators/supabase-docs-linter.js +0 -45
- package/dist/validators/supabase-docs-linter.js.map +0 -1
- package/dist/validators/wu-tasks.d.ts +0 -21
- package/dist/validators/wu-tasks.d.ts.map +0 -1
- package/dist/validators/wu-tasks.js +0 -93
- package/dist/validators/wu-tasks.js.map +0 -1
- package/dist/work-classifier.d.ts +0 -95
- package/dist/work-classifier.d.ts.map +0 -1
- package/dist/work-classifier.js +0 -408
- package/dist/work-classifier.js.map +0 -1
- package/dist/worktree-ownership.d.ts +0 -51
- package/dist/worktree-ownership.d.ts.map +0 -1
- package/dist/worktree-ownership.js +0 -77
- package/dist/worktree-ownership.js.map +0 -1
- package/dist/worktree-scanner.d.ts +0 -118
- package/dist/worktree-scanner.d.ts.map +0 -1
- package/dist/worktree-scanner.js +0 -171
- package/dist/worktree-scanner.js.map +0 -1
- package/dist/worktree-symlink.d.ts +0 -86
- package/dist/worktree-symlink.d.ts.map +0 -1
- package/dist/worktree-symlink.js +0 -349
- package/dist/worktree-symlink.js.map +0 -1
- package/dist/wu-backlog-updater.d.ts +0 -10
- package/dist/wu-backlog-updater.d.ts.map +0 -1
- package/dist/wu-backlog-updater.js +0 -40
- package/dist/wu-backlog-updater.js.map +0 -1
- package/dist/wu-checkpoint.d.ts +0 -110
- package/dist/wu-checkpoint.d.ts.map +0 -1
- package/dist/wu-checkpoint.js +0 -236
- package/dist/wu-checkpoint.js.map +0 -1
- package/dist/wu-claim-helpers.d.ts +0 -21
- package/dist/wu-claim-helpers.d.ts.map +0 -1
- package/dist/wu-claim-helpers.js +0 -66
- package/dist/wu-claim-helpers.js.map +0 -1
- package/dist/wu-claim-resume.d.ts +0 -106
- package/dist/wu-claim-resume.d.ts.map +0 -1
- package/dist/wu-claim-resume.js +0 -279
- package/dist/wu-claim-resume.js.map +0 -1
- package/dist/wu-cli-constants.d.ts +0 -425
- package/dist/wu-cli-constants.d.ts.map +0 -1
- package/dist/wu-cli-constants.js +0 -430
- package/dist/wu-cli-constants.js.map +0 -1
- package/dist/wu-consistency-checker.d.ts +0 -189
- package/dist/wu-consistency-checker.d.ts.map +0 -1
- package/dist/wu-consistency-checker.js +0 -1026
- package/dist/wu-consistency-checker.js.map +0 -1
- package/dist/wu-constants.d.ts +0 -29
- package/dist/wu-constants.d.ts.map +0 -1
- package/dist/wu-constants.js +0 -37
- package/dist/wu-constants.js.map +0 -1
- package/dist/wu-context-constants.d.ts +0 -270
- package/dist/wu-context-constants.d.ts.map +0 -1
- package/dist/wu-context-constants.js +0 -267
- package/dist/wu-context-constants.js.map +0 -1
- package/dist/wu-create-defaults.d.ts +0 -11
- package/dist/wu-create-defaults.d.ts.map +0 -1
- package/dist/wu-create-defaults.js +0 -13
- package/dist/wu-create-defaults.js.map +0 -1
- package/dist/wu-create-validators.d.ts +0 -89
- package/dist/wu-create-validators.d.ts.map +0 -1
- package/dist/wu-create-validators.js +0 -215
- package/dist/wu-create-validators.js.map +0 -1
- package/dist/wu-domain-constants.d.ts +0 -295
- package/dist/wu-domain-constants.d.ts.map +0 -1
- package/dist/wu-domain-constants.js +0 -399
- package/dist/wu-domain-constants.js.map +0 -1
- package/dist/wu-done-branch-only.d.ts +0 -120
- package/dist/wu-done-branch-only.d.ts.map +0 -1
- package/dist/wu-done-branch-only.js +0 -412
- package/dist/wu-done-branch-only.js.map +0 -1
- package/dist/wu-done-branch-utils.d.ts +0 -8
- package/dist/wu-done-branch-utils.d.ts.map +0 -1
- package/dist/wu-done-branch-utils.js +0 -34
- package/dist/wu-done-branch-utils.js.map +0 -1
- package/dist/wu-done-cleanup.d.ts +0 -6
- package/dist/wu-done-cleanup.d.ts.map +0 -1
- package/dist/wu-done-cleanup.js +0 -161
- package/dist/wu-done-cleanup.js.map +0 -1
- package/dist/wu-done-concurrent-merge.d.ts +0 -103
- package/dist/wu-done-concurrent-merge.d.ts.map +0 -1
- package/dist/wu-done-concurrent-merge.js +0 -375
- package/dist/wu-done-concurrent-merge.js.map +0 -1
- package/dist/wu-done-docs-generate.d.ts +0 -72
- package/dist/wu-done-docs-generate.d.ts.map +0 -1
- package/dist/wu-done-docs-generate.js +0 -129
- package/dist/wu-done-docs-generate.js.map +0 -1
- package/dist/wu-done-docs-only.d.ts +0 -16
- package/dist/wu-done-docs-only.d.ts.map +0 -1
- package/dist/wu-done-docs-only.js +0 -68
- package/dist/wu-done-docs-only.js.map +0 -1
- package/dist/wu-done-errors.d.ts +0 -13
- package/dist/wu-done-errors.d.ts.map +0 -1
- package/dist/wu-done-errors.js +0 -27
- package/dist/wu-done-errors.js.map +0 -1
- package/dist/wu-done-initiative-sync.d.ts +0 -13
- package/dist/wu-done-initiative-sync.d.ts.map +0 -1
- package/dist/wu-done-initiative-sync.js +0 -235
- package/dist/wu-done-initiative-sync.js.map +0 -1
- package/dist/wu-done-inputs.d.ts +0 -10
- package/dist/wu-done-inputs.d.ts.map +0 -1
- package/dist/wu-done-inputs.js +0 -55
- package/dist/wu-done-inputs.js.map +0 -1
- package/dist/wu-done-machine.d.ts +0 -175
- package/dist/wu-done-machine.d.ts.map +0 -1
- package/dist/wu-done-machine.js +0 -227
- package/dist/wu-done-machine.js.map +0 -1
- package/dist/wu-done-merged-worktree.d.ts +0 -65
- package/dist/wu-done-merged-worktree.d.ts.map +0 -1
- package/dist/wu-done-merged-worktree.js +0 -197
- package/dist/wu-done-merged-worktree.js.map +0 -1
- package/dist/wu-done-messages.d.ts +0 -120
- package/dist/wu-done-messages.d.ts.map +0 -1
- package/dist/wu-done-messages.js +0 -191
- package/dist/wu-done-messages.js.map +0 -1
- package/dist/wu-done-metadata.d.ts +0 -123
- package/dist/wu-done-metadata.d.ts.map +0 -1
- package/dist/wu-done-metadata.js +0 -240
- package/dist/wu-done-metadata.js.map +0 -1
- package/dist/wu-done-paths.d.ts +0 -87
- package/dist/wu-done-paths.d.ts.map +0 -1
- package/dist/wu-done-paths.js +0 -263
- package/dist/wu-done-paths.js.map +0 -1
- package/dist/wu-done-pr.d.ts +0 -76
- package/dist/wu-done-pr.d.ts.map +0 -1
- package/dist/wu-done-pr.js +0 -189
- package/dist/wu-done-pr.js.map +0 -1
- package/dist/wu-done-preflight.d.ts +0 -65
- package/dist/wu-done-preflight.d.ts.map +0 -1
- package/dist/wu-done-preflight.js +0 -205
- package/dist/wu-done-preflight.js.map +0 -1
- package/dist/wu-done-retry-helpers.d.ts +0 -75
- package/dist/wu-done-retry-helpers.d.ts.map +0 -1
- package/dist/wu-done-retry-helpers.js +0 -175
- package/dist/wu-done-retry-helpers.js.map +0 -1
- package/dist/wu-done-ui.d.ts +0 -29
- package/dist/wu-done-ui.d.ts.map +0 -1
- package/dist/wu-done-ui.js +0 -74
- package/dist/wu-done-ui.js.map +0 -1
- package/dist/wu-done-validation.d.ts +0 -128
- package/dist/wu-done-validation.d.ts.map +0 -1
- package/dist/wu-done-validation.js +0 -530
- package/dist/wu-done-validation.js.map +0 -1
- package/dist/wu-done-validators.d.ts +0 -16
- package/dist/wu-done-validators.d.ts.map +0 -1
- package/dist/wu-done-validators.js +0 -16
- package/dist/wu-done-validators.js.map +0 -1
- package/dist/wu-done-worktree-services.d.ts +0 -174
- package/dist/wu-done-worktree-services.d.ts.map +0 -1
- package/dist/wu-done-worktree-services.js +0 -274
- package/dist/wu-done-worktree-services.js.map +0 -1
- package/dist/wu-done-worktree.d.ts +0 -229
- package/dist/wu-done-worktree.d.ts.map +0 -1
- package/dist/wu-done-worktree.js +0 -1290
- package/dist/wu-done-worktree.js.map +0 -1
- package/dist/wu-events-cleanup.d.ts +0 -131
- package/dist/wu-events-cleanup.d.ts.map +0 -1
- package/dist/wu-events-cleanup.js +0 -404
- package/dist/wu-events-cleanup.js.map +0 -1
- package/dist/wu-git-constants.d.ts +0 -176
- package/dist/wu-git-constants.d.ts.map +0 -1
- package/dist/wu-git-constants.js +0 -178
- package/dist/wu-git-constants.js.map +0 -1
- package/dist/wu-helpers.d.ts +0 -133
- package/dist/wu-helpers.d.ts.map +0 -1
- package/dist/wu-helpers.js +0 -268
- package/dist/wu-helpers.js.map +0 -1
- package/dist/wu-id-generator.d.ts +0 -51
- package/dist/wu-id-generator.d.ts.map +0 -1
- package/dist/wu-id-generator.js +0 -110
- package/dist/wu-id-generator.js.map +0 -1
- package/dist/wu-lint.d.ts +0 -191
- package/dist/wu-lint.d.ts.map +0 -1
- package/dist/wu-lint.js +0 -338
- package/dist/wu-lint.js.map +0 -1
- package/dist/wu-list.d.ts +0 -76
- package/dist/wu-list.d.ts.map +0 -1
- package/dist/wu-list.js +0 -181
- package/dist/wu-list.js.map +0 -1
- package/dist/wu-paths-constants.d.ts +0 -264
- package/dist/wu-paths-constants.d.ts.map +0 -1
- package/dist/wu-paths-constants.js +0 -272
- package/dist/wu-paths-constants.js.map +0 -1
- package/dist/wu-paths.d.ts +0 -211
- package/dist/wu-paths.d.ts.map +0 -1
- package/dist/wu-paths.js +0 -223
- package/dist/wu-paths.js.map +0 -1
- package/dist/wu-preflight-validators.d.ts +0 -64
- package/dist/wu-preflight-validators.d.ts.map +0 -1
- package/dist/wu-preflight-validators.js +0 -277
- package/dist/wu-preflight-validators.js.map +0 -1
- package/dist/wu-recovery.d.ts +0 -220
- package/dist/wu-recovery.d.ts.map +0 -1
- package/dist/wu-recovery.js +0 -470
- package/dist/wu-recovery.js.map +0 -1
- package/dist/wu-repair-core.d.ts +0 -150
- package/dist/wu-repair-core.d.ts.map +0 -1
- package/dist/wu-repair-core.js +0 -718
- package/dist/wu-repair-core.js.map +0 -1
- package/dist/wu-rules-core.d.ts +0 -95
- package/dist/wu-rules-core.d.ts.map +0 -1
- package/dist/wu-rules-core.js +0 -401
- package/dist/wu-rules-core.js.map +0 -1
- package/dist/wu-rules-engine.d.ts +0 -29
- package/dist/wu-rules-engine.d.ts.map +0 -1
- package/dist/wu-rules-engine.js +0 -61
- package/dist/wu-rules-engine.js.map +0 -1
- package/dist/wu-rules-resolvers.d.ts +0 -19
- package/dist/wu-rules-resolvers.d.ts.map +0 -1
- package/dist/wu-rules-resolvers.js +0 -210
- package/dist/wu-rules-resolvers.js.map +0 -1
- package/dist/wu-schema-normalization.d.ts +0 -18
- package/dist/wu-schema-normalization.d.ts.map +0 -1
- package/dist/wu-schema-normalization.js +0 -87
- package/dist/wu-schema-normalization.js.map +0 -1
- package/dist/wu-schema.d.ts +0 -772
- package/dist/wu-schema.d.ts.map +0 -1
- package/dist/wu-schema.js +0 -897
- package/dist/wu-schema.js.map +0 -1
- package/dist/wu-spawn-context.d.ts +0 -66
- package/dist/wu-spawn-context.d.ts.map +0 -1
- package/dist/wu-spawn-context.js +0 -185
- package/dist/wu-spawn-context.js.map +0 -1
- package/dist/wu-spawn-helpers.d.ts +0 -110
- package/dist/wu-spawn-helpers.d.ts.map +0 -1
- package/dist/wu-spawn-helpers.js +0 -276
- package/dist/wu-spawn-helpers.js.map +0 -1
- package/dist/wu-spawn-skills.d.ts +0 -39
- package/dist/wu-spawn-skills.d.ts.map +0 -1
- package/dist/wu-spawn-skills.js +0 -214
- package/dist/wu-spawn-skills.js.map +0 -1
- package/dist/wu-spawn.d.ts +0 -394
- package/dist/wu-spawn.d.ts.map +0 -1
- package/dist/wu-spawn.js +0 -1977
- package/dist/wu-spawn.js.map +0 -1
- package/dist/wu-state-schema.d.ts +0 -237
- package/dist/wu-state-schema.d.ts.map +0 -1
- package/dist/wu-state-schema.js +0 -172
- package/dist/wu-state-schema.js.map +0 -1
- package/dist/wu-state-store.d.ts +0 -275
- package/dist/wu-state-store.d.ts.map +0 -1
- package/dist/wu-state-store.js +0 -1057
- package/dist/wu-state-store.js.map +0 -1
- package/dist/wu-status-transition.d.ts +0 -58
- package/dist/wu-status-transition.d.ts.map +0 -1
- package/dist/wu-status-transition.js +0 -370
- package/dist/wu-status-transition.js.map +0 -1
- package/dist/wu-status-updater.d.ts +0 -18
- package/dist/wu-status-updater.d.ts.map +0 -1
- package/dist/wu-status-updater.js +0 -123
- package/dist/wu-status-updater.js.map +0 -1
- package/dist/wu-statuses.d.ts +0 -154
- package/dist/wu-statuses.d.ts.map +0 -1
- package/dist/wu-statuses.js +0 -176
- package/dist/wu-statuses.js.map +0 -1
- package/dist/wu-transaction-collectors.d.ts +0 -116
- package/dist/wu-transaction-collectors.d.ts.map +0 -1
- package/dist/wu-transaction-collectors.js +0 -273
- package/dist/wu-transaction-collectors.js.map +0 -1
- package/dist/wu-transaction.d.ts +0 -172
- package/dist/wu-transaction.d.ts.map +0 -1
- package/dist/wu-transaction.js +0 -288
- package/dist/wu-transaction.js.map +0 -1
- package/dist/wu-type-helpers.d.ts +0 -26
- package/dist/wu-type-helpers.d.ts.map +0 -1
- package/dist/wu-type-helpers.js +0 -45
- package/dist/wu-type-helpers.js.map +0 -1
- package/dist/wu-ui-constants.d.ts +0 -235
- package/dist/wu-ui-constants.d.ts.map +0 -1
- package/dist/wu-ui-constants.js +0 -237
- package/dist/wu-ui-constants.js.map +0 -1
- package/dist/wu-validation-constants.d.ts +0 -61
- package/dist/wu-validation-constants.d.ts.map +0 -1
- package/dist/wu-validation-constants.js +0 -69
- package/dist/wu-validation-constants.js.map +0 -1
- package/dist/wu-validation.d.ts +0 -121
- package/dist/wu-validation.d.ts.map +0 -1
- package/dist/wu-validation.js +0 -266
- package/dist/wu-validation.js.map +0 -1
- package/dist/wu-validator.d.ts +0 -128
- package/dist/wu-validator.d.ts.map +0 -1
- package/dist/wu-validator.js +0 -445
- package/dist/wu-validator.js.map +0 -1
- package/dist/wu-yaml-fixer.d.ts +0 -74
- package/dist/wu-yaml-fixer.d.ts.map +0 -1
- package/dist/wu-yaml-fixer.js +0 -273
- package/dist/wu-yaml-fixer.js.map +0 -1
- package/dist/wu-yaml.d.ts +0 -110
- package/dist/wu-yaml.d.ts.map +0 -1
- package/dist/wu-yaml.js +0 -300
- package/dist/wu-yaml.js.map +0 -1
package/dist/wu-done-worktree.js
DELETED
|
@@ -1,1290 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Copyright (c) 2026 Hellmai Ltd
|
|
3
|
-
// SPDX-License-Identifier: AGPL-3.0-only
|
|
4
|
-
/**
|
|
5
|
-
* Worktree mode completion workflow for wu:done
|
|
6
|
-
* Extracted from wu-done.ts (WU-1215 refactoring)
|
|
7
|
-
* Updated in WU-1369 to use atomic transaction pattern.
|
|
8
|
-
*
|
|
9
|
-
* Flow (WU-1369 Atomic Pattern):
|
|
10
|
-
* 1. cd into worktree
|
|
11
|
-
* 2. Read and validate WU state
|
|
12
|
-
* 3. Run ALL validations FIRST (before UnsafeAny file writes)
|
|
13
|
-
* 4. Collect all metadata changes into transaction (in memory)
|
|
14
|
-
* 5. Commit transaction (atomic write)
|
|
15
|
-
* 6. Stage and format files
|
|
16
|
-
* 7. Git commit in worktree
|
|
17
|
-
* 8. Return to main checkout
|
|
18
|
-
* 9. Either merge (default) OR create PR (pr-mode)
|
|
19
|
-
* 10. Push to origin
|
|
20
|
-
*
|
|
21
|
-
* Key guarantee: If UnsafeAny validation fails, NO files are modified.
|
|
22
|
-
*/
|
|
23
|
-
import path from 'node:path';
|
|
24
|
-
import { writeFile } from 'node:fs/promises';
|
|
25
|
-
import { spawnSync } from 'node:child_process';
|
|
26
|
-
import { generateCommitMessage, collectMetadataToTransaction, stageAndFormatMetadata, defaultBranchFrom, branchExists, validatePostMutation, } from './wu-done-validators.js';
|
|
27
|
-
import { getGitForCwd, createGitForPath } from './git-adapter.js';
|
|
28
|
-
import { readWU, writeWU } from './wu-yaml.js';
|
|
29
|
-
import { WU_PATHS } from './wu-paths.js';
|
|
30
|
-
import { BRANCHES, REMOTES, THRESHOLDS, LOG_PREFIX, EMOJI, COMMIT_FORMATS, BOX, STRING_LITERALS, WU_STATUS, GIT_COMMANDS, GIT_FLAGS, LUMENFLOW_PATHS, } from './wu-constants.js';
|
|
31
|
-
import { RECOVERY, REBASE, PREFLIGHT, MERGE } from './wu-done-messages.js';
|
|
32
|
-
import { getDriftLevel, DRIFT_LEVELS } from './branch-drift.js';
|
|
33
|
-
import { createError, ErrorCodes } from './error-handler.js';
|
|
34
|
-
import { createRecoveryError, createValidationError } from './wu-done-errors.js';
|
|
35
|
-
import { validateDoneWU, validateAndNormalizeWUYAML } from './wu-schema.js';
|
|
36
|
-
import { validateCodePathsCommittedBeforeDone } from './wu-done-validation.js';
|
|
37
|
-
import { assertTransition } from './state-machine.js';
|
|
38
|
-
import { emitLaneSignalForCompletion } from './wu-done-branch-only.js';
|
|
39
|
-
import { WU_DONE_COMPLETION_MODES } from './wu-done-pr.js';
|
|
40
|
-
import { detectZombieState, resetWorktreeYAMLForRecovery, getRecoveryAttemptCount, incrementRecoveryAttempt, clearRecoveryAttempts, shouldEscalateToManualIntervention, MAX_RECOVERY_ATTEMPTS, } from './wu-recovery.js';
|
|
41
|
-
import { isPRModeEnabled, createPR, printPRCreatedMessage } from './wu-done-pr.js';
|
|
42
|
-
import { isBranchAlreadyMerged } from './wu-done-branch-utils.js';
|
|
43
|
-
// WU-1371: Import rebase artifact cleanup functions
|
|
44
|
-
import { detectRebasedArtifacts, cleanupRebasedArtifacts } from './rebase-artifact-cleanup.js';
|
|
45
|
-
// WU-1061: Import docs regeneration utilities
|
|
46
|
-
import { maybeRegenerateAndStageDocs, DOC_OUTPUT_FILES, formatDocOutputs, } from './wu-done-docs-generate.js';
|
|
47
|
-
import { WUTransaction, createTransactionSnapshot, restoreFromSnapshot } from './wu-transaction.js';
|
|
48
|
-
// WU-1506: Import backlog invariant repair
|
|
49
|
-
// WU-1574: Removed repairBacklogInvariants - no longer needed with state store architecture
|
|
50
|
-
// Backlog.md is now always regenerated from wu-events.jsonl, so duplicates cannot occur
|
|
51
|
-
// WU-1584: Import retry helpers for squashing duplicate commits
|
|
52
|
-
// WU-1749: Added prepareRecoveryWithSquash for zombie recovery flow
|
|
53
|
-
import { countPreviousCompletionAttempts, squashPreviousCompletionAttempts, prepareRecoveryWithSquash, } from './wu-done-retry-helpers.js';
|
|
54
|
-
// WU-1747: Import retry, lock, and checkpoint modules for concurrent load resilience
|
|
55
|
-
import { withRetry, createRetryConfig } from './retry-strategy.js';
|
|
56
|
-
import { withMergeLock } from './merge-lock.js';
|
|
57
|
-
import { withAtomicMerge } from './atomic-merge.js';
|
|
58
|
-
import {} from './wu-checkpoint.js';
|
|
59
|
-
// WU-1749: Import state store constant for append-only file path
|
|
60
|
-
import { WU_EVENTS_FILE_NAME } from './wu-state-store.js';
|
|
61
|
-
import { validateWUEvent } from './wu-state-schema.js';
|
|
62
|
-
function getErrorMessage(error) {
|
|
63
|
-
return error instanceof Error ? error.message : String(error);
|
|
64
|
-
}
|
|
65
|
-
function isErrorWithCode(error, code) {
|
|
66
|
-
if (typeof error !== 'object' || error === null || !('code' in error)) {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
return error.code === code;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Resolve all metadata/state paths as absolute worktree-local paths.
|
|
73
|
-
*
|
|
74
|
-
* WU-1563: Prevents wu:done from writing lifecycle metadata into main checkout
|
|
75
|
-
* when worktree mode is active.
|
|
76
|
-
*/
|
|
77
|
-
export function resolveWorktreeMetadataPaths(worktreePath, id) {
|
|
78
|
-
return {
|
|
79
|
-
wuPath: path.join(worktreePath, WU_PATHS.WU(id)),
|
|
80
|
-
statusPath: path.join(worktreePath, WU_PATHS.STATUS()),
|
|
81
|
-
backlogPath: path.join(worktreePath, WU_PATHS.BACKLOG()),
|
|
82
|
-
stampsDir: path.join(worktreePath, WU_PATHS.STAMPS_DIR()),
|
|
83
|
-
stampPath: path.join(worktreePath, WU_PATHS.STAMP(id)),
|
|
84
|
-
eventsPath: path.join(worktreePath, LUMENFLOW_PATHS.STATE_DIR, WU_EVENTS_FILE_NAME),
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Execute worktree mode completion
|
|
89
|
-
*
|
|
90
|
-
* @param {WorktreeContext} context - Worktree mode context
|
|
91
|
-
* @returns {Promise<WorktreeResult>} Completion result
|
|
92
|
-
* @throws {Error} On validation or git operation failure
|
|
93
|
-
*/
|
|
94
|
-
export async function executeWorktreeCompletion(context) {
|
|
95
|
-
// Save original cwd for returning after UnsafeAny worktree operations.
|
|
96
|
-
// This must be captured BEFORE zombie recovery, which temporarily chdirs into the worktree.
|
|
97
|
-
const originalCwd = process.cwd();
|
|
98
|
-
const { id, args, docMain, title, isDocsOnly, worktreePath, maxCommitLength, validateStagedFiles,
|
|
99
|
-
// NOTE: recordTransactionState/rollbackTransaction removed in WU-1369 (atomic pattern)
|
|
100
|
-
} = context;
|
|
101
|
-
const worktreeMetadataPaths = resolveWorktreeMetadataPaths(worktreePath, id);
|
|
102
|
-
const metadataWUPath = worktreeMetadataPaths.wuPath;
|
|
103
|
-
// Read WU YAML and validate current state
|
|
104
|
-
const docForUpdate = readWU(metadataWUPath, id);
|
|
105
|
-
// Check for zombie state (recovery mode)
|
|
106
|
-
// WU-1440: If zombie state detected, reset worktree YAML to in_progress
|
|
107
|
-
// and continue with normal flow (don't commit directly to main)
|
|
108
|
-
if (detectZombieState(docForUpdate, worktreePath)) {
|
|
109
|
-
console.log(`\n${RECOVERY.DETECTED}`);
|
|
110
|
-
// WU-1335: Check recovery attempt count to prevent infinite loops
|
|
111
|
-
const attemptCount = getRecoveryAttemptCount(id);
|
|
112
|
-
if (shouldEscalateToManualIntervention(attemptCount)) {
|
|
113
|
-
console.log(`\n${BOX.TOP}`);
|
|
114
|
-
console.log(`${BOX.SIDE} RECOVERY LOOP DETECTED - MANUAL INTERVENTION REQUIRED`);
|
|
115
|
-
console.log(BOX.MID);
|
|
116
|
-
console.log(`${BOX.SIDE} WU: ${id}`);
|
|
117
|
-
console.log(`${BOX.SIDE} Recovery attempts: ${attemptCount} (max: ${MAX_RECOVERY_ATTEMPTS})`);
|
|
118
|
-
console.log(BOX.SIDE);
|
|
119
|
-
console.log(`${BOX.SIDE} Automatic recovery has failed multiple times.`);
|
|
120
|
-
console.log(`${BOX.SIDE} Manual steps required:`);
|
|
121
|
-
console.log(BOX.SIDE);
|
|
122
|
-
console.log(`${BOX.SIDE} 1. cd ${worktreePath}`);
|
|
123
|
-
console.log(`${BOX.SIDE} 2. Reset WU YAML status to in_progress manually`);
|
|
124
|
-
console.log(`${BOX.SIDE} 3. git add && git commit`);
|
|
125
|
-
console.log(`${BOX.SIDE} 4. Return to main and retry wu:done`);
|
|
126
|
-
console.log(BOX.SIDE);
|
|
127
|
-
console.log(`${BOX.SIDE} Or reset the recovery counter:`);
|
|
128
|
-
console.log(`${BOX.SIDE} rm .lumenflow/recovery/${id}.recovery`);
|
|
129
|
-
console.log(BOX.BOT);
|
|
130
|
-
throw createRecoveryError(`Recovery loop detected for ${id} after ${attemptCount} attempts. Manual intervention required.`, { wuId: id, attemptCount, maxAttempts: MAX_RECOVERY_ATTEMPTS });
|
|
131
|
-
}
|
|
132
|
-
// Increment attempt counter before trying recovery
|
|
133
|
-
const newAttemptCount = incrementRecoveryAttempt(id);
|
|
134
|
-
console.log(`${LOG_PREFIX.DONE} Recovery attempt ${newAttemptCount}/${MAX_RECOVERY_ATTEMPTS} (WU-1335)`);
|
|
135
|
-
console.log(RECOVERY.RESUMING);
|
|
136
|
-
// WU-1749: Squash previous completion attempts before recovery
|
|
137
|
-
// This prevents "rebase hell" where multiple completion commits accumulate
|
|
138
|
-
// during failed retry attempts
|
|
139
|
-
// WU-1541: Use createGitForPath instead of process.chdir
|
|
140
|
-
try {
|
|
141
|
-
const gitWorktree = createGitForPath(worktreePath);
|
|
142
|
-
const squashResult = await prepareRecoveryWithSquash(id, gitWorktree);
|
|
143
|
-
if (squashResult.squashedCount > 0) {
|
|
144
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Squashed ${squashResult.squashedCount} previous completion attempt(s)`);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
catch (squashError) {
|
|
148
|
-
// Non-fatal: Log and continue with recovery
|
|
149
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Could not squash previous attempts: ${getErrorMessage(squashError)}`);
|
|
150
|
-
}
|
|
151
|
-
console.log(`${LOG_PREFIX.DONE} WU-1440: Resetting worktree YAML to in_progress for recovery flow...`);
|
|
152
|
-
// Reset the worktree YAML to in_progress (mutates docForUpdate)
|
|
153
|
-
resetWorktreeYAMLForRecovery({ worktreePath, id, doc: docForUpdate });
|
|
154
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Recovery reset complete - continuing normal flow`);
|
|
155
|
-
// Continue with normal flow - don't return early
|
|
156
|
-
// docForUpdate is now status=in_progress, so normal flow will work
|
|
157
|
-
}
|
|
158
|
-
// Capture status AFTER potential zombie recovery reset
|
|
159
|
-
const currentStatus = docForUpdate.status || WU_STATUS.IN_PROGRESS;
|
|
160
|
-
// Validate state transition
|
|
161
|
-
assertTransition(currentStatus, WU_STATUS.DONE, id);
|
|
162
|
-
// WU-1577: Abort early if local main is behind origin/main.
|
|
163
|
-
// This prevents metadata leaks: if merge succeeds but push fails because
|
|
164
|
-
// main is behind, wu-events.jsonl/backlog/status would leak onto local main.
|
|
165
|
-
// Must run BEFORE transaction to guarantee no files are modified.
|
|
166
|
-
await ensureMainNotBehindOrigin(originalCwd, id);
|
|
167
|
-
// WU-1369: Create atomic transaction for metadata updates
|
|
168
|
-
// This ensures NO files are modified if UnsafeAny validation fails
|
|
169
|
-
const transaction = new WUTransaction(id);
|
|
170
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Transaction BEGIN - atomic pattern (WU-1369)`);
|
|
171
|
-
// Save original cwd for returning after worktree operations
|
|
172
|
-
let merged = false;
|
|
173
|
-
let prUrl = null;
|
|
174
|
-
// WU-1943: Track pre-commit SHA and git commit state for rollback on merge failure
|
|
175
|
-
let preCommitSha = null;
|
|
176
|
-
let gitCommitMade = false;
|
|
177
|
-
// WU-2310: Track snapshot for file rollback on git commit failure
|
|
178
|
-
/** @type {Map<string, string|null>|null} */
|
|
179
|
-
let transactionSnapshot = null;
|
|
180
|
-
let stagedMetadataAllowlist;
|
|
181
|
-
let initiativeMetadataPath;
|
|
182
|
-
try {
|
|
183
|
-
// WU-1541: Use explicit worktree paths and git adapter instead of process.chdir
|
|
184
|
-
console.log(`\n${LOG_PREFIX.DONE} Updating metadata in worktree: ${worktreePath}`);
|
|
185
|
-
const worktreeGit = createGitForPath(worktreePath);
|
|
186
|
-
// WU-1563: Use absolute metadata paths rooted in worktreePath.
|
|
187
|
-
const workingWUPath = worktreeMetadataPaths.wuPath;
|
|
188
|
-
const workingStatusPath = worktreeMetadataPaths.statusPath;
|
|
189
|
-
const workingBacklogPath = worktreeMetadataPaths.backlogPath;
|
|
190
|
-
const workingStampsDir = worktreeMetadataPaths.stampsDir;
|
|
191
|
-
const workingStampPath = worktreeMetadataPaths.stampPath;
|
|
192
|
-
// ======================================================================
|
|
193
|
-
// PHASE 1: RUN ALL VALIDATIONS FIRST (before UnsafeAny file writes)
|
|
194
|
-
// WU-1369: This ensures no partial state on validation failure
|
|
195
|
-
// WU-1811: Validate and normalize YAML before gates/merge
|
|
196
|
-
// ======================================================================
|
|
197
|
-
console.log(`${LOG_PREFIX.DONE} Running validations (no writes until all pass)...`);
|
|
198
|
-
// WU-1811: Validate and normalize WU YAML schema with fixable corrections
|
|
199
|
-
// This catches schema issues early and auto-fixes normalizable problems
|
|
200
|
-
const normalizeResult = validateAndNormalizeWUYAML(docForUpdate);
|
|
201
|
-
if (!normalizeResult.valid) {
|
|
202
|
-
throw createValidationError(`WU YAML validation failed:\n - ${normalizeResult.errors.join('\n - ')}\n\nNext step: Fix the validation errors in ${workingWUPath} and rerun wu:done`, { wuId: id });
|
|
203
|
-
}
|
|
204
|
-
// WU-1811: If normalizations were applied, write back to YAML file
|
|
205
|
-
if (normalizeResult.wasNormalized) {
|
|
206
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} WU-1811: Applying auto-normalisations to WU YAML...`);
|
|
207
|
-
writeWU(workingWUPath, normalizeResult.normalized);
|
|
208
|
-
// Update docForUpdate to use normalized data for subsequent processing
|
|
209
|
-
Object.assign(docForUpdate, normalizeResult.normalized);
|
|
210
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} WU YAML normalised and saved`);
|
|
211
|
-
}
|
|
212
|
-
// Validate done-specific completeness (uses normalized data)
|
|
213
|
-
const normalizedWU = normalizeResult.normalized ?? docForUpdate;
|
|
214
|
-
const completenessResult = validateDoneWU(normalizedWU);
|
|
215
|
-
if (!completenessResult.valid) {
|
|
216
|
-
throw createValidationError(`Cannot mark WU as done - spec incomplete:\n ${completenessResult.errors.join('\n ')}\n\nNext step: Update ${workingWUPath} to meet completion requirements and rerun wu:done`, { wuId: id });
|
|
217
|
-
}
|
|
218
|
-
// WU-1153: Validate code_paths are committed before metadata transaction
|
|
219
|
-
// This prevents lost work from metadata rollbacks after code commits
|
|
220
|
-
console.log(`${LOG_PREFIX.DONE} Checking code_paths commit status (WU-1153)...`);
|
|
221
|
-
// WU-1541: Use worktreeGit (explicit baseDir) instead of getGitForCwd()
|
|
222
|
-
const codePathsResult = await validateCodePathsCommittedBeforeDone(normalizedWU, worktreeGit, { abortOnFailure: false });
|
|
223
|
-
if (!codePathsResult.valid) {
|
|
224
|
-
const errorMessage = await import('./wu-done-validation.js').then((m) => m.buildCodePathsCommittedErrorMessage(id, codePathsResult.uncommittedPaths));
|
|
225
|
-
throw createValidationError(errorMessage, { wuId: id });
|
|
226
|
-
}
|
|
227
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} All validations passed`);
|
|
228
|
-
// ======================================================================
|
|
229
|
-
// PHASE 2: COLLECT ALL CHANGES TO TRANSACTION (in memory, no writes)
|
|
230
|
-
// WU-1369: Atomic collection - all changes gathered before UnsafeAny writes
|
|
231
|
-
// ======================================================================
|
|
232
|
-
// WU-1574: Now async
|
|
233
|
-
await collectMetadataToTransaction({
|
|
234
|
-
id,
|
|
235
|
-
title,
|
|
236
|
-
doc: docForUpdate,
|
|
237
|
-
wuPath: workingWUPath,
|
|
238
|
-
statusPath: workingStatusPath,
|
|
239
|
-
backlogPath: workingBacklogPath,
|
|
240
|
-
stampPath: workingStampPath,
|
|
241
|
-
transaction,
|
|
242
|
-
projectRoot: worktreePath,
|
|
243
|
-
});
|
|
244
|
-
const pendingWrites = transaction.getPendingWrites();
|
|
245
|
-
stagedMetadataAllowlist = pendingWrites
|
|
246
|
-
.map((write) => path.relative(worktreePath, write.path).split(path.sep).join('/'))
|
|
247
|
-
.filter((relativePath) => Boolean(relativePath) && !relativePath.startsWith('..') && !path.isAbsolute(relativePath));
|
|
248
|
-
const initiativeMetadataWrite = pendingWrites.find((write) => write.description === 'initiative YAML');
|
|
249
|
-
initiativeMetadataPath = initiativeMetadataWrite?.path ?? null;
|
|
250
|
-
// Validate the transaction itself
|
|
251
|
-
const txValidation = transaction.validate();
|
|
252
|
-
if (!txValidation.valid) {
|
|
253
|
-
throw createError(ErrorCodes.TRANSACTION_ERROR, `Transaction validation failed:\n ${txValidation.errors.join('\n ')}`, { wuId: id });
|
|
254
|
-
}
|
|
255
|
-
// ======================================================================
|
|
256
|
-
// PHASE 3: ATOMIC COMMIT (write all files at once)
|
|
257
|
-
// WU-1369: This is the only point where files are written
|
|
258
|
-
// WU-2310: Capture snapshot BEFORE commit for rollback on git commit failure
|
|
259
|
-
// ======================================================================
|
|
260
|
-
// WU-2310: Capture file state before transaction commit
|
|
261
|
-
// This allows rollback if git commit fails AFTER files are written
|
|
262
|
-
// WU-1541: Use absolute path via worktree metadata paths instead of relative path after chdir
|
|
263
|
-
const workingEventsPath = worktreeMetadataPaths.eventsPath;
|
|
264
|
-
const pathsToSnapshot = Array.from(new Set(transaction.getPendingWrites().map((write) => write.path)));
|
|
265
|
-
transactionSnapshot = createTransactionSnapshot(pathsToSnapshot);
|
|
266
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} WU-2310: Snapshot captured for rollback`);
|
|
267
|
-
const commitResult = transaction.commit();
|
|
268
|
-
if (!commitResult.success) {
|
|
269
|
-
throw createError(ErrorCodes.TRANSACTION_ERROR, `Transaction commit failed - some files not written:\n ${commitResult.failed.map((f) => f.path).join('\n ')}`, { wuId: id, written: commitResult.written, failed: commitResult.failed });
|
|
270
|
-
}
|
|
271
|
-
// ======================================================================
|
|
272
|
-
// WU-1617: POST-MUTATION VALIDATION
|
|
273
|
-
// Verify files written by tx.commit() are valid (completed_at, locked, stamp)
|
|
274
|
-
// ======================================================================
|
|
275
|
-
const postMutationResult = validatePostMutation({
|
|
276
|
-
id,
|
|
277
|
-
wuPath: workingWUPath,
|
|
278
|
-
stampPath: workingStampPath,
|
|
279
|
-
eventsPath: workingEventsPath,
|
|
280
|
-
});
|
|
281
|
-
if (!postMutationResult.valid) {
|
|
282
|
-
throw createValidationError(`Post-mutation validation failed:\n ${postMutationResult.errors.join('\n ')}`, { wuId: id, errors: postMutationResult.errors });
|
|
283
|
-
}
|
|
284
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Post-mutation validation passed (WU-1617)`);
|
|
285
|
-
// ======================================================================
|
|
286
|
-
// PHASE 4: GIT OPERATIONS (stage, format, commit)
|
|
287
|
-
// Files are now written - proceed with git operations
|
|
288
|
-
// ======================================================================
|
|
289
|
-
// ======================================================================
|
|
290
|
-
// WU-1061: Regenerate docs if doc-source files changed
|
|
291
|
-
// This runs BEFORE stageAndFormatMetadata to include doc outputs
|
|
292
|
-
// in the single atomic commit
|
|
293
|
-
// Uses main as base to detect changes introduced by this WU
|
|
294
|
-
// ======================================================================
|
|
295
|
-
await maybeRegenerateAndStageDocs({
|
|
296
|
-
baseBranch: BRANCHES.MAIN,
|
|
297
|
-
repoRoot: worktreePath,
|
|
298
|
-
});
|
|
299
|
-
// Stage and format files
|
|
300
|
-
// WU-1541: Pass worktreeGit and worktreePath to avoid process.chdir dependency
|
|
301
|
-
await stageAndFormatMetadata({
|
|
302
|
-
id,
|
|
303
|
-
wuPath: workingWUPath,
|
|
304
|
-
statusPath: workingStatusPath,
|
|
305
|
-
backlogPath: workingBacklogPath,
|
|
306
|
-
stampsDir: workingStampsDir,
|
|
307
|
-
initiativePath: initiativeMetadataPath,
|
|
308
|
-
gitAdapter: worktreeGit,
|
|
309
|
-
repoRoot: worktreePath,
|
|
310
|
-
});
|
|
311
|
-
// Validate staged files
|
|
312
|
-
await validateStagedFiles(id, isDocsOnly, { metadataAllowlist: stagedMetadataAllowlist });
|
|
313
|
-
// ======================================================================
|
|
314
|
-
// WU-1584 Fix #1: Squash previous completion attempts before new commit
|
|
315
|
-
// This prevents N duplicate commits when wu:done is retried N times
|
|
316
|
-
// WU-1541: Use worktreeGit (explicit baseDir) instead of getGitForCwd()
|
|
317
|
-
// ======================================================================
|
|
318
|
-
const previousAttempts = await countPreviousCompletionAttempts(id, worktreeGit);
|
|
319
|
-
if (previousAttempts > 0) {
|
|
320
|
-
const squashResult = await squashPreviousCompletionAttempts(id, previousAttempts, worktreeGit);
|
|
321
|
-
if (squashResult.squashed) {
|
|
322
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} WU-1584: Squashed ${squashResult.count} previous attempt(s) - single commit will be created`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
const laneBranch = await defaultBranchFrom(docForUpdate);
|
|
326
|
-
// Generate commit message and commit
|
|
327
|
-
const msg = generateCommitMessage(id, title, maxCommitLength, {
|
|
328
|
-
branch: laneBranch ?? undefined,
|
|
329
|
-
worktreePath,
|
|
330
|
-
});
|
|
331
|
-
await assertNoConflictArtifactsInIndex(worktreeGit);
|
|
332
|
-
// WU-1943: Capture pre-commit SHA for rollback on merge failure
|
|
333
|
-
preCommitSha = await worktreeGit.getCommitHash('HEAD');
|
|
334
|
-
await worktreeGit.commit(msg);
|
|
335
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Metadata committed in worktree`);
|
|
336
|
-
// WU-1943: Track that git commit was made (needed for rollback decision)
|
|
337
|
-
gitCommitMade = true;
|
|
338
|
-
// WU-1541: No need to chdir back - we never changed directory
|
|
339
|
-
// Determine if PR mode is enabled
|
|
340
|
-
const prModeEnabled = isPRModeEnabled(docMain, args);
|
|
341
|
-
if (!args.noMerge) {
|
|
342
|
-
// Use docForUpdate (from worktree) for branch calculation - docMain may be incomplete (ref: WU-1280)
|
|
343
|
-
if (laneBranch && (await branchExists(laneBranch))) {
|
|
344
|
-
if (prModeEnabled) {
|
|
345
|
-
// PR mode: Create PR instead of auto-merge
|
|
346
|
-
const prResult = await createPR({
|
|
347
|
-
branch: laneBranch,
|
|
348
|
-
id,
|
|
349
|
-
title,
|
|
350
|
-
doc: docMain,
|
|
351
|
-
draft: args.prDraft,
|
|
352
|
-
});
|
|
353
|
-
if (prResult.success && prResult.prUrl) {
|
|
354
|
-
printPRCreatedMessage(prResult.prUrl, id);
|
|
355
|
-
prUrl = prResult.prUrl;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
// Default mode: Auto-merge with pre-flight checks
|
|
360
|
-
console.log(PREFLIGHT.RUNNING);
|
|
361
|
-
// Check branch drift (WU-1370: graduated warnings)
|
|
362
|
-
const commitsBehind = await checkBranchDrift(laneBranch);
|
|
363
|
-
if (commitsBehind > 0) {
|
|
364
|
-
const driftLevel = getDriftLevel(commitsBehind);
|
|
365
|
-
if (driftLevel === DRIFT_LEVELS.WARNING) {
|
|
366
|
-
console.log(PREFLIGHT.BRANCH_DRIFT_WARNING(commitsBehind));
|
|
367
|
-
}
|
|
368
|
-
else if (driftLevel === DRIFT_LEVELS.INFO) {
|
|
369
|
-
console.log(PREFLIGHT.BRANCH_DRIFT_INFO(commitsBehind));
|
|
370
|
-
}
|
|
371
|
-
else if (driftLevel === DRIFT_LEVELS.OK) {
|
|
372
|
-
// No message needed for OK level
|
|
373
|
-
console.log(PREFLIGHT.BRANCH_BEHIND(commitsBehind, THRESHOLDS.BRANCH_DRIFT_MAX));
|
|
374
|
-
}
|
|
375
|
-
// ERROR level is handled by checkBranchDrift throwing an error
|
|
376
|
-
}
|
|
377
|
-
// Check if branch is already merged
|
|
378
|
-
const alreadyMerged = await isBranchAlreadyMerged(laneBranch);
|
|
379
|
-
if (alreadyMerged) {
|
|
380
|
-
console.log(PREFLIGHT.ALREADY_MERGED);
|
|
381
|
-
console.log(PREFLIGHT.ALREADY_MERGED_EXPLANATION);
|
|
382
|
-
}
|
|
383
|
-
else {
|
|
384
|
-
// Check for divergence and conflicts (auto-rebase if enabled - WU-1303)
|
|
385
|
-
// noAutoRebase is true when --no-auto-rebase flag is passed
|
|
386
|
-
// WU-1371: Pass wuId for post-rebase artifact cleanup
|
|
387
|
-
await checkBranchDivergence(laneBranch, {
|
|
388
|
-
autoRebase: args.noAutoRebase !== true,
|
|
389
|
-
worktreePath,
|
|
390
|
-
wuId: id,
|
|
391
|
-
});
|
|
392
|
-
// WU-1384: Check for merge commits (GitHub requires linear history)
|
|
393
|
-
// Must run AFTER divergence check, as divergence rebase may eliminate merge commits
|
|
394
|
-
// Catches case where user did 'git merge main' instead of rebase
|
|
395
|
-
// WU-1371: Pass wuId for post-rebase artifact cleanup
|
|
396
|
-
await checkMergeCommits(laneBranch, {
|
|
397
|
-
autoRebase: args.noAutoRebase !== true,
|
|
398
|
-
worktreePath,
|
|
399
|
-
wuId: id,
|
|
400
|
-
});
|
|
401
|
-
await checkMergeConflicts(laneBranch);
|
|
402
|
-
// WU-1456: Check for empty merge (warn if no work commits)
|
|
403
|
-
// WU-1460: Pass doc to enable code_paths blocker
|
|
404
|
-
await checkEmptyMerge(laneBranch, docForUpdate);
|
|
405
|
-
// WU-1574: Backlog repair removed - state store architecture eliminates duplicates
|
|
406
|
-
// Backlog.md is always regenerated from wu-events.jsonl, not parsed/modified
|
|
407
|
-
console.log(MERGE.STARTING(laneBranch));
|
|
408
|
-
// WU-1628: Route merge+push through atomic temp-worktree path.
|
|
409
|
-
await withMergeLock(id, async () => {
|
|
410
|
-
await withAtomicMerge({
|
|
411
|
-
id,
|
|
412
|
-
laneBranch,
|
|
413
|
-
command: `pnpm wu:done --id ${id}`,
|
|
414
|
-
logPrefix: LOG_PREFIX.DONE,
|
|
415
|
-
});
|
|
416
|
-
});
|
|
417
|
-
console.log(MERGE.ATOMIC_SUCCESS);
|
|
418
|
-
merged = true;
|
|
419
|
-
console.log(MERGE.PUSHED(REMOTES.ORIGIN, BRANCHES.MAIN));
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
// Branch not found - fail loudly (use docForUpdate which has complete lane info)
|
|
425
|
-
console.error(`\n${BOX.TOP}`);
|
|
426
|
-
console.error(`${BOX.SIDE} MERGE FAILED: Lane branch not found`);
|
|
427
|
-
console.error(BOX.MID);
|
|
428
|
-
console.error(`${BOX.SIDE} Expected branch: ${laneBranch || '(null)'}`);
|
|
429
|
-
console.error(`${BOX.SIDE} WU lane: "${docForUpdate.lane}"`);
|
|
430
|
-
console.error(`${BOX.SIDE} WU id: "${docForUpdate.id}"`);
|
|
431
|
-
console.error(BOX.BOT);
|
|
432
|
-
throw createError(ErrorCodes.BRANCH_ERROR, `Lane branch not found: ${laneBranch}`, {
|
|
433
|
-
laneBranch,
|
|
434
|
-
wuId: docForUpdate.id,
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
// WU-1335: Clear recovery attempts on successful completion
|
|
439
|
-
clearRecoveryAttempts(id);
|
|
440
|
-
// WU-1498: Passive lane telemetry (fail-open)
|
|
441
|
-
await emitLaneSignalForCompletion({
|
|
442
|
-
wuId: id,
|
|
443
|
-
lane: docForUpdate.lane,
|
|
444
|
-
laneBranch,
|
|
445
|
-
completionMode: WU_DONE_COMPLETION_MODES.WORKTREE,
|
|
446
|
-
});
|
|
447
|
-
// WU-1811: All steps succeeded - worktree cleanup is safe
|
|
448
|
-
return {
|
|
449
|
-
success: true,
|
|
450
|
-
committed: true,
|
|
451
|
-
pushed: !prModeEnabled,
|
|
452
|
-
merged,
|
|
453
|
-
prUrl,
|
|
454
|
-
cleanupSafe: true,
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
catch (err) {
|
|
458
|
-
const worktreeError = err instanceof Error ? err : new Error(String(err));
|
|
459
|
-
// WU-1541: No need to restore directory - we never changed it
|
|
460
|
-
// WU-1369: Atomic transaction pattern
|
|
461
|
-
// - If error occurred BEFORE transaction.commit() → no files were written
|
|
462
|
-
// - If error occurred AFTER transaction.commit() → files written, need manual recovery
|
|
463
|
-
const wasCommitted = transaction.isCommitted;
|
|
464
|
-
// WU-1811: Provide actionable single next step based on failure state
|
|
465
|
-
if (!wasCommitted) {
|
|
466
|
-
// Abort transaction (discards pending changes, no files were written)
|
|
467
|
-
transaction.abort();
|
|
468
|
-
console.log(`\n${BOX.TOP}`);
|
|
469
|
-
console.log(`${BOX.SIDE} WU:DONE FAILED - NO FILES MODIFIED (atomic pattern)`);
|
|
470
|
-
console.log(BOX.MID);
|
|
471
|
-
console.log(`${BOX.SIDE} Error: ${worktreeError.message}`);
|
|
472
|
-
console.log(BOX.SIDE);
|
|
473
|
-
console.log(`${BOX.SIDE} WU-1369: Transaction aborted before UnsafeAny writes.`);
|
|
474
|
-
console.log(`${BOX.SIDE} WU-1811: Worktree preserved for recovery.`);
|
|
475
|
-
console.log(`${BOX.SIDE} Worktree: ${worktreePath}`);
|
|
476
|
-
console.log(BOX.MID);
|
|
477
|
-
console.log(`${BOX.SIDE} NEXT STEP: Fix the error and rerun:`);
|
|
478
|
-
console.log(`${BOX.SIDE} pnpm wu:done --id ${id}`);
|
|
479
|
-
console.log(BOX.BOT);
|
|
480
|
-
}
|
|
481
|
-
else {
|
|
482
|
-
// Transaction was committed but git operations failed
|
|
483
|
-
// Files were written - need rollback or recovery
|
|
484
|
-
// WU-2310: Rollback file changes if git commit failed (before branch commit was made)
|
|
485
|
-
// This prevents zombie states where status=done but commit never happened
|
|
486
|
-
let fileRollbackSuccess = false;
|
|
487
|
-
if (!gitCommitMade && transactionSnapshot) {
|
|
488
|
-
console.log(`\n${LOG_PREFIX.DONE} ${EMOJI.WARNING} WU-2310: Git commit failed after transaction - rolling back files...`);
|
|
489
|
-
try {
|
|
490
|
-
// WU-1541: restoreFromSnapshot uses absolute paths from the snapshot,
|
|
491
|
-
// so no chdir needed - it writes to the correct worktree paths directly
|
|
492
|
-
const rollbackResult = restoreFromSnapshot(transactionSnapshot);
|
|
493
|
-
if (rollbackResult.errors.length === 0) {
|
|
494
|
-
fileRollbackSuccess = true;
|
|
495
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} WU-2310: File rollback complete - ${rollbackResult.restored.length} files restored`);
|
|
496
|
-
}
|
|
497
|
-
else {
|
|
498
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} WU-2310: Partial file rollback - ${rollbackResult.restored.length} restored, ${rollbackResult.errors.length} failed`);
|
|
499
|
-
for (const e of rollbackResult.errors) {
|
|
500
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.FAILURE} ${e.path}: ${e.error}`);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
catch (rollbackErr) {
|
|
505
|
-
// Log but don't fail - rollback is best-effort
|
|
506
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} WU-2310: File rollback error: ${getErrorMessage(rollbackErr)}`);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
// WU-1943: If git commit was made but merge failed, rollback the branch
|
|
510
|
-
// This prevents zombie states where branch shows "done" but wasn't merged
|
|
511
|
-
if (gitCommitMade && preCommitSha) {
|
|
512
|
-
console.log(`\n${LOG_PREFIX.DONE} ${EMOJI.WARNING} Merge failed after git commit - attempting branch rollback...`);
|
|
513
|
-
try {
|
|
514
|
-
// WU-1541: Use createGitForPath instead of chdir + getGitForCwd
|
|
515
|
-
const gitWorktreeForRollback = createGitForPath(worktreePath);
|
|
516
|
-
await rollbackBranchOnMergeFailure(gitWorktreeForRollback, preCommitSha, id);
|
|
517
|
-
}
|
|
518
|
-
catch (rollbackErr) {
|
|
519
|
-
// Log but don't fail - rollback is best-effort
|
|
520
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Rollback error: ${getErrorMessage(rollbackErr)}`);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
console.log(`\n${BOX.TOP}`);
|
|
524
|
-
if (fileRollbackSuccess) {
|
|
525
|
-
console.log(`${BOX.SIDE} WU:DONE FAILED - FILES ROLLED BACK (WU-2310)`);
|
|
526
|
-
console.log(BOX.MID);
|
|
527
|
-
console.log(`${BOX.SIDE} Error: ${worktreeError.message}`);
|
|
528
|
-
console.log(BOX.SIDE);
|
|
529
|
-
console.log(`${BOX.SIDE} WU-2310: Transaction files were rolled back to pre-commit state.`);
|
|
530
|
-
console.log(`${BOX.SIDE} Worktree is now consistent (status=in_progress, no stamp).`);
|
|
531
|
-
}
|
|
532
|
-
else {
|
|
533
|
-
console.log(`${BOX.SIDE} WU:DONE FAILED - PARTIAL STATE (post-transaction)`);
|
|
534
|
-
console.log(BOX.MID);
|
|
535
|
-
console.log(`${BOX.SIDE} Error: ${worktreeError.message}`);
|
|
536
|
-
console.log(BOX.SIDE);
|
|
537
|
-
console.log(`${BOX.SIDE} Metadata files were written, but git operations failed.`);
|
|
538
|
-
if (gitCommitMade && preCommitSha) {
|
|
539
|
-
console.log(`${BOX.SIDE} WU-1943: Branch rolled back to pre-commit state.`);
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
console.log(`${BOX.SIDE} WU-1811: Worktree preserved for recovery.`);
|
|
543
|
-
console.log(`${BOX.SIDE} Worktree: ${worktreePath}`);
|
|
544
|
-
console.log(BOX.MID);
|
|
545
|
-
console.log(`${BOX.SIDE} NEXT STEP: Rerun wu:done (idempotent recovery):`);
|
|
546
|
-
console.log(`${BOX.SIDE} pnpm wu:done --id ${id}`);
|
|
547
|
-
console.log(BOX.BOT);
|
|
548
|
-
}
|
|
549
|
-
// WU-1811: Attach cleanupSafe flag to error for caller to check
|
|
550
|
-
worktreeError.cleanupSafe = false;
|
|
551
|
-
throw worktreeError;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
/**
|
|
555
|
-
* Check for branch drift (commits behind main)
|
|
556
|
-
* WU-755 pre-flight check
|
|
557
|
-
*
|
|
558
|
-
* @param {string} branch - Lane branch name
|
|
559
|
-
* @returns {Promise<number>} Number of commits behind main
|
|
560
|
-
*/
|
|
561
|
-
export async function checkBranchDrift(branch) {
|
|
562
|
-
const gitAdapter = getGitForCwd();
|
|
563
|
-
try {
|
|
564
|
-
const counts = await gitAdapter.revList([
|
|
565
|
-
'--left-right',
|
|
566
|
-
'--count',
|
|
567
|
-
`${BRANCHES.MAIN}...${branch}`,
|
|
568
|
-
]);
|
|
569
|
-
const [mainAheadRaw] = counts.split(/\s+/).map(Number);
|
|
570
|
-
const mainAhead = typeof mainAheadRaw === 'number' && Number.isFinite(mainAheadRaw) ? mainAheadRaw : 0;
|
|
571
|
-
if (mainAhead > THRESHOLDS.BRANCH_DRIFT_MAX) {
|
|
572
|
-
throw createError(ErrorCodes.GIT_ERROR, PREFLIGHT.BRANCH_DRIFT_ERROR(mainAhead, THRESHOLDS.BRANCH_DRIFT_MAX, REMOTES.ORIGIN, BRANCHES.MAIN), { branch, commitsBehind: mainAhead, threshold: THRESHOLDS.BRANCH_DRIFT_MAX });
|
|
573
|
-
}
|
|
574
|
-
return mainAhead;
|
|
575
|
-
}
|
|
576
|
-
catch (e) {
|
|
577
|
-
if (isErrorWithCode(e, ErrorCodes.GIT_ERROR))
|
|
578
|
-
throw e;
|
|
579
|
-
console.warn(`${LOG_PREFIX.DONE} Warning: Could not check branch drift: ${getErrorMessage(e)}`);
|
|
580
|
-
return 0;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
/**
|
|
584
|
-
* List of append-only files that can be auto-resolved during rebase
|
|
585
|
-
* WU-1749 Bug 3: These files can safely have conflicts resolved by keeping both additions
|
|
586
|
-
*
|
|
587
|
-
* Uses WU_PATHS constants and WU_EVENTS_FILE_NAME to avoid hardcoded path strings
|
|
588
|
-
* that would break if paths are rearranged.
|
|
589
|
-
*/
|
|
590
|
-
const APPEND_ONLY_FILES = [
|
|
591
|
-
// State store events file (append-only by design) - WU-1430: Use centralized constant
|
|
592
|
-
path.join(LUMENFLOW_PATHS.STATE_DIR, WU_EVENTS_FILE_NAME),
|
|
593
|
-
// Status and backlog are generated from state store but may conflict during rebase
|
|
594
|
-
WU_PATHS.STATUS(),
|
|
595
|
-
WU_PATHS.BACKLOG(),
|
|
596
|
-
];
|
|
597
|
-
// WU-1430: Use centralized constant
|
|
598
|
-
const WU_EVENTS_PATH = path.join(LUMENFLOW_PATHS.STATE_DIR, WU_EVENTS_FILE_NAME);
|
|
599
|
-
const WU_EVENTS_PATH_POSIX = WU_EVENTS_PATH.split(path.sep).join('/');
|
|
600
|
-
const REBASE_CONFLICT_GIT = {
|
|
601
|
-
DIFF_UNMERGED_ARGS: [GIT_COMMANDS.DIFF, '--name-only', '--diff-filter=U'],
|
|
602
|
-
// Keep whitespace checking disabled intentionally: we only want structural conflict artifacts
|
|
603
|
-
// (leftover merge markers), not generic whitespace findings in this safety check.
|
|
604
|
-
DIFF_CHECK_ARGS: [
|
|
605
|
-
'-c',
|
|
606
|
-
'core.whitespace=',
|
|
607
|
-
GIT_COMMANDS.DIFF,
|
|
608
|
-
'--check',
|
|
609
|
-
'--cached',
|
|
610
|
-
'--',
|
|
611
|
-
],
|
|
612
|
-
SHOW_OURS: (filePath) => ['show', `:2:${filePath}`],
|
|
613
|
-
SHOW_THEIRS: (filePath) => ['show', `:3:${filePath}`],
|
|
614
|
-
CHECKOUT_THEIRS: (filePath) => ['checkout', '--theirs', filePath],
|
|
615
|
-
};
|
|
616
|
-
const REBASE_CONFLICT_MESSAGES = {
|
|
617
|
-
UNMERGED_FILES_REMAIN: (files) => `Unmerged files remain in index:\n ${files}\nResolve conflicts before continuing.`,
|
|
618
|
-
STAGED_ARTIFACTS_OR_CHECK_FAILURE: (details) => `git diff --check reported conflict artifacts or failed to run cleanly. Resolve conflicts before continuing.\n${details}`,
|
|
619
|
-
};
|
|
620
|
-
const REBASE_CONFLICT_LIMITS = {
|
|
621
|
-
MAX_CONTINUE_ATTEMPTS: 6,
|
|
622
|
-
};
|
|
623
|
-
function toPosixPath(filePath) {
|
|
624
|
-
return filePath.split(path.sep).join('/');
|
|
625
|
-
}
|
|
626
|
-
function isAppendOnlyConflictFile(filePath) {
|
|
627
|
-
const normalizedFilePath = toPosixPath(filePath);
|
|
628
|
-
return APPEND_ONLY_FILES.some((appendFile) => {
|
|
629
|
-
const normalizedAppendFile = toPosixPath(appendFile);
|
|
630
|
-
return (normalizedFilePath === normalizedAppendFile ||
|
|
631
|
-
normalizedFilePath.endsWith(`/${normalizedAppendFile}`));
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
|
-
function normalizeEventForKey(event) {
|
|
635
|
-
const normalized = {};
|
|
636
|
-
for (const key of Object.keys(event).sort()) {
|
|
637
|
-
normalized[key] = event[key];
|
|
638
|
-
}
|
|
639
|
-
return normalized;
|
|
640
|
-
}
|
|
641
|
-
function parseWuEventsJsonl(content, sourceLabel) {
|
|
642
|
-
const lines = String(content)
|
|
643
|
-
.split('\n')
|
|
644
|
-
.map((line) => line.trim())
|
|
645
|
-
.filter(Boolean);
|
|
646
|
-
return lines.map((line, index) => {
|
|
647
|
-
let parsed;
|
|
648
|
-
try {
|
|
649
|
-
parsed = JSON.parse(line);
|
|
650
|
-
}
|
|
651
|
-
catch (error) {
|
|
652
|
-
throw new Error(`wu-events.jsonl ${sourceLabel} has malformed JSON on line ${index + 1}: ${getErrorMessage(error)}`, { cause: error });
|
|
653
|
-
}
|
|
654
|
-
const validation = validateWUEvent(parsed);
|
|
655
|
-
if (!validation.success) {
|
|
656
|
-
const issues = validation.error.issues
|
|
657
|
-
.map((issue) => `${issue.path.join('.')}: ${issue.message}`)
|
|
658
|
-
.join(', ');
|
|
659
|
-
throw new Error(`wu-events.jsonl ${sourceLabel} has invalid event on line ${index + 1}: ${issues}`);
|
|
660
|
-
}
|
|
661
|
-
return { event: validation.data, line };
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
async function resolveWuEventsJsonlConflict(gitCwd, filePath, worktreePath) {
|
|
665
|
-
const ours = await gitCwd.raw(REBASE_CONFLICT_GIT.SHOW_OURS(filePath));
|
|
666
|
-
const theirs = await gitCwd.raw(REBASE_CONFLICT_GIT.SHOW_THEIRS(filePath));
|
|
667
|
-
const theirsEvents = parseWuEventsJsonl(theirs, 'theirs');
|
|
668
|
-
const oursEvents = parseWuEventsJsonl(ours, 'ours');
|
|
669
|
-
const seen = new Set();
|
|
670
|
-
const mergedLines = [];
|
|
671
|
-
for (const { event, line } of theirsEvents) {
|
|
672
|
-
const key = JSON.stringify(normalizeEventForKey(event));
|
|
673
|
-
if (seen.has(key))
|
|
674
|
-
continue;
|
|
675
|
-
seen.add(key);
|
|
676
|
-
mergedLines.push(line);
|
|
677
|
-
}
|
|
678
|
-
for (const { event, line } of oursEvents) {
|
|
679
|
-
const key = JSON.stringify(normalizeEventForKey(event));
|
|
680
|
-
if (seen.has(key))
|
|
681
|
-
continue;
|
|
682
|
-
seen.add(key);
|
|
683
|
-
mergedLines.push(line);
|
|
684
|
-
}
|
|
685
|
-
const resolvedPath = path.isAbsolute(filePath) ? filePath : path.join(worktreePath, filePath);
|
|
686
|
-
await writeFile(resolvedPath, mergedLines.join('\n') + '\n', 'utf-8');
|
|
687
|
-
await gitCwd.add(filePath);
|
|
688
|
-
}
|
|
689
|
-
async function assertNoConflictArtifactsInIndex(gitCwd, files, options = {}) {
|
|
690
|
-
const unresolvedFilesOutput = await gitCwd.raw([...REBASE_CONFLICT_GIT.DIFF_UNMERGED_ARGS]);
|
|
691
|
-
const unresolvedFiles = unresolvedFilesOutput
|
|
692
|
-
.split('\n')
|
|
693
|
-
.map((line) => line.trim())
|
|
694
|
-
.filter(Boolean);
|
|
695
|
-
if (unresolvedFiles.length > 0) {
|
|
696
|
-
throw new Error(REBASE_CONFLICT_MESSAGES.UNMERGED_FILES_REMAIN(unresolvedFiles.join('\n ')));
|
|
697
|
-
}
|
|
698
|
-
if (options.checkStaged === false) {
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
|
-
const checkArgs = [...REBASE_CONFLICT_GIT.DIFF_CHECK_ARGS];
|
|
702
|
-
if (files && files.length > 0) {
|
|
703
|
-
checkArgs.push(...files);
|
|
704
|
-
}
|
|
705
|
-
try {
|
|
706
|
-
const checkOutput = await gitCwd.raw(checkArgs);
|
|
707
|
-
if (checkOutput.trim().length > 0) {
|
|
708
|
-
throw new Error(checkOutput.trim());
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
catch (error) {
|
|
712
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
713
|
-
throw new Error(REBASE_CONFLICT_MESSAGES.STAGED_ARTIFACTS_OR_CHECK_FAILURE(message), {
|
|
714
|
-
cause: error,
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
/**
|
|
719
|
-
* Auto-resolve conflicts in append-only files during rebase
|
|
720
|
-
* WU-1749 Bug 3: Keeps both additions for append-only files
|
|
721
|
-
*
|
|
722
|
-
* @param {object} gitCwd - Git adapter instance
|
|
723
|
-
* @returns {Promise<{resolved: boolean, files: string[]}>} Resolution result
|
|
724
|
-
*/
|
|
725
|
-
async function autoResolveAppendOnlyConflicts(gitCwd, worktreePath) {
|
|
726
|
-
const resolvedFiles = [];
|
|
727
|
-
try {
|
|
728
|
-
// Use git's unmerged index view so AA/AU/UA/etc are all handled (not only UU).
|
|
729
|
-
const unmergedOutput = await gitCwd.raw([...REBASE_CONFLICT_GIT.DIFF_UNMERGED_ARGS]);
|
|
730
|
-
const conflictFiles = unmergedOutput
|
|
731
|
-
.split('\n')
|
|
732
|
-
.map((line) => line.trim())
|
|
733
|
-
.filter(Boolean);
|
|
734
|
-
for (const filePath of conflictFiles) {
|
|
735
|
-
// Check if this is an append-only file
|
|
736
|
-
const isAppendOnly = isAppendOnlyConflictFile(filePath);
|
|
737
|
-
if (isAppendOnly) {
|
|
738
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} Auto-resolving append-only conflict: ${filePath}`);
|
|
739
|
-
if (toPosixPath(filePath).endsWith(WU_EVENTS_PATH_POSIX)) {
|
|
740
|
-
// For the event log we must keep BOTH sides (loss breaks state machine).
|
|
741
|
-
// Merge strategy: union by event identity (validated), prefer theirs ordering then ours additions.
|
|
742
|
-
await resolveWuEventsJsonlConflict(gitCwd, filePath, worktreePath);
|
|
743
|
-
}
|
|
744
|
-
else {
|
|
745
|
-
// Backlog/status are derived; prefer main's version during rebase and regenerate later.
|
|
746
|
-
await gitCwd.raw(REBASE_CONFLICT_GIT.CHECKOUT_THEIRS(filePath));
|
|
747
|
-
await gitCwd.add(filePath);
|
|
748
|
-
}
|
|
749
|
-
resolvedFiles.push(filePath);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
return { resolved: resolvedFiles.length > 0, files: resolvedFiles };
|
|
753
|
-
}
|
|
754
|
-
catch (error) {
|
|
755
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Could not auto-resolve conflicts: ${getErrorMessage(error)}`);
|
|
756
|
-
return { resolved: false, files: [] };
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Auto-rebase branch onto main
|
|
761
|
-
* WU-1303: Auto-rebase on wu:done to handle diverged branches automatically
|
|
762
|
-
* WU-1371: Added wuId parameter for post-rebase artifact cleanup
|
|
763
|
-
* WU-1749 Bug 3: Auto-resolve append-only file conflicts during rebase
|
|
764
|
-
*
|
|
765
|
-
* @param {string} branch - Lane branch name
|
|
766
|
-
* @param {string} worktreePath - Path to worktree
|
|
767
|
-
* @param {string} [wuId] - WU ID for artifact cleanup (e.g., 'WU-1371')
|
|
768
|
-
* @returns {Promise<{success: boolean, error?: string}>} Rebase result
|
|
769
|
-
*/
|
|
770
|
-
export async function autoRebaseBranch(branch, worktreePath, wuId) {
|
|
771
|
-
console.log(REBASE.STARTING(branch, BRANCHES.MAIN));
|
|
772
|
-
// WU-1541: Use explicit baseDir instead of process.chdir for git operations
|
|
773
|
-
const gitWorktree = createGitForPath(worktreePath);
|
|
774
|
-
const previousEditor = process.env.GIT_EDITOR;
|
|
775
|
-
process.env.GIT_EDITOR = 'true';
|
|
776
|
-
try {
|
|
777
|
-
// Fetch latest main (using worktree git context)
|
|
778
|
-
await gitWorktree.fetch(REMOTES.ORIGIN, BRANCHES.MAIN);
|
|
779
|
-
// Attempt rebase
|
|
780
|
-
try {
|
|
781
|
-
await gitWorktree.rebase(`${REMOTES.ORIGIN}/${BRANCHES.MAIN}`);
|
|
782
|
-
}
|
|
783
|
-
catch (rebaseError) {
|
|
784
|
-
// WU-1749 Bug 3: Check if conflicts are in append-only files that can be auto-resolved
|
|
785
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} Rebase hit conflicts, checking for auto-resolvable...`);
|
|
786
|
-
const resolution = await autoResolveAppendOnlyConflicts(gitWorktree, worktreePath);
|
|
787
|
-
if (resolution.resolved) {
|
|
788
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Auto-resolved ${resolution.files.length} append-only conflict(s)`);
|
|
789
|
-
await assertNoConflictArtifactsInIndex(gitWorktree, resolution.files);
|
|
790
|
-
// Continue the rebase after resolving conflicts
|
|
791
|
-
let continueAttempts = 0;
|
|
792
|
-
while (true) {
|
|
793
|
-
try {
|
|
794
|
-
await gitWorktree.raw(['rebase', '--continue']);
|
|
795
|
-
break;
|
|
796
|
-
}
|
|
797
|
-
catch (continueError) {
|
|
798
|
-
continueAttempts += 1;
|
|
799
|
-
if (continueAttempts >= REBASE_CONFLICT_LIMITS.MAX_CONTINUE_ATTEMPTS) {
|
|
800
|
-
throw continueError;
|
|
801
|
-
}
|
|
802
|
-
const nextResolution = await autoResolveAppendOnlyConflicts(gitWorktree, worktreePath);
|
|
803
|
-
if (!nextResolution.resolved) {
|
|
804
|
-
// Still have non-auto-resolvable conflicts
|
|
805
|
-
throw continueError;
|
|
806
|
-
}
|
|
807
|
-
await assertNoConflictArtifactsInIndex(gitWorktree, nextResolution.files);
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
else {
|
|
812
|
-
// No auto-resolvable conflicts - rethrow original error
|
|
813
|
-
throw rebaseError;
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
// WU-1371: Detect and cleanup rebased completion artifacts
|
|
817
|
-
// After rebase, check if main's completion artifacts (stamps, status=done)
|
|
818
|
-
// were pulled into the worktree. These must be cleaned before continuing.
|
|
819
|
-
// WU-1817: Now passes gitCwd to verify artifacts exist on origin/main
|
|
820
|
-
if (wuId) {
|
|
821
|
-
const artifacts = await detectRebasedArtifacts(worktreePath, wuId, gitWorktree);
|
|
822
|
-
if (artifacts.hasArtifacts) {
|
|
823
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Detected rebased completion artifacts`);
|
|
824
|
-
const cleanup = await cleanupRebasedArtifacts(worktreePath, wuId);
|
|
825
|
-
if (cleanup.cleaned) {
|
|
826
|
-
// Stage and commit the cleanup
|
|
827
|
-
await gitWorktree.add('.');
|
|
828
|
-
await gitWorktree.commit(COMMIT_FORMATS.REBASE_ARTIFACT_CLEANUP(wuId));
|
|
829
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Cleaned rebased artifacts and committed`);
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
// WU-1657: Reconcile generated docs after rebase to avoid format-check loops.
|
|
834
|
-
// A rebase can pull generated docs changes from main that need regeneration and/or formatting.
|
|
835
|
-
if (wuId) {
|
|
836
|
-
const docsResult = await maybeRegenerateAndStageDocs({
|
|
837
|
-
baseBranch: `${REMOTES.ORIGIN}/${BRANCHES.MAIN}`,
|
|
838
|
-
repoRoot: worktreePath,
|
|
839
|
-
});
|
|
840
|
-
if (!docsResult.regenerated) {
|
|
841
|
-
const changedDocOutputs = await gitWorktree.raw([
|
|
842
|
-
'diff',
|
|
843
|
-
'--name-only',
|
|
844
|
-
`${REMOTES.ORIGIN}/${BRANCHES.MAIN}...HEAD`,
|
|
845
|
-
'--',
|
|
846
|
-
...DOC_OUTPUT_FILES,
|
|
847
|
-
]);
|
|
848
|
-
if (changedDocOutputs.trim().length > 0) {
|
|
849
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} Reconciling rebased generated docs outputs...`);
|
|
850
|
-
formatDocOutputs(worktreePath);
|
|
851
|
-
await gitWorktree.add([...DOC_OUTPUT_FILES]);
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
const stagedDocOutputs = await gitWorktree.raw([
|
|
855
|
-
'diff',
|
|
856
|
-
'--cached',
|
|
857
|
-
'--name-only',
|
|
858
|
-
'--',
|
|
859
|
-
...DOC_OUTPUT_FILES,
|
|
860
|
-
]);
|
|
861
|
-
if (stagedDocOutputs.trim().length > 0) {
|
|
862
|
-
await gitWorktree.commit(COMMIT_FORMATS.REBASE_ARTIFACT_CLEANUP(wuId));
|
|
863
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Committed rebased generated docs reconciliation`);
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
// Force-push lane branch with lease (safe force push)
|
|
867
|
-
await gitWorktree.raw(['push', '--force-with-lease', REMOTES.ORIGIN, branch]);
|
|
868
|
-
console.log(REBASE.SUCCESS);
|
|
869
|
-
return { success: true };
|
|
870
|
-
}
|
|
871
|
-
catch (e) {
|
|
872
|
-
// Rebase failed (likely conflicts) - abort and report
|
|
873
|
-
console.error(REBASE.FAILED(getErrorMessage(e)));
|
|
874
|
-
try {
|
|
875
|
-
// Abort the failed rebase to leave worktree clean
|
|
876
|
-
await gitWorktree.raw(['rebase', '--abort']);
|
|
877
|
-
console.log(REBASE.ABORTED);
|
|
878
|
-
}
|
|
879
|
-
catch {
|
|
880
|
-
// Ignore abort errors - may already be clean
|
|
881
|
-
}
|
|
882
|
-
return {
|
|
883
|
-
success: false,
|
|
884
|
-
error: REBASE.MANUAL_FIX(worktreePath, REMOTES.ORIGIN, BRANCHES.MAIN, branch),
|
|
885
|
-
};
|
|
886
|
-
}
|
|
887
|
-
finally {
|
|
888
|
-
if (previousEditor === undefined) {
|
|
889
|
-
delete process.env.GIT_EDITOR;
|
|
890
|
-
}
|
|
891
|
-
else {
|
|
892
|
-
process.env.GIT_EDITOR = previousEditor;
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
export async function checkBranchDivergence(branch, options = {}) {
|
|
897
|
-
const { autoRebase = true, worktreePath = null, wuId = null } = options;
|
|
898
|
-
const gitAdapter = getGitForCwd();
|
|
899
|
-
try {
|
|
900
|
-
const mergeBase = await gitAdapter.mergeBase(BRANCHES.MAIN, branch);
|
|
901
|
-
const mainHead = await gitAdapter.getCommitHash(BRANCHES.MAIN);
|
|
902
|
-
if (mergeBase !== mainHead) {
|
|
903
|
-
const mainCommitsAhead = await gitAdapter.revList([
|
|
904
|
-
'--count',
|
|
905
|
-
`${mergeBase}..${BRANCHES.MAIN}`,
|
|
906
|
-
]);
|
|
907
|
-
const commitCount = Number(mainCommitsAhead);
|
|
908
|
-
console.log(PREFLIGHT.DIVERGENCE_DETECTED(commitCount));
|
|
909
|
-
// Attempt auto-rebase if enabled and worktree path provided
|
|
910
|
-
if (autoRebase && worktreePath) {
|
|
911
|
-
const rebaseResult = await autoRebaseBranch(branch, worktreePath, wuId);
|
|
912
|
-
if (rebaseResult.success) {
|
|
913
|
-
// Rebase succeeded - continue with wu:done
|
|
914
|
-
return;
|
|
915
|
-
}
|
|
916
|
-
// Rebase failed - throw with detailed instructions
|
|
917
|
-
throw createError(ErrorCodes.GIT_ERROR, rebaseResult.error, {
|
|
918
|
-
branch,
|
|
919
|
-
mergeBase,
|
|
920
|
-
mainHead,
|
|
921
|
-
mainCommitsAhead: commitCount,
|
|
922
|
-
autoRebaseAttempted: true,
|
|
923
|
-
});
|
|
924
|
-
}
|
|
925
|
-
// Auto-rebase disabled or no worktree path - throw with manual instructions
|
|
926
|
-
throw createError(ErrorCodes.GIT_ERROR, PREFLIGHT.DIVERGENCE_ERROR(commitCount, REMOTES.ORIGIN, BRANCHES.MAIN, branch), { branch, mergeBase, mainHead, mainCommitsAhead: commitCount });
|
|
927
|
-
}
|
|
928
|
-
console.log(PREFLIGHT.NO_DIVERGENCE);
|
|
929
|
-
}
|
|
930
|
-
catch (e) {
|
|
931
|
-
if (isErrorWithCode(e, ErrorCodes.GIT_ERROR))
|
|
932
|
-
throw e;
|
|
933
|
-
console.warn(`${LOG_PREFIX.DONE} Warning: Could not check branch divergence: ${getErrorMessage(e)}`);
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
/**
|
|
937
|
-
* Check for merge commits in lane branch that would violate linear history
|
|
938
|
-
* WU-1384: GitHub requires linear history; merge commits in lane branches must be eliminated
|
|
939
|
-
* WU-1371: Added wuId option for post-rebase artifact cleanup
|
|
940
|
-
*
|
|
941
|
-
* If merge commits are found, triggers auto-rebase to linearize history.
|
|
942
|
-
*
|
|
943
|
-
* @param {string} branch - Lane branch name
|
|
944
|
-
* @param {CheckBranchOptions} [options] - Check options
|
|
945
|
-
* @throws {Error} If merge commits found and auto-rebase fails or is disabled
|
|
946
|
-
*/
|
|
947
|
-
export async function checkMergeCommits(branch, options = {}) {
|
|
948
|
-
const { autoRebase = true, worktreePath = null, wuId = null } = options;
|
|
949
|
-
const gitAdapter = getGitForCwd();
|
|
950
|
-
try {
|
|
951
|
-
// Find merge commits in lane branch that are not in main
|
|
952
|
-
// --merges: only merge commits
|
|
953
|
-
// main..branch: commits in branch not reachable from main
|
|
954
|
-
const mergeCommitsRaw = await gitAdapter.raw([
|
|
955
|
-
'rev-list',
|
|
956
|
-
'--merges',
|
|
957
|
-
`${BRANCHES.MAIN}..${branch}`,
|
|
958
|
-
]);
|
|
959
|
-
const mergeCommits = mergeCommitsRaw.trim().split(STRING_LITERALS.NEWLINE).filter(Boolean);
|
|
960
|
-
const mergeCount = mergeCommits.length;
|
|
961
|
-
if (mergeCount > 0) {
|
|
962
|
-
console.log(PREFLIGHT.MERGE_COMMITS_DETECTED(mergeCount));
|
|
963
|
-
// Trigger rebase to eliminate merge commits
|
|
964
|
-
if (autoRebase && worktreePath) {
|
|
965
|
-
console.log(PREFLIGHT.MERGE_COMMITS_REBASING);
|
|
966
|
-
const rebaseResult = await autoRebaseBranch(branch, worktreePath, wuId);
|
|
967
|
-
if (rebaseResult.success) {
|
|
968
|
-
// Rebase succeeded - merge commits eliminated
|
|
969
|
-
return;
|
|
970
|
-
}
|
|
971
|
-
// Rebase failed - throw with detailed instructions
|
|
972
|
-
throw createError(ErrorCodes.GIT_ERROR, rebaseResult.error, {
|
|
973
|
-
branch,
|
|
974
|
-
mergeCommitCount: mergeCount,
|
|
975
|
-
autoRebaseAttempted: true,
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
// Auto-rebase disabled or no worktree path - throw with manual instructions
|
|
979
|
-
throw createError(ErrorCodes.GIT_ERROR, `Branch ${branch} contains ${mergeCount} merge commit(s).\n\n` +
|
|
980
|
-
`GitHub requires linear history. Merge commits must be eliminated.\n\n` +
|
|
981
|
-
`REQUIRED: Rebase your branch to linearize history:\n` +
|
|
982
|
-
` 1. cd into your worktree\n` +
|
|
983
|
-
` 2. git fetch ${REMOTES.ORIGIN} ${BRANCHES.MAIN}\n` +
|
|
984
|
-
` 3. git rebase ${REMOTES.ORIGIN}/${BRANCHES.MAIN}\n` +
|
|
985
|
-
` 4. git push --force-with-lease ${REMOTES.ORIGIN} ${branch}\n` +
|
|
986
|
-
` 5. Return to main checkout and retry`, { branch, mergeCommitCount: mergeCount });
|
|
987
|
-
}
|
|
988
|
-
console.log(PREFLIGHT.NO_MERGE_COMMITS);
|
|
989
|
-
}
|
|
990
|
-
catch (e) {
|
|
991
|
-
if (isErrorWithCode(e, ErrorCodes.GIT_ERROR))
|
|
992
|
-
throw e;
|
|
993
|
-
console.warn(`${LOG_PREFIX.DONE} Warning: Could not check for merge commits: ${getErrorMessage(e)}`);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* Check for merge conflicts using git merge-tree
|
|
998
|
-
* WU-755 pre-flight check
|
|
999
|
-
*
|
|
1000
|
-
* @param {string} branch - Lane branch name
|
|
1001
|
-
*/
|
|
1002
|
-
export async function checkMergeConflicts(branch) {
|
|
1003
|
-
const MERGE_TREE_CONFLICT_EXIT_CODE = 1;
|
|
1004
|
-
try {
|
|
1005
|
-
// Use git exit status for conflict detection (status=1 indicates conflicts).
|
|
1006
|
-
// This avoids brittle parsing of merge-tree output text.
|
|
1007
|
-
const result = spawnSync(GIT_COMMANDS.GIT, [GIT_COMMANDS.MERGE_TREE, GIT_FLAGS.WRITE_TREE, BRANCHES.MAIN, branch], {
|
|
1008
|
-
cwd: process.cwd(),
|
|
1009
|
-
encoding: 'utf-8',
|
|
1010
|
-
});
|
|
1011
|
-
if (result.error) {
|
|
1012
|
-
console.warn(`${LOG_PREFIX.DONE} Warning: Could not check merge conflicts: ${result.error.message}`);
|
|
1013
|
-
return;
|
|
1014
|
-
}
|
|
1015
|
-
if (result.status === 0) {
|
|
1016
|
-
console.log(PREFLIGHT.NO_CONFLICTS);
|
|
1017
|
-
return;
|
|
1018
|
-
}
|
|
1019
|
-
if (result.status === MERGE_TREE_CONFLICT_EXIT_CODE) {
|
|
1020
|
-
throw createError(ErrorCodes.GIT_ERROR, PREFLIGHT.CONFLICT_ERROR(REMOTES.ORIGIN, BRANCHES.MAIN), {
|
|
1021
|
-
branch,
|
|
1022
|
-
operation: 'merge-tree --write-tree',
|
|
1023
|
-
});
|
|
1024
|
-
}
|
|
1025
|
-
const stderr = typeof result.stderr === 'string' ? result.stderr.trim() : '';
|
|
1026
|
-
const detail = stderr ||
|
|
1027
|
-
`${GIT_COMMANDS.GIT} ${GIT_COMMANDS.MERGE_TREE} exited with status ${String(result.status)}`;
|
|
1028
|
-
console.warn(`${LOG_PREFIX.DONE} Warning: Could not check merge conflicts: ${detail}`);
|
|
1029
|
-
}
|
|
1030
|
-
catch (e) {
|
|
1031
|
-
if (isErrorWithCode(e, ErrorCodes.GIT_ERROR))
|
|
1032
|
-
throw e;
|
|
1033
|
-
const message = getErrorMessage(e);
|
|
1034
|
-
console.warn(`${LOG_PREFIX.DONE} Warning: Could not check merge conflicts: ${message}`);
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
/**
|
|
1038
|
-
* WU-1456: Check for empty merge (no work commits beyond claim)
|
|
1039
|
-
* WU-1460: Upgraded to BLOCK when code_paths defined but files not modified
|
|
1040
|
-
*
|
|
1041
|
-
* Detects when an agent runs wu:done without committing actual work.
|
|
1042
|
-
* - If code_paths defined: BLOCK if those files weren't modified
|
|
1043
|
-
* - If no code_paths: WARNING only (docs-only or metadata updates are valid)
|
|
1044
|
-
*
|
|
1045
|
-
* @param {string} branch - Lane branch name
|
|
1046
|
-
* @param {object} [doc] - WU document with code_paths array (optional for backwards compatibility)
|
|
1047
|
-
* @returns {Promise<void>}
|
|
1048
|
-
* @throws {Error} When code_paths defined but files not modified in commits
|
|
1049
|
-
*/
|
|
1050
|
-
export async function checkEmptyMerge(branch, doc = null) {
|
|
1051
|
-
const gitAdapter = getGitForCwd();
|
|
1052
|
-
try {
|
|
1053
|
-
// Count commits on lane branch that are not in main
|
|
1054
|
-
const commitCountRaw = await gitAdapter.raw([
|
|
1055
|
-
'rev-list',
|
|
1056
|
-
'--count',
|
|
1057
|
-
`${BRANCHES.MAIN}..${branch}`,
|
|
1058
|
-
]);
|
|
1059
|
-
const commitCount = Number(commitCountRaw.trim());
|
|
1060
|
-
// WU-1460: If code_paths defined, verify those files were modified
|
|
1061
|
-
const codePaths = Array.isArray(doc?.code_paths)
|
|
1062
|
-
? doc.code_paths.filter((filePath) => typeof filePath === 'string')
|
|
1063
|
-
: [];
|
|
1064
|
-
const hasCodePaths = codePaths.length > 0;
|
|
1065
|
-
if (hasCodePaths) {
|
|
1066
|
-
// Get list of files modified in lane branch commits
|
|
1067
|
-
const modifiedFilesRaw = await gitAdapter.raw([
|
|
1068
|
-
'diff',
|
|
1069
|
-
'--name-only',
|
|
1070
|
-
`${BRANCHES.MAIN}...${branch}`,
|
|
1071
|
-
]);
|
|
1072
|
-
const modifiedFiles = modifiedFilesRaw.trim().split('\n').filter(Boolean);
|
|
1073
|
-
// Check if UnsafeAny code_paths files are in the modified list
|
|
1074
|
-
const missingCodePaths = codePaths.filter((codePath) => !modifiedFiles.some((modified) => modified.includes(codePath) || codePath.includes(modified)));
|
|
1075
|
-
if (missingCodePaths.length > 0) {
|
|
1076
|
-
// BLOCK: code_paths defined but files not modified
|
|
1077
|
-
throw createValidationError(PREFLIGHT.CODE_PATHS_NOT_MODIFIED(missingCodePaths), {
|
|
1078
|
-
branch,
|
|
1079
|
-
codePaths,
|
|
1080
|
-
missingCodePaths,
|
|
1081
|
-
modifiedFiles,
|
|
1082
|
-
});
|
|
1083
|
-
}
|
|
1084
|
-
// All code_paths files were modified
|
|
1085
|
-
console.log(PREFLIGHT.CODE_PATHS_VERIFIED);
|
|
1086
|
-
}
|
|
1087
|
-
else if (commitCount <= 1) {
|
|
1088
|
-
// No code_paths - just warn (backwards compatible behaviour)
|
|
1089
|
-
// If only 0-1 commits beyond main, this is likely the claim commit only
|
|
1090
|
-
console.log(PREFLIGHT.EMPTY_MERGE_WARNING(commitCount));
|
|
1091
|
-
}
|
|
1092
|
-
else {
|
|
1093
|
-
console.log(PREFLIGHT.EMPTY_MERGE_CHECK);
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
catch (e) {
|
|
1097
|
-
// Re-throw validation errors (WU-1460 blocker)
|
|
1098
|
-
if (isErrorWithCode(e, ErrorCodes.VALIDATION_ERROR))
|
|
1099
|
-
throw e;
|
|
1100
|
-
console.warn(`${LOG_PREFIX.DONE} Warning: Could not check for empty merge: ${getErrorMessage(e)}`);
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
async function isMainAncestorOfBranch(gitAdapter, branch) {
|
|
1104
|
-
try {
|
|
1105
|
-
await gitAdapter.raw([GIT_COMMANDS.MERGE_BASE, GIT_FLAGS.IS_ANCESTOR, BRANCHES.MAIN, branch]);
|
|
1106
|
-
return true;
|
|
1107
|
-
}
|
|
1108
|
-
catch {
|
|
1109
|
-
return false;
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
export async function mergeLaneBranch(branch, options = {}) {
|
|
1113
|
-
const gitAdapter = getGitForCwd();
|
|
1114
|
-
console.log(MERGE.BRANCH_MERGE(branch));
|
|
1115
|
-
// WU-1747: Use exponential backoff retry for merge operations
|
|
1116
|
-
// WU-1749 Bug 2: Now rebases lane branch on retry instead of just pulling main
|
|
1117
|
-
const retryConfig = createRetryConfig('wu_done', {
|
|
1118
|
-
maxAttempts: options.maxAttempts,
|
|
1119
|
-
onRetry: async (attempt, error, _delay) => {
|
|
1120
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Merge attempt ${attempt} failed: ${getErrorMessage(error)}`);
|
|
1121
|
-
// WU-1749 Bug 2: Rebase lane branch onto new main instead of just pulling
|
|
1122
|
-
// This is required because ff-only merge will always fail if the lane branch
|
|
1123
|
-
// is still based on the old main after main has advanced
|
|
1124
|
-
if (options.worktreePath) {
|
|
1125
|
-
const mainIsAncestor = await isMainAncestorOfBranch(gitAdapter, branch);
|
|
1126
|
-
if (mainIsAncestor) {
|
|
1127
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} Main is already an ancestor - skipping auto-rebase`);
|
|
1128
|
-
return;
|
|
1129
|
-
}
|
|
1130
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} Auto-rebasing lane branch onto latest main...`);
|
|
1131
|
-
const rebaseResult = await autoRebaseBranch(branch, options.worktreePath, options.wuId);
|
|
1132
|
-
if (rebaseResult.success) {
|
|
1133
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Lane branch rebased - ff-only merge should succeed`);
|
|
1134
|
-
}
|
|
1135
|
-
else {
|
|
1136
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Auto-rebase failed: ${rebaseResult.error}`);
|
|
1137
|
-
// Fall back to pull --rebase for consistent linear-history sync
|
|
1138
|
-
try {
|
|
1139
|
-
await gitAdapter.raw([
|
|
1140
|
-
GIT_COMMANDS.PULL,
|
|
1141
|
-
GIT_FLAGS.REBASE,
|
|
1142
|
-
'--autostash',
|
|
1143
|
-
REMOTES.ORIGIN,
|
|
1144
|
-
BRANCHES.MAIN,
|
|
1145
|
-
]);
|
|
1146
|
-
console.log(MERGE.UPDATED_MAIN(REMOTES.ORIGIN));
|
|
1147
|
-
}
|
|
1148
|
-
catch (pullErr) {
|
|
1149
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Pull also failed: ${getErrorMessage(pullErr)}`);
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
else {
|
|
1154
|
-
// No worktree path - pull --rebase before retry
|
|
1155
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} Pulling latest main with --rebase before retry...`);
|
|
1156
|
-
try {
|
|
1157
|
-
await gitAdapter.raw([
|
|
1158
|
-
GIT_COMMANDS.PULL,
|
|
1159
|
-
GIT_FLAGS.REBASE,
|
|
1160
|
-
'--autostash',
|
|
1161
|
-
REMOTES.ORIGIN,
|
|
1162
|
-
BRANCHES.MAIN,
|
|
1163
|
-
]);
|
|
1164
|
-
console.log(MERGE.UPDATED_MAIN(REMOTES.ORIGIN));
|
|
1165
|
-
}
|
|
1166
|
-
catch (pullErr) {
|
|
1167
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Pull failed: ${getErrorMessage(pullErr)} - will retry anyway`);
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
},
|
|
1171
|
-
});
|
|
1172
|
-
try {
|
|
1173
|
-
await withRetry(async () => {
|
|
1174
|
-
await gitAdapter.merge(branch, { ffOnly: true });
|
|
1175
|
-
}, retryConfig);
|
|
1176
|
-
console.log(MERGE.SUCCESS(branch));
|
|
1177
|
-
}
|
|
1178
|
-
catch (e) {
|
|
1179
|
-
// All retries exhausted
|
|
1180
|
-
const mainIsAncestor = await isMainAncestorOfBranch(gitAdapter, branch);
|
|
1181
|
-
const message = mainIsAncestor
|
|
1182
|
-
? MERGE.FF_FAILED_NON_DIVERGED_ERROR(branch, getErrorMessage(e))
|
|
1183
|
-
: MERGE.FF_DIVERGED_ERROR(branch, getErrorMessage(e));
|
|
1184
|
-
throw createError(ErrorCodes.GIT_ERROR, message, {
|
|
1185
|
-
branch,
|
|
1186
|
-
originalError: getErrorMessage(e),
|
|
1187
|
-
retriesExhausted: true,
|
|
1188
|
-
mainIsAncestor,
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
/**
|
|
1193
|
-
* WU-1943: Check if the session has checkpoints for the given WU
|
|
1194
|
-
*
|
|
1195
|
-
* Used to warn agents when they're completing a WU without UnsafeAny checkpoints,
|
|
1196
|
-
* which means no recovery data if the session crashes.
|
|
1197
|
-
*
|
|
1198
|
-
* @param {string} wuId - WU ID to check
|
|
1199
|
-
* @param {Array|null} nodes - Memory nodes for the WU (from queryByWu)
|
|
1200
|
-
* @returns {boolean} True if checkpoints exist, false otherwise
|
|
1201
|
-
*/
|
|
1202
|
-
export function hasSessionCheckpoints(wuId, nodes) {
|
|
1203
|
-
if (!wuId) {
|
|
1204
|
-
return false;
|
|
1205
|
-
}
|
|
1206
|
-
if (!nodes || !Array.isArray(nodes) || nodes.length === 0) {
|
|
1207
|
-
return false;
|
|
1208
|
-
}
|
|
1209
|
-
return nodes.some((node) => node.type === 'checkpoint');
|
|
1210
|
-
}
|
|
1211
|
-
/**
|
|
1212
|
-
* WU-1943: Rollback branch to pre-commit SHA when merge fails
|
|
1213
|
-
*
|
|
1214
|
-
* When wu:done commits metadata to the lane branch but the subsequent merge
|
|
1215
|
-
* to main fails, this function rolls back the branch to its pre-commit state.
|
|
1216
|
-
* This prevents "zombie" states where the branch shows done but wasn't merged.
|
|
1217
|
-
*
|
|
1218
|
-
* @param {object} gitAdapter - Git adapter instance (must be in worktree context)
|
|
1219
|
-
* @param {string} preCommitSha - SHA to reset to (captured before metadata commit)
|
|
1220
|
-
* @param {string} wuId - WU ID for logging
|
|
1221
|
-
* @returns {Promise<{success: boolean, error?: string}>} Rollback result
|
|
1222
|
-
*/
|
|
1223
|
-
export async function rollbackBranchOnMergeFailure(gitAdapter, preCommitSha, wuId) {
|
|
1224
|
-
try {
|
|
1225
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} WU-1943: Rolling back ${wuId} branch to pre-commit state...`);
|
|
1226
|
-
// WU-2236: GitAdapter.reset expects (ref: string, options?: { hard?: boolean })
|
|
1227
|
-
// NOT an array like ['--hard', sha]
|
|
1228
|
-
await gitAdapter.reset(preCommitSha, { hard: true });
|
|
1229
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} WU-1943: Branch rollback complete for ${wuId}`);
|
|
1230
|
-
return { success: true };
|
|
1231
|
-
}
|
|
1232
|
-
catch (error) {
|
|
1233
|
-
console.log(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} WU-1943: Could not rollback branch for ${wuId}: ${getErrorMessage(error)}`);
|
|
1234
|
-
return { success: false, error: getErrorMessage(error) };
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
/**
|
|
1238
|
-
* WU-1577: Validate that local main is not behind origin/main before transaction.
|
|
1239
|
-
*
|
|
1240
|
-
* Defense-in-depth check inside the core layer. The CLI layer already has
|
|
1241
|
-
* `ensureMainUpToDate()`, but this adds a guard directly before the
|
|
1242
|
-
* transaction starts in `executeWorktreeCompletion()`. This prevents
|
|
1243
|
-
* metadata leaks when the merge succeeds but the subsequent push fails
|
|
1244
|
-
* because main was behind.
|
|
1245
|
-
*
|
|
1246
|
-
* Fail-open: if the fetch or comparison fails (network issue), returns valid=true
|
|
1247
|
-
* to avoid blocking legitimate work when there's no remote.
|
|
1248
|
-
*
|
|
1249
|
-
* @param gitAdapter - Git adapter instance (must be in main checkout context)
|
|
1250
|
-
* @returns Validation result with commitsBehind count
|
|
1251
|
-
*/
|
|
1252
|
-
export async function validateMainNotBehindOrigin(gitAdapter) {
|
|
1253
|
-
try {
|
|
1254
|
-
await gitAdapter.fetch(REMOTES.ORIGIN, BRANCHES.MAIN);
|
|
1255
|
-
const localSha = await gitAdapter.getCommitHash(BRANCHES.MAIN);
|
|
1256
|
-
const remoteSha = await gitAdapter.getCommitHash(`${REMOTES.ORIGIN}/${BRANCHES.MAIN}`);
|
|
1257
|
-
if (localSha === remoteSha) {
|
|
1258
|
-
return { valid: true, commitsBehind: 0 };
|
|
1259
|
-
}
|
|
1260
|
-
const behindRaw = await gitAdapter.revList([
|
|
1261
|
-
'--count',
|
|
1262
|
-
`${BRANCHES.MAIN}..${REMOTES.ORIGIN}/${BRANCHES.MAIN}`,
|
|
1263
|
-
]);
|
|
1264
|
-
const commitsBehind = Number(behindRaw.trim()) || 0;
|
|
1265
|
-
if (commitsBehind > 0) {
|
|
1266
|
-
return { valid: false, commitsBehind };
|
|
1267
|
-
}
|
|
1268
|
-
// Local is ahead of remote (not behind) — valid
|
|
1269
|
-
return { valid: true, commitsBehind: 0 };
|
|
1270
|
-
}
|
|
1271
|
-
catch {
|
|
1272
|
-
// Fail-open: network error or no remote — allow wu:done to proceed
|
|
1273
|
-
return { valid: true, commitsBehind: 0, failOpen: true };
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
/**
|
|
1277
|
-
* WU-1577: Helper that throws if local main is behind origin.
|
|
1278
|
-
* Extracted from executeWorktreeCompletion to keep cognitive complexity in check.
|
|
1279
|
-
*/
|
|
1280
|
-
async function ensureMainNotBehindOrigin(mainCheckoutPath, wuId) {
|
|
1281
|
-
const gitMainPreCheck = createGitForPath(mainCheckoutPath);
|
|
1282
|
-
const result = await validateMainNotBehindOrigin(gitMainPreCheck);
|
|
1283
|
-
if (!result.valid) {
|
|
1284
|
-
throw createError(ErrorCodes.GIT_ERROR, `Local main is ${result.commitsBehind} commit(s) behind origin/main.\n\n` +
|
|
1285
|
-
`wu:done aborted BEFORE UnsafeAny writes to prevent metadata leaks (WU-1577).\n\n` +
|
|
1286
|
-
`Fix: git pull origin main\n` +
|
|
1287
|
-
`Then retry: pnpm wu:done --id ${wuId}`, { wuId, commitsBehind: result.commitsBehind });
|
|
1288
|
-
}
|
|
1289
|
-
}
|
|
1290
|
-
//# sourceMappingURL=wu-done-worktree.js.map
|