@danmoisan/drm-copilot-mcp 0.0.1
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/LICENSE +21 -0
- package/README.md +50 -0
- package/out/mcp-server.js +17323 -0
- package/package.json +36 -0
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/MEMORY.md +3 -0
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/feedback_repo_root_is_source_of_truth.md +11 -0
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/feedback_vsce_verify_package_location.md +19 -0
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/project_extension_location.md +11 -0
- package/resources/claude-customizations/.claude/agent-memory/prd-feature/MEMORY.md +1 -0
- package/resources/claude-customizations/.claude/agent-memory/prd-feature/project_push_down_pattern.md +13 -0
- package/resources/claude-customizations/.claude/agent-memory/task-researcher/MEMORY.md +3 -0
- package/resources/claude-customizations/.claude/agent-memory/task-researcher/project_push_down_claude_dir.md +11 -0
- package/resources/claude-customizations/.claude/agents/atomic-executor.md +135 -0
- package/resources/claude-customizations/.claude/agents/atomic-planner.md +71 -0
- package/resources/claude-customizations/.claude/agents/csharp-typed-engineer.md +69 -0
- package/resources/claude-customizations/.claude/agents/epic-review.md +40 -0
- package/resources/claude-customizations/.claude/agents/feature-review.md +136 -0
- package/resources/claude-customizations/.claude/agents/orchestrator.md +83 -0
- package/resources/claude-customizations/.claude/agents/powershell-typed-engineer.md +80 -0
- package/resources/claude-customizations/.claude/agents/prd-feature.md +42 -0
- package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +72 -0
- package/resources/claude-customizations/.claude/agents/staged-review.md +41 -0
- package/resources/claude-customizations/.claude/agents/status-updater.md +41 -0
- package/resources/claude-customizations/.claude/agents/task-researcher.md +81 -0
- package/resources/claude-customizations/.claude/agents/typescript-engineer.md +24 -0
- package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +111 -0
- package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +146 -0
- package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +150 -0
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +238 -0
- package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +147 -0
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +235 -0
- package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +69 -0
- package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +296 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +389 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +141 -0
- package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +288 -0
- package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +171 -0
- package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +142 -0
- package/resources/claude-customizations/.claude/rules/csharp.md +62 -0
- package/resources/claude-customizations/.claude/rules/general-code-change.md +71 -0
- package/resources/claude-customizations/.claude/rules/general-unit-test.md +60 -0
- package/resources/claude-customizations/.claude/rules/powershell.md +97 -0
- package/resources/claude-customizations/.claude/rules/python-suppressions.md +143 -0
- package/resources/claude-customizations/.claude/rules/python.md +99 -0
- package/resources/claude-customizations/.claude/rules/self-explanatory-code-commenting.md +97 -0
- package/resources/claude-customizations/.claude/rules/tonality.md +80 -0
- package/resources/claude-customizations/.claude/rules/typescript-suppressions.md +66 -0
- package/resources/claude-customizations/.claude/rules/typescript.md +45 -0
- package/resources/claude-customizations/.claude/settings.json +144 -0
- package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +102 -0
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +189 -0
- package/resources/claude-customizations/.claude/skills/commit-message/SKILL.md +65 -0
- package/resources/claude-customizations/.claude/skills/csharp-change-budget-router/SKILL.md +90 -0
- package/resources/claude-customizations/.claude/skills/csharp-orchestration-state-machine/SKILL.md +58 -0
- package/resources/claude-customizations/.claude/skills/csharp-qa-gate/SKILL.md +77 -0
- package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +164 -0
- package/resources/claude-customizations/.claude/skills/execute-hard-lock/SKILL.md +82 -0
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +115 -0
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +167 -0
- package/resources/claude-customizations/.claude/skills/fill-feature-docs/SKILL.md +22 -0
- package/resources/claude-customizations/.claude/skills/invoke-csharp-engineer/SKILL.md +64 -0
- package/resources/claude-customizations/.claude/skills/invoke-powershell-engineer/SKILL.md +65 -0
- package/resources/claude-customizations/.claude/skills/invoke-python-engineer/SKILL.md +64 -0
- package/resources/claude-customizations/.claude/skills/make-skill-template/SKILL.md +147 -0
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +132 -0
- package/resources/claude-customizations/.claude/skills/policy-audit-template-usage/SKILL.md +49 -0
- package/resources/claude-customizations/.claude/skills/policy-compliance-order/SKILL.md +40 -0
- package/resources/claude-customizations/.claude/skills/powershell-change-budget-router/SKILL.md +49 -0
- package/resources/claude-customizations/.claude/skills/powershell-orchestration-state-machine/SKILL.md +58 -0
- package/resources/claude-customizations/.claude/skills/powershell-qa-gate/SKILL.md +77 -0
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +50 -0
- package/resources/claude-customizations/.claude/skills/pr-base-branch-merge-base/SKILL.md +56 -0
- package/resources/claude-customizations/.claude/skills/pr-context-artifacts/SKILL.md +30 -0
- package/resources/claude-customizations/.claude/skills/python-change-budget-router/SKILL.md +79 -0
- package/resources/claude-customizations/.claude/skills/python-qa-gate/SKILL.md +77 -0
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +40 -0
- package/resources/claude-customizations/.claude/skills/research-issue/SKILL.md +67 -0
- package/resources/claude-customizations/.claude/skills/review-epic/SKILL.md +21 -0
- package/resources/claude-customizations/.claude/skills/review-feature/SKILL.md +25 -0
- package/resources/claude-customizations/.claude/skills/review-staged/SKILL.md +21 -0
- package/resources/claude-customizations/.claude/skills/skill-canonical-location-audit/SKILL.md +49 -0
- package/resources/claude-customizations/.claude/skills/translate-copilot-to-claude/SKILL.md +295 -0
- package/resources/claude-customizations/.claude/skills/update-status/SKILL.md +21 -0
- package/resources/claude-dir-customizations/.mcp.json +8 -0
- package/resources/codex-and-agents-customizations/.agents/README.md +86 -0
- package/resources/codex-and-agents-customizations/.agents/skills/README.md +49 -0
- package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +107 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +73 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +194 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +87 -0
- package/resources/codex-and-agents-customizations/.agents/skills/commit-message/SKILL.md +70 -0
- package/resources/codex-and-agents-customizations/.agents/skills/commit-message-conventions/SKILL.md +95 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +67 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-change-budget-router/SKILL.md +94 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-orchestration-state-machine/SKILL.md +64 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +82 -0
- package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +168 -0
- package/resources/codex-and-agents-customizations/.agents/skills/execute-hard-lock/SKILL.md +88 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +129 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +106 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +181 -0
- package/resources/codex-and-agents-customizations/.agents/skills/fill-feature-docs/SKILL.md +27 -0
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-csharp-engineer/SKILL.md +73 -0
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-powershell-engineer/SKILL.md +74 -0
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-python-engineer/SKILL.md +73 -0
- package/resources/codex-and-agents-customizations/.agents/skills/make-skill-template/SKILL.md +152 -0
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +143 -0
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +317 -0
- package/resources/codex-and-agents-customizations/.agents/skills/policy-audit-template-usage/SKILL.md +53 -0
- package/resources/codex-and-agents-customizations/.agents/skills/policy-compliance-order/SKILL.md +49 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell/SKILL.md +102 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-change-budget-router/SKILL.md +53 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-orchestration-state-machine/SKILL.md +64 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-qa-gate/SKILL.md +83 -0
- package/resources/codex-and-agents-customizations/.agents/skills/pr-author/SKILL.md +55 -0
- package/resources/codex-and-agents-customizations/.agents/skills/pr-authoring/SKILL.md +124 -0
- package/resources/codex-and-agents-customizations/.agents/skills/pr-base-branch-merge-base/SKILL.md +60 -0
- package/resources/codex-and-agents-customizations/.agents/skills/pr-context-artifacts/SKILL.md +34 -0
- package/resources/codex-and-agents-customizations/.agents/skills/python/SKILL.md +104 -0
- package/resources/codex-and-agents-customizations/.agents/skills/python-change-budget-router/SKILL.md +84 -0
- package/resources/codex-and-agents-customizations/.agents/skills/python-qa-gate/SKILL.md +82 -0
- package/resources/codex-and-agents-customizations/.agents/skills/python-suppressions/SKILL.md +148 -0
- package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +49 -0
- package/resources/codex-and-agents-customizations/.agents/skills/repo-automation-adapter/SKILL.md +142 -0
- package/resources/codex-and-agents-customizations/.agents/skills/repo-automation-adapter/agents/openai.yaml +5 -0
- package/resources/codex-and-agents-customizations/.agents/skills/research-issue/SKILL.md +72 -0
- package/resources/codex-and-agents-customizations/.agents/skills/review-epic/SKILL.md +26 -0
- package/resources/codex-and-agents-customizations/.agents/skills/review-feature/SKILL.md +30 -0
- package/resources/codex-and-agents-customizations/.agents/skills/review-staged/SKILL.md +26 -0
- package/resources/codex-and-agents-customizations/.agents/skills/self-explanatory-code-commenting/SKILL.md +102 -0
- package/resources/codex-and-agents-customizations/.agents/skills/skill-canonical-location-audit/SKILL.md +52 -0
- package/resources/codex-and-agents-customizations/.agents/skills/translate-copilot-to-claude/SKILL.md +317 -0
- package/resources/codex-and-agents-customizations/.agents/skills/typescript/SKILL.md +50 -0
- package/resources/codex-and-agents-customizations/.agents/skills/typescript-suppressions/SKILL.md +71 -0
- package/resources/codex-and-agents-customizations/.agents/skills/update-status/SKILL.md +26 -0
- package/resources/codex-and-agents-customizations/.codex/agents/5.1-beast-adjusted.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/5.1-thinking-beast-mode-adjusted.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/api-architect.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +151 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +93 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planning.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commentary-remediation.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commit-steward.toml +20 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-executor.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-planning.toml +25 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-orchestrator.toml +56 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer.toml +97 -0
- package/resources/codex-and-agents-customizations/.codex/agents/epic-review.toml +52 -0
- package/resources/codex-and-agents-customizations/.codex/agents/expert-nextjs-developer.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/expert-react-frontend-engineer.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +149 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer.toml +60 -0
- package/resources/codex-and-agents-customizations/.codex/agents/gpt-5-beast-mode.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/hlbpa.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/mentor.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +121 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-executor.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-planning.toml +25 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-di-unit-test-engineer.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-orchestrator.toml +56 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer.toml +108 -0
- package/resources/codex-and-agents-customizations/.codex/agents/pr-author.toml +26 -0
- package/resources/codex-and-agents-customizations/.codex/agents/prd-feature.toml +53 -0
- package/resources/codex-and-agents-customizations/.codex/agents/prd.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/pytest-unit-test-coding.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-executor.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-planning.toml +25 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-execution-only-typed.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-orchestrator.toml +54 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +100 -0
- package/resources/codex-and-agents-customizations/.codex/agents/staged-review.toml +53 -0
- package/resources/codex-and-agents-customizations/.codex/agents/status-updater.toml +53 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher.toml +103 -0
- package/resources/codex-and-agents-customizations/.codex/agents/tdd-green.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/tdd-red.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/tdd-refactor.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/typescript-engineer.toml +48 -0
- package/resources/codex-and-agents-customizations/.codex/agents/voidbeast-gpt41enhanced.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/codex-web-setup.plan.md +26 -0
- package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +384 -0
- package/resources/codex-and-agents-customizations/.codex/config.toml +137 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +113 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +149 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +153 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +241 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +150 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +238 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +72 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +265 -0
- package/resources/codex-and-agents-customizations/.codex/prompts/feature-review-remediate.md +10 -0
- package/resources/codex-and-agents-customizations/.codex/prompts/generate-commit-message-repo.md +11 -0
- package/resources/codex-and-agents-customizations/.codex/prompts/generate-pr.md +15 -0
- package/resources/codex-and-agents-customizations/.codex/prompts/orchestrate-work.md +22 -0
- package/resources/codex-and-agents-customizations/AGENTS.md +317 -0
- package/resources/customizations/.github/agents/5.1-Beast-adjusted.agent.md +181 -0
- package/resources/customizations/.github/agents/5.1-Thinking-Beast-Mode-adjusted.agent.md +361 -0
- package/resources/customizations/.github/agents/Powershell DI Unit Test Engineer.agent.md +192 -0
- package/resources/customizations/.github/agents/api-architect.agent.md +40 -0
- package/resources/customizations/.github/agents/atomic_executor.agent.md +251 -0
- package/resources/customizations/.github/agents/atomic_planning.agent.md +658 -0
- package/resources/customizations/.github/agents/commentary-remediation.agent.md +35 -0
- package/resources/customizations/.github/agents/commit-steward.agent.md +200 -0
- package/resources/customizations/.github/agents/csharp-atomic-executor.agent.md +288 -0
- package/resources/customizations/.github/agents/csharp-atomic-planning.agent.md +354 -0
- package/resources/customizations/.github/agents/csharp-orchestrator.agent.md +375 -0
- package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +285 -0
- package/resources/customizations/.github/agents/epic-review.agent.md +374 -0
- package/resources/customizations/.github/agents/expert-nextjs-developer.agent.md +477 -0
- package/resources/customizations/.github/agents/expert-react-frontend-engineer.agent.md +739 -0
- package/resources/customizations/.github/agents/feature-review.agent.md +49 -0
- package/resources/customizations/.github/agents/gpt-5-beast-mode.agent.md +116 -0
- package/resources/customizations/.github/agents/hlbpa.agent.md +219 -0
- package/resources/customizations/.github/agents/mentor.agent.md +32 -0
- package/resources/customizations/.github/agents/orchestrator.agent.md +449 -0
- package/resources/customizations/.github/agents/powershell-atomic-executor.agent.md +287 -0
- package/resources/customizations/.github/agents/powershell-atomic-planning.agent.md +647 -0
- package/resources/customizations/.github/agents/powershell-orchestrator.agent.md +382 -0
- package/resources/customizations/.github/agents/powershell-typed-engineer.agent.md +293 -0
- package/resources/customizations/.github/agents/pr-author.agent.md +138 -0
- package/resources/customizations/.github/agents/prd-feature.agent.md +52 -0
- package/resources/customizations/.github/agents/prd.agent.md +202 -0
- package/resources/customizations/.github/agents/pytest-unit-test-coding.agent.md +202 -0
- package/resources/customizations/.github/agents/python-atomic-executor.agent.md +289 -0
- package/resources/customizations/.github/agents/python-atomic-planning.agent.md +429 -0
- package/resources/customizations/.github/agents/python-execution-only-typed.agent.md +217 -0
- package/resources/customizations/.github/agents/python-orchestrator.agent.md +380 -0
- package/resources/customizations/.github/agents/python-typed-engineer.agent.md +271 -0
- package/resources/customizations/.github/agents/staged-review.agent.md +246 -0
- package/resources/customizations/.github/agents/status_updater.agent.md +279 -0
- package/resources/customizations/.github/agents/task-researcher.agent.md +298 -0
- package/resources/customizations/.github/agents/tdd-green.agent.md +60 -0
- package/resources/customizations/.github/agents/tdd-red.agent.md +66 -0
- package/resources/customizations/.github/agents/tdd-refactor.agent.md +94 -0
- package/resources/customizations/.github/agents/typescript-engineer.agent.md +167 -0
- package/resources/customizations/.github/agents/voidbeast-gpt41enhanced.agent.md +230 -0
- package/resources/customizations/.github/codex/execute-hard-lock.prompt.md +105 -0
- package/resources/customizations/.github/codex/resume-hard-lock.prompt.md +92 -0
- package/resources/customizations/.github/copilot-instructions.md +7 -0
- package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +184 -0
- package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +52 -0
- package/resources/customizations/.github/instructions/general-code-change.instructions.md +290 -0
- package/resources/customizations/.github/instructions/general-unit-test.instructions.md +106 -0
- package/resources/customizations/.github/instructions/github-actions-ci-cd-best-practices.instructions.md +607 -0
- package/resources/customizations/.github/instructions/github-actions.instructions.md +23 -0
- package/resources/customizations/.github/instructions/powershell-code-change.instructions.md +81 -0
- package/resources/customizations/.github/instructions/powershell-unit-test.instructions.md +69 -0
- package/resources/customizations/.github/instructions/python-code-change.instructions.md +232 -0
- package/resources/customizations/.github/instructions/python-suppressions.instructions.md +609 -0
- package/resources/customizations/.github/instructions/python-unit-test.instructions.md +71 -0
- package/resources/customizations/.github/instructions/self-explanatory-code-commenting.instructions.md +238 -0
- package/resources/customizations/.github/instructions/tonality.instructions.md +133 -0
- package/resources/customizations/.github/instructions/typescript-code-change.instructions.md +203 -0
- package/resources/customizations/.github/instructions/typescript-suppressions.instructions.md +157 -0
- package/resources/customizations/.github/instructions/typescript-unit-test.instructions.md +112 -0
- package/resources/customizations/.github/prompts/add-educational-comments.prompt.md +129 -0
- package/resources/customizations/.github/prompts/breakdown-bug-prd.prompt.md +29 -0
- package/resources/customizations/.github/prompts/breakdown-epic-arch.prompt.md +66 -0
- package/resources/customizations/.github/prompts/breakdown-epic-pm.prompt.md +58 -0
- package/resources/customizations/.github/prompts/breakdown-feature-implementation.prompt.md +128 -0
- package/resources/customizations/.github/prompts/breakdown-feature-prd.prompt.md +61 -0
- package/resources/customizations/.github/prompts/code-exemplars-blueprint-generator.prompt.md +126 -0
- package/resources/customizations/.github/prompts/drafts/create-github-issues-feature-from-implementation-plan.prompt.md +28 -0
- package/resources/customizations/.github/prompts/drafts/create-implementation-plan.prompt.md +158 -0
- package/resources/customizations/.github/prompts/drafts/create-technical-spike.prompt.md +231 -0
- package/resources/customizations/.github/prompts/drafts/potential-feature-prd.prompt.md +19 -0
- package/resources/customizations/.github/prompts/drafts/update-implementation-plan.prompt.md +158 -0
- package/resources/customizations/.github/prompts/execute-plan-template.md +21 -0
- package/resources/customizations/.github/prompts/export-chat.prompt.md +7 -0
- package/resources/customizations/.github/prompts/fillout-prd-feature.prompt.md +46 -0
- package/resources/customizations/.github/prompts/generate-atomic-plan.prompt.md +96 -0
- package/resources/customizations/.github/prompts/generate-commit-message-repo.prompt.md +108 -0
- package/resources/customizations/.github/prompts/generate-pr.prompt.md +151 -0
- package/resources/customizations/.github/prompts/javascript-typescript-jest.prompt.md +44 -0
- package/resources/customizations/.github/prompts/orchestrate-csharp-work.prompt.md +66 -0
- package/resources/customizations/.github/prompts/orchestrate-powershell-work.prompt.md +50 -0
- package/resources/customizations/.github/prompts/orchestrate-python-work.prompt.md +50 -0
- package/resources/customizations/.github/prompts/orchestrate-work.prompt.md +66 -0
- package/resources/customizations/.github/prompts/remediate-comments.prompt.md +53 -0
- package/resources/customizations/.github/prompts/research-issue.prompt.md +125 -0
- package/resources/customizations/.github/prompts/review-epic.prompt.md +94 -0
- package/resources/customizations/.github/prompts/review-feature.prompt.md +130 -0
- package/resources/customizations/.github/prompts/review-staged.prompt.md +43 -0
- package/resources/customizations/.github/prompts/update_status.prompt.md +68 -0
- package/resources/customizations/.github/skills/README.md +26 -0
- package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +102 -0
- package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +174 -0
- package/resources/customizations/.github/skills/csharp-change-budget-router/SKILL.md +48 -0
- package/resources/customizations/.github/skills/csharp-orchestration-state-machine/SKILL.md +57 -0
- package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +135 -0
- package/resources/customizations/.github/skills/feature-promotion-lifecycle/SKILL.md +121 -0
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +153 -0
- package/resources/customizations/.github/skills/make-skill-template/SKILL.md +147 -0
- package/resources/customizations/.github/skills/policy-audit-template-usage/SKILL.md +48 -0
- package/resources/customizations/.github/skills/policy-compliance-order/SKILL.md +37 -0
- package/resources/customizations/.github/skills/powershell-change-budget-router/SKILL.md +48 -0
- package/resources/customizations/.github/skills/powershell-orchestration-state-machine/SKILL.md +57 -0
- package/resources/customizations/.github/skills/pr-base-branch-merge-base/SKILL.md +55 -0
- package/resources/customizations/.github/skills/pr-context-artifacts/SKILL.md +29 -0
- package/resources/customizations/.github/skills/remediation-handoff-atomic-planner/SKILL.md +39 -0
- package/resources/customizations/.github/skills/skill-canonical-location-audit/SKILL.md +48 -0
- package/resources/feature-templates/bug/plan.yyyy-MM-ddTHH-mm.md +44 -0
- package/resources/feature-templates/bug/potential_bug.md +59 -0
- package/resources/feature-templates/bug/spec.md +99 -0
- package/resources/feature-templates/epic/initiative.md +43 -0
- package/resources/feature-templates/feature/plan.yyyy-MM-ddTHH-mm.md +53 -0
- package/resources/feature-templates/feature/spec.md +66 -0
- package/resources/feature-templates/feature/user-story.md +42 -0
- package/resources/feature-templates/potential/template.md +33 -0
- package/resources/feature-templates/refactor/plan.yyyy-MM-ddTHH-mm.md +52 -0
- package/resources/feature-templates/refactor/spec.md +69 -0
- package/resources/powershell/PoshQC/PoshQC.Analyzer.psm1 +254 -0
- package/resources/powershell/PoshQC/PoshQC.FileDiscovery.psm1 +138 -0
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +409 -0
- package/resources/powershell/PoshQC/PoshQC.psd1 +31 -0
- package/resources/powershell/PoshQC/PoshQC.psm1 +101 -0
- package/resources/powershell/PoshQC/README.md +80 -0
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +59 -0
- package/resources/powershell/PoshQC/settings/pssa.settings.psd1 +55 -0
- package/resources/scripts/dev_tools/__init__.py +0 -0
- package/resources/scripts/dev_tools/agentic_sync.py +819 -0
- package/resources/scripts/dev_tools/codex_native_converter/__init__.py +11 -0
- package/resources/scripts/dev_tools/codex_native_converter/__main__.py +6 -0
- package/resources/scripts/dev_tools/codex_native_converter/cli.py +11 -0
- package/resources/scripts/dev_tools/new_active_feature_folder.py +79 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_docs.py +268 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_flow.py +366 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_io.py +306 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_markdown.py +252 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_models.py +136 -0
- package/resources/scripts/dev_tools/new_potential_bug_entry.py +465 -0
- package/resources/scripts/dev_tools/potential_to_issue.py +421 -0
- package/resources/scripts/dev_tools/potential_to_issue_content.py +212 -0
- package/resources/scripts/dev_tools/pr_context/__init__.py +0 -0
- package/resources/scripts/dev_tools/pr_context/collector.py +619 -0
- package/resources/scripts/dev_tools/pr_context/feature_docs.py +349 -0
- package/resources/scripts/dev_tools/pr_context/git.py +153 -0
- package/resources/scripts/dev_tools/pr_context/github.py +549 -0
- package/resources/scripts/dev_tools/pr_context/models.py +198 -0
- package/resources/scripts/dev_tools/pr_context/render.py +342 -0
- package/resources/scripts/dev_tools/pr_context/render_feature_excerpts.py +256 -0
- package/resources/scripts/dev_tools/pr_context/render_pr_helpers.py +291 -0
- package/resources/scripts/dev_tools/pr_context/summary_helpers.py +386 -0
- package/resources/scripts/dev_tools/pr_context/verification_evidence.py +171 -0
- package/resources/scripts/dev_tools/prompt_mode_contract.py +152 -0
- package/resources/scripts/dev_tools/push_down_claude_customizations.py +188 -0
- package/resources/scripts/dev_tools/push_down_codex_and_agents_customizations.py +139 -0
- package/resources/scripts/dev_tools/push_down_copilot_customizations.py +504 -0
- package/resources/scripts/dev_tools/push_down_copilot_customizations_filesystem.py +217 -0
- package/resources/scripts/dev_tools/push_down_copilot_customizations_rewrites.py +293 -0
- package/resources/scripts/dev_tools/resolve_file_prompt.py +457 -0
- package/resources/scripts/dev_tools/resolve_hard_lock_prompt.py +444 -0
- package/resources/scripts/dev_tools/validate_orchestration_artifacts.py +554 -0
- package/resources/templates/codex_native_converter.py +35 -0
- package/resources/templates/collect_commit_context.py +212 -0
- package/resources/templates/collect_pr_context.py +74 -0
- package/resources/templates/hello_pwsh.ps1 +3 -0
- package/resources/templates/hello_python.py +11 -0
- package/resources/templates/link-parent-child.ps1 +480 -0
- package/resources/templates/new-claude-worktree-session.ps1 +232 -0
- package/resources/templates/new-potential-entry.ps1 +187 -0
- package/resources/templates/new_active_feature_folder.py +67 -0
- package/resources/templates/new_potential_bug_entry.py +54 -0
- package/resources/templates/policy_audit/AGENTS.md +117 -0
- package/resources/templates/policy_audit/code-review.yyyy-MM-ddTHH-mm.md +165 -0
- package/resources/templates/policy_audit/feature-audit.yyyy-MM-ddTHH-mm.md +124 -0
- package/resources/templates/policy_audit/policy-audit.yyyy-MM-ddTHH-mm.md +649 -0
- package/resources/templates/potential_to_issue.py +55 -0
- package/resources/templates/push_down_claude_customizations.py +188 -0
- package/resources/templates/push_down_codex_and_agents_customizations.py +95 -0
- package/resources/templates/push_down_copilot_customizations.py +124 -0
- package/resources/templates/resolve_atomic_plan_prompt.py +75 -0
- package/resources/templates/resolve_hard_lock_prompt.py +65 -0
- package/resources/templates/run-poshqc-analyze-autofix.ps1 +16 -0
- package/resources/templates/run-poshqc-analyze.ps1 +26 -0
- package/resources/templates/run-poshqc-format.ps1 +26 -0
- package/resources/templates/run-poshqc-suite.ps1 +24 -0
- package/resources/templates/run-poshqc-test.ps1 +32 -0
- package/resources/templates/sync-agents-from-instructions.ps1 +400 -0
- package/resources/templates/validate_orchestration_artifacts.py +55 -0
- package/resources/templates/vscode-cli.helpers.ps1 +63 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
"""Orchestration and CLI flow for active feature folder creation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
from dev_tools.new_active_feature_folder_docs import (
|
|
10
|
+
should_use_minor_audit_mode,
|
|
11
|
+
update_feature_docs,
|
|
12
|
+
)
|
|
13
|
+
from dev_tools.new_active_feature_folder_io import (
|
|
14
|
+
build_folder_slug,
|
|
15
|
+
copy_feature_template_for_minor_audit,
|
|
16
|
+
copy_template,
|
|
17
|
+
default_code_launcher,
|
|
18
|
+
default_issue_fetcher,
|
|
19
|
+
find_potential_file,
|
|
20
|
+
materialize_plan_file,
|
|
21
|
+
parse_issue_number,
|
|
22
|
+
)
|
|
23
|
+
from dev_tools.new_active_feature_folder_markdown import (
|
|
24
|
+
get_section,
|
|
25
|
+
upsert_work_mode_marker,
|
|
26
|
+
)
|
|
27
|
+
from dev_tools.new_active_feature_folder_models import (
|
|
28
|
+
ActiveFolderResult,
|
|
29
|
+
FileSystem,
|
|
30
|
+
IssueMeta,
|
|
31
|
+
RealFileSystem,
|
|
32
|
+
get_est_timestamp,
|
|
33
|
+
resolve_workspace,
|
|
34
|
+
validate_feature_name,
|
|
35
|
+
)
|
|
36
|
+
from dev_tools.prompt_mode_contract import normalize_requested_work_mode
|
|
37
|
+
|
|
38
|
+
if TYPE_CHECKING:
|
|
39
|
+
from collections.abc import Callable, Iterable
|
|
40
|
+
from datetime import datetime
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def create_active_folder(
|
|
44
|
+
feature_name: str | None,
|
|
45
|
+
feature_type: str = "feature",
|
|
46
|
+
issue_number: str | None = None,
|
|
47
|
+
force: bool = False,
|
|
48
|
+
*,
|
|
49
|
+
active_file_for_feature_name: str | None = None,
|
|
50
|
+
workspace: Path | None = None,
|
|
51
|
+
fs: FileSystem | None = None,
|
|
52
|
+
issue_fetcher: Callable[[str], IssueMeta | None] = default_issue_fetcher,
|
|
53
|
+
code_launcher: Callable[[Iterable[Path]], bool] = default_code_launcher,
|
|
54
|
+
now_provider: Callable[[], datetime] | None = None,
|
|
55
|
+
work_mode: str = "full",
|
|
56
|
+
template_root: Path | None = None,
|
|
57
|
+
) -> ActiveFolderResult:
|
|
58
|
+
"""Create and seed an active feature folder from templates and potential docs."""
|
|
59
|
+
if feature_type not in {"feature", "refactor", "epic", "bug"}:
|
|
60
|
+
raise ValueError("Type must be one of: feature, refactor, epic, bug")
|
|
61
|
+
|
|
62
|
+
workspace_path = workspace or resolve_workspace()
|
|
63
|
+
filesystem = fs or RealFileSystem()
|
|
64
|
+
|
|
65
|
+
resolved_feature_name = feature_name
|
|
66
|
+
feature_name_source = "manual"
|
|
67
|
+
if active_file_for_feature_name is not None:
|
|
68
|
+
auto_resolve_error = (
|
|
69
|
+
"Select a promoted issue markdown file under "
|
|
70
|
+
"docs/features/potential/promoted or supply --feature-name directly."
|
|
71
|
+
)
|
|
72
|
+
active_file_path = Path(active_file_for_feature_name)
|
|
73
|
+
if not active_file_path.is_absolute():
|
|
74
|
+
active_file_path = workspace_path / active_file_path
|
|
75
|
+
|
|
76
|
+
promoted_root = workspace_path / "docs" / "features" / "potential" / "promoted"
|
|
77
|
+
try:
|
|
78
|
+
active_file_path.relative_to(promoted_root)
|
|
79
|
+
is_in_promoted = True
|
|
80
|
+
except ValueError:
|
|
81
|
+
is_in_promoted = False
|
|
82
|
+
|
|
83
|
+
if (
|
|
84
|
+
active_file_path.suffix.lower() != ".md"
|
|
85
|
+
or not is_in_promoted
|
|
86
|
+
or not filesystem.exists(active_file_path)
|
|
87
|
+
):
|
|
88
|
+
raise ValueError(auto_resolve_error)
|
|
89
|
+
|
|
90
|
+
resolved_feature_name = active_file_path.stem
|
|
91
|
+
feature_name_source = "active-file"
|
|
92
|
+
|
|
93
|
+
if not resolved_feature_name:
|
|
94
|
+
raise ValueError(
|
|
95
|
+
"feature_name must be provided when "
|
|
96
|
+
"--active-file-for-feature-name is not used"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
validate_feature_name(resolved_feature_name)
|
|
100
|
+
print(f"Feature name source: {feature_name_source}")
|
|
101
|
+
|
|
102
|
+
# Resolve template directory from the bundled template root when provided,
|
|
103
|
+
# otherwise fall back to the workspace's docs/features/templates/ tree.
|
|
104
|
+
if template_root is not None:
|
|
105
|
+
template_dir = template_root / feature_type
|
|
106
|
+
else:
|
|
107
|
+
template_dir = workspace_path / "docs" / "features" / "templates" / feature_type
|
|
108
|
+
if not filesystem.exists(template_dir):
|
|
109
|
+
raise FileNotFoundError(f"Template folder not found: {template_dir}")
|
|
110
|
+
|
|
111
|
+
potential_file = find_potential_file(
|
|
112
|
+
resolved_feature_name, workspace_path, filesystem
|
|
113
|
+
)
|
|
114
|
+
potential_content = filesystem.read_text(potential_file) if potential_file else ""
|
|
115
|
+
selected_work_mode = normalize_requested_work_mode(work_mode, feature_type)
|
|
116
|
+
use_minor_audit, fallback_reason = should_use_minor_audit_mode(
|
|
117
|
+
work_mode=selected_work_mode,
|
|
118
|
+
feature_type=feature_type,
|
|
119
|
+
potential_content=potential_content,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
normalized_issue_number = (issue_number or "").strip() or None
|
|
123
|
+
if normalized_issue_number and normalized_issue_number.lower() == "auto":
|
|
124
|
+
normalized_issue_number = None
|
|
125
|
+
if not normalized_issue_number:
|
|
126
|
+
normalized_issue_number = parse_issue_number(potential_content)
|
|
127
|
+
|
|
128
|
+
folder_slug = build_folder_slug(
|
|
129
|
+
resolved_feature_name,
|
|
130
|
+
potential_file,
|
|
131
|
+
normalized_issue_number,
|
|
132
|
+
)
|
|
133
|
+
target_dir = workspace_path / "docs" / "features" / "active" / folder_slug
|
|
134
|
+
|
|
135
|
+
if filesystem.exists(target_dir) and not force:
|
|
136
|
+
raise FileExistsError(
|
|
137
|
+
f"Target exists: {target_dir}. Re-run with --force to overwrite."
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
filesystem.ensure_dir(target_dir)
|
|
141
|
+
if use_minor_audit:
|
|
142
|
+
copy_feature_template_for_minor_audit(template_dir, target_dir, filesystem)
|
|
143
|
+
else:
|
|
144
|
+
copy_template(feature_type, template_dir, target_dir, filesystem)
|
|
145
|
+
|
|
146
|
+
issue_meta = None
|
|
147
|
+
if normalized_issue_number:
|
|
148
|
+
issue_meta = issue_fetcher(normalized_issue_number)
|
|
149
|
+
issue_field = f"#{normalized_issue_number}" if normalized_issue_number else "TBD"
|
|
150
|
+
if issue_meta:
|
|
151
|
+
issue_field = f"#{issue_meta.number}"
|
|
152
|
+
owner_field = issue_meta.author if issue_meta else "TBD"
|
|
153
|
+
parent_field = "none"
|
|
154
|
+
status_field = "Draft"
|
|
155
|
+
version_field = "0.1"
|
|
156
|
+
|
|
157
|
+
plan_timestamp = get_est_timestamp(now_provider)
|
|
158
|
+
updated_field = plan_timestamp
|
|
159
|
+
plan_path = materialize_plan_file(
|
|
160
|
+
feature_type=feature_type,
|
|
161
|
+
target_dir=target_dir,
|
|
162
|
+
feature_name=resolved_feature_name,
|
|
163
|
+
issue_field=issue_field,
|
|
164
|
+
owner_field=owner_field,
|
|
165
|
+
parent_field=parent_field,
|
|
166
|
+
status_field=status_field,
|
|
167
|
+
version_field=version_field,
|
|
168
|
+
plan_timestamp=plan_timestamp,
|
|
169
|
+
fs=filesystem,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
plan_updated_field = plan_timestamp
|
|
173
|
+
|
|
174
|
+
sections: dict[str, str] = {
|
|
175
|
+
"problem": get_section(potential_content, "Problem / Why"),
|
|
176
|
+
"behavior": get_section(potential_content, "Proposed Behavior"),
|
|
177
|
+
"criteria": get_section(potential_content, "Acceptance Criteria (early draft)"),
|
|
178
|
+
"constraints": get_section(potential_content, "Constraints & Risks"),
|
|
179
|
+
"tests": get_section(potential_content, "Test Conditions to Consider"),
|
|
180
|
+
"bug_summary": get_section(potential_content, "Summary"),
|
|
181
|
+
"bug_environment": get_section(potential_content, "Environment"),
|
|
182
|
+
"bug_steps": get_section(potential_content, "Steps to Reproduce"),
|
|
183
|
+
"bug_expected": get_section(potential_content, "Expected Behavior"),
|
|
184
|
+
"bug_actual": get_section(potential_content, "Actual Behavior"),
|
|
185
|
+
"bug_logs": get_section(potential_content, "Logs / Screenshots"),
|
|
186
|
+
"bug_impact": get_section(potential_content, "Impact / Severity"),
|
|
187
|
+
"bug_cause": get_section(potential_content, "Suspected Cause / Notes"),
|
|
188
|
+
"bug_validation": get_section(
|
|
189
|
+
potential_content,
|
|
190
|
+
"Proposed Fix / Validation Ideas",
|
|
191
|
+
),
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
files_to_open: list[Path]
|
|
195
|
+
potential_issue_path: Path | None = None
|
|
196
|
+
if use_minor_audit:
|
|
197
|
+
if potential_file:
|
|
198
|
+
potential_issue_path = target_dir / "issue.md"
|
|
199
|
+
filesystem.move(potential_file, potential_issue_path)
|
|
200
|
+
moved_content = filesystem.read_text(potential_issue_path)
|
|
201
|
+
filesystem.write_text(
|
|
202
|
+
potential_issue_path,
|
|
203
|
+
upsert_work_mode_marker(moved_content, "minor-audit"),
|
|
204
|
+
)
|
|
205
|
+
files_to_open = [potential_issue_path]
|
|
206
|
+
else:
|
|
207
|
+
issue_doc = target_dir / "issue.md"
|
|
208
|
+
issue_body = "\n".join(
|
|
209
|
+
[
|
|
210
|
+
f"# {resolved_feature_name}",
|
|
211
|
+
"",
|
|
212
|
+
"- Work Mode: minor-audit",
|
|
213
|
+
"## Problem / Why",
|
|
214
|
+
sections["problem"] or "(not provided in potential file)",
|
|
215
|
+
"",
|
|
216
|
+
"## Implementation Intent",
|
|
217
|
+
sections["behavior"] or "(not provided in potential file)",
|
|
218
|
+
"",
|
|
219
|
+
"## Acceptance Criteria",
|
|
220
|
+
sections["criteria"] or "(not provided in potential file)",
|
|
221
|
+
"",
|
|
222
|
+
"## Dependencies / Risks",
|
|
223
|
+
sections["constraints"] or "(not provided in potential file)",
|
|
224
|
+
"",
|
|
225
|
+
"## Verification Steps",
|
|
226
|
+
sections["tests"] or "(not provided in potential file)",
|
|
227
|
+
"",
|
|
228
|
+
"## Evidence Checklist",
|
|
229
|
+
"- [ ] baseline",
|
|
230
|
+
"- [ ] targeted verification",
|
|
231
|
+
"- [ ] end-state",
|
|
232
|
+
]
|
|
233
|
+
)
|
|
234
|
+
filesystem.write_text(issue_doc, issue_body)
|
|
235
|
+
files_to_open = [issue_doc]
|
|
236
|
+
else:
|
|
237
|
+
files_to_open = update_feature_docs(
|
|
238
|
+
feature_type,
|
|
239
|
+
resolved_feature_name,
|
|
240
|
+
target_dir,
|
|
241
|
+
issue_field,
|
|
242
|
+
owner_field,
|
|
243
|
+
updated_field,
|
|
244
|
+
parent_field,
|
|
245
|
+
status_field,
|
|
246
|
+
version_field,
|
|
247
|
+
plan_updated_field,
|
|
248
|
+
filesystem,
|
|
249
|
+
sections,
|
|
250
|
+
plan_path=plan_path,
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
if potential_file:
|
|
254
|
+
if use_minor_audit:
|
|
255
|
+
if potential_issue_path is not None:
|
|
256
|
+
print(f"Moved potential file to {potential_issue_path}")
|
|
257
|
+
else:
|
|
258
|
+
potential_issue_path = target_dir / "issue.md"
|
|
259
|
+
filesystem.move(potential_file, potential_issue_path)
|
|
260
|
+
moved_content = filesystem.read_text(potential_issue_path)
|
|
261
|
+
filesystem.write_text(
|
|
262
|
+
potential_issue_path,
|
|
263
|
+
upsert_work_mode_marker(moved_content, selected_work_mode),
|
|
264
|
+
)
|
|
265
|
+
print(f"Moved potential file to {potential_issue_path}")
|
|
266
|
+
|
|
267
|
+
if potential_file:
|
|
268
|
+
print(f"Seeded docs from potential: {potential_file.name}")
|
|
269
|
+
|
|
270
|
+
print(f"Selected mode: {'minor-audit' if use_minor_audit else selected_work_mode}")
|
|
271
|
+
if fallback_reason:
|
|
272
|
+
print(f"Fallback reason: {fallback_reason}")
|
|
273
|
+
|
|
274
|
+
if files_to_open:
|
|
275
|
+
existing = [path for path in files_to_open if filesystem.exists(path)]
|
|
276
|
+
if potential_issue_path:
|
|
277
|
+
existing.append(potential_issue_path)
|
|
278
|
+
if existing:
|
|
279
|
+
opened = code_launcher(existing)
|
|
280
|
+
if not opened:
|
|
281
|
+
print("VS Code 'code' command not found. Files to edit:")
|
|
282
|
+
for path in existing:
|
|
283
|
+
print(f" {path}")
|
|
284
|
+
|
|
285
|
+
print(f"Created/updated: {target_dir}")
|
|
286
|
+
return ActiveFolderResult(
|
|
287
|
+
target=target_dir,
|
|
288
|
+
potential_issue_path=potential_issue_path,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def parse_args() -> argparse.Namespace:
|
|
293
|
+
"""Parse CLI arguments for active-folder creation."""
|
|
294
|
+
parser = argparse.ArgumentParser(
|
|
295
|
+
description="Create docs/features/active/<name>/ from the selected template."
|
|
296
|
+
)
|
|
297
|
+
parser.add_argument(
|
|
298
|
+
"--feature-name",
|
|
299
|
+
default=None,
|
|
300
|
+
help="Feature folder name (kebab/underscore)",
|
|
301
|
+
)
|
|
302
|
+
parser.add_argument(
|
|
303
|
+
"--active-file-for-feature-name",
|
|
304
|
+
dest="active_file_for_feature_name",
|
|
305
|
+
default=None,
|
|
306
|
+
help=(
|
|
307
|
+
"Resolve feature name from active promoted markdown file path. "
|
|
308
|
+
"Must be under docs/features/potential/promoted and end with .md"
|
|
309
|
+
),
|
|
310
|
+
)
|
|
311
|
+
parser.add_argument(
|
|
312
|
+
"--type",
|
|
313
|
+
dest="feature_type",
|
|
314
|
+
choices=["feature", "refactor", "epic", "bug"],
|
|
315
|
+
default="feature",
|
|
316
|
+
help="Type of folder to create",
|
|
317
|
+
)
|
|
318
|
+
parser.add_argument(
|
|
319
|
+
"--issue-number",
|
|
320
|
+
dest="issue_number",
|
|
321
|
+
default=None,
|
|
322
|
+
help="Issue number or 'auto'",
|
|
323
|
+
)
|
|
324
|
+
parser.add_argument(
|
|
325
|
+
"--force",
|
|
326
|
+
action="store_true",
|
|
327
|
+
help="Overwrite existing target",
|
|
328
|
+
)
|
|
329
|
+
parser.add_argument(
|
|
330
|
+
"--work-mode",
|
|
331
|
+
choices=["minor-audit", "full-feature", "full-bug", "full"],
|
|
332
|
+
default="full",
|
|
333
|
+
help=(
|
|
334
|
+
"Work mode routing. Canonical values are minor-audit, full-feature, "
|
|
335
|
+
"and full-bug; full is accepted as a backward-compatible alias."
|
|
336
|
+
),
|
|
337
|
+
)
|
|
338
|
+
parser.add_argument(
|
|
339
|
+
"--template-root",
|
|
340
|
+
dest="template_root",
|
|
341
|
+
default=None,
|
|
342
|
+
help="Bundled feature-templates dir (overrides workspace).",
|
|
343
|
+
)
|
|
344
|
+
return parser.parse_args()
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def main() -> None:
|
|
348
|
+
"""CLI entry point for active-folder creation script."""
|
|
349
|
+
args = parse_args()
|
|
350
|
+
resolved_root = Path(args.template_root) if args.template_root else None
|
|
351
|
+
try:
|
|
352
|
+
create_active_folder(
|
|
353
|
+
feature_name=args.feature_name,
|
|
354
|
+
feature_type=args.feature_type,
|
|
355
|
+
issue_number=args.issue_number,
|
|
356
|
+
force=args.force,
|
|
357
|
+
active_file_for_feature_name=args.active_file_for_feature_name,
|
|
358
|
+
work_mode=args.work_mode,
|
|
359
|
+
template_root=resolved_root,
|
|
360
|
+
)
|
|
361
|
+
except (ValueError, FileExistsError) as exc:
|
|
362
|
+
print(str(exc))
|
|
363
|
+
raise SystemExit(1) from exc
|
|
364
|
+
except FileNotFoundError as exc:
|
|
365
|
+
print(f"Aborted: required file not found: {exc}")
|
|
366
|
+
raise SystemExit(1) from exc
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"""I/O and template materialization helpers for active feature folder creation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from dev_tools.new_active_feature_folder_markdown import set_header_placeholder
|
|
13
|
+
from dev_tools.new_active_feature_folder_models import (
|
|
14
|
+
EXCLUDED_POTENTIAL_NAMES,
|
|
15
|
+
NAME_PATTERN,
|
|
16
|
+
PLAN_TIMESTAMP_TEMPLATE_NAME,
|
|
17
|
+
IssueMeta,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from collections.abc import Callable, Iterable
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
from dev_tools.new_active_feature_folder_models import FileSystem
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
_INSIDERS_SIGNAL_NAMES = (
|
|
28
|
+
"TERM_PROGRAM_VERSION",
|
|
29
|
+
"VSCODE_GIT_ASKPASS_MAIN",
|
|
30
|
+
"TERM_PROGRAM",
|
|
31
|
+
"VSCODE_IPC_HOOK_CLI",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def find_potential_file(
|
|
36
|
+
feature_name: str, workspace: Path, fs: FileSystem
|
|
37
|
+
) -> Path | None:
|
|
38
|
+
"""Find the best matching potential file for a feature name."""
|
|
39
|
+
normalized = feature_name.replace("_", "-")
|
|
40
|
+
potential_dirs = [
|
|
41
|
+
workspace / "docs" / "features" / "potential",
|
|
42
|
+
workspace / "docs" / "features" / "potential" / "promoted",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
for directory in potential_dirs:
|
|
46
|
+
candidates = [
|
|
47
|
+
file
|
|
48
|
+
for file in fs.list_files(directory)
|
|
49
|
+
if file.suffix == ".md"
|
|
50
|
+
and normalized in file.name
|
|
51
|
+
and file.name not in EXCLUDED_POTENTIAL_NAMES
|
|
52
|
+
]
|
|
53
|
+
if candidates:
|
|
54
|
+
return sorted(candidates, key=lambda path: path.name, reverse=True)[0]
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def parse_issue_number(content: str) -> str | None:
|
|
59
|
+
"""Parse an issue number from markdown metadata lines."""
|
|
60
|
+
match = re.search(r"^\s*-\s*Issue\s*:\s*#?(\d+)", content, flags=re.MULTILINE)
|
|
61
|
+
if match:
|
|
62
|
+
return match.group(1)
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def build_folder_slug(
|
|
67
|
+
feature_name: str,
|
|
68
|
+
potential_file: Path | None,
|
|
69
|
+
issue_number: str | None,
|
|
70
|
+
) -> str:
|
|
71
|
+
"""Build canonical active-folder slug."""
|
|
72
|
+
slug = feature_name.replace("_", "-")
|
|
73
|
+
if potential_file:
|
|
74
|
+
slug = potential_file.stem
|
|
75
|
+
if issue_number and not slug.endswith(str(issue_number)):
|
|
76
|
+
slug = f"{slug}-{issue_number}"
|
|
77
|
+
if not NAME_PATTERN.fullmatch(slug):
|
|
78
|
+
raise ValueError(
|
|
79
|
+
f"Aborted: '{slug}' is invalid. Use kebab/underscore-case letters/numbers "
|
|
80
|
+
"(e.g., notes-feature or notes_feature)."
|
|
81
|
+
)
|
|
82
|
+
return slug
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def copy_template(
|
|
86
|
+
feature_type: str,
|
|
87
|
+
template_dir: Path,
|
|
88
|
+
target_dir: Path,
|
|
89
|
+
fs: FileSystem,
|
|
90
|
+
) -> None:
|
|
91
|
+
"""Copy template files for the selected feature type."""
|
|
92
|
+
if feature_type == "bug":
|
|
93
|
+
for name in ("spec.md", PLAN_TIMESTAMP_TEMPLATE_NAME, "plan.md"):
|
|
94
|
+
src = template_dir / name
|
|
95
|
+
if fs.exists(src):
|
|
96
|
+
fs.copy_file(src, target_dir / name)
|
|
97
|
+
if name == PLAN_TIMESTAMP_TEMPLATE_NAME:
|
|
98
|
+
break
|
|
99
|
+
else:
|
|
100
|
+
fs.copy_tree(template_dir, target_dir)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def copy_feature_template_for_minor_audit(
|
|
104
|
+
template_dir: Path,
|
|
105
|
+
target_dir: Path,
|
|
106
|
+
fs: FileSystem,
|
|
107
|
+
) -> None:
|
|
108
|
+
"""Copy only the plan template for minor-audit feature flows."""
|
|
109
|
+
timestamped_plan = template_dir / PLAN_TIMESTAMP_TEMPLATE_NAME
|
|
110
|
+
if fs.exists(timestamped_plan):
|
|
111
|
+
fs.copy_file(timestamped_plan, target_dir / PLAN_TIMESTAMP_TEMPLATE_NAME)
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
legacy_plan = template_dir / "plan.md"
|
|
115
|
+
if fs.exists(legacy_plan):
|
|
116
|
+
fs.copy_file(legacy_plan, target_dir / "plan.md")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def materialize_plan_file(
|
|
120
|
+
feature_type: str,
|
|
121
|
+
target_dir: Path,
|
|
122
|
+
feature_name: str,
|
|
123
|
+
issue_field: str,
|
|
124
|
+
owner_field: str,
|
|
125
|
+
parent_field: str,
|
|
126
|
+
status_field: str,
|
|
127
|
+
version_field: str,
|
|
128
|
+
plan_timestamp: str,
|
|
129
|
+
fs: FileSystem,
|
|
130
|
+
) -> Path | None:
|
|
131
|
+
"""Rename and stamp plan templates when timestamped templates exist."""
|
|
132
|
+
del feature_type
|
|
133
|
+
template_plan = target_dir / PLAN_TIMESTAMP_TEMPLATE_NAME
|
|
134
|
+
if fs.exists(template_plan):
|
|
135
|
+
target_plan = target_dir / f"plan.{plan_timestamp}.md"
|
|
136
|
+
fs.move(template_plan, target_plan)
|
|
137
|
+
content = fs.read_text(target_plan)
|
|
138
|
+
updated_field = plan_timestamp
|
|
139
|
+
|
|
140
|
+
content = set_header_placeholder(
|
|
141
|
+
content,
|
|
142
|
+
feature_name=feature_name,
|
|
143
|
+
issue_field=issue_field,
|
|
144
|
+
owner_field=owner_field,
|
|
145
|
+
updated_field=updated_field,
|
|
146
|
+
status_field=status_field,
|
|
147
|
+
parent_field=parent_field,
|
|
148
|
+
version_field=version_field,
|
|
149
|
+
)
|
|
150
|
+
fs.write_text(target_plan, content)
|
|
151
|
+
return target_plan
|
|
152
|
+
|
|
153
|
+
legacy = target_dir / "plan.md"
|
|
154
|
+
if fs.exists(legacy):
|
|
155
|
+
return legacy
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def default_issue_fetcher(issue_number: str) -> IssueMeta | None:
|
|
160
|
+
"""Fetch issue metadata from GitHub CLI."""
|
|
161
|
+
gh_cmd = shutil.which("gh")
|
|
162
|
+
if not gh_cmd:
|
|
163
|
+
return None
|
|
164
|
+
result = subprocess.run( # noqa: S603
|
|
165
|
+
[
|
|
166
|
+
gh_cmd,
|
|
167
|
+
"issue",
|
|
168
|
+
"view",
|
|
169
|
+
issue_number,
|
|
170
|
+
"--json",
|
|
171
|
+
"number,title,url,author,updatedAt",
|
|
172
|
+
],
|
|
173
|
+
check=False,
|
|
174
|
+
capture_output=True,
|
|
175
|
+
text=True,
|
|
176
|
+
)
|
|
177
|
+
if result.returncode != 0 or not result.stdout.strip():
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
parsed = json.loads(result.stdout.strip())
|
|
182
|
+
except json.JSONDecodeError:
|
|
183
|
+
return None
|
|
184
|
+
|
|
185
|
+
number = str(parsed.get("number", issue_number))
|
|
186
|
+
author = parsed.get("author", {}).get("login") or "name"
|
|
187
|
+
updated_at = parsed.get("updatedAt")
|
|
188
|
+
updated_date = "YYYY-MM-DD"
|
|
189
|
+
if isinstance(updated_at, str) and updated_at.strip():
|
|
190
|
+
updated_date = updated_at.split("T")[0]
|
|
191
|
+
return IssueMeta(number=number, author=author, updated_date=updated_date)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _env_lookup(name: str) -> str | None:
|
|
195
|
+
"""Return a non-blank environment variable value when one is defined.
|
|
196
|
+
|
|
197
|
+
Purpose:
|
|
198
|
+
Provide a small environment seam for VS Code session detection without
|
|
199
|
+
treating blank variables as meaningful signals.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
name (str): Environment variable name to resolve from the current process.
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
str | None: The environment variable value when present and non-blank;
|
|
206
|
+
otherwise `None`.
|
|
207
|
+
|
|
208
|
+
Raises:
|
|
209
|
+
None.
|
|
210
|
+
|
|
211
|
+
Side Effects:
|
|
212
|
+
Reads process environment state.
|
|
213
|
+
"""
|
|
214
|
+
value = os.getenv(name)
|
|
215
|
+
return value if value and value.strip() else None
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _is_insiders_session(
|
|
219
|
+
env_lookup: Callable[[str], str | None] | None = None,
|
|
220
|
+
) -> bool:
|
|
221
|
+
"""Return whether the current process appears to be running inside VS Code Insiders.
|
|
222
|
+
|
|
223
|
+
Purpose:
|
|
224
|
+
Detect the current editor flavor so launcher selection can prefer
|
|
225
|
+
`code-insiders` when the originating session is already Insiders.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
env_lookup (Callable[[str], str | None]): Environment lookup used
|
|
229
|
+
to read the known VS Code session signal variables.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
bool: `True` when any supported signal indicates an Insiders session;
|
|
233
|
+
otherwise `False`.
|
|
234
|
+
|
|
235
|
+
Raises:
|
|
236
|
+
None.
|
|
237
|
+
|
|
238
|
+
Side Effects:
|
|
239
|
+
Reads process environment state through the injected lookup.
|
|
240
|
+
"""
|
|
241
|
+
# Check the documented VS Code environment signals in a stable order so
|
|
242
|
+
# the launcher behavior stays deterministic across bundled and root copies.
|
|
243
|
+
lookup = env_lookup or _env_lookup
|
|
244
|
+
for variable_name in _INSIDERS_SIGNAL_NAMES:
|
|
245
|
+
value = lookup(variable_name)
|
|
246
|
+
if value and "insider" in value.lower():
|
|
247
|
+
return True
|
|
248
|
+
return False
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _resolve_code_cli(
|
|
252
|
+
which_lookup: Callable[[str], str | None] | None = None,
|
|
253
|
+
env_lookup: Callable[[str], str | None] | None = None,
|
|
254
|
+
) -> str | None:
|
|
255
|
+
"""Resolve the best VS Code CLI executable path for the current session.
|
|
256
|
+
[code_cmd, "--reuse-window", *[file_path.as_posix() for file_path in files]],
|
|
257
|
+
Purpose:
|
|
258
|
+
Choose the correct CLI path while preserving fallback to the standard
|
|
259
|
+
`code` command when an Insiders-specific executable is unavailable.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
which_lookup (Callable[[str], str | None]): PATH lookup used to
|
|
263
|
+
resolve CLI executables.
|
|
264
|
+
env_lookup (Callable[[str], str | None]): Environment lookup used
|
|
265
|
+
for Insiders-session detection.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
str | None: Resolved CLI executable path when one is available;
|
|
269
|
+
otherwise `None`.
|
|
270
|
+
|
|
271
|
+
Raises:
|
|
272
|
+
None.
|
|
273
|
+
|
|
274
|
+
Side Effects:
|
|
275
|
+
Reads process environment state and PATH through the injected lookups.
|
|
276
|
+
"""
|
|
277
|
+
resolved_which_lookup = which_lookup or shutil.which
|
|
278
|
+
|
|
279
|
+
# Prefer the CLI that matches the current session first, then fall back to
|
|
280
|
+
# the other supported executable name to preserve graceful behavior.
|
|
281
|
+
candidate_names = (
|
|
282
|
+
("code-insiders", "code")
|
|
283
|
+
if _is_insiders_session(env_lookup)
|
|
284
|
+
else ("code", "code-insiders")
|
|
285
|
+
)
|
|
286
|
+
for candidate_name in candidate_names:
|
|
287
|
+
resolved_command = resolved_which_lookup(candidate_name)
|
|
288
|
+
if resolved_command:
|
|
289
|
+
return resolved_command
|
|
290
|
+
return None
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def default_code_launcher(files: Iterable[Path]) -> bool:
|
|
294
|
+
"""Open created files in VS Code when available."""
|
|
295
|
+
code_cmd = _resolve_code_cli()
|
|
296
|
+
if not code_cmd:
|
|
297
|
+
return False
|
|
298
|
+
subprocess.run( # noqa: S603
|
|
299
|
+
[
|
|
300
|
+
code_cmd,
|
|
301
|
+
"--reuse-window",
|
|
302
|
+
*[str(file_path).replace("\\", "/") for file_path in files],
|
|
303
|
+
],
|
|
304
|
+
check=False,
|
|
305
|
+
)
|
|
306
|
+
return True
|