@danmoisan/drm-copilot-mcp 1.1.18 → 1.1.20
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/out/mcp-server.js +1149 -661
- package/package.json +3 -2
- package/resources/claude-customizations/.claude/agents/atomic-executor.md +28 -6
- package/resources/claude-customizations/.claude/agents/atomic-planner.md +20 -2
- package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +17 -4
- package/resources/claude-customizations/.claude/agents/epic-planner.md +5 -4
- package/resources/claude-customizations/.claude/agents/feature-review.md +6 -4
- package/resources/claude-customizations/.claude/agents/orchestrator.md +9 -5
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +35 -13
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +9 -6
- package/resources/claude-customizations/.claude/agents/pr-author.md +15 -2
- package/resources/claude-customizations/.claude/agents/prd-feature.md +1 -1
- package/resources/claude-customizations/.claude/agents/task-researcher.md +8 -0
- package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +111 -46
- package/resources/claude-customizations/.claude/hooks/enforce-completion-helpers.ps1 +105 -0
- package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +8 -1
- package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-command.ps1 +190 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-resolution.ps1 +116 -59
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +78 -77
- package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +74 -75
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +127 -35
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +61 -57
- package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +129 -39
- package/resources/claude-customizations/.claude/hooks/enforce-mermaid-validation.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +39 -51
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +17 -12
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +65 -50
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +49 -42
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +54 -72
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +8 -2
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +279 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +129 -75
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.artifact-root.ps1 +233 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +224 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +69 -24
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1 +29 -18
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +10 -4
- package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +14 -5
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +8 -2
- package/resources/claude-customizations/.claude/hooks/feature-folder-resolution.ps1 +373 -0
- package/resources/claude-customizations/.claude/hooks/feature-review-coverage-thresholds.ps1 +85 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-heredoc.ps1 +119 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-invocation-operands.ps1 +198 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-invocation.ps1 +254 -255
- package/resources/claude-customizations/.claude/hooks/hook-command-payload-powershell.ps1 +201 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-payload.ps1 +484 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-scanner.ps1 +27 -110
- package/resources/claude-customizations/.claude/hooks/hook-dependency-guard.ps1 +114 -0
- package/resources/claude-customizations/.claude/hooks/hook-docs-only-diff.ps1 +497 -0
- package/resources/claude-customizations/.claude/hooks/premortem-section.ps1 +149 -0
- package/resources/claude-customizations/.claude/hooks/subagentstop-envelope.ps1 +192 -0
- package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +40 -42
- package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +267 -113
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-metrics.ps1 +180 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +195 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +141 -395
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-resolution.ps1 +311 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-routing.ps1 +170 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +115 -190
- package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +77 -33
- package/resources/claude-customizations/.claude/hooks/validate-pr-author-output.ps1 +39 -44
- package/resources/claude-customizations/.claude/hooks/validate-prd-feature-output.ps1 +43 -14
- package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +66 -36
- package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +52 -36
- package/resources/claude-customizations/.claude/lib/bash/mutate-parallel-run.sh +191 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-cohorts.sh +13 -3
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-cli.sh +152 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-ops.sh +193 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation.sh +322 -0
- package/resources/claude-customizations/.claude/lib/bash/remove-parallel-item.sh +146 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +23 -33
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +86 -6
- package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-CiGateParser.ps1 +91 -19
- package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-MergeConfirmationParser.ps1 +203 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateEpicWaveBarrier.psm1 +346 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +24 -3
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +79 -2
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +3 -3
- package/resources/claude-customizations/.claude/rules/architecture-boundaries.md +5 -5
- package/resources/claude-customizations/.claude/rules/csharp.md +2 -2
- package/resources/claude-customizations/.claude/rules/general-code-change.md +1 -1
- package/resources/claude-customizations/.claude/rules/general-unit-test.md +3 -2
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +37 -4
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +50 -5
- package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +85 -10
- package/resources/claude-customizations/.claude/rules/quality-tiers.md +11 -7
- package/resources/claude-customizations/.claude/rules/shell.md +10 -8
- package/resources/claude-customizations/.claude/rules/typescript.md +1 -1
- package/resources/claude-customizations/.claude/settings.json +3 -4
- package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +52 -16
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +7 -3
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_detached_lib.sh +1 -1
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_enumerate_lib.sh +2 -0
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh +2 -0
- package/resources/claude-customizations/.claude/skills/csharp-change-budget-router/SKILL.md +2 -2
- package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +45 -9
- package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +5 -3
- package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +134 -0
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +4 -3
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +36 -15
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +52 -14
- package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +22 -9
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +108 -21
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +63 -7
- package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +35 -12
- package/resources/claude-customizations/.claude/skills/powershell-change-budget-router/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +3 -1
- package/resources/claude-customizations/.claude/skills/python-change-budget-router/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/quota-throttling/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +16 -8
- package/resources/claude-customizations/.claude/skills/research-issue/SKILL.md +6 -0
- package/resources/claude-customizations/pack-manifests/core.json +27 -0
- package/resources/codex-and-agents-customizations/.agents/skills/README.md +1 -0
- package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/architecture-boundaries/SKILL.md +5 -5
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +19 -7
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +43 -4
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +18 -6
- package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-change-budget-router/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +16 -1
- package/resources/codex-and-agents-customizations/.agents/skills/epic-plan/SKILL.md +17 -1
- package/resources/codex-and-agents-customizations/.agents/skills/epic-run/SKILL.md +2 -1
- package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +134 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +13 -5
- package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/general-unit-test/SKILL.md +3 -2
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +27 -8
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-change-budget-router/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/python-change-budget-router/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +11 -7
- package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
- package/resources/codex-and-agents-customizations/.agents/skills/research-issue/SKILL.md +6 -0
- package/resources/codex-and-agents-customizations/.agents/skills/translate-claude-to-codex/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/epic-orchestrator.toml +4 -1
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c1.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c2.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c3-elevated.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c3.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c4.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +318 -273
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/codex-epic-child-launch-attestation.ps1 +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +97 -44
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-helpers.ps1 +105 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-child-worktree-binding.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate-command.ps1 +190 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +54 -43
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +6 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-root-invocation.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-wave-barrier.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-worktree-removal-gate.ps1 +54 -41
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +35 -14
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +24 -11
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +13 -4
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/feature-folder-resolution.ps1 +373 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/feature-review-coverage-thresholds.ps1 +85 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-heredoc.ps1 +119 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation-operands.ps1 +198 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation.ps1 +254 -255
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload-powershell.ps1 +201 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload.ps1 +484 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-scanner.ps1 +27 -110
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-dependency-guard.ps1 +114 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-docs-only-diff.ps1 +497 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +24 -8
- package/resources/codex-and-agents-customizations/.codex/prompts/feature-review-remediate.md +6 -4
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +11 -0
- package/resources/customizations/.github/agents/atomic_executor.agent.md +21 -11
- package/resources/customizations/.github/agents/atomic_planning.agent.md +8 -3
- package/resources/customizations/.github/agents/csharp-atomic-executor.agent.md +13 -9
- package/resources/customizations/.github/agents/csharp-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/csharp-orchestrator.agent.md +2 -2
- package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +5 -5
- package/resources/customizations/.github/agents/orchestrator.agent.md +8 -5
- package/resources/customizations/.github/agents/powershell-atomic-executor.agent.md +13 -9
- package/resources/customizations/.github/agents/powershell-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/powershell-orchestrator.agent.md +2 -2
- package/resources/customizations/.github/agents/powershell-typed-engineer.agent.md +3 -3
- package/resources/customizations/.github/agents/python-atomic-executor.agent.md +13 -9
- package/resources/customizations/.github/agents/python-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/python-orchestrator.agent.md +2 -2
- package/resources/customizations/.github/agents/task-researcher.agent.md +6 -0
- package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +4 -4
- package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +2 -2
- package/resources/customizations/.github/prompts/generate-atomic-plan.prompt.md +16 -10
- package/resources/customizations/.github/prompts/orchestrate-csharp-work.prompt.md +2 -2
- package/resources/customizations/.github/prompts/orchestrate-powershell-work.prompt.md +1 -1
- package/resources/customizations/.github/prompts/orchestrate-python-work.prompt.md +1 -1
- package/resources/customizations/.github/prompts/orchestrate-work.prompt.md +2 -2
- package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +43 -4
- package/resources/customizations/.github/skills/csharp-change-budget-router/SKILL.md +1 -1
- package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/customizations/.github/skills/execution-environment/SKILL.md +134 -0
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +1 -1
- package/resources/customizations/.github/skills/powershell-change-budget-router/SKILL.md +1 -1
- package/resources/customizations/.github/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
- package/resources/feature-templates/bug/plan.yyyy-MM-ddTHH-mm.md +10 -0
- package/resources/feature-templates/feature/plan.yyyy-MM-ddTHH-mm.md +11 -0
- package/resources/feature-templates/refactor/plan.yyyy-MM-ddTHH-mm.md +11 -0
- package/resources/powershell/PoshQC/PoshQC.Coverage.psm1 +314 -0
- package/resources/powershell/PoshQC/PoshQC.CoverageMerge.psm1 +163 -0
- package/resources/powershell/PoshQC/PoshQC.Shard.psm1 +296 -0
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +48 -32
- package/resources/powershell/PoshQC/PoshQC.psd1 +7 -1
- package/resources/powershell/PoshQC/PoshQC.psm1 +18 -5
- package/resources/powershell/PoshQC/README.md +21 -3
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +5 -319
package/out/mcp-server.js
CHANGED
|
@@ -14078,6 +14078,9 @@ var Protocol = class {
|
|
|
14078
14078
|
this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
|
|
14079
14079
|
const handleTaskResult = async () => {
|
|
14080
14080
|
const taskId = request.params.taskId;
|
|
14081
|
+
if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
|
|
14082
|
+
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
|
|
14083
|
+
}
|
|
14081
14084
|
if (this._taskMessageQueue) {
|
|
14082
14085
|
let queuedMessage;
|
|
14083
14086
|
while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
|
|
@@ -14108,12 +14111,12 @@ var Protocol = class {
|
|
|
14108
14111
|
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
|
|
14109
14112
|
}
|
|
14110
14113
|
if (!isTerminal(task.status)) {
|
|
14111
|
-
await this._waitForTaskUpdate(taskId, extra.signal);
|
|
14114
|
+
await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
|
|
14112
14115
|
return await handleTaskResult();
|
|
14113
14116
|
}
|
|
14114
14117
|
if (isTerminal(task.status)) {
|
|
14115
14118
|
const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
|
|
14116
|
-
this._clearTaskQueue(taskId);
|
|
14119
|
+
this._clearTaskQueue(taskId, extra.sessionId);
|
|
14117
14120
|
return {
|
|
14118
14121
|
...result,
|
|
14119
14122
|
_meta: {
|
|
@@ -14150,7 +14153,7 @@ var Protocol = class {
|
|
|
14150
14153
|
throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
|
|
14151
14154
|
}
|
|
14152
14155
|
await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
|
|
14153
|
-
this._clearTaskQueue(request.params.taskId);
|
|
14156
|
+
this._clearTaskQueue(request.params.taskId, extra.sessionId);
|
|
14154
14157
|
const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
|
|
14155
14158
|
if (!cancelledTask) {
|
|
14156
14159
|
throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
|
|
@@ -14278,6 +14281,19 @@ var Protocol = class {
|
|
|
14278
14281
|
const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
|
|
14279
14282
|
const capturedTransport = this._transport;
|
|
14280
14283
|
const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
|
|
14284
|
+
const sessionId = capturedTransport?.sessionId;
|
|
14285
|
+
const store = this._taskStore;
|
|
14286
|
+
let relatedTaskFound = true;
|
|
14287
|
+
let relatedTaskLookup;
|
|
14288
|
+
if (relatedTaskId && store && this._taskMessageQueue && sessionId !== void 0) {
|
|
14289
|
+
relatedTaskFound = false;
|
|
14290
|
+
relatedTaskLookup = (async () => {
|
|
14291
|
+
if (!await store.getTask(relatedTaskId, sessionId)) {
|
|
14292
|
+
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
|
|
14293
|
+
}
|
|
14294
|
+
relatedTaskFound = true;
|
|
14295
|
+
})();
|
|
14296
|
+
}
|
|
14281
14297
|
if (handler === void 0) {
|
|
14282
14298
|
const errorResponse = {
|
|
14283
14299
|
jsonrpc: "2.0",
|
|
@@ -14287,7 +14303,10 @@ var Protocol = class {
|
|
|
14287
14303
|
message: "Method not found"
|
|
14288
14304
|
}
|
|
14289
14305
|
};
|
|
14290
|
-
if (relatedTaskId &&
|
|
14306
|
+
if (relatedTaskId && relatedTaskLookup) {
|
|
14307
|
+
const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
|
|
14308
|
+
relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error2) => this._onerror(new Error(`Failed to send an error response: ${error2}`)));
|
|
14309
|
+
} else if (relatedTaskId && this._taskMessageQueue) {
|
|
14291
14310
|
this._enqueueTaskMessage(relatedTaskId, {
|
|
14292
14311
|
type: "error",
|
|
14293
14312
|
message: errorResponse,
|
|
@@ -14338,7 +14357,10 @@ var Protocol = class {
|
|
|
14338
14357
|
closeSSEStream: extra?.closeSSEStream,
|
|
14339
14358
|
closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
|
|
14340
14359
|
};
|
|
14341
|
-
Promise.resolve().then(() => {
|
|
14360
|
+
(relatedTaskLookup ?? Promise.resolve()).then(() => {
|
|
14361
|
+
if (relatedTaskLookup && abortController.signal.aborted) {
|
|
14362
|
+
throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
|
|
14363
|
+
}
|
|
14342
14364
|
if (taskCreationParams) {
|
|
14343
14365
|
this.assertTaskHandlerCapability(request.method);
|
|
14344
14366
|
}
|
|
@@ -14373,7 +14395,7 @@ var Protocol = class {
|
|
|
14373
14395
|
...error2["data"] !== void 0 && { data: error2["data"] }
|
|
14374
14396
|
}
|
|
14375
14397
|
};
|
|
14376
|
-
if (relatedTaskId && this._taskMessageQueue) {
|
|
14398
|
+
if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
|
|
14377
14399
|
await this._enqueueTaskMessage(relatedTaskId, {
|
|
14378
14400
|
type: "error",
|
|
14379
14401
|
message: errorResponse,
|
|
@@ -14853,7 +14875,7 @@ var Protocol = class {
|
|
|
14853
14875
|
throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
|
|
14854
14876
|
}
|
|
14855
14877
|
const maxQueueSize = this._options?.maxTaskQueueSize;
|
|
14856
|
-
await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
|
|
14878
|
+
await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
|
|
14857
14879
|
}
|
|
14858
14880
|
/**
|
|
14859
14881
|
* Clears the message queue for a task and rejects any pending request resolvers.
|
|
@@ -14882,12 +14904,13 @@ var Protocol = class {
|
|
|
14882
14904
|
* Uses polling to check for updates at the task's configured poll interval.
|
|
14883
14905
|
* @param taskId The task ID to wait for
|
|
14884
14906
|
* @param signal Abort signal to cancel the wait
|
|
14907
|
+
* @param sessionId Session of the request that waits, passed to the task store
|
|
14885
14908
|
* @returns Promise that resolves when an update occurs or rejects if aborted
|
|
14886
14909
|
*/
|
|
14887
|
-
async _waitForTaskUpdate(taskId, signal) {
|
|
14910
|
+
async _waitForTaskUpdate(taskId, signal, sessionId) {
|
|
14888
14911
|
let interval = this._options?.defaultTaskPollInterval ?? 1e3;
|
|
14889
14912
|
try {
|
|
14890
|
-
const task = await this._taskStore?.getTask(taskId);
|
|
14913
|
+
const task = await this._taskStore?.getTask(taskId, sessionId);
|
|
14891
14914
|
if (task?.pollInterval) {
|
|
14892
14915
|
interval = task.pollInterval;
|
|
14893
14916
|
}
|
|
@@ -17831,7 +17854,8 @@ function toAuthorityMcpResult(tool, workspaceRoot, result) {
|
|
|
17831
17854
|
primary_failure_code: result.primaryFailureCode,
|
|
17832
17855
|
affected_paths: result.affectedPaths,
|
|
17833
17856
|
unsupported_capabilities: result.unsupportedCapabilities,
|
|
17834
|
-
resolution: result.resolution
|
|
17857
|
+
resolution: result.resolution,
|
|
17858
|
+
...result.failureCause === void 0 ? {} : { failure_cause: result.failureCause }
|
|
17835
17859
|
};
|
|
17836
17860
|
}
|
|
17837
17861
|
function toTransitionMcpResult(workspaceRoot, result) {
|
|
@@ -17850,7 +17874,8 @@ function toTransitionMcpResult(workspaceRoot, result) {
|
|
|
17850
17874
|
destination_checkpoint_sha256: result.destinationCheckpointSha256,
|
|
17851
17875
|
primary_failure_code: result.primaryFailureCode,
|
|
17852
17876
|
affected_paths: result.affectedPaths,
|
|
17853
|
-
unsupported_capabilities: result.unsupportedCapabilities
|
|
17877
|
+
unsupported_capabilities: result.unsupportedCapabilities,
|
|
17878
|
+
...result.failureCause === void 0 ? {} : { failure_cause: result.failureCause }
|
|
17854
17879
|
};
|
|
17855
17880
|
}
|
|
17856
17881
|
async function handlePortableHandoffTool(tool, rawInput, service) {
|
|
@@ -18295,6 +18320,33 @@ function buildPoshQcWorkflowArguments(tool, input) {
|
|
|
18295
18320
|
// ../../extensions/drm-copilot/src/lib/push-down/filesystem-adapter.ts
|
|
18296
18321
|
var fs2 = __toESM(require("node:fs"));
|
|
18297
18322
|
var nodePath2 = __toESM(require("node:path"));
|
|
18323
|
+
|
|
18324
|
+
// ../../extensions/drm-copilot/src/lib/string-ordering.ts
|
|
18325
|
+
function rankCodeUnit(unit) {
|
|
18326
|
+
if (unit >= 55296 && unit <= 57343) {
|
|
18327
|
+
return unit + 8192;
|
|
18328
|
+
}
|
|
18329
|
+
if (unit >= 57344) {
|
|
18330
|
+
return unit - 2048;
|
|
18331
|
+
}
|
|
18332
|
+
return unit;
|
|
18333
|
+
}
|
|
18334
|
+
function compareCodePoint(left, right) {
|
|
18335
|
+
const sharedLength = Math.min(left.length, right.length);
|
|
18336
|
+
for (let index = 0; index < sharedLength; index += 1) {
|
|
18337
|
+
const leftUnit = left.charCodeAt(index);
|
|
18338
|
+
const rightUnit = right.charCodeAt(index);
|
|
18339
|
+
if (leftUnit !== rightUnit) {
|
|
18340
|
+
return rankCodeUnit(leftUnit) < rankCodeUnit(rightUnit) ? -1 : 1;
|
|
18341
|
+
}
|
|
18342
|
+
}
|
|
18343
|
+
if (left.length === right.length) {
|
|
18344
|
+
return 0;
|
|
18345
|
+
}
|
|
18346
|
+
return left.length < right.length ? -1 : 1;
|
|
18347
|
+
}
|
|
18348
|
+
|
|
18349
|
+
// ../../extensions/drm-copilot/src/lib/push-down/filesystem-adapter.ts
|
|
18298
18350
|
function toPosixPath(value) {
|
|
18299
18351
|
return value.replace(/\\/g, "/");
|
|
18300
18352
|
}
|
|
@@ -18343,9 +18395,7 @@ var RealPushDownFileSystem = class {
|
|
|
18343
18395
|
}
|
|
18344
18396
|
};
|
|
18345
18397
|
walk(normalizedRoot);
|
|
18346
|
-
return files.sort(
|
|
18347
|
-
(left, right) => left < right ? -1 : left > right ? 1 : 0
|
|
18348
|
-
);
|
|
18398
|
+
return files.sort(compareCodePoint);
|
|
18349
18399
|
}
|
|
18350
18400
|
/**
|
|
18351
18401
|
* @param path Path to inspect.
|
|
@@ -18555,7 +18605,7 @@ function enumerateSourceFiles(fs12, sourceRoot, rootFolders) {
|
|
|
18555
18605
|
const sorted = [...rootFiles].sort((left, right) => {
|
|
18556
18606
|
const leftRel = relativeToPosix(left, rootPath) ?? left;
|
|
18557
18607
|
const rightRel = relativeToPosix(right, rootPath) ?? right;
|
|
18558
|
-
return leftRel
|
|
18608
|
+
return compareCodePoint(leftRel, rightRel);
|
|
18559
18609
|
});
|
|
18560
18610
|
orderedFiles.push(...sorted);
|
|
18561
18611
|
}
|
|
@@ -18613,7 +18663,7 @@ function stringifySorted(value, indent) {
|
|
|
18613
18663
|
}
|
|
18614
18664
|
if (input !== null && typeof input === "object") {
|
|
18615
18665
|
const entries = Object.entries(input).sort(
|
|
18616
|
-
([leftKey], [rightKey]) => leftKey
|
|
18666
|
+
([leftKey], [rightKey]) => compareCodePoint(leftKey, rightKey)
|
|
18617
18667
|
);
|
|
18618
18668
|
const result = {};
|
|
18619
18669
|
for (const [key, val] of entries) {
|
|
@@ -18667,11 +18717,11 @@ function pushDownCustomizations(options) {
|
|
|
18667
18717
|
effectiveSource,
|
|
18668
18718
|
effectiveRoots
|
|
18669
18719
|
)) {
|
|
18670
|
-
const
|
|
18671
|
-
if (
|
|
18720
|
+
const relativePath = relativeToPosix(sourcePath, effectiveSource);
|
|
18721
|
+
if (relativePath === null) {
|
|
18672
18722
|
continue;
|
|
18673
18723
|
}
|
|
18674
|
-
const destinationPath = joinPosix2(destinationRoot,
|
|
18724
|
+
const destinationPath = joinPosix2(destinationRoot, relativePath);
|
|
18675
18725
|
const destinationStatus = fs12.isFile(
|
|
18676
18726
|
destinationPath
|
|
18677
18727
|
) ? "overwritten" : "created";
|
|
@@ -18696,7 +18746,7 @@ function pushDownCustomizations(options) {
|
|
|
18696
18746
|
fs12.ensureDir(destParent);
|
|
18697
18747
|
fs12.writeTextFile(destinationPath, rewrittenText);
|
|
18698
18748
|
fileResults.push({
|
|
18699
|
-
relativePath
|
|
18749
|
+
relativePath,
|
|
18700
18750
|
destinationStatus,
|
|
18701
18751
|
rewrittenReferenceCount: rewrittenDelta,
|
|
18702
18752
|
placeholderRewriteCount: placeholderDelta,
|
|
@@ -18787,12 +18837,14 @@ function loadPackManifests(manifestDir, selectedPackNames, fs12) {
|
|
|
18787
18837
|
(name) => !MANIFEST_PACK_NAMES.has(name)
|
|
18788
18838
|
);
|
|
18789
18839
|
if (unknown2.length > 0) {
|
|
18790
|
-
throw new ManifestError(
|
|
18840
|
+
throw new ManifestError(
|
|
18841
|
+
`Unknown Codex pack name(s): ${unknown2.sort(compareCodePoint)}`
|
|
18842
|
+
);
|
|
18791
18843
|
}
|
|
18792
18844
|
const namesToLoad = new Set(selectedPackNames);
|
|
18793
18845
|
namesToLoad.add(CORE_PACK_NAME);
|
|
18794
18846
|
const manifests = /* @__PURE__ */ new Map();
|
|
18795
|
-
for (const name of [...namesToLoad].sort()) {
|
|
18847
|
+
for (const name of [...namesToLoad].sort(compareCodePoint)) {
|
|
18796
18848
|
const manifestPath = joinPosix3(manifestDir, `${name}.json`);
|
|
18797
18849
|
if (!fs12.isFile(manifestPath)) {
|
|
18798
18850
|
throw new ManifestError(
|
|
@@ -18815,14 +18867,16 @@ function resolveManifestPackNames(selectedPackNames, csharpVariant) {
|
|
|
18815
18867
|
);
|
|
18816
18868
|
if (variantSpecific.length > 0) {
|
|
18817
18869
|
throw new ManifestError(
|
|
18818
|
-
`Use public Codex pack 'csharp' with csharpVariant instead of variant-specific pack name(s): ${variantSpecific.sort().join(", ")}.`
|
|
18870
|
+
`Use public Codex pack 'csharp' with csharpVariant instead of variant-specific pack name(s): ${variantSpecific.sort(compareCodePoint).join(", ")}.`
|
|
18819
18871
|
);
|
|
18820
18872
|
}
|
|
18821
18873
|
const unknown2 = [...selectedPackNames].filter(
|
|
18822
18874
|
(name) => !SUPPORTED_PACK_NAMES.has(name)
|
|
18823
18875
|
);
|
|
18824
18876
|
if (unknown2.length > 0) {
|
|
18825
|
-
throw new ManifestError(
|
|
18877
|
+
throw new ManifestError(
|
|
18878
|
+
`Unknown Codex pack name(s): ${unknown2.sort(compareCodePoint)}`
|
|
18879
|
+
);
|
|
18826
18880
|
}
|
|
18827
18881
|
const manifestNames = new Set(selectedPackNames);
|
|
18828
18882
|
if (manifestNames.has(PUBLIC_CSHARP_PACK_NAME)) {
|
|
@@ -18918,7 +18972,7 @@ function resolveVariantSourcePath(destinationRelativePath, csharpVariant) {
|
|
|
18918
18972
|
return destinationRelativePath;
|
|
18919
18973
|
}
|
|
18920
18974
|
function assertSingleCsharpToolchain(publishedPaths, selectedPackNames) {
|
|
18921
|
-
const selectedCsharp = [...selectedPackNames].filter((name) => CSHARP_PACK_NAMES.has(name)).sort();
|
|
18975
|
+
const selectedCsharp = [...selectedPackNames].filter((name) => CSHARP_PACK_NAMES.has(name)).sort(compareCodePoint);
|
|
18922
18976
|
if (selectedCsharp.length > 1) {
|
|
18923
18977
|
throw new ManifestError(
|
|
18924
18978
|
`C# mutual exclusion violated: both modern and legacy Codex C# packs were selected (${selectedCsharp.join(", ")}); select exactly one C# variant.`
|
|
@@ -19208,7 +19262,7 @@ function loadPackManifests2(manifestDir, selectedPackNames, fs12) {
|
|
|
19208
19262
|
const namesToLoad = new Set(selectedPackNames);
|
|
19209
19263
|
namesToLoad.add(CORE_PACK_NAME2);
|
|
19210
19264
|
const manifests = /* @__PURE__ */ new Map();
|
|
19211
|
-
for (const name of [...namesToLoad].sort()) {
|
|
19265
|
+
for (const name of [...namesToLoad].sort(compareCodePoint)) {
|
|
19212
19266
|
const manifestPath = joinPosix5(manifestDir, `${name}.json`);
|
|
19213
19267
|
if (!fs12.isFile(manifestPath)) {
|
|
19214
19268
|
throw new ManifestError2(
|
|
@@ -19303,7 +19357,7 @@ function resolveVariantSourcePath2(destinationRelativePath, csharpVariant) {
|
|
|
19303
19357
|
return destinationRelativePath;
|
|
19304
19358
|
}
|
|
19305
19359
|
function assertSingleCsharpToolchain2(publishedPaths, selectedPackNames) {
|
|
19306
|
-
const selectedCsharp = [...selectedPackNames].filter((name) => CSHARP_PACK_NAMES2.has(name)).sort();
|
|
19360
|
+
const selectedCsharp = [...selectedPackNames].filter((name) => CSHARP_PACK_NAMES2.has(name)).sort(compareCodePoint);
|
|
19307
19361
|
if (selectedCsharp.length > 1) {
|
|
19308
19362
|
throw new ManifestError2(
|
|
19309
19363
|
`C# mutual exclusion violated: both modern and legacy C# packs were selected ([${selectedCsharp.map((n) => `'${n}'`).join(", ")}]); select exactly one C# variant.`
|
|
@@ -19313,6 +19367,10 @@ function assertSingleCsharpToolchain2(publishedPaths, selectedPackNames) {
|
|
|
19313
19367
|
}
|
|
19314
19368
|
|
|
19315
19369
|
// ../../extensions/drm-copilot/src/lib/push-down/claude-filesystem-adapter.ts
|
|
19370
|
+
var LOCAL_RUNTIME_RELATIVE_DIRECTORIES = [
|
|
19371
|
+
".claude/state",
|
|
19372
|
+
".claude/worktrees"
|
|
19373
|
+
];
|
|
19316
19374
|
function normalizePosix3(value) {
|
|
19317
19375
|
return value.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
19318
19376
|
}
|
|
@@ -19378,6 +19436,21 @@ var ExcludingFileSystem = class {
|
|
|
19378
19436
|
sourceRelativePosix(path16) {
|
|
19379
19437
|
return relativeToPosix3(path16, this.sourceRoot);
|
|
19380
19438
|
}
|
|
19439
|
+
/**
|
|
19440
|
+
* Return whether a path is a local runtime directory or lies below one.
|
|
19441
|
+
*
|
|
19442
|
+
* @param path An absolute candidate POSIX path from the inner adapter.
|
|
19443
|
+
* @returns True when the source-relative path is in a runtime directory.
|
|
19444
|
+
*/
|
|
19445
|
+
isLocalRuntimePath(path16) {
|
|
19446
|
+
const relative2 = this.sourceRelativePosix(path16);
|
|
19447
|
+
if (relative2 === null) {
|
|
19448
|
+
return false;
|
|
19449
|
+
}
|
|
19450
|
+
return LOCAL_RUNTIME_RELATIVE_DIRECTORIES.some(
|
|
19451
|
+
(directory) => relative2 === directory || relative2.startsWith(`${directory}/`)
|
|
19452
|
+
);
|
|
19453
|
+
}
|
|
19381
19454
|
/**
|
|
19382
19455
|
* Return whether a candidate path is in the active published set.
|
|
19383
19456
|
*
|
|
@@ -19403,15 +19476,15 @@ var ExcludingFileSystem = class {
|
|
|
19403
19476
|
* @returns True when the file is outside the memory subtree or general-scoped.
|
|
19404
19477
|
*/
|
|
19405
19478
|
isScopeIncluded(path16) {
|
|
19406
|
-
const
|
|
19407
|
-
if (
|
|
19479
|
+
const relativePath = relativeToPosix3(path16, this.repoRoot);
|
|
19480
|
+
if (relativePath === null) {
|
|
19408
19481
|
return true;
|
|
19409
19482
|
}
|
|
19410
|
-
if (!isUnderAgentMemory(
|
|
19483
|
+
if (!isUnderAgentMemory(relativePath)) {
|
|
19411
19484
|
return true;
|
|
19412
19485
|
}
|
|
19413
19486
|
const content = this.readText(path16);
|
|
19414
|
-
return isGeneralMemoryFile(
|
|
19487
|
+
return isGeneralMemoryFile(relativePath, content);
|
|
19415
19488
|
}
|
|
19416
19489
|
/**
|
|
19417
19490
|
* Return whether a candidate file passes the memory-mode filter.
|
|
@@ -19461,7 +19534,7 @@ var ExcludingFileSystem = class {
|
|
|
19461
19534
|
}
|
|
19462
19535
|
listFiles(root) {
|
|
19463
19536
|
return this.inner.listFiles(root).filter(
|
|
19464
|
-
(p) => !this.excluded.has(normalizePosix3(p)) && this.isPackIncluded(p) && this.isScopeIncluded(p) && this.isMemoryModeIncluded(p)
|
|
19537
|
+
(p) => !this.isLocalRuntimePath(p) && !this.excluded.has(normalizePosix3(p)) && this.isPackIncluded(p) && this.isScopeIncluded(p) && this.isMemoryModeIncluded(p)
|
|
19465
19538
|
);
|
|
19466
19539
|
}
|
|
19467
19540
|
isDir(path16) {
|
|
@@ -19678,9 +19751,6 @@ var EXCLUDED_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
|
19678
19751
|
"tests",
|
|
19679
19752
|
"venv"
|
|
19680
19753
|
]);
|
|
19681
|
-
function compareOrdinal(left, right) {
|
|
19682
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
19683
|
-
}
|
|
19684
19754
|
function isExcludedDirectoryName(name) {
|
|
19685
19755
|
return name.startsWith(".") || EXCLUDED_DIR_NAMES.has(name);
|
|
19686
19756
|
}
|
|
@@ -19709,7 +19779,7 @@ function classifyProjectDirectories(observations) {
|
|
|
19709
19779
|
structureObserved = true;
|
|
19710
19780
|
}
|
|
19711
19781
|
}
|
|
19712
|
-
return { modulePaths: modulePaths.sort(
|
|
19782
|
+
return { modulePaths: modulePaths.sort(compareCodePoint), structureObserved };
|
|
19713
19783
|
}
|
|
19714
19784
|
|
|
19715
19785
|
// ../../extensions/drm-copilot/src/lib/push-down/claude-blast-radius-derive-core.ts
|
|
@@ -19777,12 +19847,12 @@ function pruneAncestors(paths) {
|
|
|
19777
19847
|
function topLevelDirectories(observations) {
|
|
19778
19848
|
const names = [];
|
|
19779
19849
|
for (const observation of observations) {
|
|
19780
|
-
const
|
|
19781
|
-
if (
|
|
19782
|
-
names.push(
|
|
19850
|
+
const relativePath = observation.relativePath;
|
|
19851
|
+
if (relativePath !== "" && !relativePath.includes("/")) {
|
|
19852
|
+
names.push(relativePath);
|
|
19783
19853
|
}
|
|
19784
19854
|
}
|
|
19785
|
-
return names.sort(
|
|
19855
|
+
return names.sort(compareCodePoint);
|
|
19786
19856
|
}
|
|
19787
19857
|
function assembleModules(derivedPaths) {
|
|
19788
19858
|
const combined = /* @__PURE__ */ new Map();
|
|
@@ -19793,7 +19863,7 @@ function assembleModules(derivedPaths) {
|
|
|
19793
19863
|
combined.set(name, [...globs]);
|
|
19794
19864
|
}
|
|
19795
19865
|
const modules = {};
|
|
19796
|
-
for (const name of [...combined.keys()].sort(
|
|
19866
|
+
for (const name of [...combined.keys()].sort(compareCodePoint)) {
|
|
19797
19867
|
const globs = combined.get(name);
|
|
19798
19868
|
if (globs !== void 0) {
|
|
19799
19869
|
modules[name] = globs;
|
|
@@ -19869,9 +19939,7 @@ var realDirectoryLister = (root) => {
|
|
|
19869
19939
|
} catch {
|
|
19870
19940
|
return [];
|
|
19871
19941
|
}
|
|
19872
|
-
return entries.map((entry) => ({ name: entry.name, isDir: entry.isDirectory() })).sort(
|
|
19873
|
-
(left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0
|
|
19874
|
-
);
|
|
19942
|
+
return entries.map((entry) => ({ name: entry.name, isDir: entry.isDirectory() })).sort((left, right) => compareCodePoint(left.name, right.name));
|
|
19875
19943
|
};
|
|
19876
19944
|
function listTolerantly(lister, path16) {
|
|
19877
19945
|
try {
|
|
@@ -20065,7 +20133,7 @@ function composeModules(base, overlay, overlayPath) {
|
|
|
20065
20133
|
merged[name] = globs;
|
|
20066
20134
|
}
|
|
20067
20135
|
const composed = {};
|
|
20068
|
-
for (const name of Object.keys(merged).sort(
|
|
20136
|
+
for (const name of Object.keys(merged).sort(compareCodePoint)) {
|
|
20069
20137
|
const globs = merged[name] ?? [];
|
|
20070
20138
|
composed[name] = globs;
|
|
20071
20139
|
for (const glob of Array.isArray(globs) ? globs : []) {
|
|
@@ -20393,19 +20461,19 @@ function matchesExclusionEntry(entry, candidate) {
|
|
|
20393
20461
|
function planExclusions(payloadRelativePaths, manifest, destinationExists) {
|
|
20394
20462
|
const kept = [];
|
|
20395
20463
|
const skipped = [];
|
|
20396
|
-
for (const
|
|
20464
|
+
for (const relativePath of payloadRelativePaths) {
|
|
20397
20465
|
const entry = manifest.entries.find(
|
|
20398
|
-
(candidate) => matchesExclusionEntry(candidate,
|
|
20466
|
+
(candidate) => matchesExclusionEntry(candidate, relativePath)
|
|
20399
20467
|
);
|
|
20400
20468
|
if (entry === void 0) {
|
|
20401
|
-
kept.push(
|
|
20469
|
+
kept.push(relativePath);
|
|
20402
20470
|
continue;
|
|
20403
20471
|
}
|
|
20404
20472
|
skipped.push({
|
|
20405
|
-
relativePath
|
|
20473
|
+
relativePath,
|
|
20406
20474
|
entry: entry.normalized,
|
|
20407
20475
|
line: entry.line,
|
|
20408
|
-
destinationStatus: destinationExists(
|
|
20476
|
+
destinationStatus: destinationExists(relativePath) ? "present" : "absent"
|
|
20409
20477
|
});
|
|
20410
20478
|
}
|
|
20411
20479
|
const claimed = new Set(
|
|
@@ -20416,16 +20484,16 @@ function planExclusions(payloadRelativePaths, manifest, destinationExists) {
|
|
|
20416
20484
|
);
|
|
20417
20485
|
return { kept, skipped, unmatchedEntries };
|
|
20418
20486
|
}
|
|
20419
|
-
function assertManifestPathIsRootLevel(
|
|
20420
|
-
if (
|
|
20487
|
+
function assertManifestPathIsRootLevel(relativePath, rootFolders) {
|
|
20488
|
+
if (relativePath.includes("/")) {
|
|
20421
20489
|
throw new Error(
|
|
20422
|
-
`Exclusion manifest path must be root-level: ${
|
|
20490
|
+
`Exclusion manifest path must be root-level: ${relativePath}`
|
|
20423
20491
|
);
|
|
20424
20492
|
}
|
|
20425
|
-
const root = rootFolders.find((name) =>
|
|
20493
|
+
const root = rootFolders.find((name) => relativePath.startsWith(name));
|
|
20426
20494
|
if (root !== void 0) {
|
|
20427
20495
|
throw new Error(
|
|
20428
|
-
`Exclusion manifest path must not begin with published root ${root}: ${
|
|
20496
|
+
`Exclusion manifest path must not begin with published root ${root}: ${relativePath}`
|
|
20429
20497
|
);
|
|
20430
20498
|
}
|
|
20431
20499
|
}
|
|
@@ -21020,12 +21088,12 @@ var RealFileSystem = class {
|
|
|
21020
21088
|
return;
|
|
21021
21089
|
}
|
|
21022
21090
|
for (const entry of entries) {
|
|
21023
|
-
const
|
|
21024
|
-
if (matcher.test(
|
|
21025
|
-
matches.push(joinPosix8(normalizedRoot,
|
|
21091
|
+
const relativePath = relativePrefix === "" ? entry.name : `${relativePrefix}/${entry.name}`;
|
|
21092
|
+
if (matcher.test(relativePath)) {
|
|
21093
|
+
matches.push(joinPosix8(normalizedRoot, relativePath));
|
|
21026
21094
|
}
|
|
21027
21095
|
if (entry.isDirectory()) {
|
|
21028
|
-
walk(nodePath3.join(currentDir, entry.name),
|
|
21096
|
+
walk(nodePath3.join(currentDir, entry.name), relativePath);
|
|
21029
21097
|
}
|
|
21030
21098
|
}
|
|
21031
21099
|
};
|
|
@@ -21423,12 +21491,12 @@ function extractTemplateVariables(template) {
|
|
|
21423
21491
|
}
|
|
21424
21492
|
function replaceAllVariables(template, variables) {
|
|
21425
21493
|
const referenced = extractTemplateVariables(template);
|
|
21426
|
-
const missing = [...referenced].filter((name) => !(name in variables)).sort();
|
|
21494
|
+
const missing = [...referenced].filter((name) => !(name in variables)).sort(compareCodePoint);
|
|
21427
21495
|
if (missing.length > 0) {
|
|
21428
21496
|
throw new Error(`Unresolved template variables: ${missing.join(", ")}`);
|
|
21429
21497
|
}
|
|
21430
21498
|
let resolved = template;
|
|
21431
|
-
for (const key of [...referenced].sort()) {
|
|
21499
|
+
for (const key of [...referenced].sort(compareCodePoint)) {
|
|
21432
21500
|
resolved = resolved.split(`\${${key}}`).join(variables[key] ?? "");
|
|
21433
21501
|
}
|
|
21434
21502
|
if (extractTemplateVariables(resolved).size > 0) {
|
|
@@ -21877,9 +21945,7 @@ function validationFindingToJson(finding) {
|
|
|
21877
21945
|
}
|
|
21878
21946
|
function sourceArtifactToJson(artifact) {
|
|
21879
21947
|
const sortedFrontmatter = {};
|
|
21880
|
-
for (const key of Object.keys(artifact.frontmatter).sort(
|
|
21881
|
-
(left, right) => left < right ? -1 : left > right ? 1 : 0
|
|
21882
|
-
)) {
|
|
21948
|
+
for (const key of Object.keys(artifact.frontmatter).sort(compareCodePoint)) {
|
|
21883
21949
|
sortedFrontmatter[key] = artifact.frontmatter[key];
|
|
21884
21950
|
}
|
|
21885
21951
|
return {
|
|
@@ -22377,9 +22443,7 @@ function normalizeSelectedPaths(sourceRoot, selectedPaths) {
|
|
|
22377
22443
|
for (const candidatePath of selectedPaths) {
|
|
22378
22444
|
normalized.add(normalizeRelativePath(sourceRoot, candidatePath));
|
|
22379
22445
|
}
|
|
22380
|
-
return [...normalized].sort(
|
|
22381
|
-
(left, right) => left < right ? -1 : left > right ? 1 : 0
|
|
22382
|
-
);
|
|
22446
|
+
return [...normalized].sort(compareCodePoint);
|
|
22383
22447
|
}
|
|
22384
22448
|
function collectFilesRecursive(fileSystem, absoluteDir, out) {
|
|
22385
22449
|
for (const childName of fileSystem.listDirectory(absoluteDir)) {
|
|
@@ -22412,9 +22476,7 @@ function iterSupportedArtifacts(fileSystem, sourceRoot, sourceEcosystem) {
|
|
|
22412
22476
|
discovered.add(filePath.slice(rootPrefix.length));
|
|
22413
22477
|
}
|
|
22414
22478
|
}
|
|
22415
|
-
return [...discovered].sort(
|
|
22416
|
-
(left, right) => left < right ? -1 : left > right ? 1 : 0
|
|
22417
|
-
);
|
|
22479
|
+
return [...discovered].sort(compareCodePoint);
|
|
22418
22480
|
}
|
|
22419
22481
|
function discoverSourceArtifacts(fileSystem, sourceRoot, sourceEcosystem, selectedPaths) {
|
|
22420
22482
|
const allArtifacts = iterSupportedArtifacts(
|
|
@@ -22440,9 +22502,7 @@ function discoverSourceArtifacts(fileSystem, sourceRoot, sourceEcosystem, select
|
|
|
22440
22502
|
matched.push(artifactPath);
|
|
22441
22503
|
}
|
|
22442
22504
|
}
|
|
22443
|
-
return matched.sort(
|
|
22444
|
-
(left, right) => left < right ? -1 : left > right ? 1 : 0
|
|
22445
|
-
);
|
|
22505
|
+
return matched.sort(compareCodePoint);
|
|
22446
22506
|
}
|
|
22447
22507
|
function isUnderSelectedDirectory(artifactPath, selectedSet) {
|
|
22448
22508
|
const segments = artifactPath.split("/");
|
|
@@ -22853,7 +22913,7 @@ var BASE_REWRITE_RULES = [
|
|
|
22853
22913
|
},
|
|
22854
22914
|
{
|
|
22855
22915
|
pattern: /Return the finalized plan for validation-only preflight through `atomic-executor` and preserve the same target file path across revision loops\. Do not claim nested worker delegation from within planner execution\./g,
|
|
22856
|
-
replacement: 'Before reporting completion, explicitly spawn the `atomic-executor` subagent for validation-only preflight. The delegated prompt MUST include the exact directive `DIRECTIVE: PREFLIGHT VALIDATION ONLY`.\n\n- `atomic-executor` MUST return exactly one of:\n - `PREFLIGHT: ALL CLEAR`\n - `PREFLIGHT: REVISIONS REQUIRED`\n- Treat executor preflight findings as binding plan defects.\n- If preflight returns `PREFLIGHT: REVISIONS REQUIRED`, revise the same target plan file using the executor\'s precise plan delta and
|
|
22916
|
+
replacement: 'Before reporting completion, explicitly spawn the `atomic-executor` subagent for validation-only preflight. The delegated prompt MUST include the exact directive `DIRECTIVE: PREFLIGHT VALIDATION ONLY`.\n\n- `atomic-executor` MUST return exactly one of:\n - `PREFLIGHT: ALL CLEAR`\n - `PREFLIGHT: REVISIONS REQUIRED`\n- Treat executor preflight findings as binding plan defects.\n- If preflight returns `PREFLIGHT: REVISIONS REQUIRED`, revise the same target plan file once using the executor\'s precise plan delta and its full `PREFLIGHT-DEFECT:` list, and run one confirming preflight. Preflight is single-pass: trivial defects are fixed in place by the executor, and a plan returns to the planner at most once; a second substantive result halts with `blocked_reason: "validator_failed"`.\n- Reuse the same target plan file for the single permitted preflight revision in the same planning cycle.\n- If the required `atomic-executor` handoff cannot be started or completed, stop and report blocked state; do not self-approve the plan.\n- Before reporting completion, the target plan MUST pass the `validate_orchestration_artifacts` MCP tool with `artifact_type: "plan"` and `artifact_path: <plan-path>`.\n\nDo not claim nested worker delegation from within planner execution.',
|
|
22857
22917
|
description: "Expand the Claude atomic-planner preflight shorthand into the strict Codex atomic-executor handoff contract."
|
|
22858
22918
|
},
|
|
22859
22919
|
{
|
|
@@ -23283,23 +23343,19 @@ function buildPromptTranslationTraces(fileSystem, runOptions, mappingRecord) {
|
|
|
23283
23343
|
});
|
|
23284
23344
|
}
|
|
23285
23345
|
return [...translationTraces].sort((left, right) => {
|
|
23286
|
-
|
|
23287
|
-
|
|
23288
|
-
|
|
23289
|
-
if (left.sectionId !== right.sectionId) {
|
|
23290
|
-
return left.sectionId < right.sectionId ? -1 : 1;
|
|
23346
|
+
const bySource = compareCodePoint(left.sourcePath, right.sourcePath);
|
|
23347
|
+
if (bySource !== 0) {
|
|
23348
|
+
return bySource;
|
|
23291
23349
|
}
|
|
23292
|
-
|
|
23293
|
-
|
|
23350
|
+
const bySection = compareCodePoint(left.sectionId, right.sectionId);
|
|
23351
|
+
if (bySection !== 0) {
|
|
23352
|
+
return bySection;
|
|
23294
23353
|
}
|
|
23295
|
-
return
|
|
23354
|
+
return compareCodePoint(left.targetRole, right.targetRole);
|
|
23296
23355
|
});
|
|
23297
23356
|
}
|
|
23298
23357
|
|
|
23299
23358
|
// ../../extensions/drm-copilot/src/lib/codex-native-converter/engine-pipeline.ts
|
|
23300
|
-
function compareStrings(left, right) {
|
|
23301
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
23302
|
-
}
|
|
23303
23359
|
function planMappings(fileSystem, runOptions) {
|
|
23304
23360
|
const discoveredPaths = discoverSourceArtifacts(
|
|
23305
23361
|
fileSystem,
|
|
@@ -23321,7 +23377,7 @@ function planMappings(fileSystem, runOptions) {
|
|
|
23321
23377
|
mappingRecords.push(mappedRecord);
|
|
23322
23378
|
}
|
|
23323
23379
|
return [...mappingRecords].sort(
|
|
23324
|
-
(left, right) =>
|
|
23380
|
+
(left, right) => compareCodePoint(left.sourcePath, right.sourcePath)
|
|
23325
23381
|
);
|
|
23326
23382
|
}
|
|
23327
23383
|
function renderGeneratedOutput(fileSystem, runOptions, mappingRecords, plannedEmissions) {
|
|
@@ -23348,7 +23404,7 @@ function renderGeneratedOutput(fileSystem, runOptions, mappingRecords, plannedEm
|
|
|
23348
23404
|
sectionEmissionsByTarget.set(plannedEmission.targetPath, bucket);
|
|
23349
23405
|
}
|
|
23350
23406
|
for (const targetPath of [...mappingRecordsByTarget.keys()].sort(
|
|
23351
|
-
|
|
23407
|
+
compareCodePoint
|
|
23352
23408
|
)) {
|
|
23353
23409
|
const recordsForTarget = mappingRecordsByTarget.get(targetPath) ?? [];
|
|
23354
23410
|
if (recordsForTarget.length === 0) {
|
|
@@ -23376,7 +23432,7 @@ function renderGeneratedOutput(fileSystem, runOptions, mappingRecords, plannedEm
|
|
|
23376
23432
|
...new Set(
|
|
23377
23433
|
plannedEmissions.filter((emission) => emission.targetPath !== null).map((emission) => emission.sourcePath)
|
|
23378
23434
|
)
|
|
23379
|
-
].sort(
|
|
23435
|
+
].sort(compareCodePoint);
|
|
23380
23436
|
for (const sourcePath of parsedSourcePaths) {
|
|
23381
23437
|
const sourceArtifact = parseSourceArtifact(
|
|
23382
23438
|
fileSystem,
|
|
@@ -23390,7 +23446,7 @@ function renderGeneratedOutput(fileSystem, runOptions, mappingRecords, plannedEm
|
|
|
23390
23446
|
}
|
|
23391
23447
|
}
|
|
23392
23448
|
for (const targetPath of [...sectionEmissionsByTarget.keys()].sort(
|
|
23393
|
-
|
|
23449
|
+
compareCodePoint
|
|
23394
23450
|
)) {
|
|
23395
23451
|
if (targetPath in generatedOutput) {
|
|
23396
23452
|
continue;
|
|
@@ -23413,15 +23469,15 @@ function buildTranslationTraces(fileSystem, runOptions, mappingRecords) {
|
|
|
23413
23469
|
);
|
|
23414
23470
|
}
|
|
23415
23471
|
return [...translationTraces].sort((left, right) => {
|
|
23416
|
-
const bySource =
|
|
23472
|
+
const bySource = compareCodePoint(left.sourcePath, right.sourcePath);
|
|
23417
23473
|
if (bySource !== 0) {
|
|
23418
23474
|
return bySource;
|
|
23419
23475
|
}
|
|
23420
|
-
const bySection =
|
|
23476
|
+
const bySection = compareCodePoint(left.sectionId, right.sectionId);
|
|
23421
23477
|
if (bySection !== 0) {
|
|
23422
23478
|
return bySection;
|
|
23423
23479
|
}
|
|
23424
|
-
return
|
|
23480
|
+
return compareCodePoint(left.targetRole, right.targetRole);
|
|
23425
23481
|
});
|
|
23426
23482
|
}
|
|
23427
23483
|
function buildPlannedEmissions(translationTraces) {
|
|
@@ -23439,7 +23495,9 @@ function buildPlannedEmissions(translationTraces) {
|
|
|
23439
23495
|
}
|
|
23440
23496
|
function writeDestinationOutputs(fileSystem, destinationRoot, generatedOutput) {
|
|
23441
23497
|
const normalizedRoot = destinationRoot.replace(/\/+$/, "");
|
|
23442
|
-
for (const targetPath of Object.keys(generatedOutput).sort(
|
|
23498
|
+
for (const targetPath of Object.keys(generatedOutput).sort(
|
|
23499
|
+
compareCodePoint
|
|
23500
|
+
)) {
|
|
23443
23501
|
const fullPath = normalizedRoot === "" ? targetPath : `${normalizedRoot}/${targetPath}`;
|
|
23444
23502
|
fileSystem.writeTextFile(fullPath, generatedOutput[targetPath] ?? "");
|
|
23445
23503
|
}
|
|
@@ -23453,7 +23511,7 @@ function sortKeysDeep(value) {
|
|
|
23453
23511
|
if (value !== null && typeof value === "object") {
|
|
23454
23512
|
const sorted = {};
|
|
23455
23513
|
for (const key of Object.keys(value).sort(
|
|
23456
|
-
|
|
23514
|
+
compareCodePoint
|
|
23457
23515
|
)) {
|
|
23458
23516
|
sorted[key] = sortKeysDeep(value[key]);
|
|
23459
23517
|
}
|
|
@@ -23529,7 +23587,7 @@ function extractTopologyDestinations(renderedText, knownDestinationPaths) {
|
|
|
23529
23587
|
if (left[0] !== right[0]) {
|
|
23530
23588
|
return left[0] - right[0];
|
|
23531
23589
|
}
|
|
23532
|
-
return left[1]
|
|
23590
|
+
return compareCodePoint(left[1], right[1]);
|
|
23533
23591
|
});
|
|
23534
23592
|
return destinationsByPosition.map(([, destinationPath]) => destinationPath);
|
|
23535
23593
|
}
|
|
@@ -23541,7 +23599,7 @@ function buildTopologyEdges(fileSystem, runOptions, mappingRecords, translationT
|
|
|
23541
23599
|
...new Set(
|
|
23542
23600
|
mappingRecords.filter((record3) => record3.targetPath !== null).map((record3) => record3.targetPath)
|
|
23543
23601
|
)
|
|
23544
|
-
].sort(
|
|
23602
|
+
].sort(compareCodePoint);
|
|
23545
23603
|
const topologyEdges = [];
|
|
23546
23604
|
const translationTraceSourcePaths = new Set(
|
|
23547
23605
|
translationTraces.map((trace) => trace.sourcePath)
|
|
@@ -23587,13 +23645,11 @@ function buildTopologyEdges(fileSystem, runOptions, mappingRecords, translationT
|
|
|
23587
23645
|
}
|
|
23588
23646
|
}
|
|
23589
23647
|
return [...topologyEdges].sort((left, right) => {
|
|
23590
|
-
|
|
23591
|
-
|
|
23592
|
-
|
|
23593
|
-
if (left.destinationPath !== right.destinationPath) {
|
|
23594
|
-
return left.destinationPath < right.destinationPath ? -1 : 1;
|
|
23648
|
+
const bySource = compareCodePoint(left.sourcePath, right.sourcePath);
|
|
23649
|
+
if (bySource !== 0) {
|
|
23650
|
+
return bySource;
|
|
23595
23651
|
}
|
|
23596
|
-
return
|
|
23652
|
+
return compareCodePoint(left.destinationPath, right.destinationPath);
|
|
23597
23653
|
});
|
|
23598
23654
|
}
|
|
23599
23655
|
|
|
@@ -23666,38 +23722,35 @@ function renderDestinationToRepeatedSourceChart(topologyEdges) {
|
|
|
23666
23722
|
}
|
|
23667
23723
|
|
|
23668
23724
|
// ../../extensions/drm-copilot/src/lib/codex-native-converter/reporting-render.ts
|
|
23669
|
-
function compareStrings2(left, right) {
|
|
23670
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
23671
|
-
}
|
|
23672
23725
|
function renderConversionReport(runOptions, mappingRecords, topologyEdges, translationTraces, validationFindings) {
|
|
23673
23726
|
const blockingCount = validationFindings.filter(
|
|
23674
23727
|
(finding) => finding.blocking
|
|
23675
23728
|
).length;
|
|
23676
23729
|
const destinationRootText = runOptions.destinationRoot !== null ? toPosixPath2(runOptions.destinationRoot) : "review-only";
|
|
23677
23730
|
const sortedMappingRecords = [...mappingRecords].sort(
|
|
23678
|
-
(left, right) =>
|
|
23731
|
+
(left, right) => compareCodePoint(left.sourcePath, right.sourcePath)
|
|
23679
23732
|
);
|
|
23680
23733
|
const sortedTopologyEdges = [...topologyEdges].sort((left, right) => {
|
|
23681
|
-
const bySource =
|
|
23734
|
+
const bySource = compareCodePoint(left.sourcePath, right.sourcePath);
|
|
23682
23735
|
if (bySource !== 0) {
|
|
23683
23736
|
return bySource;
|
|
23684
23737
|
}
|
|
23685
|
-
return
|
|
23738
|
+
return compareCodePoint(left.destinationPath, right.destinationPath);
|
|
23686
23739
|
});
|
|
23687
23740
|
const sortedTranslationTraces = [...translationTraces].sort((left, right) => {
|
|
23688
|
-
const bySource =
|
|
23741
|
+
const bySource = compareCodePoint(left.sourcePath, right.sourcePath);
|
|
23689
23742
|
if (bySource !== 0) {
|
|
23690
23743
|
return bySource;
|
|
23691
23744
|
}
|
|
23692
|
-
const bySection =
|
|
23745
|
+
const bySection = compareCodePoint(left.sectionId, right.sectionId);
|
|
23693
23746
|
if (bySection !== 0) {
|
|
23694
23747
|
return bySection;
|
|
23695
23748
|
}
|
|
23696
|
-
const byRole =
|
|
23749
|
+
const byRole = compareCodePoint(left.targetRole, right.targetRole);
|
|
23697
23750
|
if (byRole !== 0) {
|
|
23698
23751
|
return byRole;
|
|
23699
23752
|
}
|
|
23700
|
-
return
|
|
23753
|
+
return compareCodePoint(left.targetPath ?? "", right.targetPath ?? "");
|
|
23701
23754
|
});
|
|
23702
23755
|
const lines = [
|
|
23703
23756
|
"# Conversion Report",
|
|
@@ -23765,18 +23818,18 @@ function renderConversionReport(runOptions, mappingRecords, topologyEdges, trans
|
|
|
23765
23818
|
lines.push("- None");
|
|
23766
23819
|
} else {
|
|
23767
23820
|
const sortedFindings = [...validationFindings].sort((left, right) => {
|
|
23768
|
-
const byCode =
|
|
23821
|
+
const byCode = compareCodePoint(left.code, right.code);
|
|
23769
23822
|
if (byCode !== 0) {
|
|
23770
23823
|
return byCode;
|
|
23771
23824
|
}
|
|
23772
|
-
const bySource =
|
|
23825
|
+
const bySource = compareCodePoint(
|
|
23773
23826
|
left.sourcePath ?? "",
|
|
23774
23827
|
right.sourcePath ?? ""
|
|
23775
23828
|
);
|
|
23776
23829
|
if (bySource !== 0) {
|
|
23777
23830
|
return bySource;
|
|
23778
23831
|
}
|
|
23779
|
-
return
|
|
23832
|
+
return compareCodePoint(left.targetPath ?? "", right.targetPath ?? "");
|
|
23780
23833
|
});
|
|
23781
23834
|
for (const validationFinding of sortedFindings) {
|
|
23782
23835
|
lines.push(
|
|
@@ -23795,7 +23848,7 @@ function sortKeysDeep2(value) {
|
|
|
23795
23848
|
if (value !== null && typeof value === "object") {
|
|
23796
23849
|
const sorted = {};
|
|
23797
23850
|
for (const key of Object.keys(value).sort(
|
|
23798
|
-
|
|
23851
|
+
compareCodePoint
|
|
23799
23852
|
)) {
|
|
23800
23853
|
sorted[key] = sortKeysDeep2(value[key]);
|
|
23801
23854
|
}
|
|
@@ -23837,21 +23890,23 @@ function joinPosix12(root, child) {
|
|
|
23837
23890
|
}
|
|
23838
23891
|
function sortBySourcePath(mappingRecords) {
|
|
23839
23892
|
return [...mappingRecords].sort(
|
|
23840
|
-
(left, right) => left.sourcePath
|
|
23893
|
+
(left, right) => compareCodePoint(left.sourcePath, right.sourcePath)
|
|
23841
23894
|
);
|
|
23842
23895
|
}
|
|
23843
23896
|
function sortFindings(validationFindings) {
|
|
23844
|
-
const compare = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
23845
23897
|
return [...validationFindings].sort((left, right) => {
|
|
23846
|
-
const byCode =
|
|
23898
|
+
const byCode = compareCodePoint(left.code, right.code);
|
|
23847
23899
|
if (byCode !== 0) {
|
|
23848
23900
|
return byCode;
|
|
23849
23901
|
}
|
|
23850
|
-
const bySource =
|
|
23902
|
+
const bySource = compareCodePoint(
|
|
23903
|
+
left.sourcePath ?? "",
|
|
23904
|
+
right.sourcePath ?? ""
|
|
23905
|
+
);
|
|
23851
23906
|
if (bySource !== 0) {
|
|
23852
23907
|
return bySource;
|
|
23853
23908
|
}
|
|
23854
|
-
return
|
|
23909
|
+
return compareCodePoint(left.targetPath ?? "", right.targetPath ?? "");
|
|
23855
23910
|
});
|
|
23856
23911
|
}
|
|
23857
23912
|
function writeConversionReportSet(fileSystem, runOptions, mappingRecords, topologyEdges, translationTraces, validationFindings, generatedOutput) {
|
|
@@ -23890,7 +23945,7 @@ function writeConversionReportSet(fileSystem, runOptions, mappingRecords, topolo
|
|
|
23890
23945
|
dumpsSortedWithNewline(validationResultsPayload)
|
|
23891
23946
|
);
|
|
23892
23947
|
for (const targetPath of Object.keys(generatedOutput).sort(
|
|
23893
|
-
|
|
23948
|
+
compareCodePoint
|
|
23894
23949
|
)) {
|
|
23895
23950
|
fileSystem.writeTextFile(
|
|
23896
23951
|
joinPosix12(proposedTreeRoot, targetPath),
|
|
@@ -24056,9 +24111,7 @@ function validateDuplicateTargets(mappingRecords, plannedEmissions) {
|
|
|
24056
24111
|
conflictingTargets.add(targetPath);
|
|
24057
24112
|
}
|
|
24058
24113
|
}
|
|
24059
|
-
for (const targetPath of [...conflictingTargets].sort(
|
|
24060
|
-
(left, right) => left < right ? -1 : left > right ? 1 : 0
|
|
24061
|
-
)) {
|
|
24114
|
+
for (const targetPath of [...conflictingTargets].sort(compareCodePoint)) {
|
|
24062
24115
|
for (const plannedEmission of sectionEmissionsByTarget.get(targetPath) ?? []) {
|
|
24063
24116
|
findings.push(
|
|
24064
24117
|
buildFinding({
|
|
@@ -24101,17 +24154,19 @@ function validateConversionPlan(runOptions, mappingRecords, plannedEmissions, ge
|
|
|
24101
24154
|
...validateDuplicateTargets(mappingRecords, plannedEmissions),
|
|
24102
24155
|
...validateGeneratedOutput(generatedOutput)
|
|
24103
24156
|
];
|
|
24104
|
-
const compare = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
24105
24157
|
return [...findings].sort((left, right) => {
|
|
24106
|
-
const byCode =
|
|
24158
|
+
const byCode = compareCodePoint(left.code, right.code);
|
|
24107
24159
|
if (byCode !== 0) {
|
|
24108
24160
|
return byCode;
|
|
24109
24161
|
}
|
|
24110
|
-
const bySource =
|
|
24162
|
+
const bySource = compareCodePoint(
|
|
24163
|
+
left.sourcePath ?? "",
|
|
24164
|
+
right.sourcePath ?? ""
|
|
24165
|
+
);
|
|
24111
24166
|
if (bySource !== 0) {
|
|
24112
24167
|
return bySource;
|
|
24113
24168
|
}
|
|
24114
|
-
return
|
|
24169
|
+
return compareCodePoint(left.targetPath ?? "", right.targetPath ?? "");
|
|
24115
24170
|
});
|
|
24116
24171
|
}
|
|
24117
24172
|
|
|
@@ -24888,13 +24943,13 @@ function validateLaunchBindings(features, context) {
|
|
|
24888
24943
|
});
|
|
24889
24944
|
return errors;
|
|
24890
24945
|
}
|
|
24891
|
-
function validateEpicPlannerChildLaunchBindings(features) {
|
|
24946
|
+
function validateEpicPlannerChildLaunchBindings(features, options = {}) {
|
|
24892
24947
|
return validateLaunchBindings(features, {
|
|
24893
24948
|
expectedExecutionContext: "epic_preparation_child",
|
|
24894
24949
|
planner: true,
|
|
24895
24950
|
requireGeneratedOrchestrator: true,
|
|
24896
24951
|
skipNotStarted: false,
|
|
24897
|
-
requireLaunchPaths:
|
|
24952
|
+
requireLaunchPaths: options.requireLaunchPaths === true
|
|
24898
24953
|
});
|
|
24899
24954
|
}
|
|
24900
24955
|
function validateEpicChildLaunchBindings(state, options = {}) {
|
|
@@ -25261,7 +25316,7 @@ function validateCodexModelRoutingGate(state) {
|
|
|
25261
25316
|
deploymentAgents.add(deployment);
|
|
25262
25317
|
}
|
|
25263
25318
|
}
|
|
25264
|
-
for (const agent of [...delegated].sort()) {
|
|
25319
|
+
for (const agent of [...delegated].sort(compareCodePoint)) {
|
|
25265
25320
|
if (!logicalAgents.has(agent) && !deploymentAgents.has(agent)) {
|
|
25266
25321
|
errors.push(
|
|
25267
25322
|
`Checkpoint ${CODEX_MODEL_ROUTING_RECEIPTS_KEY} is missing a receipt for delegated agent: ${agent}.`
|
|
@@ -25355,7 +25410,7 @@ function normalizeLanguages(value) {
|
|
|
25355
25410
|
const normalized = new Set(
|
|
25356
25411
|
value.map((language) => language.trim().toLowerCase())
|
|
25357
25412
|
);
|
|
25358
|
-
return [...normalized].sort();
|
|
25413
|
+
return [...normalized].sort(compareCodePoint);
|
|
25359
25414
|
}
|
|
25360
25415
|
function requireInteger(value, fieldName) {
|
|
25361
25416
|
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
@@ -25691,7 +25746,7 @@ function validateCodexTopologyGate(state, options = {}) {
|
|
|
25691
25746
|
allowedNames.add(receipt.logical_agent);
|
|
25692
25747
|
if ([...delegated].every((agent) => !allowedNames.has(agent))) {
|
|
25693
25748
|
errors.push(
|
|
25694
|
-
`Checkpoint delegation_receipts is missing the exact resolved topology agent for ${receipt.logical_agent}: ${[...allowedNames].sort().join(", ")}.`
|
|
25749
|
+
`Checkpoint delegation_receipts is missing the exact resolved topology agent for ${receipt.logical_agent}: ${[...allowedNames].sort(compareCodePoint).join(", ")}.`
|
|
25695
25750
|
);
|
|
25696
25751
|
}
|
|
25697
25752
|
}
|
|
@@ -25801,7 +25856,7 @@ function validateFeatureFolderUniquenessAndDependencies(features) {
|
|
|
25801
25856
|
}
|
|
25802
25857
|
}
|
|
25803
25858
|
}
|
|
25804
|
-
for (const folder of [...duplicates].sort()) {
|
|
25859
|
+
for (const folder of [...duplicates].sort(compareCodePoint)) {
|
|
25805
25860
|
errors.push(
|
|
25806
25861
|
`Epic checkpoint has duplicate features[].feature_folder: ${folder}`
|
|
25807
25862
|
);
|
|
@@ -26139,6 +26194,53 @@ function validateCommittedFile(git, ref, path16, label) {
|
|
|
26139
26194
|
}
|
|
26140
26195
|
return [];
|
|
26141
26196
|
}
|
|
26197
|
+
function repositoryRelativePath(value, field) {
|
|
26198
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
26199
|
+
return {
|
|
26200
|
+
errors: [`${field} must be a non-empty repository-relative path.`]
|
|
26201
|
+
};
|
|
26202
|
+
}
|
|
26203
|
+
if (value.includes("\\")) {
|
|
26204
|
+
return { errors: [`${field} must use forward slashes.`] };
|
|
26205
|
+
}
|
|
26206
|
+
const parts = value.split("/").filter((part) => part.length > 0 && part !== ".");
|
|
26207
|
+
if (value.startsWith("/") || /^[A-Za-z]:/.test(value) || parts.includes("..")) {
|
|
26208
|
+
return { errors: [`${field} must stay within the workspace root.`] };
|
|
26209
|
+
}
|
|
26210
|
+
return { path: parts.length === 0 ? "." : parts.join("/"), errors: [] };
|
|
26211
|
+
}
|
|
26212
|
+
function derivedPlanPath(feature) {
|
|
26213
|
+
return repositoryRelativePath(feature["plan_path"], "plan_path").path;
|
|
26214
|
+
}
|
|
26215
|
+
function pairPlansWithFeatures(features, plans) {
|
|
26216
|
+
const entries = [];
|
|
26217
|
+
if (Array.isArray(features)) {
|
|
26218
|
+
features.forEach((item, index) => {
|
|
26219
|
+
if (isRecord(item)) {
|
|
26220
|
+
entries.push([index, item]);
|
|
26221
|
+
}
|
|
26222
|
+
});
|
|
26223
|
+
}
|
|
26224
|
+
const paired = [];
|
|
26225
|
+
let position = 0;
|
|
26226
|
+
for (const plan of plans) {
|
|
26227
|
+
let entry = entries[position];
|
|
26228
|
+
while (entry !== void 0 && derivedPlanPath(entry[1]) !== plan) {
|
|
26229
|
+
position += 1;
|
|
26230
|
+
entry = entries[position];
|
|
26231
|
+
}
|
|
26232
|
+
if (entry === void 0) {
|
|
26233
|
+
return plans.map((fallbackPlan, slot) => [
|
|
26234
|
+
slot,
|
|
26235
|
+
entries[slot]?.[1] ?? {},
|
|
26236
|
+
fallbackPlan
|
|
26237
|
+
]);
|
|
26238
|
+
}
|
|
26239
|
+
paired.push([entry[0], entry[1], plan]);
|
|
26240
|
+
position += 1;
|
|
26241
|
+
}
|
|
26242
|
+
return paired;
|
|
26243
|
+
}
|
|
26142
26244
|
function validatePlanningGitIntegrity(state, parsed, plans, git) {
|
|
26143
26245
|
const branch = state["integration_branch"];
|
|
26144
26246
|
if (typeof branch !== "string" || !git.refExists(branch)) {
|
|
@@ -26160,8 +26262,8 @@ function validatePlanningGitIntegrity(state, parsed, plans, git) {
|
|
|
26160
26262
|
);
|
|
26161
26263
|
}
|
|
26162
26264
|
}
|
|
26163
|
-
const
|
|
26164
|
-
|
|
26265
|
+
const pairs = pairPlansWithFeatures(state["features"], plans);
|
|
26266
|
+
pairs.forEach(([index, feature, plan]) => {
|
|
26165
26267
|
const derived = git.lastCommit(plan);
|
|
26166
26268
|
if (derived === void 0) {
|
|
26167
26269
|
errors.push(
|
|
@@ -26176,7 +26278,6 @@ function validatePlanningGitIntegrity(state, parsed, plans, git) {
|
|
|
26176
26278
|
return;
|
|
26177
26279
|
}
|
|
26178
26280
|
const candidates = [derived];
|
|
26179
|
-
const feature = features[index] ?? {};
|
|
26180
26281
|
const featureCommit = feature["planning_commit"];
|
|
26181
26282
|
if (featureCommit !== void 0) {
|
|
26182
26283
|
if (typeof featureCommit !== "string" || !COMMIT_RE.test(featureCommit)) {
|
|
@@ -26234,7 +26335,7 @@ function validatePlanningGitIntegrity(state, parsed, plans, git) {
|
|
|
26234
26335
|
}
|
|
26235
26336
|
}
|
|
26236
26337
|
});
|
|
26237
|
-
for (const extra of Object.keys(integrity.planHashes).filter((path16) => !plans.includes(path16)).sort()) {
|
|
26338
|
+
for (const extra of Object.keys(integrity.planHashes).filter((path16) => !plans.includes(path16)).sort(compareCodePoint)) {
|
|
26238
26339
|
errors.push(
|
|
26239
26340
|
`Optional plan_hashes contains unknown planner path: '${extra}'.`
|
|
26240
26341
|
);
|
|
@@ -26520,7 +26621,7 @@ function validateStatus(feature, index, receipt, receiptPath, status, statusPath
|
|
|
26520
26621
|
}
|
|
26521
26622
|
return errors;
|
|
26522
26623
|
}
|
|
26523
|
-
function validateEpicPlannerLaunchEvidence(state, context) {
|
|
26624
|
+
function validateEpicPlannerLaunchEvidence(state, context, options = {}) {
|
|
26524
26625
|
const features = state["features"];
|
|
26525
26626
|
if (!Array.isArray(features)) {
|
|
26526
26627
|
return [];
|
|
@@ -26532,6 +26633,9 @@ function validateEpicPlannerLaunchEvidence(state, context) {
|
|
|
26532
26633
|
if (!isRecord2(item)) {
|
|
26533
26634
|
return;
|
|
26534
26635
|
}
|
|
26636
|
+
if (options.requireLaunchPaths === true && !featureCarriesLaunchPath(item)) {
|
|
26637
|
+
return;
|
|
26638
|
+
}
|
|
26535
26639
|
const receipt = validateReceipt3(item, index, context);
|
|
26536
26640
|
errors.push(...receipt.errors);
|
|
26537
26641
|
const featureStatus = launchPath(
|
|
@@ -26578,21 +26682,6 @@ var SLUG_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
|
26578
26682
|
function join9(root, relative2) {
|
|
26579
26683
|
return `${toPosixPath2(root).replace(/\/+$/, "")}/${relative2.replace(/^\/+/, "")}`;
|
|
26580
26684
|
}
|
|
26581
|
-
function relativePath(value, field) {
|
|
26582
|
-
if (typeof value !== "string" || value.trim().length === 0) {
|
|
26583
|
-
return {
|
|
26584
|
-
errors: [`${field} must be a non-empty repository-relative path.`]
|
|
26585
|
-
};
|
|
26586
|
-
}
|
|
26587
|
-
if (value.includes("\\")) {
|
|
26588
|
-
return { errors: [`${field} must use forward slashes.`] };
|
|
26589
|
-
}
|
|
26590
|
-
const parts = value.split("/");
|
|
26591
|
-
if (value.startsWith("/") || /^[A-Za-z]:/.test(value) || parts.includes("..") || parts.includes(".")) {
|
|
26592
|
-
return { errors: [`${field} must stay within the workspace root.`] };
|
|
26593
|
-
}
|
|
26594
|
-
return { path: parts.join("/"), errors: [] };
|
|
26595
|
-
}
|
|
26596
26685
|
function readRequired(context, relative2, label) {
|
|
26597
26686
|
const path16 = join9(context.workspaceRoot, relative2);
|
|
26598
26687
|
if (!context.fileSystem.isFile(path16)) {
|
|
@@ -26633,12 +26722,15 @@ function validateArtifactSource(stateText, context) {
|
|
|
26633
26722
|
}
|
|
26634
26723
|
function validateFeatureFiles(feature, index, context) {
|
|
26635
26724
|
const prefix = `Epic planner checkpoint features[${index}]`;
|
|
26636
|
-
const folderResult =
|
|
26725
|
+
const folderResult = repositoryRelativePath(
|
|
26637
26726
|
feature["feature_folder"],
|
|
26638
26727
|
`${prefix}.feature_folder`
|
|
26639
26728
|
);
|
|
26640
|
-
const planResult =
|
|
26641
|
-
|
|
26729
|
+
const planResult = repositoryRelativePath(
|
|
26730
|
+
feature["plan_path"],
|
|
26731
|
+
`${prefix}.plan_path`
|
|
26732
|
+
);
|
|
26733
|
+
const researchResult = repositoryRelativePath(
|
|
26642
26734
|
feature["research_path"],
|
|
26643
26735
|
`${prefix}.research_path`
|
|
26644
26736
|
);
|
|
@@ -26683,7 +26775,7 @@ function validateFeatureFiles(feature, index, context) {
|
|
|
26683
26775
|
const evidenceValue = feature["preflight_evidence_path"];
|
|
26684
26776
|
const evidencePaths = [];
|
|
26685
26777
|
if (evidenceValue !== void 0) {
|
|
26686
|
-
const evidence =
|
|
26778
|
+
const evidence = repositoryRelativePath(
|
|
26687
26779
|
evidenceValue,
|
|
26688
26780
|
`${prefix}.preflight_evidence_path`
|
|
26689
26781
|
);
|
|
@@ -26764,7 +26856,7 @@ function validateKickoffAgainstState(parsed, state, label) {
|
|
|
26764
26856
|
}
|
|
26765
26857
|
return errors;
|
|
26766
26858
|
}
|
|
26767
|
-
function validateEpicReadinessIntegrity(state, stateText, context) {
|
|
26859
|
+
function validateEpicReadinessIntegrity(state, stateText, context, options = {}) {
|
|
26768
26860
|
const errors = validateArtifactSource(stateText, context);
|
|
26769
26861
|
const slug = state["epic_feature_folder"];
|
|
26770
26862
|
if (typeof slug !== "string" || !SLUG_RE.test(slug)) {
|
|
@@ -26785,7 +26877,7 @@ function validateEpicReadinessIntegrity(state, stateText, context) {
|
|
|
26785
26877
|
}
|
|
26786
26878
|
const manifest = readRequired(context, manifestPath, "the epic manifest");
|
|
26787
26879
|
errors.push(...manifest.errors);
|
|
26788
|
-
const ignoredResult =
|
|
26880
|
+
const ignoredResult = repositoryRelativePath(
|
|
26789
26881
|
state["kickoff_prompt_path"],
|
|
26790
26882
|
"Epic planner checkpoint kickoff_prompt_path"
|
|
26791
26883
|
);
|
|
@@ -26833,7 +26925,7 @@ function validateEpicReadinessIntegrity(state, stateText, context) {
|
|
|
26833
26925
|
}
|
|
26834
26926
|
});
|
|
26835
26927
|
}
|
|
26836
|
-
errors.push(...validateEpicPlannerLaunchEvidence(state, context));
|
|
26928
|
+
errors.push(...validateEpicPlannerLaunchEvidence(state, context, options));
|
|
26837
26929
|
if (parsed !== void 0) {
|
|
26838
26930
|
errors.push(
|
|
26839
26931
|
...validatePlanningGitIntegrity(state, parsed, plans, context.git),
|
|
@@ -26969,18 +27061,19 @@ function extractFeatures2(value) {
|
|
|
26969
27061
|
if (!Array.isArray(value)) {
|
|
26970
27062
|
return {
|
|
26971
27063
|
errors: ["Epic planner checkpoint features must be a list."],
|
|
26972
|
-
|
|
27064
|
+
indexedFeatures: [],
|
|
27065
|
+
entries: []
|
|
26973
27066
|
};
|
|
26974
27067
|
}
|
|
26975
27068
|
const errors = [];
|
|
26976
|
-
const
|
|
27069
|
+
const indexedFeatures = [];
|
|
26977
27070
|
value.forEach((item, index) => {
|
|
26978
27071
|
const prefix = `Epic planner checkpoint features[${index}]`;
|
|
26979
27072
|
if (!isObject7(item)) {
|
|
26980
27073
|
errors.push(`${prefix} must be an object.`);
|
|
26981
27074
|
return;
|
|
26982
27075
|
}
|
|
26983
|
-
|
|
27076
|
+
indexedFeatures.push([index, item]);
|
|
26984
27077
|
const missing = REQUIRED_FEATURE_KEYS.filter((key) => !(key in item));
|
|
26985
27078
|
if (missing.length > 0) {
|
|
26986
27079
|
errors.push(`${prefix} missing required keys: ${missing.join(", ")}.`);
|
|
@@ -27000,13 +27093,14 @@ function extractFeatures2(value) {
|
|
|
27000
27093
|
);
|
|
27001
27094
|
}
|
|
27002
27095
|
});
|
|
27003
|
-
return { errors,
|
|
27096
|
+
return { errors, indexedFeatures, entries: value };
|
|
27004
27097
|
}
|
|
27005
|
-
function validateDependencyWaves(
|
|
27098
|
+
function validateDependencyWaves(indexedFeatures) {
|
|
27099
|
+
const features = indexedFeatures.map(([, feature]) => feature);
|
|
27006
27100
|
const errors = [];
|
|
27007
27101
|
const seenFolders = /* @__PURE__ */ new Set();
|
|
27008
27102
|
const seenIssues = /* @__PURE__ */ new Set();
|
|
27009
|
-
|
|
27103
|
+
indexedFeatures.forEach(([index2, feature]) => {
|
|
27010
27104
|
const prefix = `Epic planner checkpoint features[${index2}]`;
|
|
27011
27105
|
const folder = feature["feature_folder"];
|
|
27012
27106
|
if (typeof folder === "string" && folder.length > 0) {
|
|
@@ -27029,7 +27123,7 @@ function validateDependencyWaves(features) {
|
|
|
27029
27123
|
});
|
|
27030
27124
|
const index = buildFeatureReferenceIndex(features);
|
|
27031
27125
|
const manifest = /* @__PURE__ */ new Map();
|
|
27032
|
-
|
|
27126
|
+
indexedFeatures.forEach(([featureIndex, feature]) => {
|
|
27033
27127
|
const folder = feature["feature_folder"];
|
|
27034
27128
|
const dependencies = feature["depends_on"];
|
|
27035
27129
|
if (typeof folder !== "string" || folder.length === 0 || !Array.isArray(dependencies)) {
|
|
@@ -27058,7 +27152,7 @@ function validateDependencyWaves(features) {
|
|
|
27058
27152
|
}
|
|
27059
27153
|
throw error2;
|
|
27060
27154
|
}
|
|
27061
|
-
|
|
27155
|
+
indexedFeatures.forEach(([index2, feature]) => {
|
|
27062
27156
|
const folder = feature["feature_folder"];
|
|
27063
27157
|
if (typeof folder !== "string" || !expectedWaves.has(folder)) {
|
|
27064
27158
|
return;
|
|
@@ -27072,14 +27166,14 @@ function validateDependencyWaves(features) {
|
|
|
27072
27166
|
});
|
|
27073
27167
|
return errors;
|
|
27074
27168
|
}
|
|
27075
|
-
function validateReadyFeatures(
|
|
27169
|
+
function validateReadyFeatures(indexedFeatures, keyGated) {
|
|
27076
27170
|
const errors = [];
|
|
27077
|
-
if (
|
|
27171
|
+
if (indexedFeatures.length < 2) {
|
|
27078
27172
|
errors.push(
|
|
27079
27173
|
"Execution-ready epic planning requires at least two features."
|
|
27080
27174
|
);
|
|
27081
27175
|
}
|
|
27082
|
-
|
|
27176
|
+
indexedFeatures.forEach(([index, feature]) => {
|
|
27083
27177
|
const prefix = `Epic planner checkpoint features[${index}]`;
|
|
27084
27178
|
const issueNum = feature["issue_num"];
|
|
27085
27179
|
if (typeof issueNum !== "number" || !Number.isInteger(issueNum) || issueNum <= 0) {
|
|
@@ -27101,36 +27195,40 @@ function validateReadyFeatures(features) {
|
|
|
27101
27195
|
if (feature["preflight_status"] !== "PREFLIGHT: ALL CLEAR") {
|
|
27102
27196
|
errors.push(`${prefix}.preflight_status must be 'PREFLIGHT: ALL CLEAR'.`);
|
|
27103
27197
|
}
|
|
27104
|
-
|
|
27105
|
-
|
|
27106
|
-
...validateCodexModelRoutingReceipt(
|
|
27107
|
-
receipt,
|
|
27108
|
-
`${prefix}.model_routing_receipt`
|
|
27109
|
-
)
|
|
27110
|
-
);
|
|
27111
|
-
if (isObject7(receipt) && receipt["logical_agent"] !== "orchestrator") {
|
|
27198
|
+
if (!keyGated || "model_routing_receipt" in feature) {
|
|
27199
|
+
const receipt = feature["model_routing_receipt"];
|
|
27112
27200
|
errors.push(
|
|
27113
|
-
|
|
27201
|
+
...validateCodexModelRoutingReceipt(
|
|
27202
|
+
receipt,
|
|
27203
|
+
`${prefix}.model_routing_receipt`
|
|
27204
|
+
)
|
|
27114
27205
|
);
|
|
27115
|
-
|
|
27116
|
-
if (isObject7(receipt)) {
|
|
27117
|
-
if (receipt["complexity_band"] !== feature["complexity_band"]) {
|
|
27206
|
+
if (isObject7(receipt) && receipt["logical_agent"] !== "orchestrator") {
|
|
27118
27207
|
errors.push(
|
|
27119
|
-
`${prefix}.model_routing_receipt.
|
|
27208
|
+
`${prefix}.model_routing_receipt.logical_agent must be 'orchestrator'.`
|
|
27120
27209
|
);
|
|
27121
27210
|
}
|
|
27122
|
-
if (receipt
|
|
27123
|
-
|
|
27124
|
-
|
|
27125
|
-
|
|
27211
|
+
if (isObject7(receipt)) {
|
|
27212
|
+
if (receipt["complexity_band"] !== feature["complexity_band"]) {
|
|
27213
|
+
errors.push(
|
|
27214
|
+
`${prefix}.model_routing_receipt.complexity_band must match feature complexity_band ${pythonRepr6(feature["complexity_band"])}.`
|
|
27215
|
+
);
|
|
27216
|
+
}
|
|
27217
|
+
if (receipt["execution_context"] !== "epic_preparation_child") {
|
|
27218
|
+
errors.push(
|
|
27219
|
+
`${prefix}.model_routing_receipt.execution_context must be 'epic_preparation_child'.`
|
|
27220
|
+
);
|
|
27221
|
+
}
|
|
27126
27222
|
}
|
|
27127
27223
|
}
|
|
27128
|
-
|
|
27129
|
-
|
|
27130
|
-
|
|
27131
|
-
|
|
27132
|
-
|
|
27133
|
-
|
|
27224
|
+
if (!keyGated || "topology_receipt" in feature) {
|
|
27225
|
+
errors.push(
|
|
27226
|
+
...validateChildTopologyReceipt(
|
|
27227
|
+
feature["topology_receipt"],
|
|
27228
|
+
`${prefix}.topology_receipt`
|
|
27229
|
+
)
|
|
27230
|
+
);
|
|
27231
|
+
}
|
|
27134
27232
|
});
|
|
27135
27233
|
return errors;
|
|
27136
27234
|
}
|
|
@@ -27153,7 +27251,7 @@ function validateEpicPlannerStateText(text2, options = {}) {
|
|
|
27153
27251
|
errors.push(...worthiness.errors);
|
|
27154
27252
|
const featureResult = extractFeatures2(value["features"]);
|
|
27155
27253
|
errors.push(...featureResult.errors);
|
|
27156
|
-
errors.push(...validateDependencyWaves(featureResult.
|
|
27254
|
+
errors.push(...validateDependencyWaves(featureResult.indexedFeatures));
|
|
27157
27255
|
const maxParallel = value["max_parallel_features"];
|
|
27158
27256
|
if (typeof maxParallel !== "number" || !Number.isInteger(maxParallel) || maxParallel < 1 || maxParallel > 8) {
|
|
27159
27257
|
errors.push(
|
|
@@ -27166,6 +27264,7 @@ function validateEpicPlannerStateText(text2, options = {}) {
|
|
|
27166
27264
|
);
|
|
27167
27265
|
}
|
|
27168
27266
|
if (options.requireReadyForExecution === true) {
|
|
27267
|
+
const requireLaunchPaths = options.requireCodexModelRouting !== true && options.requireCodexTopology !== true;
|
|
27169
27268
|
if (worthiness.verdict !== "epic") {
|
|
27170
27269
|
errors.push(
|
|
27171
27270
|
"Execution readiness requires epic_worthiness.verdict 'epic'."
|
|
@@ -27176,11 +27275,20 @@ function validateEpicPlannerStateText(text2, options = {}) {
|
|
|
27176
27275
|
`Execution-ready planner checkpoint next_step must be '${READY_NEXT_STEP}'.`
|
|
27177
27276
|
);
|
|
27178
27277
|
}
|
|
27179
|
-
errors.push(...validateReadyFeatures(featureResult.features));
|
|
27180
27278
|
errors.push(
|
|
27181
|
-
...
|
|
27279
|
+
...validateReadyFeatures(
|
|
27280
|
+
featureResult.indexedFeatures,
|
|
27281
|
+
requireLaunchPaths
|
|
27282
|
+
)
|
|
27283
|
+
);
|
|
27284
|
+
errors.push(
|
|
27285
|
+
...validateEpicPlannerChildLaunchBindings(featureResult.entries, {
|
|
27286
|
+
requireLaunchPaths
|
|
27287
|
+
})
|
|
27182
27288
|
);
|
|
27183
|
-
|
|
27289
|
+
if (!requireLaunchPaths || "topology_receipt" in value) {
|
|
27290
|
+
errors.push(...validatePlannerTopologyReceipt(value["topology_receipt"]));
|
|
27291
|
+
}
|
|
27184
27292
|
const expectedKickoff = `artifacts/orchestration/epic-kickoff-${String(
|
|
27185
27293
|
value["epic_feature_folder"]
|
|
27186
27294
|
)}.md`;
|
|
@@ -27198,7 +27306,8 @@ function validateEpicPlannerStateText(text2, options = {}) {
|
|
|
27198
27306
|
...validateEpicReadinessIntegrity(
|
|
27199
27307
|
value,
|
|
27200
27308
|
text2,
|
|
27201
|
-
options.readinessContext
|
|
27309
|
+
options.readinessContext,
|
|
27310
|
+
{ requireLaunchPaths }
|
|
27202
27311
|
)
|
|
27203
27312
|
);
|
|
27204
27313
|
}
|
|
@@ -27266,6 +27375,10 @@ var PROMOTION_ENTRY_TOOLS = /* @__PURE__ */ new Set([
|
|
|
27266
27375
|
]);
|
|
27267
27376
|
var POTENTIAL_RECORD_PREFIX = "docs/features/potential/";
|
|
27268
27377
|
var POTENTIAL_RECORD_SUFFIX = ".md";
|
|
27378
|
+
var RECORD_OPTIONAL_ORIGINS = /* @__PURE__ */ new Set([
|
|
27379
|
+
"transferred",
|
|
27380
|
+
"filed_before_orchestration"
|
|
27381
|
+
]);
|
|
27269
27382
|
var ISSUE_NUM_PATTERN = /^[1-9][0-9]*$/;
|
|
27270
27383
|
var ERROR_NOT_OBJECT = "Checkpoint issue_adoption must be an object when present.";
|
|
27271
27384
|
var ERROR_ISSUE_NUM_FORMAT = "Checkpoint issue_adoption.issue_num must be a string of decimal digits without a leading zero.";
|
|
@@ -27360,7 +27473,10 @@ function waivedToolErrors(waived, options) {
|
|
|
27360
27473
|
}
|
|
27361
27474
|
return errors;
|
|
27362
27475
|
}
|
|
27363
|
-
function potentialRecordErrors(waived, potentialRecord) {
|
|
27476
|
+
function potentialRecordErrors(waived, potentialRecord, origin, recordPresent) {
|
|
27477
|
+
if (!recordPresent && typeof origin === "string" && RECORD_OPTIONAL_ORIGINS.has(origin)) {
|
|
27478
|
+
return [];
|
|
27479
|
+
}
|
|
27364
27480
|
if (typeof potentialRecord === "string" && potentialRecord.startsWith(POTENTIAL_RECORD_PREFIX) && potentialRecord.endsWith(POTENTIAL_RECORD_SUFFIX)) {
|
|
27365
27481
|
return [];
|
|
27366
27482
|
}
|
|
@@ -27394,7 +27510,14 @@ function resolveIssueAdoption(state, options) {
|
|
|
27394
27510
|
return { errors, waivedTools: /* @__PURE__ */ new Set() };
|
|
27395
27511
|
}
|
|
27396
27512
|
errors.push(...waivedToolErrors(waived, options));
|
|
27397
|
-
errors.push(
|
|
27513
|
+
errors.push(
|
|
27514
|
+
...potentialRecordErrors(
|
|
27515
|
+
waived,
|
|
27516
|
+
adoption["potential_record"],
|
|
27517
|
+
adoption["origin"],
|
|
27518
|
+
Object.prototype.hasOwnProperty.call(adoption, "potential_record")
|
|
27519
|
+
)
|
|
27520
|
+
);
|
|
27398
27521
|
if (errors.length > 0) {
|
|
27399
27522
|
return { errors, waivedTools: /* @__PURE__ */ new Set() };
|
|
27400
27523
|
}
|
|
@@ -28121,7 +28244,7 @@ function validateModelRoutingExistence(state) {
|
|
|
28121
28244
|
}
|
|
28122
28245
|
}
|
|
28123
28246
|
}
|
|
28124
|
-
return [...delegated].filter((agent) => !receiptAgents2.has(agent)).sort().map(
|
|
28247
|
+
return [...delegated].filter((agent) => !receiptAgents2.has(agent)).sort(compareCodePoint).map(
|
|
28125
28248
|
(agent) => `Checkpoint model_routing_receipts is missing a receipt for delegated agent: ${agent}.`
|
|
28126
28249
|
);
|
|
28127
28250
|
}
|
|
@@ -28230,7 +28353,7 @@ function validateNamespacedDelegationReceipts(receipts) {
|
|
|
28230
28353
|
const errors = [];
|
|
28231
28354
|
const unsupportedKeys = Object.keys(receipts).filter(
|
|
28232
28355
|
(key) => key !== AGENT_RECEIPT_NAMESPACE_KEY && key !== PROMOTION_RECEIPT_NAMESPACE_KEY
|
|
28233
|
-
).sort();
|
|
28356
|
+
).sort(compareCodePoint);
|
|
28234
28357
|
for (const key of unsupportedKeys) {
|
|
28235
28358
|
errors.push(
|
|
28236
28359
|
`Checkpoint delegation_receipts object contains unsupported key: ${key}`
|
|
@@ -28256,7 +28379,7 @@ function validateNamespacedDelegationReceipts(receipts) {
|
|
|
28256
28379
|
}
|
|
28257
28380
|
const unsupportedPromotionKeys = Object.keys(promotionReceipts).filter(
|
|
28258
28381
|
(key) => !PROMOTION_RECEIPT_KEYS.includes(key)
|
|
28259
|
-
).sort();
|
|
28382
|
+
).sort(compareCodePoint);
|
|
28260
28383
|
for (const key of unsupportedPromotionKeys) {
|
|
28261
28384
|
errors.push(
|
|
28262
28385
|
"Checkpoint delegation_receipts.promotion contains unsupported key: " + key
|
|
@@ -28726,7 +28849,7 @@ function classifyKind(argv) {
|
|
|
28726
28849
|
}
|
|
28727
28850
|
return "other";
|
|
28728
28851
|
}
|
|
28729
|
-
function
|
|
28852
|
+
function splitPlanLines(text2) {
|
|
28730
28853
|
if (text2 === "") {
|
|
28731
28854
|
return [];
|
|
28732
28855
|
}
|
|
@@ -28736,6 +28859,11 @@ function splitLines2(text2) {
|
|
|
28736
28859
|
}
|
|
28737
28860
|
return lines;
|
|
28738
28861
|
}
|
|
28862
|
+
var PLAN_WHITESPACE_CLASS = String.raw`[\t\n\v\f\r \u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]`;
|
|
28863
|
+
var PLAN_WHITESPACE_RUN_RE = new RegExp(`${PLAN_WHITESPACE_CLASS}+`);
|
|
28864
|
+
function normalizePlanWhitespace(value) {
|
|
28865
|
+
return value.split(PLAN_WHITESPACE_RUN_RE).filter((word) => word !== "").join(" ");
|
|
28866
|
+
}
|
|
28739
28867
|
function inlineSpans(line) {
|
|
28740
28868
|
const spans = [];
|
|
28741
28869
|
for (const match of line.matchAll(INLINE_SPAN_RE)) {
|
|
@@ -28779,7 +28907,7 @@ function extractPlanCommands(text2) {
|
|
|
28779
28907
|
let inFence = false;
|
|
28780
28908
|
let windowLines = [];
|
|
28781
28909
|
let windowStart = 0;
|
|
28782
|
-
const lines =
|
|
28910
|
+
const lines = splitPlanLines(text2);
|
|
28783
28911
|
for (let index = 0; index < lines.length; index += 1) {
|
|
28784
28912
|
const line = lines[index] ?? "";
|
|
28785
28913
|
const lineNumber = index + 1;
|
|
@@ -28829,6 +28957,166 @@ function extractPlanCommands(text2) {
|
|
|
28829
28957
|
return commands;
|
|
28830
28958
|
}
|
|
28831
28959
|
|
|
28960
|
+
// ../../extensions/drm-copilot/src/lib/validate/plan-gate-document.ts
|
|
28961
|
+
var G11_SEVERITY = "blocking";
|
|
28962
|
+
var G12_SEVERITY = "blocking";
|
|
28963
|
+
var G13_SEVERITY = "blocking";
|
|
28964
|
+
var PLAN_TASK_GUIDELINE = 40;
|
|
28965
|
+
var PLAN_LINE_GUIDELINE = 400;
|
|
28966
|
+
var G11_PROSE_PATTERN = String.raw`\b[Ll]ines?[ \t]+[0-9]+`;
|
|
28967
|
+
var G11_PATH_PATTERN = String.raw`[A-Za-z0-9_./-]+\.[A-Za-z][A-Za-z0-9]{0,5}:[0-9]+`;
|
|
28968
|
+
var G11_ANCHOR_PATTERN = String.raw`#L[0-9]+`;
|
|
28969
|
+
var G12_SHA_PATTERN = String.raw`\b[0-9a-f]{7,40}\b`;
|
|
28970
|
+
var G13_TASK_PATTERN = String.raw`^- \[[ xX]\] \[P[0-9]+-T[0-9]+\] `;
|
|
28971
|
+
var INLINE_CODE_PATTERN = "`[^`]*`";
|
|
28972
|
+
var FENCE_RE2 = /^\s*```/;
|
|
28973
|
+
var PROSE_RE = new RegExp(G11_PROSE_PATTERN, "g");
|
|
28974
|
+
var PATH_RE = new RegExp(G11_PATH_PATTERN, "g");
|
|
28975
|
+
var ANCHOR_RE = new RegExp(G11_ANCHOR_PATTERN, "g");
|
|
28976
|
+
var SHA_RE = new RegExp(G12_SHA_PATTERN, "g");
|
|
28977
|
+
var TASK_RE = new RegExp(G13_TASK_PATTERN);
|
|
28978
|
+
var INLINE_CODE_RE = new RegExp(INLINE_CODE_PATTERN, "g");
|
|
28979
|
+
var WHITESPACE_RE = new RegExp(`^${PLAN_WHITESPACE_CLASS}$`);
|
|
28980
|
+
var JUSTIFICATION_HEADING_RE = /^##[ \t]+Size Justification[ \t]*$/;
|
|
28981
|
+
var SECTION_END_RE = /^#{1,2}(?:[ \t]|$)/;
|
|
28982
|
+
var HEADING_RE = /^#{1,6}(?:[ \t]|$)/;
|
|
28983
|
+
var DIGITS = "0123456789";
|
|
28984
|
+
var HEX_LETTERS = "abcdef";
|
|
28985
|
+
var SHA_BEFORE_REJECT = "-_.";
|
|
28986
|
+
var SHA_AFTER_REJECT = "-_";
|
|
28987
|
+
function unfencedLines(text2) {
|
|
28988
|
+
const result = [];
|
|
28989
|
+
let inFence = false;
|
|
28990
|
+
for (const [index, line] of splitPlanLines(text2).entries()) {
|
|
28991
|
+
if (FENCE_RE2.test(line)) {
|
|
28992
|
+
inFence = !inFence;
|
|
28993
|
+
continue;
|
|
28994
|
+
}
|
|
28995
|
+
if (!inFence) {
|
|
28996
|
+
result.push([index + 1, line]);
|
|
28997
|
+
}
|
|
28998
|
+
}
|
|
28999
|
+
return result;
|
|
29000
|
+
}
|
|
29001
|
+
function maskInlineCode(line) {
|
|
29002
|
+
return line.replace(INLINE_CODE_RE, (span) => " ".repeat(span.length));
|
|
29003
|
+
}
|
|
29004
|
+
function isWhitespace(character) {
|
|
29005
|
+
return character !== void 0 && WHITESPACE_RE.test(character);
|
|
29006
|
+
}
|
|
29007
|
+
function enclosingToken(line, start, end) {
|
|
29008
|
+
let left = start;
|
|
29009
|
+
while (left > 0 && !isWhitespace(line[left - 1])) {
|
|
29010
|
+
left -= 1;
|
|
29011
|
+
}
|
|
29012
|
+
let right = end;
|
|
29013
|
+
while (right < line.length && !isWhitespace(line[right])) {
|
|
29014
|
+
right += 1;
|
|
29015
|
+
}
|
|
29016
|
+
return line.slice(left, right);
|
|
29017
|
+
}
|
|
29018
|
+
function lineCitations(text2) {
|
|
29019
|
+
const findings = [];
|
|
29020
|
+
for (const [lineNumber, line] of unfencedLines(text2)) {
|
|
29021
|
+
for (const match of maskInlineCode(line).matchAll(PROSE_RE)) {
|
|
29022
|
+
findings.push([lineNumber, match[0]]);
|
|
29023
|
+
}
|
|
29024
|
+
for (const match of line.matchAll(PATH_RE)) {
|
|
29025
|
+
const token = enclosingToken(
|
|
29026
|
+
line,
|
|
29027
|
+
match.index,
|
|
29028
|
+
match.index + match[0].length
|
|
29029
|
+
);
|
|
29030
|
+
if (!token.includes("://")) {
|
|
29031
|
+
findings.push([lineNumber, match[0]]);
|
|
29032
|
+
}
|
|
29033
|
+
}
|
|
29034
|
+
for (const match of line.matchAll(ANCHOR_RE)) {
|
|
29035
|
+
findings.push([lineNumber, match[0]]);
|
|
29036
|
+
}
|
|
29037
|
+
}
|
|
29038
|
+
return findings;
|
|
29039
|
+
}
|
|
29040
|
+
function isShaCandidate(line, start, end) {
|
|
29041
|
+
const token = line.slice(start, end);
|
|
29042
|
+
if (![...token].some((character) => DIGITS.includes(character))) {
|
|
29043
|
+
return false;
|
|
29044
|
+
}
|
|
29045
|
+
if (![...token].some((character) => HEX_LETTERS.includes(character))) {
|
|
29046
|
+
return false;
|
|
29047
|
+
}
|
|
29048
|
+
const before = start > 0 ? line.charAt(start - 1) : "";
|
|
29049
|
+
if (before !== "" && SHA_BEFORE_REJECT.includes(before)) {
|
|
29050
|
+
return false;
|
|
29051
|
+
}
|
|
29052
|
+
const after = end < line.length ? line.charAt(end) : "";
|
|
29053
|
+
return !(after !== "" && SHA_AFTER_REJECT.includes(after));
|
|
29054
|
+
}
|
|
29055
|
+
function shaCitations(text2) {
|
|
29056
|
+
const findings = [];
|
|
29057
|
+
for (const [lineNumber, line] of unfencedLines(text2)) {
|
|
29058
|
+
for (const match of line.matchAll(SHA_RE)) {
|
|
29059
|
+
if (isShaCandidate(line, match.index, match.index + match[0].length)) {
|
|
29060
|
+
findings.push([lineNumber, match[0]]);
|
|
29061
|
+
}
|
|
29062
|
+
}
|
|
29063
|
+
}
|
|
29064
|
+
return findings;
|
|
29065
|
+
}
|
|
29066
|
+
function hasSizeJustification(text2) {
|
|
29067
|
+
let inSection = false;
|
|
29068
|
+
for (const [, line] of unfencedLines(text2)) {
|
|
29069
|
+
if (JUSTIFICATION_HEADING_RE.test(line)) {
|
|
29070
|
+
inSection = true;
|
|
29071
|
+
continue;
|
|
29072
|
+
}
|
|
29073
|
+
if (!inSection) {
|
|
29074
|
+
continue;
|
|
29075
|
+
}
|
|
29076
|
+
if (SECTION_END_RE.test(line)) {
|
|
29077
|
+
inSection = false;
|
|
29078
|
+
continue;
|
|
29079
|
+
}
|
|
29080
|
+
if (normalizePlanWhitespace(line) !== "" && !HEADING_RE.test(line)) {
|
|
29081
|
+
return true;
|
|
29082
|
+
}
|
|
29083
|
+
}
|
|
29084
|
+
return false;
|
|
29085
|
+
}
|
|
29086
|
+
function planSize(text2) {
|
|
29087
|
+
const tasks = unfencedLines(text2).filter(
|
|
29088
|
+
([, line]) => TASK_RE.test(line)
|
|
29089
|
+
).length;
|
|
29090
|
+
return [tasks, splitPlanLines(text2).length];
|
|
29091
|
+
}
|
|
29092
|
+
function lineCitationMessage(lineNumber, value) {
|
|
29093
|
+
return `Line ${String(lineNumber)}: line-number citation \`${value}\` anchors on a position that moves when main moves; cite the symbol, heading, or test name instead.`;
|
|
29094
|
+
}
|
|
29095
|
+
function shaCitationMessage(lineNumber, value) {
|
|
29096
|
+
return `Line ${String(lineNumber)}: commit-SHA citation \`${value}\` names a commit that goes stale when main moves; cite the branch, ref name, or merge base derivation instead.`;
|
|
29097
|
+
}
|
|
29098
|
+
function planSizeMessage(tasks, lines) {
|
|
29099
|
+
return `Line 1: plan size \`${String(tasks)} tasks, ${String(lines)} lines\` exceeds the guideline of ${String(PLAN_TASK_GUIDELINE)} tasks or ${String(PLAN_LINE_GUIDELINE)} lines and carries no \`## Size Justification\` section; split the item or state why the size is necessary.`;
|
|
29100
|
+
}
|
|
29101
|
+
function channelFor(report, severity) {
|
|
29102
|
+
return severity === "blocking" ? report.blocking : report.warnings;
|
|
29103
|
+
}
|
|
29104
|
+
function evaluateDocumentGates(report, text2) {
|
|
29105
|
+
const g11 = channelFor(report, G11_SEVERITY);
|
|
29106
|
+
for (const [lineNumber, value] of lineCitations(text2)) {
|
|
29107
|
+
g11.push(lineCitationMessage(lineNumber, value));
|
|
29108
|
+
}
|
|
29109
|
+
const g12 = channelFor(report, G12_SEVERITY);
|
|
29110
|
+
for (const [lineNumber, value] of shaCitations(text2)) {
|
|
29111
|
+
g12.push(shaCitationMessage(lineNumber, value));
|
|
29112
|
+
}
|
|
29113
|
+
const [tasks, lines] = planSize(text2);
|
|
29114
|
+
const overGuideline = tasks > PLAN_TASK_GUIDELINE || lines > PLAN_LINE_GUIDELINE;
|
|
29115
|
+
if (overGuideline && !hasSizeJustification(text2)) {
|
|
29116
|
+
channelFor(report, G13_SEVERITY).push(planSizeMessage(tasks, lines));
|
|
29117
|
+
}
|
|
29118
|
+
}
|
|
29119
|
+
|
|
28832
29120
|
// ../../extensions/drm-copilot/src/lib/validate/plan-gate-rules.ts
|
|
28833
29121
|
function emptyPlanGateReport() {
|
|
28834
29122
|
return { blocking: [], warnings: [] };
|
|
@@ -28949,7 +29237,7 @@ function planQuotesLiteral(text2, literal2, excludeSpan) {
|
|
|
28949
29237
|
return normalizeWhitespace(remainder).includes(needle);
|
|
28950
29238
|
}
|
|
28951
29239
|
function windowJoin(lines, size = WINDOW_SIZE) {
|
|
28952
|
-
const dense = lines.
|
|
29240
|
+
const dense = lines.map((line) => normalizePlanWhitespace(line)).filter((line) => line !== "");
|
|
28953
29241
|
const windows = [];
|
|
28954
29242
|
for (let index = 0; index < dense.length; index += 1) {
|
|
28955
29243
|
windows.push(dense.slice(index, index + size).join(" "));
|
|
@@ -28957,15 +29245,15 @@ function windowJoin(lines, size = WINDOW_SIZE) {
|
|
|
28957
29245
|
return windows;
|
|
28958
29246
|
}
|
|
28959
29247
|
function hasCrossLinePresence(context, literal2) {
|
|
28960
|
-
const
|
|
29248
|
+
const needle = normalizePlanWhitespace(literal2);
|
|
29249
|
+
const words2 = needle.split(" ");
|
|
28961
29250
|
if (words2.length < 2) {
|
|
28962
29251
|
return false;
|
|
28963
29252
|
}
|
|
28964
|
-
const needle = words2.join(" ");
|
|
28965
29253
|
const firstWord = words2[0] ?? "";
|
|
28966
29254
|
for (const path16 of context.git.filesContaining(firstWord)) {
|
|
28967
29255
|
const lines = context.git.readTrackedText(path16).split(/\r\n|\n|\r/);
|
|
28968
|
-
if (lines.some((line) =>
|
|
29256
|
+
if (lines.some((line) => normalizePlanWhitespace(line).includes(needle))) {
|
|
28969
29257
|
continue;
|
|
28970
29258
|
}
|
|
28971
29259
|
if (windowJoin(lines).some((window2) => window2.includes(needle))) {
|
|
@@ -29211,6 +29499,71 @@ function evaluateObservabilityGates(report, commands, context) {
|
|
|
29211
29499
|
}
|
|
29212
29500
|
}
|
|
29213
29501
|
|
|
29502
|
+
// ../../extensions/drm-copilot/src/lib/validate/plan-gate-scratch.ts
|
|
29503
|
+
var G10_SEVERITY = "blocking";
|
|
29504
|
+
var BACKTICK = "`";
|
|
29505
|
+
var SCRATCH_DEFINITION_PATTERN = String.raw`(?:^|[^A-Za-z0-9_<>$/.-])${BACKTICK}?SCRATCH${BACKTICK}?(?:\*\*)?[ \t]*(?:means\b|:=|=|:|is (?:the|a|an)\b|resolves to\b|abbreviates\b|denotes\b|refers to\b|stands for\b)`;
|
|
29506
|
+
var SCRATCH_NAMESPACE_PATTERN = String.raw`issue-(?:<issue-num>|[0-9]+)`;
|
|
29507
|
+
var FENCE_RE3 = /^\s*```/;
|
|
29508
|
+
var DEFINITION_RE = new RegExp(SCRATCH_DEFINITION_PATTERN);
|
|
29509
|
+
var NAMESPACE_RE = new RegExp(SCRATCH_NAMESPACE_PATTERN);
|
|
29510
|
+
var LEADING_WHITESPACE_RE = new RegExp(`^${PLAN_WHITESPACE_CLASS}`);
|
|
29511
|
+
function continuesLogicalLine(line) {
|
|
29512
|
+
if (normalizePlanWhitespace(line) === "" || !LEADING_WHITESPACE_RE.test(line)) {
|
|
29513
|
+
return false;
|
|
29514
|
+
}
|
|
29515
|
+
return !FENCE_RE3.test(line);
|
|
29516
|
+
}
|
|
29517
|
+
function isBareDefinition(logical) {
|
|
29518
|
+
const match = DEFINITION_RE.exec(logical);
|
|
29519
|
+
if (match === null) {
|
|
29520
|
+
return false;
|
|
29521
|
+
}
|
|
29522
|
+
return !NAMESPACE_RE.test(logical.slice(match.index + match[0].length));
|
|
29523
|
+
}
|
|
29524
|
+
function recordIfBare(findings, pending) {
|
|
29525
|
+
const logical = normalizePlanWhitespace(pending.parts.join(" "));
|
|
29526
|
+
if (isBareDefinition(logical)) {
|
|
29527
|
+
findings.push([pending.start + 1, logical]);
|
|
29528
|
+
}
|
|
29529
|
+
}
|
|
29530
|
+
function bareScratchDefinitions(text2) {
|
|
29531
|
+
const findings = [];
|
|
29532
|
+
let inFence = false;
|
|
29533
|
+
let pending = null;
|
|
29534
|
+
for (const [index, line] of splitPlanLines(text2).entries()) {
|
|
29535
|
+
if (pending !== null && continuesLogicalLine(line)) {
|
|
29536
|
+
pending.parts.push(line);
|
|
29537
|
+
continue;
|
|
29538
|
+
}
|
|
29539
|
+
if (pending !== null) {
|
|
29540
|
+
recordIfBare(findings, pending);
|
|
29541
|
+
pending = null;
|
|
29542
|
+
}
|
|
29543
|
+
if (FENCE_RE3.test(line)) {
|
|
29544
|
+
inFence = !inFence;
|
|
29545
|
+
continue;
|
|
29546
|
+
}
|
|
29547
|
+
if (inFence || normalizePlanWhitespace(line) === "") {
|
|
29548
|
+
continue;
|
|
29549
|
+
}
|
|
29550
|
+
pending = { start: index, parts: [line] };
|
|
29551
|
+
}
|
|
29552
|
+
if (pending !== null) {
|
|
29553
|
+
recordIfBare(findings, pending);
|
|
29554
|
+
}
|
|
29555
|
+
return findings;
|
|
29556
|
+
}
|
|
29557
|
+
function scratchFindingMessage(lineNumber, logicalLine) {
|
|
29558
|
+
return `Line ${String(lineNumber)}: SCRATCH definition \`${logicalLine}\` is not namespaced by issue number; define SCRATCH as \`<session scratchpad>/issue-<issue-num>/\`.`;
|
|
29559
|
+
}
|
|
29560
|
+
function evaluateScratchGate(report, text2, severity = G10_SEVERITY) {
|
|
29561
|
+
const channel = severity === "blocking" ? report.blocking : report.warnings;
|
|
29562
|
+
for (const [lineNumber, logicalLine] of bareScratchDefinitions(text2)) {
|
|
29563
|
+
channel.push(scratchFindingMessage(lineNumber, logicalLine));
|
|
29564
|
+
}
|
|
29565
|
+
}
|
|
29566
|
+
|
|
29214
29567
|
// ../../extensions/drm-copilot/src/lib/validate/plan-gate-discrimination.ts
|
|
29215
29568
|
var G5_SEVERITY = "warning";
|
|
29216
29569
|
var CommandRunnerPlanGateRepository = class {
|
|
@@ -29310,6 +29663,8 @@ function evaluatePlanGates(text2, context) {
|
|
|
29310
29663
|
if (context !== void 0) {
|
|
29311
29664
|
evaluateLiteralRules(report, text2, commands, context);
|
|
29312
29665
|
}
|
|
29666
|
+
evaluateScratchGate(report, text2);
|
|
29667
|
+
evaluateDocumentGates(report, text2);
|
|
29313
29668
|
return report;
|
|
29314
29669
|
}
|
|
29315
29670
|
|
|
@@ -30245,45 +30600,149 @@ function validateParallelOrchestratorStateText(text2, options = {}) {
|
|
|
30245
30600
|
return errors;
|
|
30246
30601
|
}
|
|
30247
30602
|
|
|
30248
|
-
// ../../extensions/drm-copilot/src/lib/validate/parallel-planner-state-
|
|
30249
|
-
var
|
|
30250
|
-
var
|
|
30251
|
-
|
|
30252
|
-
|
|
30253
|
-
"
|
|
30254
|
-
"parallel_slug",
|
|
30255
|
-
"parallel_manifest_path",
|
|
30256
|
-
"mode",
|
|
30257
|
-
"max_concurrency",
|
|
30258
|
-
"items",
|
|
30259
|
-
"cohorts",
|
|
30260
|
-
"conflict_edges",
|
|
30261
|
-
"recolor_generation",
|
|
30262
|
-
"completed_steps",
|
|
30263
|
-
"next_step",
|
|
30264
|
-
"last_updated"
|
|
30265
|
-
];
|
|
30266
|
-
var REQUIRED_ITEM_KEYS = [
|
|
30267
|
-
"issue_num",
|
|
30268
|
-
"feature_folder",
|
|
30269
|
-
"kind",
|
|
30270
|
-
"state",
|
|
30271
|
-
"blast_radius",
|
|
30272
|
-
"preparation_status",
|
|
30273
|
-
"research_path",
|
|
30274
|
-
"plan_path",
|
|
30275
|
-
"preflight_status"
|
|
30276
|
-
];
|
|
30277
|
-
var VALID_COMPLEXITY_BANDS = [
|
|
30278
|
-
"C1",
|
|
30279
|
-
"C2",
|
|
30280
|
-
"C3",
|
|
30281
|
-
"C4"
|
|
30603
|
+
// ../../extensions/drm-copilot/src/lib/validate/parallel-planner-state-routing.ts
|
|
30604
|
+
var BAND_ORDER2 = ["C1", "C2", "C3", "C4"];
|
|
30605
|
+
var VALID_FABLE_POLICIES = [
|
|
30606
|
+
"disabled",
|
|
30607
|
+
"available",
|
|
30608
|
+
"preferred"
|
|
30282
30609
|
];
|
|
30283
|
-
var
|
|
30284
|
-
|
|
30285
|
-
|
|
30286
|
-
|
|
30610
|
+
var ROUTING_AGENT = "orchestrator";
|
|
30611
|
+
function sameValue(left, right) {
|
|
30612
|
+
return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
30613
|
+
}
|
|
30614
|
+
function isListOfStrings(value) {
|
|
30615
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
30616
|
+
}
|
|
30617
|
+
function validateAssessmentEntry(assessment, context) {
|
|
30618
|
+
const errors = [];
|
|
30619
|
+
const band = assessment["band"];
|
|
30620
|
+
const floor = assessment["floor"];
|
|
30621
|
+
if (!isEnumMember(BAND_ORDER2, band)) {
|
|
30622
|
+
errors.push(
|
|
30623
|
+
`${context} band must be one of C1, C2, C3, C4; got: ${pythonStr2(band)}.`
|
|
30624
|
+
);
|
|
30625
|
+
}
|
|
30626
|
+
if (!isListOfStrings(assessment["signals_present"])) {
|
|
30627
|
+
errors.push(`${context} signals_present must be a list of strings.`);
|
|
30628
|
+
}
|
|
30629
|
+
if (isEnumMember(BAND_ORDER2, band) && isEnumMember(BAND_ORDER2, floor) && BAND_ORDER2.indexOf(String(band)) < BAND_ORDER2.indexOf(String(floor))) {
|
|
30630
|
+
errors.push(
|
|
30631
|
+
`${context} band ${pythonStr2(band)} is below its floor ${pythonStr2(floor)}.`
|
|
30632
|
+
);
|
|
30633
|
+
}
|
|
30634
|
+
if (!isNonEmptyString2(assessment["rationale"])) {
|
|
30635
|
+
errors.push(`${context} rationale must be a non-empty string.`);
|
|
30636
|
+
}
|
|
30637
|
+
return errors;
|
|
30638
|
+
}
|
|
30639
|
+
function validateAssessment(assessment, band, entryContext) {
|
|
30640
|
+
const context = `${entryContext} complexity_assessment`;
|
|
30641
|
+
const errors = validateAssessmentEntry(assessment, context);
|
|
30642
|
+
if (!isNonEmptyString2(assessment["assessed_at"])) {
|
|
30643
|
+
errors.push(`${context}.assessed_at must be a non-empty string.`);
|
|
30644
|
+
}
|
|
30645
|
+
const assessedBand = assessment["band"];
|
|
30646
|
+
if (!sameValue(assessedBand, band)) {
|
|
30647
|
+
errors.push(
|
|
30648
|
+
`${context}.band ${pythonRepr10(assessedBand)} does not equal complexity_band ${pythonRepr10(band)}.`
|
|
30649
|
+
);
|
|
30650
|
+
}
|
|
30651
|
+
return errors;
|
|
30652
|
+
}
|
|
30653
|
+
function validateReceipt4(receipt, band, entryContext) {
|
|
30654
|
+
const context = `${entryContext} model_routing_receipt`;
|
|
30655
|
+
const errors = [];
|
|
30656
|
+
const receiptBand = receipt["complexity_band"];
|
|
30657
|
+
if (!isEnumMember(BAND_ORDER2, receiptBand)) {
|
|
30658
|
+
errors.push(
|
|
30659
|
+
`${context} complexity_band must be one of C1, C2, C3, C4; got: ${pythonStr2(receiptBand)}.`
|
|
30660
|
+
);
|
|
30661
|
+
}
|
|
30662
|
+
const agent = receipt["agent"];
|
|
30663
|
+
if (agent !== ROUTING_AGENT) {
|
|
30664
|
+
errors.push(
|
|
30665
|
+
`${context}.agent must be ${pythonRepr10(ROUTING_AGENT)}; found: ${pythonRepr10(agent)}.`
|
|
30666
|
+
);
|
|
30667
|
+
}
|
|
30668
|
+
if (!sameValue(receiptBand, band)) {
|
|
30669
|
+
errors.push(
|
|
30670
|
+
`${context}.complexity_band ${pythonRepr10(receiptBand)} does not equal complexity_band ${pythonRepr10(band)}.`
|
|
30671
|
+
);
|
|
30672
|
+
}
|
|
30673
|
+
const fablePolicy = receipt["fable_policy"];
|
|
30674
|
+
if (!isEnumMember(VALID_FABLE_POLICIES, fablePolicy)) {
|
|
30675
|
+
errors.push(
|
|
30676
|
+
enumError(
|
|
30677
|
+
entryContext,
|
|
30678
|
+
"model_routing_receipt.fable_policy",
|
|
30679
|
+
VALID_FABLE_POLICIES,
|
|
30680
|
+
fablePolicy
|
|
30681
|
+
)
|
|
30682
|
+
);
|
|
30683
|
+
}
|
|
30684
|
+
return errors;
|
|
30685
|
+
}
|
|
30686
|
+
function validateReadyItemRouting(record3, entryContext) {
|
|
30687
|
+
const errors = [];
|
|
30688
|
+
const band = record3["complexity_band"];
|
|
30689
|
+
if (!isEnumMember(BAND_ORDER2, band)) {
|
|
30690
|
+
errors.push(enumError(entryContext, "complexity_band", BAND_ORDER2, band));
|
|
30691
|
+
}
|
|
30692
|
+
const assessment = record3["complexity_assessment"];
|
|
30693
|
+
if (isObject15(assessment)) {
|
|
30694
|
+
errors.push(...validateAssessment(assessment, band, entryContext));
|
|
30695
|
+
} else {
|
|
30696
|
+
errors.push(`${entryContext} complexity_assessment must be an object.`);
|
|
30697
|
+
}
|
|
30698
|
+
const receipt = record3["model_routing_receipt"];
|
|
30699
|
+
if (isObject15(receipt)) {
|
|
30700
|
+
errors.push(...validateReceipt4(receipt, band, entryContext));
|
|
30701
|
+
} else {
|
|
30702
|
+
errors.push(`${entryContext} model_routing_receipt must be an object.`);
|
|
30703
|
+
}
|
|
30704
|
+
return errors;
|
|
30705
|
+
}
|
|
30706
|
+
|
|
30707
|
+
// ../../extensions/drm-copilot/src/lib/validate/parallel-planner-state-core.ts
|
|
30708
|
+
var CONTEXT2 = "Parallel planner checkpoint";
|
|
30709
|
+
var MIN_CONCURRENCY2 = 1;
|
|
30710
|
+
var MAX_CONCURRENCY2 = 32;
|
|
30711
|
+
var REQUIRED_KEYS5 = [
|
|
30712
|
+
"objective",
|
|
30713
|
+
"parallel_slug",
|
|
30714
|
+
"parallel_manifest_path",
|
|
30715
|
+
"mode",
|
|
30716
|
+
"max_concurrency",
|
|
30717
|
+
"items",
|
|
30718
|
+
"cohorts",
|
|
30719
|
+
"conflict_edges",
|
|
30720
|
+
"recolor_generation",
|
|
30721
|
+
"completed_steps",
|
|
30722
|
+
"next_step",
|
|
30723
|
+
"last_updated"
|
|
30724
|
+
];
|
|
30725
|
+
var REQUIRED_ITEM_KEYS = [
|
|
30726
|
+
"issue_num",
|
|
30727
|
+
"feature_folder",
|
|
30728
|
+
"kind",
|
|
30729
|
+
"state",
|
|
30730
|
+
"blast_radius",
|
|
30731
|
+
"preparation_status",
|
|
30732
|
+
"research_path",
|
|
30733
|
+
"plan_path",
|
|
30734
|
+
"preflight_status"
|
|
30735
|
+
];
|
|
30736
|
+
var VALID_COMPLEXITY_BANDS = [
|
|
30737
|
+
"C1",
|
|
30738
|
+
"C2",
|
|
30739
|
+
"C3",
|
|
30740
|
+
"C4"
|
|
30741
|
+
];
|
|
30742
|
+
var READY_NEXT_STEP2 = "PARALLEL_EXECUTION_READY";
|
|
30743
|
+
var READY_PREPARATION_STATUS = "prepared";
|
|
30744
|
+
var READY_PREFLIGHT_STATUS = "PREFLIGHT: ALL CLEAR";
|
|
30745
|
+
var READY_RADIUS_SOURCE = "declared";
|
|
30287
30746
|
var MINIMUM_READY_ITEMS = 2;
|
|
30288
30747
|
var READY_ITEM_PATH_KEYS = ["research_path", "plan_path"];
|
|
30289
30748
|
function kickoffPathFor(slug) {
|
|
@@ -30422,7 +30881,9 @@ function validateReadyGate(state) {
|
|
|
30422
30881
|
);
|
|
30423
30882
|
}
|
|
30424
30883
|
for (const { index, record: record3 } of itemRecords(items)) {
|
|
30425
|
-
|
|
30884
|
+
const entryContext = itemContext(CONTEXT2, index);
|
|
30885
|
+
errors.push(...validateReadyItem(record3, entryContext));
|
|
30886
|
+
errors.push(...validateReadyItemRouting(record3, entryContext));
|
|
30426
30887
|
}
|
|
30427
30888
|
}
|
|
30428
30889
|
const nextStep = state["next_step"];
|
|
@@ -31588,6 +32049,8 @@ function dispatchValidatorErrors(input) {
|
|
|
31588
32049
|
case "epic-planner-state": {
|
|
31589
32050
|
const options = {
|
|
31590
32051
|
...input.requireReadyForExecution === void 0 ? {} : { requireReadyForExecution: input.requireReadyForExecution },
|
|
32052
|
+
...input.requireCodexModelRouting === void 0 ? {} : { requireCodexModelRouting: input.requireCodexModelRouting },
|
|
32053
|
+
...input.requireCodexTopology === void 0 ? {} : { requireCodexTopology: input.requireCodexTopology },
|
|
31591
32054
|
...input.fs === void 0 || input.root === void 0 || input.artifactPath === void 0 || input.runner === void 0 ? {} : {
|
|
31592
32055
|
readinessContext: {
|
|
31593
32056
|
workspaceRoot: input.root,
|
|
@@ -31785,6 +32248,76 @@ function createGitCheckoutContext(runner) {
|
|
|
31785
32248
|
return { observe, isHeadRelationshipSatisfied };
|
|
31786
32249
|
}
|
|
31787
32250
|
|
|
32251
|
+
// ../../extensions/drm-copilot/src/lib/validate/orchestration-handoff-materializer-request.ts
|
|
32252
|
+
var HANDOFF_ERROR_CODE_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
32253
|
+
var HANDOFF_ERROR_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
32254
|
+
function describeHandoffFailureCause(stage, error2) {
|
|
32255
|
+
if (typeof error2 === "object" && error2 !== null && "code" in error2) {
|
|
32256
|
+
const code = error2.code;
|
|
32257
|
+
if (typeof code === "string" && HANDOFF_ERROR_CODE_PATTERN.test(code)) {
|
|
32258
|
+
return `${stage}: ${code}`;
|
|
32259
|
+
}
|
|
32260
|
+
}
|
|
32261
|
+
if (error2 instanceof Error) {
|
|
32262
|
+
return HANDOFF_ERROR_NAME_PATTERN.test(error2.name) ? `${stage}: ${error2.name}` : `${stage}: Error`;
|
|
32263
|
+
}
|
|
32264
|
+
return `${stage}: non-error value`;
|
|
32265
|
+
}
|
|
32266
|
+
function describeEnvelopeParseFailure(error2) {
|
|
32267
|
+
return {
|
|
32268
|
+
code: error2 instanceof HandoffContractError ? error2.code : "HANDOFF_UNSUPPORTED_VERSION",
|
|
32269
|
+
failureCause: describeHandoffFailureCause("envelope-parse", error2)
|
|
32270
|
+
};
|
|
32271
|
+
}
|
|
32272
|
+
function toReferenceRequest(request) {
|
|
32273
|
+
return {
|
|
32274
|
+
workspaceRoot: request.workspaceRoot,
|
|
32275
|
+
handoffEnvelopePath: request.handoffEnvelopePath,
|
|
32276
|
+
expectedHandoffEnvelopeSha256: request.expectedHandoffEnvelopeSha256,
|
|
32277
|
+
destinationProvider: request.destinationProvider,
|
|
32278
|
+
expectedRepositoryId: request.expectedRepositoryId,
|
|
32279
|
+
expectedWorkspaceRoot: request.expectedWorkspaceRoot,
|
|
32280
|
+
expectedBranch: request.expectedBranch,
|
|
32281
|
+
expectedSourceHeadSha: request.expectedSourceHeadSha,
|
|
32282
|
+
allowedHeadRelationship: request.allowedHeadRelationship,
|
|
32283
|
+
expectedIssueNumber: request.expectedIssueNumber,
|
|
32284
|
+
expectedFeatureFolder: request.expectedFeatureFolder,
|
|
32285
|
+
expectedWorkMode: request.expectedWorkMode,
|
|
32286
|
+
expectedPlanPath: request.expectedPlanPath,
|
|
32287
|
+
expectedPlanSha256: request.expectedPlanSha256
|
|
32288
|
+
};
|
|
32289
|
+
}
|
|
32290
|
+
function blockedResult(request, primaryFailureCode, options = {}) {
|
|
32291
|
+
return {
|
|
32292
|
+
status: "blocked",
|
|
32293
|
+
handoffId: options.handoffId ?? null,
|
|
32294
|
+
sourceCheckpointSha256: request.expectedSourceCheckpointSha256,
|
|
32295
|
+
handoffEnvelopeSha256: request.expectedHandoffEnvelopeSha256,
|
|
32296
|
+
handoffHistorySha256: options.handoffHistorySha256 ?? null,
|
|
32297
|
+
requestedTransition: "prepared_to_atomic_execution",
|
|
32298
|
+
destinationCheckpointPath: null,
|
|
32299
|
+
destinationCheckpointSha256: null,
|
|
32300
|
+
primaryFailureCode,
|
|
32301
|
+
affectedPaths: options.affectedPaths ?? [],
|
|
32302
|
+
unsupportedCapabilities: options.unsupportedCapabilities ?? [],
|
|
32303
|
+
...options.failureCause === void 0 ? {} : { failureCause: options.failureCause }
|
|
32304
|
+
};
|
|
32305
|
+
}
|
|
32306
|
+
function authorityFailure(request, authority, handoffHistorySha256) {
|
|
32307
|
+
if (authority.status === "validated") return null;
|
|
32308
|
+
return blockedResult(
|
|
32309
|
+
request,
|
|
32310
|
+
authority.primaryFailureCode ?? "HANDOFF_VALIDATOR_UNAVAILABLE",
|
|
32311
|
+
{
|
|
32312
|
+
handoffId: authority.handoffId,
|
|
32313
|
+
handoffHistorySha256,
|
|
32314
|
+
affectedPaths: authority.affectedPaths,
|
|
32315
|
+
unsupportedCapabilities: authority.unsupportedCapabilities,
|
|
32316
|
+
...authority.failureCause === void 0 ? {} : { failureCause: authority.failureCause }
|
|
32317
|
+
}
|
|
32318
|
+
);
|
|
32319
|
+
}
|
|
32320
|
+
|
|
31788
32321
|
// ../../extensions/drm-copilot/src/lib/validate/orchestration-handoff-path-boundary.ts
|
|
31789
32322
|
var fs6 = __toESM(require("node:fs"));
|
|
31790
32323
|
var path11 = __toESM(require("node:path"));
|
|
@@ -31813,6 +32346,13 @@ function normalizedRepositorySegments(repositoryPath2) {
|
|
|
31813
32346
|
function missingPath(error2) {
|
|
31814
32347
|
return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
|
|
31815
32348
|
}
|
|
32349
|
+
function guardedResolution(stage, operation) {
|
|
32350
|
+
try {
|
|
32351
|
+
return { ok: true, value: operation() };
|
|
32352
|
+
} catch (error2) {
|
|
32353
|
+
return { ok: false, cause: describeHandoffFailureCause(stage, error2) };
|
|
32354
|
+
}
|
|
32355
|
+
}
|
|
31816
32356
|
function lexicalCandidate(canonicalWorkspaceRoot, repositoryPath2, caseSensitive) {
|
|
31817
32357
|
if (!path11.isAbsolute(canonicalWorkspaceRoot)) return null;
|
|
31818
32358
|
const segments = normalizedRepositorySegments(repositoryPath2);
|
|
@@ -31823,14 +32363,13 @@ function lexicalCandidate(canonicalWorkspaceRoot, repositoryPath2, caseSensitive
|
|
|
31823
32363
|
function createHandoffPathBoundary(fileSystem, caseSensitive = process.platform !== "win32") {
|
|
31824
32364
|
const resolveWorkspaceRoot = (workspaceRoot) => {
|
|
31825
32365
|
if (!path11.isAbsolute(workspaceRoot)) return null;
|
|
31826
|
-
|
|
32366
|
+
const resolution = guardedResolution("workspace-root", () => {
|
|
31827
32367
|
const canonicalRoot = normalizedAbsolutePath(
|
|
31828
32368
|
fileSystem.realpath(path11.resolve(workspaceRoot))
|
|
31829
32369
|
);
|
|
31830
32370
|
return fileSystem.stat(canonicalRoot).isDirectory() ? canonicalRoot : null;
|
|
31831
|
-
}
|
|
31832
|
-
|
|
31833
|
-
}
|
|
32371
|
+
});
|
|
32372
|
+
return resolution.ok ? resolution.value : null;
|
|
31834
32373
|
};
|
|
31835
32374
|
const resolveExistingTarget = (canonicalWorkspaceRoot, repositoryPath2) => {
|
|
31836
32375
|
const candidate = lexicalCandidate(
|
|
@@ -31839,14 +32378,12 @@ function createHandoffPathBoundary(fileSystem, caseSensitive = process.platform
|
|
|
31839
32378
|
caseSensitive
|
|
31840
32379
|
);
|
|
31841
32380
|
if (candidate === null) return null;
|
|
31842
|
-
|
|
31843
|
-
|
|
31844
|
-
|
|
31845
|
-
|
|
31846
|
-
|
|
31847
|
-
|
|
31848
|
-
return null;
|
|
31849
|
-
}
|
|
32381
|
+
const resolution = guardedResolution(
|
|
32382
|
+
"target-path",
|
|
32383
|
+
() => normalizedAbsolutePath(fileSystem.realpath(candidate))
|
|
32384
|
+
);
|
|
32385
|
+
if (!resolution.ok) return null;
|
|
32386
|
+
return isContained(canonicalWorkspaceRoot, resolution.value, caseSensitive) ? resolution.value : null;
|
|
31850
32387
|
};
|
|
31851
32388
|
const resolveCreatableTarget = (canonicalWorkspaceRoot, repositoryPath2) => {
|
|
31852
32389
|
const candidate = lexicalCandidate(
|
|
@@ -31949,7 +32486,8 @@ function blocked(request, code, options = {}) {
|
|
|
31949
32486
|
primaryFailureCode: code,
|
|
31950
32487
|
affectedPaths: options.affectedPaths ?? [],
|
|
31951
32488
|
unsupportedCapabilities: options.unsupportedCapabilities ?? [],
|
|
31952
|
-
resolution: null
|
|
32489
|
+
resolution: null,
|
|
32490
|
+
...options.failureCause === void 0 ? {} : { failureCause: options.failureCause }
|
|
31953
32491
|
};
|
|
31954
32492
|
}
|
|
31955
32493
|
function readEnvelope(fileSystem, request, pathBoundary, canonicalWorkspaceRoot) {
|
|
@@ -31958,13 +32496,17 @@ function readEnvelope(fileSystem, request, pathBoundary, canonicalWorkspaceRoot)
|
|
|
31958
32496
|
request.handoffEnvelopePath
|
|
31959
32497
|
);
|
|
31960
32498
|
if (envelopePath === null) {
|
|
31961
|
-
return blocked(request, "HANDOFF_PLAN_PATH_INVALID"
|
|
32499
|
+
return blocked(request, "HANDOFF_PLAN_PATH_INVALID", {
|
|
32500
|
+
failureCause: "target-path: unresolved"
|
|
32501
|
+
});
|
|
31962
32502
|
}
|
|
31963
32503
|
let envelopeText;
|
|
31964
32504
|
try {
|
|
31965
32505
|
envelopeText = fileSystem.readTextFile(envelopePath);
|
|
31966
|
-
} catch {
|
|
31967
|
-
return blocked(request, "HANDOFF_VALIDATOR_UNAVAILABLE"
|
|
32506
|
+
} catch (error2) {
|
|
32507
|
+
return blocked(request, "HANDOFF_VALIDATOR_UNAVAILABLE", {
|
|
32508
|
+
failureCause: describeHandoffFailureCause("envelope-read", error2)
|
|
32509
|
+
});
|
|
31968
32510
|
}
|
|
31969
32511
|
if (sha256(envelopeText) !== request.expectedHandoffEnvelopeSha256) {
|
|
31970
32512
|
return blocked(request, "HANDOFF_SOURCE_HASH_MISMATCH");
|
|
@@ -31972,10 +32514,10 @@ function readEnvelope(fileSystem, request, pathBoundary, canonicalWorkspaceRoot)
|
|
|
31972
32514
|
try {
|
|
31973
32515
|
return parseHandoffEnvelopeText(envelopeText);
|
|
31974
32516
|
} catch (error2) {
|
|
31975
|
-
|
|
31976
|
-
|
|
31977
|
-
|
|
31978
|
-
);
|
|
32517
|
+
const failure = describeEnvelopeParseFailure(error2);
|
|
32518
|
+
return blocked(request, failure.code, {
|
|
32519
|
+
failureCause: failure.failureCause
|
|
32520
|
+
});
|
|
31979
32521
|
}
|
|
31980
32522
|
}
|
|
31981
32523
|
function observedPlanSha256(fileSystem, expectedPlanPath, pathBoundary, canonicalWorkspaceRoot) {
|
|
@@ -31983,11 +32525,11 @@ function observedPlanSha256(fileSystem, expectedPlanPath, pathBoundary, canonica
|
|
|
31983
32525
|
canonicalWorkspaceRoot,
|
|
31984
32526
|
expectedPlanPath
|
|
31985
32527
|
);
|
|
31986
|
-
if (planPath === null) return
|
|
32528
|
+
if (planPath === null) return { failureCause: "target-path: unresolved" };
|
|
31987
32529
|
try {
|
|
31988
|
-
return sha256(fileSystem.readTextFile(planPath));
|
|
31989
|
-
} catch {
|
|
31990
|
-
return
|
|
32530
|
+
return { sha256: sha256(fileSystem.readTextFile(planPath)) };
|
|
32531
|
+
} catch (error2) {
|
|
32532
|
+
return { failureCause: describeHandoffFailureCause("plan-read", error2) };
|
|
31991
32533
|
}
|
|
31992
32534
|
}
|
|
31993
32535
|
function canonicalizeObservedPath(value) {
|
|
@@ -32047,7 +32589,9 @@ function resolvePortableHandoffAuthority(fileSystem, request, kind, pathBoundary
|
|
|
32047
32589
|
request.workspaceRoot
|
|
32048
32590
|
);
|
|
32049
32591
|
if (canonicalWorkspaceRoot === null) {
|
|
32050
|
-
return blocked(request, "HANDOFF_PLAN_PATH_INVALID"
|
|
32592
|
+
return blocked(request, "HANDOFF_PLAN_PATH_INVALID", {
|
|
32593
|
+
failureCause: "workspace-root: unresolved"
|
|
32594
|
+
});
|
|
32051
32595
|
}
|
|
32052
32596
|
const effectiveCheckoutContext = checkoutContext ?? createGitCheckoutContext(new SubprocessRunner());
|
|
32053
32597
|
const observation = effectiveCheckoutContext.observe(
|
|
@@ -32085,17 +32629,19 @@ function resolvePortableHandoffAuthority(fileSystem, request, kind, pathBoundary
|
|
|
32085
32629
|
handoffId: envelope.handoffId
|
|
32086
32630
|
});
|
|
32087
32631
|
}
|
|
32088
|
-
const
|
|
32632
|
+
const planObservation = observedPlanSha256(
|
|
32089
32633
|
fileSystem,
|
|
32090
32634
|
request.expectedPlanPath,
|
|
32091
32635
|
effectivePathBoundary,
|
|
32092
32636
|
canonicalWorkspaceRoot
|
|
32093
32637
|
);
|
|
32094
|
-
if (
|
|
32638
|
+
if ("failureCause" in planObservation) {
|
|
32095
32639
|
return blocked(request, "HANDOFF_PLAN_PATH_INVALID", {
|
|
32096
|
-
handoffId: envelope.handoffId
|
|
32640
|
+
handoffId: envelope.handoffId,
|
|
32641
|
+
failureCause: planObservation.failureCause
|
|
32097
32642
|
});
|
|
32098
32643
|
}
|
|
32644
|
+
const planSha256 = planObservation.sha256;
|
|
32099
32645
|
const validation = collectHandoffValidationFailures(envelope, {
|
|
32100
32646
|
repositoryId: request.expectedRepositoryId,
|
|
32101
32647
|
workspaceRoot: request.expectedWorkspaceRoot,
|
|
@@ -32199,54 +32745,6 @@ function porcelainAffectedPaths(output) {
|
|
|
32199
32745
|
return [...paths].sort((left, right) => left.localeCompare(right));
|
|
32200
32746
|
}
|
|
32201
32747
|
|
|
32202
|
-
// ../../extensions/drm-copilot/src/lib/validate/orchestration-handoff-materializer-request.ts
|
|
32203
|
-
function toReferenceRequest(request) {
|
|
32204
|
-
return {
|
|
32205
|
-
workspaceRoot: request.workspaceRoot,
|
|
32206
|
-
handoffEnvelopePath: request.handoffEnvelopePath,
|
|
32207
|
-
expectedHandoffEnvelopeSha256: request.expectedHandoffEnvelopeSha256,
|
|
32208
|
-
destinationProvider: request.destinationProvider,
|
|
32209
|
-
expectedRepositoryId: request.expectedRepositoryId,
|
|
32210
|
-
expectedWorkspaceRoot: request.expectedWorkspaceRoot,
|
|
32211
|
-
expectedBranch: request.expectedBranch,
|
|
32212
|
-
expectedSourceHeadSha: request.expectedSourceHeadSha,
|
|
32213
|
-
allowedHeadRelationship: request.allowedHeadRelationship,
|
|
32214
|
-
expectedIssueNumber: request.expectedIssueNumber,
|
|
32215
|
-
expectedFeatureFolder: request.expectedFeatureFolder,
|
|
32216
|
-
expectedWorkMode: request.expectedWorkMode,
|
|
32217
|
-
expectedPlanPath: request.expectedPlanPath,
|
|
32218
|
-
expectedPlanSha256: request.expectedPlanSha256
|
|
32219
|
-
};
|
|
32220
|
-
}
|
|
32221
|
-
function blockedResult(request, primaryFailureCode, options = {}) {
|
|
32222
|
-
return {
|
|
32223
|
-
status: "blocked",
|
|
32224
|
-
handoffId: options.handoffId ?? null,
|
|
32225
|
-
sourceCheckpointSha256: request.expectedSourceCheckpointSha256,
|
|
32226
|
-
handoffEnvelopeSha256: request.expectedHandoffEnvelopeSha256,
|
|
32227
|
-
handoffHistorySha256: options.handoffHistorySha256 ?? null,
|
|
32228
|
-
requestedTransition: "prepared_to_atomic_execution",
|
|
32229
|
-
destinationCheckpointPath: null,
|
|
32230
|
-
destinationCheckpointSha256: null,
|
|
32231
|
-
primaryFailureCode,
|
|
32232
|
-
affectedPaths: options.affectedPaths ?? [],
|
|
32233
|
-
unsupportedCapabilities: options.unsupportedCapabilities ?? []
|
|
32234
|
-
};
|
|
32235
|
-
}
|
|
32236
|
-
function authorityFailure(request, authority, handoffHistorySha256) {
|
|
32237
|
-
if (authority.status === "validated") return null;
|
|
32238
|
-
return blockedResult(
|
|
32239
|
-
request,
|
|
32240
|
-
authority.primaryFailureCode ?? "HANDOFF_VALIDATOR_UNAVAILABLE",
|
|
32241
|
-
{
|
|
32242
|
-
handoffId: authority.handoffId,
|
|
32243
|
-
handoffHistorySha256,
|
|
32244
|
-
affectedPaths: authority.affectedPaths,
|
|
32245
|
-
unsupportedCapabilities: authority.unsupportedCapabilities
|
|
32246
|
-
}
|
|
32247
|
-
);
|
|
32248
|
-
}
|
|
32249
|
-
|
|
32250
32748
|
// ../../extensions/drm-copilot/src/lib/validate/orchestration-handoff-provider-adapters.ts
|
|
32251
32749
|
var PROVIDER_ADAPTERS = {
|
|
32252
32750
|
claude: {
|
|
@@ -32412,7 +32910,9 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32412
32910
|
request.workspaceRoot
|
|
32413
32911
|
);
|
|
32414
32912
|
if (canonicalWorkspaceRoot === null) {
|
|
32415
|
-
return blockedResult(request, "HANDOFF_PLAN_PATH_INVALID"
|
|
32913
|
+
return blockedResult(request, "HANDOFF_PLAN_PATH_INVALID", {
|
|
32914
|
+
failureCause: "workspace-root: unresolved"
|
|
32915
|
+
});
|
|
32416
32916
|
}
|
|
32417
32917
|
const sourcePath = pathBoundary.resolveExistingTarget(
|
|
32418
32918
|
canonicalWorkspaceRoot,
|
|
@@ -32423,15 +32923,19 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32423
32923
|
request.handoffEnvelopePath
|
|
32424
32924
|
);
|
|
32425
32925
|
if (sourcePath === null || envelopePath === null) {
|
|
32426
|
-
return blockedResult(request, "HANDOFF_PLAN_PATH_INVALID"
|
|
32926
|
+
return blockedResult(request, "HANDOFF_PLAN_PATH_INVALID", {
|
|
32927
|
+
failureCause: "target-path: unresolved"
|
|
32928
|
+
});
|
|
32427
32929
|
}
|
|
32428
32930
|
let sourceBytes;
|
|
32429
32931
|
let envelopeBytes;
|
|
32430
32932
|
try {
|
|
32431
32933
|
sourceBytes = this.dependencies.fileSystem.readFile(sourcePath);
|
|
32432
32934
|
envelopeBytes = this.dependencies.fileSystem.readFile(envelopePath);
|
|
32433
|
-
} catch {
|
|
32434
|
-
return blockedResult(request, "HANDOFF_VALIDATOR_UNAVAILABLE"
|
|
32935
|
+
} catch (error2) {
|
|
32936
|
+
return blockedResult(request, "HANDOFF_VALIDATOR_UNAVAILABLE", {
|
|
32937
|
+
failureCause: describeHandoffFailureCause("checkpoint-read", error2)
|
|
32938
|
+
});
|
|
32435
32939
|
}
|
|
32436
32940
|
if (sha2562(sourceBytes) !== request.expectedSourceCheckpointSha256 || sha2562(envelopeBytes) !== request.expectedHandoffEnvelopeSha256) {
|
|
32437
32941
|
return blockedResult(request, "HANDOFF_SOURCE_HASH_MISMATCH");
|
|
@@ -32439,8 +32943,10 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32439
32943
|
let envelopeText;
|
|
32440
32944
|
try {
|
|
32441
32945
|
envelopeText = textDecoder.decode(envelopeBytes);
|
|
32442
|
-
} catch {
|
|
32443
|
-
return blockedResult(request, "HANDOFF_UNSUPPORTED_VERSION"
|
|
32946
|
+
} catch (error2) {
|
|
32947
|
+
return blockedResult(request, "HANDOFF_UNSUPPORTED_VERSION", {
|
|
32948
|
+
failureCause: describeHandoffFailureCause("envelope-decode", error2)
|
|
32949
|
+
});
|
|
32444
32950
|
}
|
|
32445
32951
|
const validation = this.dependencies.validator.validateEnvelope(envelopeText);
|
|
32446
32952
|
if (validation.primaryFailureCode !== null || validation.envelope === null) {
|
|
@@ -32449,7 +32955,8 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32449
32955
|
validation.primaryFailureCode ?? "HANDOFF_VALIDATOR_UNAVAILABLE",
|
|
32450
32956
|
{
|
|
32451
32957
|
affectedPaths: validation.affectedPaths,
|
|
32452
|
-
unsupportedCapabilities: validation.unsupportedCapabilities
|
|
32958
|
+
unsupportedCapabilities: validation.unsupportedCapabilities,
|
|
32959
|
+
failureCause: validation.failureCause
|
|
32453
32960
|
}
|
|
32454
32961
|
);
|
|
32455
32962
|
}
|
|
@@ -32496,7 +33003,8 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32496
33003
|
if (archivePath === null || destinationPath === null || candidatePath === null) {
|
|
32497
33004
|
return blockedResult(request, "HANDOFF_PLAN_PATH_INVALID", {
|
|
32498
33005
|
handoffId: envelope.handoffId,
|
|
32499
|
-
handoffHistorySha256: lastHistoryEntry.entrySha256
|
|
33006
|
+
handoffHistorySha256: lastHistoryEntry.entrySha256,
|
|
33007
|
+
failureCause: "target-path: unresolved"
|
|
32500
33008
|
});
|
|
32501
33009
|
}
|
|
32502
33010
|
const referenceRequest = toReferenceRequest(request);
|
|
@@ -32529,7 +33037,11 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32529
33037
|
error2 instanceof Error && "code" in error2 ? error2.code : "HANDOFF_VALIDATOR_UNAVAILABLE",
|
|
32530
33038
|
{
|
|
32531
33039
|
handoffId: envelope.handoffId,
|
|
32532
|
-
handoffHistorySha256: lastHistoryEntry.entrySha256
|
|
33040
|
+
handoffHistorySha256: lastHistoryEntry.entrySha256,
|
|
33041
|
+
failureCause: describeHandoffFailureCause(
|
|
33042
|
+
"destination-projection",
|
|
33043
|
+
error2
|
|
33044
|
+
)
|
|
32533
33045
|
}
|
|
32534
33046
|
);
|
|
32535
33047
|
}
|
|
@@ -32538,7 +33050,8 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32538
33050
|
return blockedResult(request, "HANDOFF_VALIDATOR_UNAVAILABLE", {
|
|
32539
33051
|
handoffId: envelope.handoffId,
|
|
32540
33052
|
handoffHistorySha256: lastHistoryEntry.entrySha256,
|
|
32541
|
-
affectedPaths: [envelope.destinationCheckpointPath]
|
|
33053
|
+
affectedPaths: [envelope.destinationCheckpointPath],
|
|
33054
|
+
failureCause: "destination-projection: invalid"
|
|
32542
33055
|
});
|
|
32543
33056
|
}
|
|
32544
33057
|
let porcelainStatus;
|
|
@@ -32546,10 +33059,11 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32546
33059
|
porcelainStatus = await this.dependencies.git.readPorcelainStatus(
|
|
32547
33060
|
canonicalWorkspaceRoot
|
|
32548
33061
|
);
|
|
32549
|
-
} catch {
|
|
33062
|
+
} catch (error2) {
|
|
32550
33063
|
return blockedResult(request, "HANDOFF_VALIDATOR_UNAVAILABLE", {
|
|
32551
33064
|
handoffId: envelope.handoffId,
|
|
32552
|
-
handoffHistorySha256: lastHistoryEntry.entrySha256
|
|
33065
|
+
handoffHistorySha256: lastHistoryEntry.entrySha256,
|
|
33066
|
+
failureCause: describeHandoffFailureCause("git-status", error2)
|
|
32553
33067
|
});
|
|
32554
33068
|
}
|
|
32555
33069
|
const affectedPaths = porcelainAffectedPaths(porcelainStatus);
|
|
@@ -32595,24 +33109,30 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32595
33109
|
preparation.sourceBytes,
|
|
32596
33110
|
{ exclusive: true }
|
|
32597
33111
|
);
|
|
32598
|
-
} catch {
|
|
33112
|
+
} catch (writeError) {
|
|
33113
|
+
const writeCause = describeHandoffFailureCause(
|
|
33114
|
+
"archive-write",
|
|
33115
|
+
writeError
|
|
33116
|
+
);
|
|
32599
33117
|
let archivedBytes;
|
|
32600
33118
|
try {
|
|
32601
33119
|
archivedBytes = this.dependencies.fileSystem.readFile(
|
|
32602
33120
|
preparation.archivePath
|
|
32603
33121
|
);
|
|
32604
|
-
} catch {
|
|
33122
|
+
} catch (readError) {
|
|
32605
33123
|
return blockedResult(request, "HANDOFF_VALIDATOR_UNAVAILABLE", {
|
|
32606
33124
|
handoffId: preparation.result.handoffId,
|
|
32607
33125
|
handoffHistorySha256: preparation.result.handoffHistorySha256,
|
|
32608
|
-
affectedPaths: [preparation.archivePath]
|
|
33126
|
+
affectedPaths: [preparation.archivePath],
|
|
33127
|
+
failureCause: `${writeCause}; ${describeHandoffFailureCause("archive-readback", readError)}`
|
|
32609
33128
|
});
|
|
32610
33129
|
}
|
|
32611
33130
|
if (sha2562(archivedBytes) !== expectedSourceSha256) {
|
|
32612
33131
|
return blockedResult(request, "HANDOFF_SOURCE_HASH_MISMATCH", {
|
|
32613
33132
|
handoffId: preparation.result.handoffId,
|
|
32614
33133
|
handoffHistorySha256: preparation.result.handoffHistorySha256,
|
|
32615
|
-
affectedPaths: [preparation.archivePath]
|
|
33134
|
+
affectedPaths: [preparation.archivePath],
|
|
33135
|
+
failureCause: writeCause
|
|
32616
33136
|
});
|
|
32617
33137
|
}
|
|
32618
33138
|
}
|
|
@@ -32622,24 +33142,30 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32622
33142
|
preparation.projectionBytes,
|
|
32623
33143
|
{ exclusive: true }
|
|
32624
33144
|
);
|
|
32625
|
-
} catch {
|
|
33145
|
+
} catch (writeError) {
|
|
33146
|
+
const writeCause = describeHandoffFailureCause(
|
|
33147
|
+
"candidate-write",
|
|
33148
|
+
writeError
|
|
33149
|
+
);
|
|
32626
33150
|
let existingCandidate;
|
|
32627
33151
|
try {
|
|
32628
33152
|
existingCandidate = this.dependencies.fileSystem.readFile(
|
|
32629
33153
|
preparation.candidatePath
|
|
32630
33154
|
);
|
|
32631
|
-
} catch {
|
|
33155
|
+
} catch (readError) {
|
|
32632
33156
|
return blockedResult(request, "HANDOFF_VALIDATOR_UNAVAILABLE", {
|
|
32633
33157
|
handoffId: preparation.result.handoffId,
|
|
32634
33158
|
handoffHistorySha256: preparation.result.handoffHistorySha256,
|
|
32635
|
-
affectedPaths: [preparation.candidatePath]
|
|
33159
|
+
affectedPaths: [preparation.candidatePath],
|
|
33160
|
+
failureCause: `${writeCause}; ${describeHandoffFailureCause("candidate-readback", readError)}`
|
|
32636
33161
|
});
|
|
32637
33162
|
}
|
|
32638
33163
|
if (sha2562(existingCandidate) !== sha2562(preparation.projectionBytes)) {
|
|
32639
33164
|
return blockedResult(request, "HANDOFF_VALIDATOR_UNAVAILABLE", {
|
|
32640
33165
|
handoffId: preparation.result.handoffId,
|
|
32641
33166
|
handoffHistorySha256: preparation.result.handoffHistorySha256,
|
|
32642
|
-
affectedPaths: [preparation.candidatePath]
|
|
33167
|
+
affectedPaths: [preparation.candidatePath],
|
|
33168
|
+
failureCause: writeCause
|
|
32643
33169
|
});
|
|
32644
33170
|
}
|
|
32645
33171
|
}
|
|
@@ -32649,35 +33175,51 @@ var OrchestrationHandoffMaterializer = class {
|
|
|
32649
33175
|
);
|
|
32650
33176
|
const writtenText = textDecoder.decode(writtenCandidate);
|
|
32651
33177
|
if (sha2562(writtenCandidate) !== sha2562(preparation.projectionBytes) || this.dependencies.validator.validateDestinationProjection(writtenText).length > 0) {
|
|
32652
|
-
throw new Error("Candidate validation failed.")
|
|
33178
|
+
throw Object.assign(new Error("Candidate validation failed."), {
|
|
33179
|
+
code: "HANDOFF_CANDIDATE_MISMATCH"
|
|
33180
|
+
});
|
|
32653
33181
|
}
|
|
32654
|
-
} catch {
|
|
32655
|
-
this.
|
|
32656
|
-
|
|
32657
|
-
|
|
32658
|
-
|
|
32659
|
-
|
|
32660
|
-
});
|
|
33182
|
+
} catch (error2) {
|
|
33183
|
+
return this.discardedCandidateResult(
|
|
33184
|
+
request,
|
|
33185
|
+
preparation,
|
|
33186
|
+
describeHandoffFailureCause("candidate-validate", error2)
|
|
33187
|
+
);
|
|
32661
33188
|
}
|
|
32662
33189
|
try {
|
|
32663
33190
|
this.dependencies.fileSystem.replaceFile(
|
|
32664
33191
|
preparation.candidatePath,
|
|
32665
33192
|
preparation.destinationPath
|
|
32666
33193
|
);
|
|
32667
|
-
} catch {
|
|
32668
|
-
this.
|
|
32669
|
-
|
|
32670
|
-
|
|
32671
|
-
|
|
32672
|
-
|
|
32673
|
-
});
|
|
33194
|
+
} catch (error2) {
|
|
33195
|
+
return this.discardedCandidateResult(
|
|
33196
|
+
request,
|
|
33197
|
+
preparation,
|
|
33198
|
+
describeHandoffFailureCause("candidate-replace", error2)
|
|
33199
|
+
);
|
|
32674
33200
|
}
|
|
32675
33201
|
return { ...preparation.result, status: "materialized" };
|
|
32676
33202
|
}
|
|
33203
|
+
/** Discard the candidate and block, appending any cleanup failure cause. */
|
|
33204
|
+
discardedCandidateResult(request, preparation, cause) {
|
|
33205
|
+
const cleanupCause = this.discardCandidate(preparation.candidatePath);
|
|
33206
|
+
return blockedResult(request, "HANDOFF_VALIDATOR_UNAVAILABLE", {
|
|
33207
|
+
handoffId: preparation.result.handoffId,
|
|
33208
|
+
handoffHistorySha256: preparation.result.handoffHistorySha256,
|
|
33209
|
+
affectedPaths: [preparation.candidatePath],
|
|
33210
|
+
failureCause: cleanupCause === null ? cause : `${cause}; ${cleanupCause}`
|
|
33211
|
+
});
|
|
33212
|
+
}
|
|
33213
|
+
/**
|
|
33214
|
+
* Remove the candidate. Returns `null` on success, otherwise the cleanup
|
|
33215
|
+
* cause; the blocked result names the retained candidate for explicit cleanup.
|
|
33216
|
+
*/
|
|
32677
33217
|
discardCandidate(candidatePath) {
|
|
32678
33218
|
try {
|
|
32679
33219
|
this.dependencies.fileSystem.removeFile(candidatePath);
|
|
32680
|
-
|
|
33220
|
+
return null;
|
|
33221
|
+
} catch (error2) {
|
|
33222
|
+
return describeHandoffFailureCause("candidate-cleanup", error2);
|
|
32681
33223
|
}
|
|
32682
33224
|
}
|
|
32683
33225
|
};
|
|
@@ -32695,11 +33237,13 @@ function validateEnvelope(text2) {
|
|
|
32695
33237
|
unsupportedCapabilities: []
|
|
32696
33238
|
};
|
|
32697
33239
|
} catch (error2) {
|
|
33240
|
+
const failure = describeEnvelopeParseFailure(error2);
|
|
32698
33241
|
return {
|
|
32699
33242
|
envelope: null,
|
|
32700
|
-
primaryFailureCode:
|
|
33243
|
+
primaryFailureCode: failure.code,
|
|
32701
33244
|
affectedPaths: [],
|
|
32702
|
-
unsupportedCapabilities: []
|
|
33245
|
+
unsupportedCapabilities: [],
|
|
33246
|
+
failureCause: failure.failureCause
|
|
32703
33247
|
};
|
|
32704
33248
|
}
|
|
32705
33249
|
}
|
|
@@ -32707,8 +33251,10 @@ function validateDestinationProjection(text2) {
|
|
|
32707
33251
|
let value;
|
|
32708
33252
|
try {
|
|
32709
33253
|
value = JSON.parse(text2);
|
|
32710
|
-
} catch {
|
|
32711
|
-
return [
|
|
33254
|
+
} catch (error2) {
|
|
33255
|
+
return [
|
|
33256
|
+
`destination checkpoint must be valid JSON (${describeHandoffFailureCause("destination-projection", error2)})`
|
|
33257
|
+
];
|
|
32712
33258
|
}
|
|
32713
33259
|
if (!isRecord4(value)) return ["destination checkpoint must be an object"];
|
|
32714
33260
|
const provider = value["provider"];
|
|
@@ -33024,7 +33570,7 @@ function truncate(text2, limit = 800) {
|
|
|
33024
33570
|
}
|
|
33025
33571
|
return rstrip3(text2.slice(0, limit - 3)) + "...";
|
|
33026
33572
|
}
|
|
33027
|
-
function
|
|
33573
|
+
function splitLines2(value) {
|
|
33028
33574
|
if (value === "") {
|
|
33029
33575
|
return [];
|
|
33030
33576
|
}
|
|
@@ -33035,7 +33581,7 @@ function splitLines3(value) {
|
|
|
33035
33581
|
return lines;
|
|
33036
33582
|
}
|
|
33037
33583
|
function truncateLines(text2, limit) {
|
|
33038
|
-
const lines =
|
|
33584
|
+
const lines = splitLines2(text2);
|
|
33039
33585
|
if (lines.length <= limit) {
|
|
33040
33586
|
return text2;
|
|
33041
33587
|
}
|
|
@@ -33075,14 +33621,11 @@ function formatList(values, emptyText) {
|
|
|
33075
33621
|
}
|
|
33076
33622
|
return valuesList.map((item) => `- ${item}`).join("\n");
|
|
33077
33623
|
}
|
|
33078
|
-
function
|
|
33079
|
-
|
|
33080
|
-
|
|
33081
|
-
|
|
33082
|
-
|
|
33083
|
-
return 1;
|
|
33084
|
-
}
|
|
33085
|
-
return 0;
|
|
33624
|
+
function sortedSet(values) {
|
|
33625
|
+
return [...new Set(values)].sort(compareCodePoint);
|
|
33626
|
+
}
|
|
33627
|
+
function escapeRegExp4(value) {
|
|
33628
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
33086
33629
|
}
|
|
33087
33630
|
|
|
33088
33631
|
// ../../extensions/drm-copilot/src/lib/pr-context/git-client.ts
|
|
@@ -33275,9 +33818,6 @@ function extractClosingNumbers(raw) {
|
|
|
33275
33818
|
}
|
|
33276
33819
|
return numbers;
|
|
33277
33820
|
}
|
|
33278
|
-
function sortedSet(values) {
|
|
33279
|
-
return [...new Set(values)].sort(compareCodePoint);
|
|
33280
|
-
}
|
|
33281
33821
|
function authorLogin(record3, key) {
|
|
33282
33822
|
const raw = record3[key];
|
|
33283
33823
|
if (isRecord5(raw)) {
|
|
@@ -33933,7 +34473,7 @@ function convertNumstat(numstatText) {
|
|
|
33933
34473
|
let adds = 0;
|
|
33934
34474
|
let dels = 0;
|
|
33935
34475
|
const files = [];
|
|
33936
|
-
for (const rawLine of
|
|
34476
|
+
for (const rawLine of splitLines2(numstatText)) {
|
|
33937
34477
|
if (!rawLine.trim()) {
|
|
33938
34478
|
continue;
|
|
33939
34479
|
}
|
|
@@ -33996,70 +34536,199 @@ function summarizeConventionalCommits(subjects) {
|
|
|
33996
34536
|
}
|
|
33997
34537
|
counts.set("other", 0);
|
|
33998
34538
|
const typePattern = /^(feat|fix|refactor|perf|docs|test|chore|build|ci|style)(\(|!|:)/u;
|
|
33999
|
-
for (const rawLine of
|
|
34539
|
+
for (const rawLine of splitLines2(subjects)) {
|
|
34000
34540
|
const line = rawLine.trim();
|
|
34001
34541
|
if (!line) {
|
|
34002
34542
|
continue;
|
|
34003
34543
|
}
|
|
34004
|
-
const match = typePattern.exec(line);
|
|
34005
|
-
const label = match ? match[1] : "other";
|
|
34006
|
-
counts.set(label, (counts.get(label) ?? 0) + 1);
|
|
34007
|
-
}
|
|
34008
|
-
const nonZero = [...counts.entries()].filter(([, value]) => value > 0);
|
|
34009
|
-
if (nonZero.length === 0) {
|
|
34010
|
-
return "(no recognizable conventional commit types)";
|
|
34544
|
+
const match = typePattern.exec(line);
|
|
34545
|
+
const label = match ? match[1] : "other";
|
|
34546
|
+
counts.set(label, (counts.get(label) ?? 0) + 1);
|
|
34547
|
+
}
|
|
34548
|
+
const nonZero = [...counts.entries()].filter(([, value]) => value > 0);
|
|
34549
|
+
if (nonZero.length === 0) {
|
|
34550
|
+
return "(no recognizable conventional commit types)";
|
|
34551
|
+
}
|
|
34552
|
+
return nonZero.map(([name, value]) => `${padName(name)} : ${value}`).join("\n");
|
|
34553
|
+
}
|
|
34554
|
+
function extractChangedPaths(contextText) {
|
|
34555
|
+
const paths = [];
|
|
34556
|
+
let capture = false;
|
|
34557
|
+
for (const line of splitLines2(contextText)) {
|
|
34558
|
+
if (line.startsWith("===== Changed files")) {
|
|
34559
|
+
capture = true;
|
|
34560
|
+
continue;
|
|
34561
|
+
}
|
|
34562
|
+
if (capture) {
|
|
34563
|
+
if (line.startsWith("=====")) {
|
|
34564
|
+
break;
|
|
34565
|
+
}
|
|
34566
|
+
if (line.trim() && line.includes(" ")) {
|
|
34567
|
+
const partsArr = line.split(" ");
|
|
34568
|
+
const pathPart = partsArr[partsArr.length - 1];
|
|
34569
|
+
paths.push(formatDiffPath(pathPart.trim()));
|
|
34570
|
+
} else if (line.trim()) {
|
|
34571
|
+
paths.push(formatDiffPath(line.trim()));
|
|
34572
|
+
}
|
|
34573
|
+
}
|
|
34574
|
+
}
|
|
34575
|
+
return paths;
|
|
34576
|
+
}
|
|
34577
|
+
function pathSuffix(name) {
|
|
34578
|
+
const segment = name.split(/[/\\]/u).pop() ?? "";
|
|
34579
|
+
const dotIndex = segment.lastIndexOf(".");
|
|
34580
|
+
if (dotIndex <= 0 || dotIndex === segment.length - 1) {
|
|
34581
|
+
return "";
|
|
34582
|
+
}
|
|
34583
|
+
return segment.slice(dotIndex);
|
|
34584
|
+
}
|
|
34585
|
+
function padCount(count) {
|
|
34586
|
+
return String(count).padStart(8, " ");
|
|
34587
|
+
}
|
|
34588
|
+
function padName(name) {
|
|
34589
|
+
return name.padEnd(9, " ");
|
|
34590
|
+
}
|
|
34591
|
+
function isDigits(value) {
|
|
34592
|
+
return value.length > 0 && /^\d+$/u.test(value);
|
|
34593
|
+
}
|
|
34594
|
+
|
|
34595
|
+
// ../../extensions/drm-copilot/src/lib/pr-context/feature-docs-parsers.ts
|
|
34596
|
+
function parseSection(markdown, heading) {
|
|
34597
|
+
const escaped = escapeRegExp4(heading);
|
|
34598
|
+
const pattern = new RegExp(
|
|
34599
|
+
`^##\\s+${escaped}\\s*\\r?\\n([\\s\\S]*?)(?=^##\\s+|$(?![\\s\\S]))`,
|
|
34600
|
+
"m"
|
|
34601
|
+
);
|
|
34602
|
+
const match = pattern.exec(markdown);
|
|
34603
|
+
if (!match) {
|
|
34604
|
+
return "";
|
|
34605
|
+
}
|
|
34606
|
+
return match[1].trim();
|
|
34607
|
+
}
|
|
34608
|
+
function completedPlanTasks(markdown, limit = 10) {
|
|
34609
|
+
const tasks = [];
|
|
34610
|
+
for (const line of splitLines2(markdown)) {
|
|
34611
|
+
if (/\[x\]/iu.test(line)) {
|
|
34612
|
+
const cleaned = line.replace(/^[-*]\s*\[[xX]\]\s*/u, "").trim();
|
|
34613
|
+
tasks.push(cleaned);
|
|
34614
|
+
}
|
|
34615
|
+
if (tasks.length >= limit) {
|
|
34616
|
+
break;
|
|
34617
|
+
}
|
|
34618
|
+
}
|
|
34619
|
+
return tasks;
|
|
34620
|
+
}
|
|
34621
|
+
function extractIssueReferences2(text2) {
|
|
34622
|
+
if (!text2) {
|
|
34623
|
+
return [];
|
|
34624
|
+
}
|
|
34625
|
+
const matches = text2.match(new RegExp(ISSUE_REFERENCE_PATTERN, "gu")) ?? [];
|
|
34626
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34627
|
+
const ordered = [];
|
|
34628
|
+
for (const item of matches) {
|
|
34629
|
+
if (!seen.has(item)) {
|
|
34630
|
+
seen.add(item);
|
|
34631
|
+
ordered.push(item);
|
|
34632
|
+
}
|
|
34633
|
+
}
|
|
34634
|
+
return ordered;
|
|
34635
|
+
}
|
|
34636
|
+
function resolveFeatureDir(fs12, baseDir, feature) {
|
|
34637
|
+
const direct = `${baseDir}/${feature}`;
|
|
34638
|
+
if (fs12.exists(direct)) {
|
|
34639
|
+
return direct;
|
|
34640
|
+
}
|
|
34641
|
+
const pattern = new RegExp(
|
|
34642
|
+
`(?:^|[-_])${escapeRegExp4(feature)}(?:[-_]|$)`,
|
|
34643
|
+
"u"
|
|
34644
|
+
);
|
|
34645
|
+
const strongMatches = [];
|
|
34646
|
+
const weakMatches = [];
|
|
34647
|
+
for (const name of fs12.listDirectory(baseDir)) {
|
|
34648
|
+
const candidate = `${baseDir}/${name}`;
|
|
34649
|
+
if (!fs12.isDirectory(candidate)) {
|
|
34650
|
+
continue;
|
|
34651
|
+
}
|
|
34652
|
+
if (pattern.test(name)) {
|
|
34653
|
+
strongMatches.push(candidate);
|
|
34654
|
+
} else if (name.includes(feature)) {
|
|
34655
|
+
weakMatches.push(candidate);
|
|
34656
|
+
}
|
|
34657
|
+
}
|
|
34658
|
+
if (strongMatches.length > 0) {
|
|
34659
|
+
return strongMatches[0];
|
|
34660
|
+
}
|
|
34661
|
+
if (weakMatches.length > 0) {
|
|
34662
|
+
return weakMatches[0];
|
|
34663
|
+
}
|
|
34664
|
+
return null;
|
|
34665
|
+
}
|
|
34666
|
+
function readText(fs12, path16) {
|
|
34667
|
+
return fs12.exists(path16) ? fs12.readTextFile(path16) : "";
|
|
34668
|
+
}
|
|
34669
|
+
function latestGlobPath(fs12, directory, pattern) {
|
|
34670
|
+
const matches = [...fs12.glob(directory, pattern)].sort(compareCodePoint);
|
|
34671
|
+
return matches.length > 0 ? matches[matches.length - 1] : null;
|
|
34672
|
+
}
|
|
34673
|
+
function verificationText(planText) {
|
|
34674
|
+
for (const heading of ["Verification", "Test Plan"]) {
|
|
34675
|
+
const sectionText = parseSection(planText, heading);
|
|
34676
|
+
if (sectionText) {
|
|
34677
|
+
return sectionText;
|
|
34678
|
+
}
|
|
34011
34679
|
}
|
|
34012
|
-
return
|
|
34680
|
+
return "";
|
|
34013
34681
|
}
|
|
34014
|
-
function
|
|
34015
|
-
const
|
|
34016
|
-
|
|
34017
|
-
|
|
34018
|
-
|
|
34019
|
-
|
|
34020
|
-
|
|
34021
|
-
|
|
34022
|
-
|
|
34023
|
-
if (
|
|
34024
|
-
|
|
34025
|
-
}
|
|
34026
|
-
if (line.trim() && line.includes(" ")) {
|
|
34027
|
-
const partsArr = line.split(" ");
|
|
34028
|
-
const pathPart = partsArr[partsArr.length - 1];
|
|
34029
|
-
paths.push(formatDiffPath(pathPart.trim()));
|
|
34030
|
-
} else if (line.trim()) {
|
|
34031
|
-
paths.push(formatDiffPath(line.trim()));
|
|
34682
|
+
function parsePrimaryIssueFromMetadata(params) {
|
|
34683
|
+
const pattern = /^\s*[-*]?\s*Issue:\s*(#\d+)\s*$/iu;
|
|
34684
|
+
for (const sourceText of [
|
|
34685
|
+
params.specText,
|
|
34686
|
+
params.storyText,
|
|
34687
|
+
params.issueText
|
|
34688
|
+
]) {
|
|
34689
|
+
for (const line of splitLines2(sourceText)) {
|
|
34690
|
+
const match = pattern.exec(line);
|
|
34691
|
+
if (match) {
|
|
34692
|
+
return match[1];
|
|
34032
34693
|
}
|
|
34033
34694
|
}
|
|
34034
34695
|
}
|
|
34035
|
-
return
|
|
34696
|
+
return null;
|
|
34036
34697
|
}
|
|
34037
|
-
function
|
|
34038
|
-
const
|
|
34039
|
-
const
|
|
34040
|
-
|
|
34041
|
-
|
|
34698
|
+
function parseReadinessValue(text2) {
|
|
34699
|
+
const normalized = text2.replaceAll("**", "");
|
|
34700
|
+
const match = /^\s*(?:Readiness|Overall feature readiness):\s*(.+?)\s*$/im.exec(
|
|
34701
|
+
normalized
|
|
34702
|
+
);
|
|
34703
|
+
if (!match) {
|
|
34704
|
+
return null;
|
|
34042
34705
|
}
|
|
34043
|
-
|
|
34044
|
-
|
|
34045
|
-
|
|
34046
|
-
|
|
34047
|
-
|
|
34048
|
-
function padName(name) {
|
|
34049
|
-
return name.padEnd(9, " ");
|
|
34050
|
-
}
|
|
34051
|
-
function isDigits(value) {
|
|
34052
|
-
return value.length > 0 && /^\d+$/u.test(value);
|
|
34706
|
+
const value = match[1].trim().toUpperCase();
|
|
34707
|
+
if (value === "PASS" || value === "NEEDS REVISION" || value === "BLOCKED") {
|
|
34708
|
+
return value;
|
|
34709
|
+
}
|
|
34710
|
+
return null;
|
|
34053
34711
|
}
|
|
34054
|
-
function
|
|
34055
|
-
|
|
34056
|
-
|
|
34712
|
+
function resolveReadinessSignal(fs12, featureDir) {
|
|
34713
|
+
const auditFiles = [...fs12.glob(featureDir, "feature-audit.*.md")].sort(
|
|
34714
|
+
compareCodePoint
|
|
34715
|
+
);
|
|
34716
|
+
for (let index = auditFiles.length - 1; index >= 0; index -= 1) {
|
|
34717
|
+
const auditPath = auditFiles[index];
|
|
34718
|
+
const readiness = parseReadinessValue(readText(fs12, auditPath));
|
|
34719
|
+
if (readiness) {
|
|
34720
|
+
return [readiness, auditPath];
|
|
34721
|
+
}
|
|
34057
34722
|
}
|
|
34058
|
-
|
|
34059
|
-
|
|
34060
|
-
|
|
34723
|
+
return [null, null];
|
|
34724
|
+
}
|
|
34725
|
+
function relativeToPosix8(root, path16) {
|
|
34726
|
+
const normalizedRoot = toPosixPath2(root).replace(/\/+$/u, "");
|
|
34727
|
+
const normalized = toPosixPath2(path16);
|
|
34728
|
+
if (normalized.startsWith(`${normalizedRoot}/`)) {
|
|
34729
|
+
return normalized.slice(normalizedRoot.length + 1);
|
|
34061
34730
|
}
|
|
34062
|
-
return
|
|
34731
|
+
return normalized.replace(/^\/+/u, "");
|
|
34063
34732
|
}
|
|
34064
34733
|
|
|
34065
34734
|
// ../../extensions/drm-copilot/src/lib/pr-context/render.ts
|
|
@@ -34120,8 +34789,8 @@ function buildPrContext(options) {
|
|
|
34120
34789
|
const oneline = git.log("--pretty=format:%h %ad %an %s", revRange);
|
|
34121
34790
|
const subjects = git.log("--pretty=%s", revRange);
|
|
34122
34791
|
const authors = git.log("--format=%an <%ae>", revRange);
|
|
34123
|
-
const authorsList =
|
|
34124
|
-
|
|
34792
|
+
const authorsList = sortedSet(
|
|
34793
|
+
splitLines2(authors).map((line) => line.trim()).filter((line) => line)
|
|
34125
34794
|
);
|
|
34126
34795
|
const nameStatus = git.diffRange(["--name-status", mergeBase, headSha]);
|
|
34127
34796
|
const numstat = git.diffRange(["--numstat", mergeBase, headSha]);
|
|
@@ -34129,7 +34798,7 @@ function buildPrContext(options) {
|
|
|
34129
34798
|
const stat = git.diffRange(["--stat", mergeBase, headSha]);
|
|
34130
34799
|
const [additions, deletions, files] = convertNumstat(numstat);
|
|
34131
34800
|
const extSummary = extensionSummary(files);
|
|
34132
|
-
const mergePrs = extractMergePrNumbers(
|
|
34801
|
+
const mergePrs = extractMergePrNumbers(splitLines2(oneline));
|
|
34133
34802
|
const issueCandidates = extractIssueReferences(
|
|
34134
34803
|
oneline + "\n" + subjects
|
|
34135
34804
|
).filter((ref) => !mergePrs.includes(ref));
|
|
@@ -34149,9 +34818,9 @@ function buildPrContext(options) {
|
|
|
34149
34818
|
issues.push(formattedRef);
|
|
34150
34819
|
}
|
|
34151
34820
|
}
|
|
34152
|
-
referencedIssues =
|
|
34153
|
-
referencedPrs =
|
|
34154
|
-
let issuesDisplay =
|
|
34821
|
+
referencedIssues = sortedSet(issues);
|
|
34822
|
+
referencedPrs = sortedSet([...prs, ...mergePrs]);
|
|
34823
|
+
let issuesDisplay = sortedSet([
|
|
34155
34824
|
...referencedIssues,
|
|
34156
34825
|
...featureIssueList
|
|
34157
34826
|
]).join(", ");
|
|
@@ -34261,8 +34930,8 @@ Deletions: ${deletions}
|
|
|
34261
34930
|
text: combinedText,
|
|
34262
34931
|
referencedIssues,
|
|
34263
34932
|
referencedPrs,
|
|
34264
|
-
verifiedClosing:
|
|
34265
|
-
invalidReferences:
|
|
34933
|
+
verifiedClosing: sortedSet(verifiedClosing),
|
|
34934
|
+
invalidReferences: sortedSet(invalidReferences),
|
|
34266
34935
|
baseRef,
|
|
34267
34936
|
resolvedBase,
|
|
34268
34937
|
baseSha,
|
|
@@ -34276,161 +34945,6 @@ Deletions: ${deletions}
|
|
|
34276
34945
|
function errorMessage(exc) {
|
|
34277
34946
|
return exc instanceof Error ? exc.message : String(exc);
|
|
34278
34947
|
}
|
|
34279
|
-
function sortedSet2(values) {
|
|
34280
|
-
return [...new Set(values)].sort(compareCodePoint);
|
|
34281
|
-
}
|
|
34282
|
-
function splitLines5(value) {
|
|
34283
|
-
if (value === "") {
|
|
34284
|
-
return [];
|
|
34285
|
-
}
|
|
34286
|
-
const lines = value.split(/\r\n|\r|\n/u);
|
|
34287
|
-
if (lines.length > 0 && lines[lines.length - 1] === "" && /(\r\n|\r|\n)$/u.test(value)) {
|
|
34288
|
-
lines.pop();
|
|
34289
|
-
}
|
|
34290
|
-
return lines;
|
|
34291
|
-
}
|
|
34292
|
-
|
|
34293
|
-
// ../../extensions/drm-copilot/src/lib/pr-context/feature-docs-parsers.ts
|
|
34294
|
-
function parseSection2(markdown, heading) {
|
|
34295
|
-
const escaped = escapeRegExp4(heading);
|
|
34296
|
-
const pattern = new RegExp(
|
|
34297
|
-
`^##\\s+${escaped}\\s*\\r?\\n([\\s\\S]*?)(?=^##\\s+|$(?![\\s\\S]))`,
|
|
34298
|
-
"m"
|
|
34299
|
-
);
|
|
34300
|
-
const match = pattern.exec(markdown);
|
|
34301
|
-
if (!match) {
|
|
34302
|
-
return "";
|
|
34303
|
-
}
|
|
34304
|
-
return match[1].trim();
|
|
34305
|
-
}
|
|
34306
|
-
function completedPlanTasks2(markdown, limit = 10) {
|
|
34307
|
-
const tasks = [];
|
|
34308
|
-
for (const line of splitLines3(markdown)) {
|
|
34309
|
-
if (/\[x\]/iu.test(line)) {
|
|
34310
|
-
const cleaned = line.replace(/^[-*]\s*\[[xX]\]\s*/u, "").trim();
|
|
34311
|
-
tasks.push(cleaned);
|
|
34312
|
-
}
|
|
34313
|
-
if (tasks.length >= limit) {
|
|
34314
|
-
break;
|
|
34315
|
-
}
|
|
34316
|
-
}
|
|
34317
|
-
return tasks;
|
|
34318
|
-
}
|
|
34319
|
-
function extractIssueReferences2(text2) {
|
|
34320
|
-
if (!text2) {
|
|
34321
|
-
return [];
|
|
34322
|
-
}
|
|
34323
|
-
const matches = text2.match(new RegExp(ISSUE_REFERENCE_PATTERN, "gu")) ?? [];
|
|
34324
|
-
const seen = /* @__PURE__ */ new Set();
|
|
34325
|
-
const ordered = [];
|
|
34326
|
-
for (const item of matches) {
|
|
34327
|
-
if (!seen.has(item)) {
|
|
34328
|
-
seen.add(item);
|
|
34329
|
-
ordered.push(item);
|
|
34330
|
-
}
|
|
34331
|
-
}
|
|
34332
|
-
return ordered;
|
|
34333
|
-
}
|
|
34334
|
-
function resolveFeatureDir2(fs12, baseDir, feature) {
|
|
34335
|
-
const direct = `${baseDir}/${feature}`;
|
|
34336
|
-
if (fs12.exists(direct)) {
|
|
34337
|
-
return direct;
|
|
34338
|
-
}
|
|
34339
|
-
const pattern = new RegExp(
|
|
34340
|
-
`(?:^|[-_])${escapeRegExp4(feature)}(?:[-_]|$)`,
|
|
34341
|
-
"u"
|
|
34342
|
-
);
|
|
34343
|
-
const strongMatches = [];
|
|
34344
|
-
const weakMatches = [];
|
|
34345
|
-
for (const name of fs12.listDirectory(baseDir)) {
|
|
34346
|
-
const candidate = `${baseDir}/${name}`;
|
|
34347
|
-
if (!fs12.isDirectory(candidate)) {
|
|
34348
|
-
continue;
|
|
34349
|
-
}
|
|
34350
|
-
if (pattern.test(name)) {
|
|
34351
|
-
strongMatches.push(candidate);
|
|
34352
|
-
} else if (name.includes(feature)) {
|
|
34353
|
-
weakMatches.push(candidate);
|
|
34354
|
-
}
|
|
34355
|
-
}
|
|
34356
|
-
if (strongMatches.length > 0) {
|
|
34357
|
-
return strongMatches[0];
|
|
34358
|
-
}
|
|
34359
|
-
if (weakMatches.length > 0) {
|
|
34360
|
-
return weakMatches[0];
|
|
34361
|
-
}
|
|
34362
|
-
return null;
|
|
34363
|
-
}
|
|
34364
|
-
function readText(fs12, path16) {
|
|
34365
|
-
return fs12.exists(path16) ? fs12.readTextFile(path16) : "";
|
|
34366
|
-
}
|
|
34367
|
-
function latestGlobPath(fs12, directory, pattern) {
|
|
34368
|
-
const matches = [...fs12.glob(directory, pattern)].sort(compareCodePoint);
|
|
34369
|
-
return matches.length > 0 ? matches[matches.length - 1] : null;
|
|
34370
|
-
}
|
|
34371
|
-
function verificationText(planText) {
|
|
34372
|
-
for (const heading of ["Verification", "Test Plan"]) {
|
|
34373
|
-
const sectionText = parseSection2(planText, heading);
|
|
34374
|
-
if (sectionText) {
|
|
34375
|
-
return sectionText;
|
|
34376
|
-
}
|
|
34377
|
-
}
|
|
34378
|
-
return "";
|
|
34379
|
-
}
|
|
34380
|
-
function parsePrimaryIssueFromMetadata(params) {
|
|
34381
|
-
const pattern = /^\s*[-*]?\s*Issue:\s*(#\d+)\s*$/iu;
|
|
34382
|
-
for (const sourceText of [
|
|
34383
|
-
params.specText,
|
|
34384
|
-
params.storyText,
|
|
34385
|
-
params.issueText
|
|
34386
|
-
]) {
|
|
34387
|
-
for (const line of splitLines3(sourceText)) {
|
|
34388
|
-
const match = pattern.exec(line);
|
|
34389
|
-
if (match) {
|
|
34390
|
-
return match[1];
|
|
34391
|
-
}
|
|
34392
|
-
}
|
|
34393
|
-
}
|
|
34394
|
-
return null;
|
|
34395
|
-
}
|
|
34396
|
-
function parseReadinessValue(text2) {
|
|
34397
|
-
const normalized = text2.replaceAll("**", "");
|
|
34398
|
-
const match = /^\s*(?:Readiness|Overall feature readiness):\s*(.+?)\s*$/im.exec(
|
|
34399
|
-
normalized
|
|
34400
|
-
);
|
|
34401
|
-
if (!match) {
|
|
34402
|
-
return null;
|
|
34403
|
-
}
|
|
34404
|
-
const value = match[1].trim().toUpperCase();
|
|
34405
|
-
if (value === "PASS" || value === "NEEDS REVISION" || value === "BLOCKED") {
|
|
34406
|
-
return value;
|
|
34407
|
-
}
|
|
34408
|
-
return null;
|
|
34409
|
-
}
|
|
34410
|
-
function resolveReadinessSignal(fs12, featureDir) {
|
|
34411
|
-
const auditFiles = [...fs12.glob(featureDir, "feature-audit.*.md")].sort(
|
|
34412
|
-
compareCodePoint
|
|
34413
|
-
);
|
|
34414
|
-
for (let index = auditFiles.length - 1; index >= 0; index -= 1) {
|
|
34415
|
-
const auditPath = auditFiles[index];
|
|
34416
|
-
const readiness = parseReadinessValue(readText(fs12, auditPath));
|
|
34417
|
-
if (readiness) {
|
|
34418
|
-
return [readiness, auditPath];
|
|
34419
|
-
}
|
|
34420
|
-
}
|
|
34421
|
-
return [null, null];
|
|
34422
|
-
}
|
|
34423
|
-
function relativeToPosix8(root, path16) {
|
|
34424
|
-
const normalizedRoot = toPosixPath2(root).replace(/\/+$/u, "");
|
|
34425
|
-
const normalized = toPosixPath2(path16);
|
|
34426
|
-
if (normalized.startsWith(`${normalizedRoot}/`)) {
|
|
34427
|
-
return normalized.slice(normalizedRoot.length + 1);
|
|
34428
|
-
}
|
|
34429
|
-
return normalized.replace(/^\/+/u, "");
|
|
34430
|
-
}
|
|
34431
|
-
function escapeRegExp4(value) {
|
|
34432
|
-
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
34433
|
-
}
|
|
34434
34948
|
|
|
34435
34949
|
// ../../extensions/drm-copilot/src/lib/pr-context/verification-evidence.ts
|
|
34436
34950
|
var REQUIRED_FIELDS = ["Timestamp", "Command", "EXIT_CODE"];
|
|
@@ -34453,7 +34967,7 @@ function discoverCanonicalEvidenceFiles(fs12, root, feature) {
|
|
|
34453
34967
|
for (const pattern of CANONICAL_GLOBS) {
|
|
34454
34968
|
for (const candidate of fs12.glob(featureRoot, pattern)) {
|
|
34455
34969
|
if (fs12.isFile(candidate)) {
|
|
34456
|
-
discovered.add(
|
|
34970
|
+
discovered.add(relativeToPosix8(normalizedRoot, candidate));
|
|
34457
34971
|
}
|
|
34458
34972
|
}
|
|
34459
34973
|
}
|
|
@@ -34462,7 +34976,7 @@ function discoverCanonicalEvidenceFiles(fs12, root, feature) {
|
|
|
34462
34976
|
function parseVerificationEvidenceMarkdown(params) {
|
|
34463
34977
|
const { feature, sourceFile, markdown } = params;
|
|
34464
34978
|
const parsed = /* @__PURE__ */ new Map();
|
|
34465
|
-
for (const rawLine of
|
|
34979
|
+
for (const rawLine of splitLines2(markdown)) {
|
|
34466
34980
|
const colonIndex = rawLine.indexOf(":");
|
|
34467
34981
|
if (colonIndex === -1) {
|
|
34468
34982
|
continue;
|
|
@@ -34530,9 +35044,9 @@ function parseVerificationEvidenceMarkdown(params) {
|
|
|
34530
35044
|
};
|
|
34531
35045
|
}
|
|
34532
35046
|
function parseVerificationEvidenceFile(params) {
|
|
34533
|
-
const { fs: fs12, root, feature, relativePath
|
|
35047
|
+
const { fs: fs12, root, feature, relativePath } = params;
|
|
34534
35048
|
const normalizedRoot = toPosixPath2(root).replace(/\/+$/u, "");
|
|
34535
|
-
const relPosix = toPosixPath2(
|
|
35049
|
+
const relPosix = toPosixPath2(relativePath).replace(/^\/+/u, "");
|
|
34536
35050
|
const markdown = fs12.readTextFile(`${normalizedRoot}/${relPosix}`);
|
|
34537
35051
|
return parseVerificationEvidenceMarkdown({
|
|
34538
35052
|
feature,
|
|
@@ -34546,23 +35060,6 @@ function parseIntegerStrict(value) {
|
|
|
34546
35060
|
}
|
|
34547
35061
|
return Number.parseInt(value, 10);
|
|
34548
35062
|
}
|
|
34549
|
-
function relativeToPosix9(root, absolute) {
|
|
34550
|
-
const normalized = toPosixPath2(absolute);
|
|
34551
|
-
if (normalized.startsWith(`${root}/`)) {
|
|
34552
|
-
return normalized.slice(root.length + 1);
|
|
34553
|
-
}
|
|
34554
|
-
return normalized.replace(/^\/+/u, "");
|
|
34555
|
-
}
|
|
34556
|
-
function splitLines6(value) {
|
|
34557
|
-
if (value === "") {
|
|
34558
|
-
return [];
|
|
34559
|
-
}
|
|
34560
|
-
const lines = value.split(/\r\n|\r|\n/u);
|
|
34561
|
-
if (lines.length > 0 && lines[lines.length - 1] === "" && /(\r\n|\r|\n)$/u.test(value)) {
|
|
34562
|
-
lines.pop();
|
|
34563
|
-
}
|
|
34564
|
-
return lines;
|
|
34565
|
-
}
|
|
34566
35063
|
|
|
34567
35064
|
// ../../extensions/drm-copilot/src/lib/pr-context/feature-docs.ts
|
|
34568
35065
|
var SPEC_HEADINGS = [
|
|
@@ -34593,8 +35090,8 @@ function gatherFeatureExcerpts2(fs12, root, changedFiles) {
|
|
|
34593
35090
|
const baseDir = `${normalizedRoot}/docs/features/active`;
|
|
34594
35091
|
const promotedDir = `${normalizedRoot}/docs/features/potential/promoted`;
|
|
34595
35092
|
for (const feature of [...features].sort(compareCodePoint)) {
|
|
34596
|
-
const featureDir =
|
|
34597
|
-
const promotedFeatureDir =
|
|
35093
|
+
const featureDir = resolveFeatureDir(fs12, baseDir, feature);
|
|
35094
|
+
const promotedFeatureDir = resolveFeatureDir(fs12, promotedDir, feature);
|
|
34598
35095
|
if (featureDir === null && promotedFeatureDir === null) {
|
|
34599
35096
|
continue;
|
|
34600
35097
|
}
|
|
@@ -34669,7 +35166,7 @@ function gatherFeatureExcerpts2(fs12, root, changedFiles) {
|
|
|
34669
35166
|
function buildSpecParts(specText) {
|
|
34670
35167
|
const specParts = [];
|
|
34671
35168
|
for (const heading of SPEC_HEADINGS) {
|
|
34672
|
-
const sectionText =
|
|
35169
|
+
const sectionText = parseSection(specText, heading);
|
|
34673
35170
|
if (sectionText) {
|
|
34674
35171
|
specParts.push(`${heading}: ${truncate(sectionText)}`);
|
|
34675
35172
|
}
|
|
@@ -34677,7 +35174,7 @@ function buildSpecParts(specText) {
|
|
|
34677
35174
|
return specParts;
|
|
34678
35175
|
}
|
|
34679
35176
|
function buildPlanSection(planText) {
|
|
34680
|
-
const planTasks =
|
|
35177
|
+
const planTasks = completedPlanTasks(planText);
|
|
34681
35178
|
return planTasks.length > 0 ? planTasks.map((task) => `- ${task}`).join("\n") : "";
|
|
34682
35179
|
}
|
|
34683
35180
|
function buildVerificationBlock(planText) {
|
|
@@ -34686,7 +35183,7 @@ function buildVerificationBlock(planText) {
|
|
|
34686
35183
|
}
|
|
34687
35184
|
function buildStoryParts(userStoryText, promotedStoryText) {
|
|
34688
35185
|
const storyParts = [];
|
|
34689
|
-
const storyStatements =
|
|
35186
|
+
const storyStatements = parseSection(userStoryText, "Story Statement");
|
|
34690
35187
|
if (storyStatements) {
|
|
34691
35188
|
const storyLines = storyStatements.split(/\r\n|\r|\n/u).filter((line) => line.trim()).map((line) => line.replace(/^[- ]+|[- ]+$/gu, ""));
|
|
34692
35189
|
if (storyLines.length > 0) {
|
|
@@ -34695,14 +35192,14 @@ function buildStoryParts(userStoryText, promotedStoryText) {
|
|
|
34695
35192
|
);
|
|
34696
35193
|
}
|
|
34697
35194
|
}
|
|
34698
|
-
const problemSection =
|
|
35195
|
+
const problemSection = parseSection(userStoryText, "Problem / Why");
|
|
34699
35196
|
if (problemSection) {
|
|
34700
35197
|
storyParts.push("Problem / Why:\n" + truncate(problemSection));
|
|
34701
35198
|
}
|
|
34702
35199
|
if (storyParts.length === 0 && promotedStoryText) {
|
|
34703
|
-
let promotedProblem =
|
|
35200
|
+
let promotedProblem = parseSection(promotedStoryText, "Problem / Why");
|
|
34704
35201
|
if (!promotedProblem) {
|
|
34705
|
-
promotedProblem =
|
|
35202
|
+
promotedProblem = parseSection(promotedStoryText, "Summary");
|
|
34706
35203
|
}
|
|
34707
35204
|
if (promotedProblem) {
|
|
34708
35205
|
storyParts.push("Problem / Why:\n" + truncate(promotedProblem));
|
|
@@ -34775,7 +35272,7 @@ function extractDigestBullets(body, headings, limit) {
|
|
|
34775
35272
|
if (!sectionText) {
|
|
34776
35273
|
continue;
|
|
34777
35274
|
}
|
|
34778
|
-
for (const line of
|
|
35275
|
+
for (const line of splitLines2(sectionText)) {
|
|
34779
35276
|
if (!line.trim()) {
|
|
34780
35277
|
continue;
|
|
34781
35278
|
}
|
|
@@ -34916,7 +35413,7 @@ function parseNumstatDetailed(numstatText) {
|
|
|
34916
35413
|
let addsTotal = 0;
|
|
34917
35414
|
let delsTotal = 0;
|
|
34918
35415
|
const perFile = /* @__PURE__ */ new Map();
|
|
34919
|
-
for (const rawLine of
|
|
35416
|
+
for (const rawLine of splitLines2(numstatText)) {
|
|
34920
35417
|
if (!rawLine.trim()) {
|
|
34921
35418
|
continue;
|
|
34922
35419
|
}
|
|
@@ -34935,7 +35432,7 @@ function parseNumstatDetailed(numstatText) {
|
|
|
34935
35432
|
}
|
|
34936
35433
|
function parseNameStatusMap(nameStatusText) {
|
|
34937
35434
|
const mapping = /* @__PURE__ */ new Map();
|
|
34938
|
-
for (const rawLine of
|
|
35435
|
+
for (const rawLine of splitLines2(nameStatusText)) {
|
|
34939
35436
|
if (!rawLine.trim()) {
|
|
34940
35437
|
continue;
|
|
34941
35438
|
}
|
|
@@ -34983,7 +35480,7 @@ function scopingDocChanges(options) {
|
|
|
34983
35480
|
path16
|
|
34984
35481
|
]);
|
|
34985
35482
|
let headingTouched = false;
|
|
34986
|
-
for (const line of
|
|
35483
|
+
for (const line of splitLines2(diffText)) {
|
|
34987
35484
|
if (!line.startsWith("+") || line.startsWith("+++")) {
|
|
34988
35485
|
continue;
|
|
34989
35486
|
}
|
|
@@ -34999,7 +35496,7 @@ function scopingDocChanges(options) {
|
|
|
34999
35496
|
material = true;
|
|
35000
35497
|
reasons.push("key section touched");
|
|
35001
35498
|
}
|
|
35002
|
-
const addedLines =
|
|
35499
|
+
const addedLines = splitLines2(diffText).filter((line) => line.startsWith("+") && !line.startsWith("+++")).map((line) => line.replace(/^\++/u, "").trim());
|
|
35003
35500
|
if (addedLines.length > 0 && addedLines.every(
|
|
35004
35501
|
(line) => !line || line.startsWith("[") || line.startsWith("http")
|
|
35005
35502
|
)) {
|
|
@@ -35149,10 +35646,10 @@ function collectPrContext(options) {
|
|
|
35149
35646
|
});
|
|
35150
35647
|
const changedPaths = extractChangedPaths(contextResult.text);
|
|
35151
35648
|
const featureDocs = gatherFeatureExcerpts2(fs12, resolvedRoot, changedPaths);
|
|
35152
|
-
const additionalContextFiles =
|
|
35649
|
+
const additionalContextFiles = sortedSet(
|
|
35153
35650
|
featureDocs.flatMap((doc) => doc.contextFiles).filter((path16) => path16)
|
|
35154
35651
|
);
|
|
35155
|
-
const featureIssueRefs =
|
|
35652
|
+
const featureIssueRefs = sortedSet(
|
|
35156
35653
|
featureDocs.flatMap((doc) => doc.issueRefs).filter((ref) => ref.trim())
|
|
35157
35654
|
);
|
|
35158
35655
|
if (featureIssueRefs.length > 0) {
|
|
@@ -35210,7 +35707,7 @@ function collectPrContext(options) {
|
|
|
35210
35707
|
pendingPrimary.push(featureDoc.primaryIssueRef);
|
|
35211
35708
|
}
|
|
35212
35709
|
}
|
|
35213
|
-
const readinessSignals =
|
|
35710
|
+
const readinessSignals = sortedSet(
|
|
35214
35711
|
featureDocs.map((doc) => doc.readinessSignal).filter((signal) => Boolean(signal))
|
|
35215
35712
|
);
|
|
35216
35713
|
const selection = selectPendingPrimary({ gh, ghAvailable, pendingPrimary });
|
|
@@ -35221,7 +35718,7 @@ function collectPrContext(options) {
|
|
|
35221
35718
|
ghAvailable,
|
|
35222
35719
|
pendingPrimaryExcluded: selection.excluded
|
|
35223
35720
|
});
|
|
35224
|
-
const issuesToFetch =
|
|
35721
|
+
const issuesToFetch = sortedSet([
|
|
35225
35722
|
...verified,
|
|
35226
35723
|
...referencedIssues,
|
|
35227
35724
|
...selection.kept
|
|
@@ -35309,7 +35806,7 @@ function collectPrContext(options) {
|
|
|
35309
35806
|
verified,
|
|
35310
35807
|
verifiedReason,
|
|
35311
35808
|
authorReason,
|
|
35312
|
-
authorAsserted:
|
|
35809
|
+
authorAsserted: sortedSet(authorAsserted),
|
|
35313
35810
|
issuesToAutocloseSection,
|
|
35314
35811
|
issueDetails,
|
|
35315
35812
|
prDetailsList,
|
|
@@ -35330,9 +35827,6 @@ function collectPrContext(options) {
|
|
|
35330
35827
|
function errorMessage2(exc) {
|
|
35331
35828
|
return exc instanceof Error ? exc.message : String(exc);
|
|
35332
35829
|
}
|
|
35333
|
-
function sortedSet3(values) {
|
|
35334
|
-
return [...new Set(values)].sort(compareCodePoint);
|
|
35335
|
-
}
|
|
35336
35830
|
|
|
35337
35831
|
// ../../extensions/drm-copilot/src/lib/pr-context/collector-output.ts
|
|
35338
35832
|
function renderVerificationEvidenceSection(fs12, resolvedRoot, featureDocs) {
|
|
@@ -35365,7 +35859,7 @@ function renderVerificationEvidenceSection(fs12, resolvedRoot, featureDocs) {
|
|
|
35365
35859
|
}
|
|
35366
35860
|
const lines = [];
|
|
35367
35861
|
const sorted = [...parseableRecords].sort(
|
|
35368
|
-
(left, right) => left.sourceFile
|
|
35862
|
+
(left, right) => compareCodePoint(left.sourceFile, right.sourceFile)
|
|
35369
35863
|
);
|
|
35370
35864
|
for (const record3 of sorted) {
|
|
35371
35865
|
const expected = record3.expectedExitCode;
|
|
@@ -35898,7 +36392,7 @@ function getSection(content, heading) {
|
|
|
35898
36392
|
}
|
|
35899
36393
|
return match[1].trim();
|
|
35900
36394
|
}
|
|
35901
|
-
function buildBody(workMode, problem, behavior, criteria, constraints, tests,
|
|
36395
|
+
function buildBody(workMode, problem, behavior, criteria, constraints, tests, relativePath) {
|
|
35902
36396
|
return `- Work Mode: ${workMode}
|
|
35903
36397
|
## Problem / Why
|
|
35904
36398
|
${problem}
|
|
@@ -35916,20 +36410,20 @@ ${constraints}
|
|
|
35916
36410
|
${tests}
|
|
35917
36411
|
|
|
35918
36412
|
## Source
|
|
35919
|
-
From: ${
|
|
36413
|
+
From: ${relativePath}
|
|
35920
36414
|
`;
|
|
35921
36415
|
}
|
|
35922
|
-
function buildBugBody(workMode, sections,
|
|
36416
|
+
function buildBugBody(workMode, sections, relativePath) {
|
|
35923
36417
|
const parts = [`- Work Mode: ${workMode}`];
|
|
35924
36418
|
for (const heading of BUG_SECTION_HEADINGS) {
|
|
35925
36419
|
parts.push(`## ${heading}
|
|
35926
36420
|
${sections[heading] ?? ""}`);
|
|
35927
36421
|
}
|
|
35928
36422
|
parts.push(`## Source
|
|
35929
|
-
From: ${
|
|
36423
|
+
From: ${relativePath}`);
|
|
35930
36424
|
return parts.join("\n\n") + "\n";
|
|
35931
36425
|
}
|
|
35932
|
-
function buildMinorAuditBody(workMode, problem, implementationIntent, acceptanceCriteria, dependenciesRisks, verificationSteps, evidenceChecklist,
|
|
36426
|
+
function buildMinorAuditBody(workMode, problem, implementationIntent, acceptanceCriteria, dependenciesRisks, verificationSteps, evidenceChecklist, relativePath) {
|
|
35933
36427
|
return `- Work Mode: ${workMode}
|
|
35934
36428
|
## Problem / Why
|
|
35935
36429
|
${problem}
|
|
@@ -35950,7 +36444,7 @@ ${verificationSteps}
|
|
|
35950
36444
|
${evidenceChecklist}
|
|
35951
36445
|
|
|
35952
36446
|
## Source
|
|
35953
|
-
From: ${
|
|
36447
|
+
From: ${relativePath}
|
|
35954
36448
|
`;
|
|
35955
36449
|
}
|
|
35956
36450
|
function parseIssueReference(output) {
|
|
@@ -36115,13 +36609,13 @@ function posixBasename(pathStr) {
|
|
|
36115
36609
|
const lastSlash = normalized.lastIndexOf("/");
|
|
36116
36610
|
return lastSlash === -1 ? normalized : normalized.slice(lastSlash + 1);
|
|
36117
36611
|
}
|
|
36118
|
-
function buildIssueBody(content, selectedMode, promotionType,
|
|
36612
|
+
function buildIssueBody(content, selectedMode, promotionType, relativePath) {
|
|
36119
36613
|
if (promotionType === "bug") {
|
|
36120
36614
|
const bugSections = {};
|
|
36121
36615
|
for (const heading of BUG_SECTION_HEADINGS) {
|
|
36122
36616
|
bugSections[heading] = getSection(content, heading) || PLACEHOLDER;
|
|
36123
36617
|
}
|
|
36124
|
-
return buildBugBody(selectedMode, bugSections,
|
|
36618
|
+
return buildBugBody(selectedMode, bugSections, relativePath);
|
|
36125
36619
|
}
|
|
36126
36620
|
if (selectedMode === "minor-audit") {
|
|
36127
36621
|
const problem2 = getSection(content, "Problem / Why") || PLACEHOLDER;
|
|
@@ -36141,7 +36635,7 @@ function buildIssueBody(content, selectedMode, promotionType, relativePath2) {
|
|
|
36141
36635
|
dependenciesRisks,
|
|
36142
36636
|
verificationSteps,
|
|
36143
36637
|
evidenceChecklist,
|
|
36144
|
-
|
|
36638
|
+
relativePath
|
|
36145
36639
|
);
|
|
36146
36640
|
}
|
|
36147
36641
|
const problem = getSection(content, "Problem / Why") || PLACEHOLDER;
|
|
@@ -36156,7 +36650,7 @@ function buildIssueBody(content, selectedMode, promotionType, relativePath2) {
|
|
|
36156
36650
|
criteria,
|
|
36157
36651
|
constraints,
|
|
36158
36652
|
tests,
|
|
36159
|
-
|
|
36653
|
+
relativePath
|
|
36160
36654
|
);
|
|
36161
36655
|
}
|
|
36162
36656
|
function promotePotential(options) {
|
|
@@ -36191,7 +36685,7 @@ function promotePotential(options) {
|
|
|
36191
36685
|
const featurePath = getFeaturePath(featureName);
|
|
36192
36686
|
const prefix = TITLE_PREFIXES[promotionType] ?? "Feature";
|
|
36193
36687
|
const issueTitle = normalizeSmartPunctuation(`${prefix}: ${featureName}`);
|
|
36194
|
-
const
|
|
36688
|
+
const relativePath = computeRelativePath(resolved, workspacePath);
|
|
36195
36689
|
let selectedMode;
|
|
36196
36690
|
try {
|
|
36197
36691
|
selectedMode = normalizeRequestedWorkMode(workMode, promotionType);
|
|
@@ -36200,7 +36694,7 @@ function promotePotential(options) {
|
|
|
36200
36694
|
throw new PromotionError(message);
|
|
36201
36695
|
}
|
|
36202
36696
|
const fallbackReason = "";
|
|
36203
|
-
let body = buildIssueBody(content, selectedMode, promotionType,
|
|
36697
|
+
let body = buildIssueBody(content, selectedMode, promotionType, relativePath);
|
|
36204
36698
|
body = normalizeSmartPunctuation(body);
|
|
36205
36699
|
const messages = [];
|
|
36206
36700
|
const emitLine = (message) => {
|
|
@@ -36582,12 +37076,12 @@ function validateFeatureName2(featureName) {
|
|
|
36582
37076
|
function escapeRegExp6(value) {
|
|
36583
37077
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
36584
37078
|
}
|
|
36585
|
-
function
|
|
37079
|
+
function splitLines3(text2) {
|
|
36586
37080
|
return text2.split(/\r\n|\r|\n/);
|
|
36587
37081
|
}
|
|
36588
37082
|
function formatChecklist(text2) {
|
|
36589
37083
|
const lines = [];
|
|
36590
|
-
for (const rawLine of
|
|
37084
|
+
for (const rawLine of splitLines3(text2)) {
|
|
36591
37085
|
const trimmed = rawLine.trim();
|
|
36592
37086
|
if (!trimmed) {
|
|
36593
37087
|
continue;
|
|
@@ -36616,7 +37110,7 @@ function getSection2(content, name) {
|
|
|
36616
37110
|
function upsertWorkModeMarker(content, mode) {
|
|
36617
37111
|
const markerLine = `- Work Mode: ${mode}`;
|
|
36618
37112
|
const markerPattern = /^- Work Mode:\s*(minor-audit|full-feature|full-bug|full)\s*$/;
|
|
36619
|
-
const lines =
|
|
37113
|
+
const lines = splitLines3(content).filter((line) => !markerPattern.test(line));
|
|
36620
37114
|
for (let idx = 0; idx < lines.length; idx += 1) {
|
|
36621
37115
|
const line = lines[idx] ?? "";
|
|
36622
37116
|
if (line.replace(/^\s+/, "").startsWith("## ")) {
|
|
@@ -37609,13 +38103,7 @@ function findParentKey(toolUseId, transcriptsByKey) {
|
|
|
37609
38103
|
return void 0;
|
|
37610
38104
|
}
|
|
37611
38105
|
function compareByAgentId(a, b) {
|
|
37612
|
-
|
|
37613
|
-
return -1;
|
|
37614
|
-
}
|
|
37615
|
-
if (a.meta.agentId > b.meta.agentId) {
|
|
37616
|
-
return 1;
|
|
37617
|
-
}
|
|
37618
|
-
return 0;
|
|
38106
|
+
return compareCodePoint(a.meta.agentId, b.meta.agentId);
|
|
37619
38107
|
}
|
|
37620
38108
|
function sortBySpawnIndex(children, parentTranscript) {
|
|
37621
38109
|
return [...children].sort((a, b) => {
|
|
@@ -37659,7 +38147,7 @@ function buildNode(input) {
|
|
|
37659
38147
|
agentType,
|
|
37660
38148
|
description,
|
|
37661
38149
|
depth,
|
|
37662
|
-
models: [...models].sort(),
|
|
38150
|
+
models: [...models].sort(compareCodePoint),
|
|
37663
38151
|
children
|
|
37664
38152
|
};
|
|
37665
38153
|
}
|
|
@@ -37789,7 +38277,7 @@ function formatTree(node) {
|
|
|
37789
38277
|
}
|
|
37790
38278
|
function renderLines(node) {
|
|
37791
38279
|
const indent = " ".repeat(node.depth);
|
|
37792
|
-
const sortedModels = [...node.models].sort();
|
|
38280
|
+
const sortedModels = [...node.models].sort(compareCodePoint);
|
|
37793
38281
|
const line = `${indent}${node.agentType} \xB7 [${sortedModels.join(",")}] \xB7 ${node.depth} \xB7 ${node.description}`;
|
|
37794
38282
|
const childLines = node.children.flatMap((child) => renderLines(child));
|
|
37795
38283
|
return [line, ...childLines];
|