@danmoisan/drm-copilot-mcp 1.1.17 → 1.1.19

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.
Files changed (225) hide show
  1. package/out/mcp-server.js +1405 -684
  2. package/package.json +6 -4
  3. package/resources/claude-customizations/.claude/agents/atomic-executor.md +11 -0
  4. package/resources/claude-customizations/.claude/agents/atomic-planner.md +10 -0
  5. package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +12 -4
  6. package/resources/claude-customizations/.claude/agents/epic-planner.md +5 -4
  7. package/resources/claude-customizations/.claude/agents/feature-review.md +16 -5
  8. package/resources/claude-customizations/.claude/agents/orchestrator.md +21 -7
  9. package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +37 -13
  10. package/resources/claude-customizations/.claude/agents/parallel-planner.md +9 -6
  11. package/resources/claude-customizations/.claude/agents/pr-author.md +15 -2
  12. package/resources/claude-customizations/.claude/agents/prd-feature.md +1 -1
  13. package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +7 -1
  14. package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +7 -1
  15. package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
  16. package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +111 -46
  17. package/resources/claude-customizations/.claude/hooks/enforce-completion-helpers.ps1 +105 -0
  18. package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +8 -1
  19. package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +7 -1
  20. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-resolution.ps1 +116 -59
  21. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +55 -23
  22. package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +74 -75
  23. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +127 -35
  24. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +61 -57
  25. package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +7 -1
  26. package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +129 -39
  27. package/resources/claude-customizations/.claude/hooks/enforce-mermaid-validation.ps1 +7 -1
  28. package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +9 -3
  29. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +39 -51
  30. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
  31. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
  32. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
  33. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +17 -12
  34. package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +9 -3
  35. package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +65 -50
  36. package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +49 -42
  37. package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +54 -72
  38. package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +8 -2
  39. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +279 -0
  40. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +129 -75
  41. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.artifact-root.ps1 +233 -0
  42. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +224 -0
  43. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +69 -24
  44. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1 +29 -18
  45. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +10 -4
  46. package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +14 -5
  47. package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +8 -2
  48. package/resources/claude-customizations/.claude/hooks/feature-folder-resolution.ps1 +373 -0
  49. package/resources/claude-customizations/.claude/hooks/feature-review-coverage-thresholds.ps1 +85 -0
  50. package/resources/claude-customizations/.claude/hooks/hook-command-heredoc.ps1 +119 -0
  51. package/resources/claude-customizations/.claude/hooks/hook-command-invocation-operands.ps1 +198 -0
  52. package/resources/claude-customizations/.claude/hooks/hook-command-invocation.ps1 +254 -255
  53. package/resources/claude-customizations/.claude/hooks/hook-command-payload-powershell.ps1 +201 -0
  54. package/resources/claude-customizations/.claude/hooks/hook-command-payload.ps1 +484 -0
  55. package/resources/claude-customizations/.claude/hooks/hook-command-scanner.ps1 +27 -110
  56. package/resources/claude-customizations/.claude/hooks/hook-dependency-guard.ps1 +114 -0
  57. package/resources/claude-customizations/.claude/hooks/hook-docs-only-diff.ps1 +493 -0
  58. package/resources/claude-customizations/.claude/hooks/subagentstop-envelope.ps1 +192 -0
  59. package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +9 -3
  60. package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +40 -42
  61. package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +66 -38
  62. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-metrics.ps1 +180 -0
  63. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +195 -0
  64. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +141 -395
  65. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-resolution.ps1 +311 -0
  66. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-routing.ps1 +170 -0
  67. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +115 -190
  68. package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +64 -32
  69. package/resources/claude-customizations/.claude/hooks/validate-pr-author-output.ps1 +39 -44
  70. package/resources/claude-customizations/.claude/hooks/validate-prd-feature-output.ps1 +43 -14
  71. package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +66 -36
  72. package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +31 -34
  73. package/resources/claude-customizations/.claude/lib/bash/mutate-parallel-run.sh +191 -0
  74. package/resources/claude-customizations/.claude/lib/bash/parallel-cohorts.sh +13 -3
  75. package/resources/claude-customizations/.claude/lib/bash/parallel-lane-assertion.sh +4 -2
  76. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-cli.sh +152 -0
  77. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-ops.sh +193 -0
  78. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation.sh +322 -0
  79. package/resources/claude-customizations/.claude/lib/bash/remove-parallel-item.sh +146 -0
  80. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +23 -33
  81. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +86 -6
  82. package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-CiGateParser.ps1 +91 -19
  83. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1 +6 -13
  84. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateEpicWaveBarrier.psm1 +346 -0
  85. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +396 -0
  86. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateReceipts.psm1 +22 -15
  87. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRemediationAccounting.psm1 +337 -0
  88. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRoutingContract.psm1 +9 -1
  89. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +79 -2
  90. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +3 -3
  91. package/resources/claude-customizations/.claude/rules/architecture-boundaries.md +5 -5
  92. package/resources/claude-customizations/.claude/rules/csharp.md +2 -2
  93. package/resources/claude-customizations/.claude/rules/general-code-change.md +1 -1
  94. package/resources/claude-customizations/.claude/rules/general-unit-test.md +3 -2
  95. package/resources/claude-customizations/.claude/rules/orchestrator-state.md +153 -4
  96. package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +50 -5
  97. package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +47 -8
  98. package/resources/claude-customizations/.claude/rules/quality-tiers.md +11 -7
  99. package/resources/claude-customizations/.claude/rules/shell.md +10 -8
  100. package/resources/claude-customizations/.claude/rules/typescript.md +1 -1
  101. package/resources/claude-customizations/.claude/settings.json +3 -4
  102. package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +9 -1
  103. package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +7 -1
  104. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +11 -3
  105. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup-worktrees.sh +11 -2
  106. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_detached_lib.sh +1 -1
  107. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_enumerate_lib.sh +171 -5
  108. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_lib.sh +1 -1
  109. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_report_records_lib.sh +6 -43
  110. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh +6 -15
  111. package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +45 -11
  112. package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +1 -1
  113. package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +13 -0
  114. package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +10 -0
  115. package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +7 -4
  116. package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +42 -16
  117. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +52 -14
  118. package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +22 -9
  119. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +97 -19
  120. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +63 -7
  121. package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +35 -12
  122. package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +3 -1
  123. package/resources/claude-customizations/.claude/skills/quota-throttling/SKILL.md +1 -1
  124. package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
  125. package/resources/claude-customizations/pack-manifests/core.json +25 -0
  126. package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +9 -1
  127. package/resources/codex-and-agents-customizations/.agents/skills/architecture-boundaries/SKILL.md +5 -5
  128. package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +11 -0
  129. package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +4 -0
  130. package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +10 -0
  131. package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +2 -2
  132. package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +2 -2
  133. package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +13 -3
  134. package/resources/codex-and-agents-customizations/.agents/skills/epic-plan/SKILL.md +17 -1
  135. package/resources/codex-and-agents-customizations/.agents/skills/epic-run/SKILL.md +2 -1
  136. package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +13 -0
  137. package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +1 -1
  138. package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +30 -6
  139. package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +16 -6
  140. package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +1 -1
  141. package/resources/codex-and-agents-customizations/.agents/skills/general-unit-test/SKILL.md +3 -2
  142. package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +43 -11
  143. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-state/SKILL.md +41 -2
  144. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +19 -4
  145. package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +11 -7
  146. package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +2 -0
  147. package/resources/codex-and-agents-customizations/.agents/skills/translate-claude-to-codex/SKILL.md +1 -1
  148. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +2 -2
  149. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +2 -2
  150. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +11 -0
  151. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +11 -0
  152. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +11 -0
  153. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +11 -0
  154. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +11 -0
  155. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +11 -0
  156. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +10 -0
  157. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +10 -0
  158. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +10 -0
  159. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +10 -0
  160. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +10 -0
  161. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +10 -0
  162. package/resources/codex-and-agents-customizations/.codex/agents/epic-orchestrator.toml +2 -1
  163. package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +6 -6
  164. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c1.toml +1 -0
  165. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c2.toml +1 -0
  166. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3-elevated.toml +1 -0
  167. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3.toml +1 -0
  168. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c4.toml +1 -0
  169. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer.toml +1 -0
  170. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +3 -3
  171. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +3 -3
  172. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +3 -3
  173. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +3 -3
  174. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +3 -3
  175. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +3 -3
  176. package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +318 -273
  177. package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
  178. package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +7 -1
  179. package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +7 -1
  180. package/resources/codex-and-agents-customizations/.codex/hooks/codex-epic-child-launch-attestation.ps1 +1 -1
  181. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
  182. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +8 -2
  183. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +97 -44
  184. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-helpers.ps1 +105 -0
  185. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-child-worktree-binding.ps1 +7 -1
  186. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +37 -5
  187. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +6 -0
  188. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-root-invocation.ps1 +7 -1
  189. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-wave-barrier.ps1 +7 -1
  190. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-worktree-removal-gate.ps1 +54 -41
  191. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +7 -1
  192. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +35 -14
  193. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
  194. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
  195. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
  196. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +24 -11
  197. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +8 -2
  198. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +13 -4
  199. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +8 -2
  200. package/resources/codex-and-agents-customizations/.codex/hooks/feature-folder-resolution.ps1 +373 -0
  201. package/resources/codex-and-agents-customizations/.codex/hooks/feature-review-coverage-thresholds.ps1 +85 -0
  202. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-heredoc.ps1 +119 -0
  203. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation-operands.ps1 +198 -0
  204. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation.ps1 +254 -255
  205. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload-powershell.ps1 +201 -0
  206. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload.ps1 +484 -0
  207. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-scanner.ps1 +27 -110
  208. package/resources/codex-and-agents-customizations/.codex/hooks/hook-dependency-guard.ps1 +114 -0
  209. package/resources/codex-and-agents-customizations/.codex/hooks/hook-docs-only-diff.ps1 +493 -0
  210. package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +8 -2
  211. package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +7 -1
  212. package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +24 -8
  213. package/resources/codex-and-agents-customizations/pack-manifests/core.json +9 -0
  214. package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +2 -2
  215. package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +4 -4
  216. package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +2 -2
  217. package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +9 -1
  218. package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +4 -0
  219. package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +13 -0
  220. package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +1 -1
  221. package/resources/powershell/PoshQC/PoshQC.Coverage.psm1 +314 -0
  222. package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +25 -28
  223. package/resources/powershell/PoshQC/PoshQC.psm1 +1 -0
  224. package/resources/powershell/PoshQC/README.md +8 -2
  225. package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +2 -315
