@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,409 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Runs the bundled PoshQC suite in one pass.
|
|
4
|
+
.DESCRIPTION
|
|
5
|
+
Executes formatting, analysis, and Pester checks against the selected workspace root and scan folders.
|
|
6
|
+
#>
|
|
7
|
+
function Invoke-PoshQCSuite {
|
|
8
|
+
[CmdletBinding()]
|
|
9
|
+
param(
|
|
10
|
+
[string] $Root,
|
|
11
|
+
[string[]] $ScanFolders,
|
|
12
|
+
[string] $PssaSettingsPath = $script:PssaSettings,
|
|
13
|
+
[string] $PesterSettingsPath = $script:PesterSettings,
|
|
14
|
+
[string[]] $ExcludeDirs = $script:DefaultExcludedDirs,
|
|
15
|
+
[switch] $DisableKoverageCopy,
|
|
16
|
+
[string] $KoverageOutputPath
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
$ErrorActionPreference = 'Stop'
|
|
20
|
+
|
|
21
|
+
Invoke-PoshQCFormat -Root $Root -ScanFolders $ScanFolders -SettingsPath $PssaSettingsPath -ExcludeDirs $ExcludeDirs
|
|
22
|
+
Invoke-PoshQCAnalyze -Root $Root -ScanFolders $ScanFolders -SettingsPath $PssaSettingsPath -ExcludeDirs $ExcludeDirs
|
|
23
|
+
Invoke-PoshQCTest -Root $Root -ScanFolders $ScanFolders -SettingsPath $PesterSettingsPath -ExcludeDirs $ExcludeDirs -DisableKoverageCopy:$DisableKoverageCopy -KoverageOutputPath $KoverageOutputPath
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
<#
|
|
27
|
+
.SYNOPSIS
|
|
28
|
+
Converts coverage XML paths from absolute to relative.
|
|
29
|
+
.DESCRIPTION
|
|
30
|
+
Rewrites Pester coverage XML file paths to be relative to the repo root for Koverage compatibility.
|
|
31
|
+
.PARAMETER InputPath
|
|
32
|
+
Path to input coverage XML file.
|
|
33
|
+
.PARAMETER OutputPath
|
|
34
|
+
Path to write relative-path coverage XML.
|
|
35
|
+
.PARAMETER RepoRoot
|
|
36
|
+
Repository root directory for path relativization.
|
|
37
|
+
.PARAMETER InputContent
|
|
38
|
+
Alternative to InputPath - provide XML content directly.
|
|
39
|
+
.PARAMETER PassThru
|
|
40
|
+
Return the converted XML content as output.
|
|
41
|
+
#>
|
|
42
|
+
function Convert-PoshQCCoverageToRelative {
|
|
43
|
+
[CmdletBinding()]
|
|
44
|
+
param(
|
|
45
|
+
[Parameter()][string] $InputPath,
|
|
46
|
+
[Parameter()][string] $OutputPath,
|
|
47
|
+
[Parameter()][string] $RepoRoot,
|
|
48
|
+
[Parameter()][string] $InputContent,
|
|
49
|
+
[switch] $PassThru,
|
|
50
|
+
[scriptblock] $ResolvePath = { param([string] $Path) (Resolve-Path -Path $Path -ErrorAction Stop).Path },
|
|
51
|
+
[scriptblock] $JoinPath = { param([string] $Parent, [string] $Child) Join-Path -Path $Parent -ChildPath $Child },
|
|
52
|
+
[scriptblock] $TestPathExists = { param([string] $Path) Test-Path $Path },
|
|
53
|
+
[scriptblock] $ReadContent = { param([string] $Path) Get-Content -Path $Path -Raw },
|
|
54
|
+
[scriptblock] $WriteContent = { param([string] $Path, [string] $Content) Set-Content -Path $Path -Value $Content -Encoding UTF8 },
|
|
55
|
+
[scriptblock] $EnsureDirectory = {
|
|
56
|
+
param([string] $Path)
|
|
57
|
+
$dir = Split-Path -Parent $Path
|
|
58
|
+
if ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
|
59
|
+
},
|
|
60
|
+
[scriptblock] $GetDefaultOutputPath = {
|
|
61
|
+
param([string] $ResolvedInputPath, [string] $ResolvedRoot)
|
|
62
|
+
$coverageDir = if ($ResolvedInputPath) { Split-Path -Parent $ResolvedInputPath } else { $ResolvedRoot }
|
|
63
|
+
$coverageBase = if ($ResolvedInputPath) { [IO.Path]::GetFileNameWithoutExtension($ResolvedInputPath) } else { 'powershell-coverage' }
|
|
64
|
+
Join-Path -Path $coverageDir -ChildPath "$coverageBase.koverage.xml"
|
|
65
|
+
},
|
|
66
|
+
[scriptblock] $Logger = {
|
|
67
|
+
param([string] $Message)
|
|
68
|
+
Write-Information $Message -InformationAction Continue
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
$ErrorActionPreference = 'Stop'
|
|
73
|
+
|
|
74
|
+
if (-not $RepoRoot) {
|
|
75
|
+
$RepoRoot = $PWD.ProviderPath
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (-not $InputPath -and -not $InputContent) {
|
|
79
|
+
& $Logger 'No coverage input provided; skipping conversion.'
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
$resolvedRoot = $RepoRoot
|
|
84
|
+
try {
|
|
85
|
+
$maybeResolvedRoot = & $ResolvePath $RepoRoot
|
|
86
|
+
if ($maybeResolvedRoot) {
|
|
87
|
+
$resolvedRoot = if ($maybeResolvedRoot -is [string]) { $maybeResolvedRoot } else { $maybeResolvedRoot.Path }
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
$resolvedRoot = $RepoRoot
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
$resolvedInputPath = $null
|
|
95
|
+
if ($InputPath) {
|
|
96
|
+
$resolvedInputPath = if ([IO.Path]::IsPathRooted($InputPath)) { $InputPath } else { & $JoinPath $resolvedRoot $InputPath }
|
|
97
|
+
if (-not (& $TestPathExists $resolvedInputPath)) {
|
|
98
|
+
& $Logger "Coverage file not found; skipping Koverage output: $resolvedInputPath"
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (-not $InputContent) {
|
|
103
|
+
$InputContent = & $ReadContent $resolvedInputPath
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
$repoRootClean = ConvertTo-PoshQCPath $resolvedRoot
|
|
108
|
+
# Normalize to forward slashes for consistent regex matching across platforms
|
|
109
|
+
$repoRootNormalized = $repoRootClean -replace '\\', '/'
|
|
110
|
+
$escapedRoot = [regex]::Escape($repoRootNormalized)
|
|
111
|
+
# Replace forward slashes with character class that matches both separators
|
|
112
|
+
$flexiblePattern = $escapedRoot -replace '/', '[\\/]'
|
|
113
|
+
# Match both forward and backslashes after the path
|
|
114
|
+
$escapedPrefixPattern = "$flexiblePattern[\\/]"
|
|
115
|
+
$fixedContent = $InputContent -replace $escapedPrefixPattern, ''
|
|
116
|
+
|
|
117
|
+
if ($PassThru) {
|
|
118
|
+
return $fixedContent
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (-not $OutputPath) {
|
|
122
|
+
$OutputPath = & $GetDefaultOutputPath $resolvedInputPath $resolvedRoot
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
$resolvedOutputPath = if ([IO.Path]::IsPathRooted($OutputPath)) { $OutputPath } else { & $JoinPath $resolvedRoot $OutputPath }
|
|
126
|
+
& $EnsureDirectory $resolvedOutputPath
|
|
127
|
+
& $WriteContent $resolvedOutputPath $fixedContent
|
|
128
|
+
& $Logger "Wrote Koverage coverage copy: $resolvedOutputPath"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
<#
|
|
132
|
+
.SYNOPSIS
|
|
133
|
+
Runs Pester tests with coverage reporting.
|
|
134
|
+
.DESCRIPTION
|
|
135
|
+
Executes Pester tests using repo configuration, generates coverage reports in multiple formats.
|
|
136
|
+
.PARAMETER Root
|
|
137
|
+
Root directory for test discovery. Defaults to current location.
|
|
138
|
+
.PARAMETER ScanFolders
|
|
139
|
+
Optional workspace-relative or workspace-contained folders to scan instead of the entire root.
|
|
140
|
+
.PARAMETER SettingsPath
|
|
141
|
+
Path to Pester configuration file.
|
|
142
|
+
.PARAMETER ExcludeDirs
|
|
143
|
+
Directory names to exclude from test/coverage paths.
|
|
144
|
+
.PARAMETER KoverageOutputPath
|
|
145
|
+
Custom path for Koverage-compatible coverage XML output.
|
|
146
|
+
.PARAMETER DisableKoverageCopy
|
|
147
|
+
Skip creation of Koverage-friendly coverage copy.
|
|
148
|
+
.PARAMETER ScanFolders
|
|
149
|
+
Optional workspace-relative or workspace-contained folders to scan instead of the entire root.
|
|
150
|
+
#>
|
|
151
|
+
function Invoke-PoshQCTest {
|
|
152
|
+
[CmdletBinding()]
|
|
153
|
+
param(
|
|
154
|
+
[string] $Root,
|
|
155
|
+
[string[]] $ScanFolders,
|
|
156
|
+
[string] $SettingsPath = $script:PesterSettings,
|
|
157
|
+
[string[]] $ExcludeDirs = $script:DefaultExcludedDirs,
|
|
158
|
+
[string] $KoverageOutputPath,
|
|
159
|
+
[switch] $DisableKoverageCopy,
|
|
160
|
+
[scriptblock] $EnsureModule = {
|
|
161
|
+
param([string] $Name, [string] $ErrorMessage)
|
|
162
|
+
if (-not (Get-Module -ListAvailable -Name $Name)) { throw $ErrorMessage }
|
|
163
|
+
Import-Module $Name -ErrorAction Stop
|
|
164
|
+
},
|
|
165
|
+
[scriptblock] $TestPathExists = { param([string] $Path) Test-Path $Path },
|
|
166
|
+
[scriptblock] $LoadSettings = { param([string] $Path) Import-PowerShellDataFile -Path $Path },
|
|
167
|
+
[scriptblock] $BuildConfiguration = { param($Settings) New-PesterConfiguration -Hashtable $Settings },
|
|
168
|
+
[scriptblock] $ExpandRunPaths = {
|
|
169
|
+
param($Config, [string] $RootPath, [string[]] $Excluded)
|
|
170
|
+
$initialPaths = if ($Config.Run.Path -is [System.Array]) { @($Config.Run.Path) } elseif ($Config.Run.Path -and $Config.Run.Path.Value) { @($Config.Run.Path.Value) } else { @() }
|
|
171
|
+
if ($initialPaths) {
|
|
172
|
+
$resolvedPaths = @(
|
|
173
|
+
$initialPaths |
|
|
174
|
+
ForEach-Object { Join-Path $RootPath $_ } |
|
|
175
|
+
Where-Object { $Excluded -notcontains (Split-Path -Path $_ -Leaf) }
|
|
176
|
+
)
|
|
177
|
+
$Config.Run.Path = $resolvedPaths
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if ($Excluded) {
|
|
181
|
+
$excludedPaths = @($Excluded | ForEach-Object { Join-Path $RootPath $_ })
|
|
182
|
+
$existingExclude = if ($Config.Run.ExcludePath -is [System.Array]) { @($Config.Run.ExcludePath | ForEach-Object { Join-Path $RootPath $_ }) } elseif ($Config.Run.ExcludePath -and $Config.Run.ExcludePath.Value) { @($Config.Run.ExcludePath.Value | ForEach-Object { Join-Path $RootPath $_ }) } else { @() }
|
|
183
|
+
$Config.Run.ExcludePath = $existingExclude + $excludedPaths
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
$Config
|
|
187
|
+
},
|
|
188
|
+
[scriptblock] $EnsureResultPath = {
|
|
189
|
+
param($Config, [string] $RootPath)
|
|
190
|
+
if ($Config.TestResult.Enabled.Value -and $Config.TestResult.OutputPath.Value) {
|
|
191
|
+
$resultPath = $Config.TestResult.OutputPath.Value
|
|
192
|
+
$resultDir = Split-Path -Parent $resultPath
|
|
193
|
+
if (-not [string]::IsNullOrWhiteSpace($resultDir)) {
|
|
194
|
+
$resolvedResultDir = if ([IO.Path]::IsPathRooted($resultDir)) { $resultDir } else { Join-Path $RootPath $resultDir }
|
|
195
|
+
New-Item -ItemType Directory -Path $resolvedResultDir -Force | Out-Null
|
|
196
|
+
}
|
|
197
|
+
$Config.TestResult.OutputPath = if ([IO.Path]::IsPathRooted($resultPath)) {
|
|
198
|
+
$resultPath
|
|
199
|
+
} else {
|
|
200
|
+
Join-Path $RootPath $resultPath
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
$Config
|
|
204
|
+
},
|
|
205
|
+
[scriptblock] $ResolveScanFolders = {
|
|
206
|
+
param([string] $RootPath, [string[]] $Folders)
|
|
207
|
+
Resolve-PoshQCScanFolder -Root $RootPath -ScanFolders $Folders
|
|
208
|
+
},
|
|
209
|
+
[scriptblock] $ExpandCoveragePaths = {
|
|
210
|
+
param($Config, [string] $RootPath)
|
|
211
|
+
if (-not $Config.CodeCoverage) { return $Config }
|
|
212
|
+
|
|
213
|
+
if ($Config.CodeCoverage.Path.Value) {
|
|
214
|
+
$Config.CodeCoverage.Path = @(
|
|
215
|
+
$Config.CodeCoverage.Path.Value | ForEach-Object { if ([IO.Path]::IsPathRooted($_)) { $_ } else { Join-Path $RootPath $_ } }
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if ($Config.CodeCoverage.OutputPath.Value) {
|
|
220
|
+
$coveragePath = $Config.CodeCoverage.OutputPath.Value
|
|
221
|
+
$coverageDir = Split-Path -Parent $coveragePath
|
|
222
|
+
if (-not [string]::IsNullOrWhiteSpace($coverageDir)) {
|
|
223
|
+
$resolvedCoverageDir = if ([IO.Path]::IsPathRooted($coverageDir)) { $coverageDir } else { Join-Path $RootPath $coverageDir }
|
|
224
|
+
New-Item -ItemType Directory -Path $resolvedCoverageDir -Force | Out-Null
|
|
225
|
+
}
|
|
226
|
+
$Config.CodeCoverage.OutputPath = if ([IO.Path]::IsPathRooted($coveragePath)) {
|
|
227
|
+
$coveragePath
|
|
228
|
+
} else {
|
|
229
|
+
Join-Path $RootPath $coveragePath
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
$Config
|
|
234
|
+
},
|
|
235
|
+
[scriptblock] $EnumerateTests = {
|
|
236
|
+
param([string[]] $Paths, [string[]] $Excluded, [scriptblock] $TestPathFn)
|
|
237
|
+
$tests = @()
|
|
238
|
+
foreach ($path in $Paths) {
|
|
239
|
+
if (-not (& $TestPathFn $path)) { continue }
|
|
240
|
+
$tests += Get-ChildItem -Path $path -Recurse -Include *.Tests.ps1 | Where-Object {
|
|
241
|
+
$parts = $_.FullName -split '[\\/]+' | Where-Object { $_ -ne '' }
|
|
242
|
+
foreach ($dir in $Excluded) {
|
|
243
|
+
if ($parts -contains $dir) { return $false }
|
|
244
|
+
}
|
|
245
|
+
return $true
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
@($tests | Sort-Object -Property FullName -Stable)
|
|
249
|
+
},
|
|
250
|
+
[scriptblock] $Logger = {
|
|
251
|
+
param([string] $Message)
|
|
252
|
+
# Use Write-Information so the replayed summary stays visible while respecting approved verbs.
|
|
253
|
+
Write-Information $Message -InformationAction Continue
|
|
254
|
+
},
|
|
255
|
+
[scriptblock] $InvokePester = { param($Config) Invoke-Pester -Configuration $Config },
|
|
256
|
+
[scriptblock] $CopyCoverage = {
|
|
257
|
+
param([string] $CoveragePath, [string] $RepoRoot, [string] $KoveragePath)
|
|
258
|
+
Convert-PoshQCCoverageToRelative -InputPath $CoveragePath -OutputPath $KoveragePath -RepoRoot $RepoRoot
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
$ErrorActionPreference = 'Stop'
|
|
263
|
+
|
|
264
|
+
if (-not $Root) {
|
|
265
|
+
$Root = $PWD.ProviderPath
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
& $EnsureModule 'Pester' "Pester is not installed. Run Install-PoshQCTool (alias Install-PoshQCTools) first."
|
|
269
|
+
|
|
270
|
+
if (-not (& $TestPathExists $SettingsPath)) {
|
|
271
|
+
throw "Settings not found: $SettingsPath"
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
$settings = & $LoadSettings $SettingsPath
|
|
275
|
+
$config = & $BuildConfiguration $settings
|
|
276
|
+
$config = & $ExpandRunPaths $config $Root $ExcludeDirs
|
|
277
|
+
$config = & $EnsureResultPath $config $Root
|
|
278
|
+
$config = & $ExpandCoveragePaths $config $Root
|
|
279
|
+
if ($ScanFolders -and $ScanFolders.Count -gt 0) {
|
|
280
|
+
$resolvedScanFolders = @(& $ResolveScanFolders $Root $ScanFolders)
|
|
281
|
+
if ($resolvedScanFolders.Count -gt 0) {
|
|
282
|
+
$config.Run.Path = $resolvedScanFolders
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
# Reduce console noise from Pester while we replay a concise summary at the end.
|
|
287
|
+
if ($config.Output -and $config.Output.Verbosity) {
|
|
288
|
+
$config.Output.Verbosity = 'Normal'
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (-not $config.Run.PassThru) {
|
|
292
|
+
$config.Run.PassThru = $true
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
$coverageEnabled = $false
|
|
296
|
+
if ($config.CodeCoverage) {
|
|
297
|
+
if ($config.CodeCoverage.Enabled -is [bool]) {
|
|
298
|
+
$coverageEnabled = $config.CodeCoverage.Enabled
|
|
299
|
+
} elseif ($config.CodeCoverage.Enabled -and $config.CodeCoverage.Enabled.Value) {
|
|
300
|
+
$coverageEnabled = [bool]$config.CodeCoverage.Enabled.Value
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if ($coverageEnabled -and $config.CodeCoverage) {
|
|
305
|
+
if ($config.CodeCoverage.Path.Value) {
|
|
306
|
+
$resolvedCoveragePaths = @(
|
|
307
|
+
$config.CodeCoverage.Path.Value |
|
|
308
|
+
ForEach-Object {
|
|
309
|
+
if ([IO.Path]::IsPathRooted($_)) { $_ } else { Join-Path $Root $_ }
|
|
310
|
+
}
|
|
311
|
+
)
|
|
312
|
+
$config.CodeCoverage.Path = $resolvedCoveragePaths
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if ($config.CodeCoverage.OutputPath.Value) {
|
|
316
|
+
$coveragePath = $config.CodeCoverage.OutputPath.Value
|
|
317
|
+
$coverageDir = Split-Path -Parent $coveragePath
|
|
318
|
+
if (-not [string]::IsNullOrWhiteSpace($coverageDir)) {
|
|
319
|
+
$resolvedCoverageDir = if ([IO.Path]::IsPathRooted($coverageDir)) { $coverageDir } else { Join-Path $Root $coverageDir }
|
|
320
|
+
New-Item -ItemType Directory -Path $resolvedCoverageDir -Force | Out-Null
|
|
321
|
+
}
|
|
322
|
+
$config.CodeCoverage.OutputPath = if ([IO.Path]::IsPathRooted($coveragePath)) {
|
|
323
|
+
$coveragePath
|
|
324
|
+
} else {
|
|
325
|
+
Join-Path $Root $coveragePath
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
$coverageOutputPath = $null
|
|
331
|
+
if ($config.CodeCoverage) {
|
|
332
|
+
if ($config.CodeCoverage.OutputPath -is [string]) {
|
|
333
|
+
$coverageOutputPath = $config.CodeCoverage.OutputPath
|
|
334
|
+
} elseif ($config.CodeCoverage.OutputPath -and $config.CodeCoverage.OutputPath.Value) {
|
|
335
|
+
$coverageOutputPath = $config.CodeCoverage.OutputPath.Value
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
$runPaths = if ($config.Run.Path -is [System.Array]) { [string[]]$config.Run.Path } elseif ($config.Run.Path -and $config.Run.Path.Value) { [string[]]$config.Run.Path.Value } else { @() }
|
|
340
|
+
$testFiles = & $EnumerateTests $runPaths $ExcludeDirs $TestPathExists
|
|
341
|
+
if (-not $testFiles) {
|
|
342
|
+
& $Logger "No Pester test files found under configured paths for root $Root"
|
|
343
|
+
return
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
$pesterResult = & $InvokePester $config
|
|
347
|
+
|
|
348
|
+
$shouldEmitKoverageCopy = -not $DisableKoverageCopy
|
|
349
|
+
if ($shouldEmitKoverageCopy -and $coverageEnabled -and $coverageOutputPath) {
|
|
350
|
+
$derivedKoveragePath = $null
|
|
351
|
+
if ($coverageOutputPath) {
|
|
352
|
+
$coverageBaseName = [IO.Path]::GetFileNameWithoutExtension($coverageOutputPath)
|
|
353
|
+
$coverageParent = Split-Path -Parent $coverageOutputPath
|
|
354
|
+
$derivedKoveragePath = Join-Path $coverageParent "$coverageBaseName.koverage.xml"
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
$effectiveKoveragePath = if ($PSBoundParameters.ContainsKey('KoverageOutputPath') -and -not [string]::IsNullOrWhiteSpace($KoverageOutputPath)) {
|
|
358
|
+
$KoverageOutputPath
|
|
359
|
+
} else {
|
|
360
|
+
$derivedKoveragePath
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
& $CopyCoverage $coverageOutputPath $Root $effectiveKoveragePath
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if ($pesterResult) {
|
|
367
|
+
$durationSeconds = [math]::Round($pesterResult.Duration.TotalSeconds, 2)
|
|
368
|
+
$testsSummary = "Tests completed in {0:N2}s" -f $durationSeconds
|
|
369
|
+
$countsSummary = "Tests Passed: {0}, Failed: {1}, Skipped: {2}, Inconclusive: {3}, NotRun: {4}" -f `
|
|
370
|
+
$pesterResult.PassedCount, `
|
|
371
|
+
$pesterResult.FailedCount, `
|
|
372
|
+
$pesterResult.SkippedCount, `
|
|
373
|
+
$pesterResult.InconclusiveCount, `
|
|
374
|
+
$pesterResult.NotRunCount
|
|
375
|
+
|
|
376
|
+
$coverageLines = $null
|
|
377
|
+
if ($coverageEnabled -and $pesterResult.CodeCoverage) {
|
|
378
|
+
$coverageReport = $pesterResult.CodeCoverage.CoverageReport
|
|
379
|
+
if ($coverageReport -is [string] -and -not [string]::IsNullOrWhiteSpace($coverageReport)) {
|
|
380
|
+
$rawCoverageLines = @($coverageReport -split "`r?`n")
|
|
381
|
+
$trimmedCoverageLines = @()
|
|
382
|
+
|
|
383
|
+
foreach ($line in $rawCoverageLines) {
|
|
384
|
+
if ([string]::IsNullOrWhiteSpace($line)) { continue }
|
|
385
|
+
if ($line -match '^\s*Missed commands') { break }
|
|
386
|
+
$trimmedCoverageLines += $line.TrimEnd()
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (-not $trimmedCoverageLines -and $rawCoverageLines) {
|
|
390
|
+
$trimmedCoverageLines = @($rawCoverageLines[0])
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if ($trimmedCoverageLines) {
|
|
394
|
+
$coverageLines = $trimmedCoverageLines
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
& $Logger ''
|
|
400
|
+
& $Logger 'Pester summary (replayed for readability):'
|
|
401
|
+
& $Logger $testsSummary
|
|
402
|
+
& $Logger $countsSummary
|
|
403
|
+
if ($coverageLines) {
|
|
404
|
+
foreach ($line in $coverageLines) {
|
|
405
|
+
& $Logger $line
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
@{
|
|
2
|
+
RootModule = 'PoshQC.psm1'
|
|
3
|
+
ModuleVersion = '0.1.1'
|
|
4
|
+
GUID = '6a9b1a8b-1e8b-4c1f-9d6a-34b8e8c2f0e4'
|
|
5
|
+
Author = 'Dan Moisan'
|
|
6
|
+
CompanyName = 'Dan Moisan'
|
|
7
|
+
Copyright = '(c) Dan Moisan. All rights reserved.'
|
|
8
|
+
Description = 'Reusable PowerShell QC helpers (format, analyze, test) using Invoke-Formatter, PSScriptAnalyzer, and Pester.'
|
|
9
|
+
PowerShellVersion = '5.1'
|
|
10
|
+
CompatiblePSEditions = @('Desktop', 'Core')
|
|
11
|
+
RequiredModules = @(
|
|
12
|
+
@{ ModuleName = 'PSScriptAnalyzer'; ModuleVersion = '1.22.0' },
|
|
13
|
+
@{ ModuleName = 'Pester'; ModuleVersion = '5.6.1' }
|
|
14
|
+
)
|
|
15
|
+
FunctionsToExport = @(
|
|
16
|
+
'Convert-PoshQCCoverageToRelative',
|
|
17
|
+
'Get-PoshQCFileList',
|
|
18
|
+
'Install-PoshQCTool',
|
|
19
|
+
'Invoke-PoshQCFormat',
|
|
20
|
+
'Invoke-PoshQCAnalyze',
|
|
21
|
+
'Invoke-PoshQCAnalyzeAutofix',
|
|
22
|
+
'Invoke-PoshQCSuite',
|
|
23
|
+
'Invoke-PoshQCTest'
|
|
24
|
+
)
|
|
25
|
+
CmdletsToExport = @()
|
|
26
|
+
VariablesToExport = @()
|
|
27
|
+
AliasesToExport = @('Install-PoshQCTools')
|
|
28
|
+
PrivateData = @{}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
$script:ModuleRoot = Split-Path -Parent $PSCommandPath
|
|
2
|
+
$script:PssaSettings = Join-Path $ModuleRoot 'settings/pssa.settings.psd1'
|
|
3
|
+
$script:PesterSettings = Join-Path $ModuleRoot 'settings/pester.runsettings.psd1'
|
|
4
|
+
|
|
5
|
+
$script:DefaultExcludedDirs = @(
|
|
6
|
+
'.git', '.venv', 'venv', 'node_modules', 'dist', 'build', '.pytest_cache',
|
|
7
|
+
'__pycache__', '.mypy_cache', '.ruff_cache', '.vscode', '.idea', 'artifacts',
|
|
8
|
+
'.vscode-test'
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
<#
|
|
12
|
+
.SYNOPSIS
|
|
13
|
+
Installs PoshQC dependencies (PSScriptAnalyzer and Pester).
|
|
14
|
+
.DESCRIPTION
|
|
15
|
+
Ensures PSGallery is trusted and installs required module versions in the CurrentUser scope.
|
|
16
|
+
#>
|
|
17
|
+
function Install-PoshQCTool {
|
|
18
|
+
[CmdletBinding()]
|
|
19
|
+
param(
|
|
20
|
+
[scriptblock] $SetTls = { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 },
|
|
21
|
+
[scriptblock] $GetRepository = { param([string] $Name) Get-PSRepository -Name $Name -ErrorAction SilentlyContinue },
|
|
22
|
+
[scriptblock] $RegisterRepository = { Register-PSRepository -Default -InstallationPolicy Trusted },
|
|
23
|
+
[scriptblock] $SetRepository = { param([string] $Name, [string] $Policy) Set-PSRepository -Name $Name -InstallationPolicy $Policy -ErrorAction Stop },
|
|
24
|
+
[scriptblock] $FindModule = { param([string] $Name) Get-Module -ListAvailable -Name $Name },
|
|
25
|
+
[scriptblock] $InstallModule = { param([string] $Name, [string] $Version) Install-Module -Name $Name -RequiredVersion $Version -Scope CurrentUser -AllowClobber -Force },
|
|
26
|
+
[scriptblock] $Logger = {
|
|
27
|
+
param([string] $Message, [string] $Level = 'Information')
|
|
28
|
+
switch ($Level) {
|
|
29
|
+
'Warning' { Write-Warning $Message }
|
|
30
|
+
'Verbose' { Write-Verbose $Message }
|
|
31
|
+
default { Write-Information $Message -InformationAction Continue }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
$ErrorActionPreference = 'Stop'
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
& $SetTls
|
|
40
|
+
} catch {
|
|
41
|
+
& $Logger "Unable to enforce TLS 1.2 for module install: $($_.Exception.Message)" 'Verbose'
|
|
42
|
+
}
|
|
43
|
+
$gallery = & $GetRepository 'PSGallery'
|
|
44
|
+
if (-not $gallery) {
|
|
45
|
+
& $Logger 'PSGallery not found; registering.'
|
|
46
|
+
& $RegisterRepository
|
|
47
|
+
} elseif ($gallery.InstallationPolicy -ne 'Trusted') {
|
|
48
|
+
try {
|
|
49
|
+
& $SetRepository 'PSGallery' 'Trusted'
|
|
50
|
+
} catch {
|
|
51
|
+
& $Logger 'Could not set PSGallery as trusted automatically. You may be prompted during install.' 'Warning'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
$requiredModules = @(
|
|
56
|
+
@{ Name = 'PSScriptAnalyzer'; Version = '1.22.0' },
|
|
57
|
+
@{ Name = 'Pester'; Version = '5.6.1' }
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
foreach ($module in $requiredModules) {
|
|
61
|
+
$installed = & $FindModule $module.Name | Where-Object { $_.Version -ge [version]$module.Version } | Select-Object -First 1
|
|
62
|
+
if ($installed) {
|
|
63
|
+
& $Logger "$($module.Name) $($installed.Version) already present."
|
|
64
|
+
continue
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
& $Logger "Installing $($module.Name) $($module.Version) (CurrentUser scope)..."
|
|
68
|
+
try {
|
|
69
|
+
& $InstallModule $module.Name $module.Version
|
|
70
|
+
} catch {
|
|
71
|
+
throw "Failed to install $($module.Name) $($module.Version): $($_.Exception.Message)"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
$post = & $FindModule $module.Name | Where-Object { $_.Version -ge [version]$module.Version } | Select-Object -First 1
|
|
75
|
+
if (-not $post) {
|
|
76
|
+
throw "Failed to install $($module.Name) $($module.Version)."
|
|
77
|
+
}
|
|
78
|
+
& $Logger "$($module.Name) $($module.Version) installed."
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# PowerShell 7.6+ treats dot-sourced .psm1 files as isolated modules, so
|
|
83
|
+
# functions defined in them do not enter the parent module scope. Loading the
|
|
84
|
+
# file content as a scriptblock bypasses that behaviour.
|
|
85
|
+
. ([scriptblock]::Create((Get-Content (Join-Path $script:ModuleRoot 'PoshQC.FileDiscovery.psm1') -Raw)))
|
|
86
|
+
. ([scriptblock]::Create((Get-Content (Join-Path $script:ModuleRoot 'PoshQC.Analyzer.psm1') -Raw)))
|
|
87
|
+
. ([scriptblock]::Create((Get-Content (Join-Path $script:ModuleRoot 'PoshQC.Testing.psm1') -Raw)))
|
|
88
|
+
|
|
89
|
+
Set-Alias -Name Install-PoshQCTools -Value Install-PoshQCTool
|
|
90
|
+
|
|
91
|
+
Export-ModuleMember -Function @(
|
|
92
|
+
'Get-PoshQCFileList',
|
|
93
|
+
'Install-PoshQCTool',
|
|
94
|
+
'Invoke-PoshQCFormat',
|
|
95
|
+
'Invoke-PoshQCAnalyze',
|
|
96
|
+
'Invoke-PoshQCAnalyzeAutofix',
|
|
97
|
+
'Invoke-PoshQCSuite',
|
|
98
|
+
'Invoke-PoshQCTest',
|
|
99
|
+
'Convert-PoshQCCoverageToRelative'
|
|
100
|
+
) -Alias @('Install-PoshQCTools')
|
|
101
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# PoshQC
|
|
2
|
+
|
|
3
|
+
PoshQC is a lightweight PowerShell quality gate that wraps Invoke-Formatter, PSScriptAnalyzer, and Pester with repo-safe defaults. It targets both Windows PowerShell 5.1 and PowerShell 7.6+.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- Formats PowerShell code with consistent indentation and pipeline alignment.
|
|
8
|
+
- Lints with PSScriptAnalyzer using a strict, dual-runtime ruleset.
|
|
9
|
+
- Runs Pester tests with code coverage (CoverageGutters output), plus an optional Koverage-friendly copy.
|
|
10
|
+
- Provides a single suite entry point that can format, analyze, and test a selected workspace scope.
|
|
11
|
+
- Provides a one-time dependency installer for PSScriptAnalyzer and Pester.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- PowerShell 5.1 or 7.6+
|
|
16
|
+
- Modules: PSScriptAnalyzer 1.22.0, Pester 5.6.1 (installed automatically via the helper if missing)
|
|
17
|
+
|
|
18
|
+
## Getting started
|
|
19
|
+
|
|
20
|
+
1) Install dependencies (CurrentUser scope):
|
|
21
|
+
|
|
22
|
+
```powershell
|
|
23
|
+
Import-Module ./PoshQC.psm1
|
|
24
|
+
Install-PoshQCTool # alias: Install-PoshQCTools
|
|
25
|
+
```
|
|
26
|
+
2) Format everything under the repo root:
|
|
27
|
+
|
|
28
|
+
```powershell
|
|
29
|
+
Import-Module ./PoshQC.psm1
|
|
30
|
+
Invoke-PoshQCFormat -Root .
|
|
31
|
+
```
|
|
32
|
+
3) Lint with PSScriptAnalyzer:
|
|
33
|
+
|
|
34
|
+
```powershell
|
|
35
|
+
Invoke-PoshQCAnalyze -Root .
|
|
36
|
+
```
|
|
37
|
+
4) Test with Pester + coverage:
|
|
38
|
+
|
|
39
|
+
```powershell
|
|
40
|
+
Invoke-PoshQCTest -Root .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
5) Run the full suite against a selected scope:
|
|
44
|
+
|
|
45
|
+
```powershell
|
|
46
|
+
Import-Module ./PoshQC.psm1
|
|
47
|
+
Invoke-PoshQCSuite -Root . -ScanFolders @('scripts', 'tests/powershell')
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- Writes JUnit XML to `artifacts/pester/pester-junit.xml`.
|
|
51
|
+
- Writes CoverageGutters XML to `artifacts/pester/powershell-coverage.xml`.
|
|
52
|
+
- Also emits `*.koverage.xml` (relative paths) for VS Code Coverage Gutters and Koverage. Disable with `-DisableKoverageCopy` or override the path with `-KoverageOutputPath`.
|
|
53
|
+
|
|
54
|
+
## Functions
|
|
55
|
+
|
|
56
|
+
- `Install-PoshQCTool` / `Install-PoshQCTools`: install required modules.
|
|
57
|
+
- `Invoke-PoshQCFormat`: run Invoke-Formatter across the repo, honoring exclusions.
|
|
58
|
+
- `Invoke-PoshQCAnalyze`: run PSScriptAnalyzer with the bundled settings.
|
|
59
|
+
- `Invoke-PoshQCSuite`: run format, analyze, and test in one pass, optionally narrowing the scan scope with `-ScanFolders`.
|
|
60
|
+
- `Invoke-PoshQCTest`: run Pester using the bundled runsettings, including coverage and optional Koverage copy.
|
|
61
|
+
- `Convert-PoshQCCoverageToRelative`: utility to strip repo-root prefixes and write a `.koverage.xml` copy (used internally by `Invoke-PoshQCTest`).
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
- PSScriptAnalyzer settings: `./settings/pssa.settings.psd1`
|
|
66
|
+
- Enforces compatible syntax for 5.1 and 7.6, 4-space indentation, ShouldProcess for state-changing functions, and safety guards (no Invoke-Expression, no global vars, etc.).
|
|
67
|
+
- Pester settings: `./settings/pester.runsettings.psd1`
|
|
68
|
+
- Runs tests under `scripts` and `tests/powershell`, outputs JUnit XML and CoverageGutters coverage, and enables coverage over `scripts/dev-tools/*.ps1`, `scripts/powershell/**/*.psm1`, and `src/**/*.ps1`.
|
|
69
|
+
- When `-ScanFolders` is supplied to `Invoke-PoshQCSuite` or the lower-level commands, the suite narrows discovery to those workspace-relative or workspace-contained folders.
|
|
70
|
+
|
|
71
|
+
## Typical workflow
|
|
72
|
+
|
|
73
|
+
- Day-to-day: run `Invoke-PoshQCFormat`, `Invoke-PoshQCAnalyze`, then `Invoke-PoshQCTest` before committing.
|
|
74
|
+
- Bundled / scoped: run `Invoke-PoshQCSuite -Root . -ScanFolders @('scripts', 'tests/powershell')` when you want the suite to focus on selected workspace folders.
|
|
75
|
+
- CI: call `Invoke-PoshQCTest` to get tests + coverage and consume JUnit/CoverageGutters artifacts.
|
|
76
|
+
|
|
77
|
+
## Notes for standalone use
|
|
78
|
+
|
|
79
|
+
- Place `PoshQC.psm1`, `PoshQC.psd1`, and the `settings/` folder together; import the module from that directory.
|
|
80
|
+
- Adjust `settings/pester.runsettings.psd1` and `settings/pssa.settings.psd1` to match your repo paths and policies.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
@{
|
|
2
|
+
Run = @{
|
|
3
|
+
Path = @('scripts', 'tests/powershell', 'tests/scripts')
|
|
4
|
+
Exit = $true
|
|
5
|
+
}
|
|
6
|
+
Should = @{
|
|
7
|
+
ErrorAction = 'Stop'
|
|
8
|
+
}
|
|
9
|
+
Output = @{
|
|
10
|
+
Verbosity = 'Detailed'
|
|
11
|
+
}
|
|
12
|
+
TestResult = @{
|
|
13
|
+
Enabled = $true
|
|
14
|
+
OutputFormat = 'JUnitXml'
|
|
15
|
+
OutputPath = 'artifacts/pester/pester-junit.xml'
|
|
16
|
+
}
|
|
17
|
+
CodeCoverage = @{
|
|
18
|
+
Enabled = $true
|
|
19
|
+
# Use Pester's CoverageGutters format so VS Code Coverage Gutters
|
|
20
|
+
# can map file paths correctly.
|
|
21
|
+
OutputFormat = 'CoverageGutters'
|
|
22
|
+
OutputPath = 'artifacts/pester/powershell-coverage.xml'
|
|
23
|
+
Path = @(
|
|
24
|
+
'.claude/hooks/validate-bash.ps1'
|
|
25
|
+
'.claude/hooks/check-python-test-purity.ps1'
|
|
26
|
+
'.claude/hooks/check-powershell-test-purity.ps1'
|
|
27
|
+
'.claude/hooks/enforce-python-batch-budget.ps1'
|
|
28
|
+
'.claude/hooks/enforce-powershell-batch-budget.ps1'
|
|
29
|
+
)
|
|
30
|
+
ExcludedPath = @(
|
|
31
|
+
'.claude/hooks/validate-feature-review-coverage.ps1' # Feature-review wrapper around repository evidence; not deterministic in normal unit-test execution.
|
|
32
|
+
'scripts/dev-tools/bootstrap-host.ps1' # Host bootstrap entrypoint for external setup; not deterministic in normal unit-test execution.
|
|
33
|
+
'scripts/dev-tools/bootstrap-host.helpers.ps1' # Bootstrap helper for host setup; not deterministic in normal unit-test execution.
|
|
34
|
+
'scripts/dev-tools/format-powershell.ps1' # Thin formatter wrapper around external tooling; not deterministic in normal unit-test execution.
|
|
35
|
+
'scripts/dev-tools/load-openai-key.ps1' # Local secret-loading wrapper; not deterministic in normal unit-test execution.
|
|
36
|
+
'scripts/dev-tools/publish-sideloaded-extension.ps1' # VS Code extension publication wrapper; not deterministic in normal unit-test execution.
|
|
37
|
+
'scripts/dev-tools/run-actionlint.ps1' # External actionlint wrapper; not deterministic in normal unit-test execution.
|
|
38
|
+
'scripts/dev-tools/run-pester.ps1' # Pester CLI wrapper; not deterministic in normal unit-test execution.
|
|
39
|
+
'scripts/dev-tools/run-poshqc-suite.ps1' # PoshQC CLI wrapper; not deterministic in normal unit-test execution.
|
|
40
|
+
'scripts/dev-tools/run-psscriptanalyzer.ps1' # PSScriptAnalyzer CLI wrapper; not deterministic in normal unit-test execution.
|
|
41
|
+
'scripts/dev-tools/verify-host.ps1' # Host verification wrapper for local tools; not deterministic in normal unit-test execution.
|
|
42
|
+
'scripts/dev-tools/vscode-cli.helpers.ps1' # VS Code CLI helper around external processes; not deterministic in normal unit-test execution.
|
|
43
|
+
'scripts/powershell/PoshQC/PoshQC.Analyzer.psm1' # Analyzer orchestration module over external tooling; not deterministic in normal unit-test execution.
|
|
44
|
+
'scripts/powershell/PoshQC/PoshQC.FileDiscovery.psm1' # File-discovery module coupled to workspace traversal; not deterministic in normal unit-test execution.
|
|
45
|
+
'scripts/powershell/PoshQC/PoshQC.Testing.psm1' # Pester orchestration module over external tooling; not deterministic in normal unit-test execution.
|
|
46
|
+
)
|
|
47
|
+
# Optional: don't fail the run on coverage percentage
|
|
48
|
+
CoveragePercentTarget = 0
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|