@@ -15,6 +15,10 @@
15
15
  dot-sourced as: . (Join-Path $PSScriptRoot 'hook-command-scanner.ps1')
16
16
  #>
17
17
 
18
+ # Heredoc header and body readers (issue #824). They read $script:CommandLineSegmentDelimiters,
19
+ # which is declared below; both are resolved when a scan runs, after this file has loaded.
20
+ . (Join-Path $PSScriptRoot 'hook-command-heredoc.ps1')
21
+
18
22
  # The wrapper carve-out set (D2 Piece 2). A segment led by one of these names keeps its raw
19
23
  # text as scan text, because a wrapper's quoted argument is a nested command line rather
20
24
  # than inert data. Pinned by test through Get-CommandLineWrapperName (rule R6).
@@ -125,8 +129,10 @@ function ConvertTo-CommandLineSegmentRecord {
125
129
  ScanText selection follows D2 Piece 2 in order: RawText when the segment is
126
130
  Unbalanced or carries a live substitution; RawText when it is wrapper-led;
127
131
  MaskedText otherwise. TokenText is the segment text with heredoc bodies replaced by
128
- spaces and quoted spans intact. Unbalanced also carries the unmaskable-delimiter
129
- case of rule R3, because such a heredoc cannot be shown to close.
132
+ spaces and quoted spans intact; it is carried on the record (issue #824). Unbalanced
133
+ also carries the unmaskable-delimiter case of rule R3, because such a heredoc cannot
134
+ be shown to close. Delimiter is the separator that ended the segment, or '' at end
135
+ of text (issue #824).
130
136
  .OUTPUTS
131
137
  System.Management.Automation.PSCustomObject
132
138
  #>
@@ -137,7 +143,8 @@ function ConvertTo-CommandLineSegmentRecord {
137
143
  [Parameter(Mandatory)][AllowEmptyString()][string] $MaskedText,
138
144
  [Parameter(Mandatory)][AllowEmptyString()][string] $TokenText,
139
145
  [Parameter(Mandatory)][bool] $HasLiveSubstitution,
140
- [Parameter(Mandatory)][bool] $Unbalanced
146
+ [Parameter(Mandatory)][bool] $Unbalanced,
147
+ [Parameter(Mandatory)][AllowEmptyString()][string] $Delimiter
141
148
  )
142
149
 
143
150
  $tokens = @(ConvertTo-CommandLineToken -Segment $TokenText)
@@ -159,6 +166,8 @@ function ConvertTo-CommandLineSegmentRecord {
159
166
  HasLiveSubstitution = $HasLiveSubstitution
160
167
  Unbalanced = $Unbalanced
161
168
  ScanText = $scanText
169
+ Delimiter = $Delimiter
170
+ TokenText = $TokenText
162
171
  }
163
172
  }
164
173
 
@@ -195,111 +204,6 @@ function Test-CommandLineSegmentRawScan {
195
204
  return ([bool]$Segment.IsWrapperLed -or [bool]$Segment.HasLiveSubstitution -or [bool]$Segment.Unbalanced)
196
205
  }
197
206
 
198
- function Read-CommandLineHeredocHeader {
199
- <#
200
- .SYNOPSIS
201
- Read a heredoc header beginning at a '<<' operator and report its delimiter.
202
- .DESCRIPTION
203
- Handles the plain '<<' form, the tab-stripping '<<-' form, and an optionally quoted
204
- delimiter word. A delimiter produced by expansion is reported as non-literal, which
205
- makes the segment unresolvable under R3. Returns NextIndex, Delimiter, StripTabs,
206
- and IsLiteral.
207
- .OUTPUTS
208
- System.Management.Automation.PSCustomObject
209
- #>
210
- [CmdletBinding()]
211
- [OutputType([pscustomobject])]
212
- param(
213
- [Parameter(Mandatory)][string] $Text,
214
- [Parameter(Mandatory)][int] $StartIndex
215
- )
216
-
217
- $cursor = $StartIndex + 2
218
- $stripTabs = $false
219
- if ($cursor -lt $Text.Length -and $Text[$cursor] -eq '-') {
220
- $stripTabs = $true
221
- $cursor++
222
- }
223
-
224
- while ($cursor -lt $Text.Length -and ($Text[$cursor] -eq ' ' -or $Text[$cursor] -eq "`t")) { $cursor++ }
225
-
226
- $word = [System.Text.StringBuilder]::new()
227
- $isLiteral = $true
228
- $openQuote = [char]0
229
- while ($cursor -lt $Text.Length) {
230
- $character = $Text[$cursor]
231
- if ($openQuote -ne [char]0) {
232
- if ($character -eq $openQuote) {
233
- $openQuote = [char]0
234
- } else {
235
- if ($openQuote -eq '"' -and ($character -eq '$' -or $character -eq '`')) { $isLiteral = $false }
236
- [void]$word.Append($character)
237
- }
238
- $cursor++
239
- continue
240
- }
241
-
242
- if ($character -eq '"' -or $character -eq "'") {
243
- $openQuote = $character
244
- $cursor++
245
- continue
246
- }
247
-
248
- if ([char]::IsWhiteSpace($character) -or $script:CommandLineSegmentDelimiters -contains $character) { break }
249
- if ($character -eq '$' -or $character -eq '`') { $isLiteral = $false }
250
- [void]$word.Append($character)
251
- $cursor++
252
- }
253
-
254
- $delimiter = $word.ToString()
255
- if ($openQuote -ne [char]0 -or [string]::IsNullOrEmpty($delimiter)) { $isLiteral = $false }
256
-
257
- return [pscustomobject]@{
258
- NextIndex = $cursor
259
- Delimiter = $delimiter
260
- StripTabs = $stripTabs
261
- IsLiteral = $isLiteral
262
- }
263
- }
264
-
265
- function Read-CommandLineHeredocBody {
266
- <#
267
- .SYNOPSIS
268
- Consume one heredoc body from a start index and report where it ends.
269
- .DESCRIPTION
270
- Consumes lines until a line whose content - after optional leading tabs for the
271
- '<<-' form - equals the delimiter exactly, case-sensitively as in the shell. An
272
- unterminated body is consumed to end of text and reported through Unbalanced.
273
- .OUTPUTS
274
- System.Management.Automation.PSCustomObject
275
- #>
276
- [CmdletBinding()]
277
- [OutputType([pscustomobject])]
278
- param(
279
- [Parameter(Mandatory)][string] $Text,
280
- [Parameter(Mandatory)][int] $StartIndex,
281
- [Parameter(Mandatory)][AllowEmptyString()][string] $Delimiter,
282
- [Parameter(Mandatory)][bool] $StripTabs
283
- )
284
-
285
- $cursor = $StartIndex
286
- $length = $Text.Length
287
- while ($cursor -lt $length) {
288
- $lineEnd = $Text.IndexOf("`n", $cursor)
289
- if ($lineEnd -lt 0) { $lineEnd = $length }
290
-
291
- $line = $Text.Substring($cursor, $lineEnd - $cursor).TrimEnd("`r")
292
- if ($StripTabs) { $line = $line.TrimStart("`t") }
293
-
294
- $cursor = if ($lineEnd -lt $length) { $lineEnd + 1 } else { $length }
295
- if ($line -ceq $Delimiter) {
296
- return [pscustomobject]@{ NextIndex = $cursor; Terminated = $true }
297
- }
298
- }
299
-
300
- return [pscustomobject]@{ NextIndex = $length; Terminated = $false }
301
- }
302
-
303
207
  function Read-CommandLineSegment {
304
208
  <#
305
209
  .SYNOPSIS
@@ -333,6 +237,12 @@ function Read-CommandLineSegment {
333
237
  ScanText [string] the clause-ordered selection: RawText when
334
238
  Unbalanced or HasLiveSubstitution or
335
239
  IsWrapperLed; MaskedText otherwise
240
+ Delimiter [string] the separator that ended the segment: ';', '&&',
241
+ '||', '|', '&', newline, '(', ')', '{', '}', '$(',
242
+ the backtick, or '' at end of text. '&&' and '||'
243
+ are consumed as one separator.
244
+ TokenText [string] the segment text with attached heredoc bodies
245
+ replaced by spaces and quoted spans intact
336
246
  Returns an empty array for null, empty, or whitespace-only input.
337
247
  #>
338
248
  [CmdletBinding()]
@@ -433,6 +343,7 @@ function Read-CommandLineSegment {
433
343
 
434
344
  $isSubstitutionOpener = $character -eq '$' -and $next -eq '('
435
345
  if ($isSubstitutionOpener -or $script:CommandLineSegmentDelimiters -contains $character) {
346
+ $delimiter = [string]$character
436
347
  if ($character -eq "`n" -and $pending.Count -gt 0) {
437
348
  [void]$raw.Append($character)
438
349
  [void]$tokenText.Append($character)
@@ -449,6 +360,12 @@ function Read-CommandLineSegment {
449
360
  }
450
361
  $pending.Clear()
451
362
  } elseif ($isSubstitutionOpener) {
363
+ $delimiter = '$('
364
+ $index += 2
365
+ } elseif (($character -eq '&' -or $character -eq '|') -and $next -eq $character) {
366
+ # '&&' and '||' are one separator, so the second character no longer opens an
367
+ # empty segment of its own (issue #824).
368
+ $delimiter = "$character$next"
452
369
  $index += 2
453
370
  } else {
454
371
  $index++
@@ -456,7 +373,7 @@ function Read-CommandLineSegment {
456
373
 
457
374
  $rawText = $raw.ToString()
458
375
  if (-not [string]::IsNullOrWhiteSpace($rawText)) {
459
- $records.Add((ConvertTo-CommandLineSegmentRecord -RawText $rawText -MaskedText $masked.ToString() -TokenText $tokenText.ToString() -HasLiveSubstitution $hasLiveSubstitution -Unbalanced $unbalanced))
376
+ $records.Add((ConvertTo-CommandLineSegmentRecord -RawText $rawText -MaskedText $masked.ToString() -TokenText $tokenText.ToString() -HasLiveSubstitution $hasLiveSubstitution -Unbalanced $unbalanced -Delimiter $delimiter))
460
377
  }
461
378
  [void]$raw.Clear()
462
379
  [void]$masked.Clear()
@@ -476,7 +393,7 @@ function Read-CommandLineSegment {
476
393
 
477
394
  $rawText = $raw.ToString()
478
395
  if (-not [string]::IsNullOrWhiteSpace($rawText)) {
479
- $records.Add((ConvertTo-CommandLineSegmentRecord -RawText $rawText -MaskedText $masked.ToString() -TokenText $tokenText.ToString() -HasLiveSubstitution $hasLiveSubstitution -Unbalanced $unbalanced))
396
+ $records.Add((ConvertTo-CommandLineSegmentRecord -RawText $rawText -MaskedText $masked.ToString() -TokenText $tokenText.ToString() -HasLiveSubstitution $hasLiveSubstitution -Unbalanced $unbalanced -Delimiter ''))
480
397
  }
481
398
 
482
399
  return $records.ToArray()
@@ -0,0 +1,114 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Shared dependency-failure recording and blocking-result construction for registered hooks (issue #786).
4
+
5
+ .DESCRIPTION
6
+ Dot-sourced by every registered PreToolUse and SubagentStop hook as the first statement after its
7
+ param() block, inside a try whose catch sets $script:HookDependencyGuardLoadFailed. Every guarded
8
+ module load and sibling dot-source of the hook records a failure through Add-HookDependencyFailure;
9
+ the hook's decision function and its tail return Get-HookDependencyFailureDecision when a failure is
10
+ recorded, so a missing or broken dependency blocks instead of failing open.
11
+
12
+ The failure list lives in the hook's script scope and is created only when it is absent, so a hook
13
+ that dot-sources another hook entry keeps the records made before the second dot-source.
14
+
15
+ .NOTES
16
+ PowerShell 7+. Import-free: it loads no module and dot-sources no file. It uses built-in cmdlets and
17
+ .NET types only, writes to no output stream, and calls no function defined by a hook or by a guarded
18
+ dependency. Every absence test reads the list through Get-Variable, so it holds under strict mode.
19
+ Byte-identical at .claude/hooks, .codex/hooks, and both bundle mirrors.
20
+ #>
21
+
22
+ if ($null -eq (Get-Variable -Name HookDependencyFailures -Scope Script -ValueOnly -ErrorAction SilentlyContinue)) { $script:HookDependencyFailures = [System.Collections.Generic.List[object]]::new() }
23
+
24
+ function Add-HookDependencyFailure {
25
+ <#
26
+ .SYNOPSIS
27
+ Records one dependency that failed to load.
28
+ .PARAMETER Name
29
+ The file name of the module or sibling script that failed to load.
30
+ .PARAMETER ErrorRecord
31
+ The caught error; its first exception line is kept. When omitted, the message reads
32
+ 'no error record'.
33
+ #>
34
+ [CmdletBinding()]
35
+ param(
36
+ [Parameter(Mandatory)]
37
+ [string] $Name,
38
+
39
+ [System.Management.Automation.ErrorRecord] $ErrorRecord
40
+ )
41
+
42
+ if ($null -eq (Get-Variable -Name HookDependencyFailures -Scope Script -ValueOnly -ErrorAction SilentlyContinue)) { $script:HookDependencyFailures = [System.Collections.Generic.List[object]]::new() }
43
+ $message = 'no error record'
44
+ if ($null -ne $ErrorRecord) { $message = ([string]$ErrorRecord.Exception.Message -split "`r?`n")[0] }
45
+ [void]$script:HookDependencyFailures.Add([pscustomobject]@{ Name = $Name; Message = $message })
46
+ }
47
+
48
+ function Test-HookDependencyFailure {
49
+ <#
50
+ .SYNOPSIS
51
+ Returns $true when at least one dependency failure is recorded.
52
+ #>
53
+ [CmdletBinding()]
54
+ [OutputType([bool])]
55
+ param()
56
+
57
+ $variable = Get-Variable -Name HookDependencyFailures -Scope Script -ErrorAction SilentlyContinue
58
+ return ($null -ne $variable -and $null -ne $variable.Value -and $variable.Value.Count -gt 0)
59
+ }
60
+
61
+ function Get-HookDependencyFailureReason {
62
+ <#
63
+ .SYNOPSIS
64
+ Builds the blocking reason from the hook's prefix and the first recorded failure.
65
+ .PARAMETER ReasonPrefix
66
+ The hook's existing leading token or prose prefix, ending with a colon.
67
+ #>
68
+ [CmdletBinding()]
69
+ [OutputType([string])]
70
+ param(
71
+ [Parameter(Mandatory)]
72
+ [string] $ReasonPrefix
73
+ )
74
+
75
+ $first = (Get-Variable -Name HookDependencyFailures -Scope Script -ErrorAction SilentlyContinue).Value[0]
76
+ return "$ReasonPrefix the dependency '$($first.Name)' failed to load ($($first.Message)); the gate fails closed."
77
+ }
78
+
79
+ function Get-HookDependencyFailureDecision {
80
+ <#
81
+ .SYNOPSIS
82
+ Returns the blocking result for a recorded dependency failure, or $null when none is recorded.
83
+ .PARAMETER HookEvent
84
+ PreToolUse returns the deny decision in the hookSpecificOutput shape; SubagentStop returns an
85
+ object carrying ExitCode 2 and the Reason the hook writes to stderr.
86
+ .PARAMETER ReasonPrefix
87
+ The hook's existing leading token or prose prefix, ending with a colon.
88
+ #>
89
+ [CmdletBinding()]
90
+ [OutputType([System.Collections.Specialized.OrderedDictionary], [pscustomobject])]
91
+ param(
92
+ [Parameter(Mandatory)]
93
+ [ValidateSet('PreToolUse', 'SubagentStop')]
94
+ [string] $HookEvent,
95
+
96
+ [Parameter(Mandatory)]
97
+ [string] $ReasonPrefix
98
+ )
99
+
100
+ if (-not (Test-HookDependencyFailure)) {
101
+ return $null
102
+ }
103
+ $reason = Get-HookDependencyFailureReason -ReasonPrefix $ReasonPrefix
104
+ if ($HookEvent -eq 'SubagentStop') {
105
+ return [pscustomobject]@{ ExitCode = 2; Reason = $reason }
106
+ }
107
+ return [ordered]@{
108
+ hookSpecificOutput = [ordered]@{
109
+ hookEventName = 'PreToolUse'
110
+ permissionDecision = 'deny'
111
+ permissionDecisionReason = $reason
112
+ }
113
+ }
114
+ }