@danmoisan/drm-copilot-mcp 1.0.21 → 1.0.22

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 (31) hide show
  1. package/out/mcp-server.js +1624 -190
  2. package/package.json +1 -1
  3. package/resources/claude-customizations/.claude/agent-memory/epic-orchestrator/MEMORY.md +5 -1
  4. package/resources/claude-customizations/.claude/agent-memory/epic-orchestrator/feedback_commit_push_memory_before_pr.md +48 -2
  5. package/resources/claude-customizations/.claude/agent-memory/epic-orchestrator/feedback_no_sendmessage_tool.md +35 -0
  6. package/resources/claude-customizations/.claude/agent-memory/epic-orchestrator/feedback_worktree_isolation_branches_from_main.md +45 -0
  7. package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +238 -0
  8. package/resources/claude-customizations/.claude/agents/parallel-planner.md +149 -0
  9. package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +23 -11
  10. package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +259 -0
  11. package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +499 -0
  12. package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate-helpers.ps1 +302 -0
  13. package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +359 -0
  14. package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +244 -0
  15. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadius.psm1 +379 -0
  16. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusConfig.psm1 +491 -0
  17. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +490 -0
  18. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusGlob.psm1 +429 -0
  19. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusValidation.psm1 +366 -0
  20. package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +184 -0
  21. package/resources/claude-customizations/.claude/settings.json +25 -0
  22. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +148 -0
  23. package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +93 -0
  24. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +960 -0
  25. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +420 -0
  26. package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +176 -0
  27. package/resources/claude-customizations/.claude/skills/parallel-run/SKILL.md +56 -0
  28. package/resources/claude-customizations/pack-manifests/core.json +19 -1
  29. package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
  30. package/resources/config/orchestration-routing.json +22 -0
  31. package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +29 -0
@@ -0,0 +1,259 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Pre-tool-use hook that gates the destructive parallel abandon disposition behind an
4
+ explicit confirmation marker.
5
+
6
+ .DESCRIPTION
7
+ Invoked by the Claude Code PreToolUse hook on the "Bash" matcher before any Bash
8
+ command runs. Reads CLAUDE_TOOL_INPUT, extracts the command text, and matches it
9
+ against the two tokens declared at the top of this file: the abandon disposition
10
+ token and the confirmation marker. A command carrying the abandon disposition token
11
+ without the confirmation marker in the SAME command is denied with reason prefix
12
+ PARALLEL_ABANDON_BLOCKED. A command carrying both is allowed. A command carrying no
13
+ abandon disposition token is out of scope and is allowed unchanged.
14
+
15
+ The gate exists because the abandon disposition of /parallel-remove closes a pull
16
+ request and removes a worktree. Both side effects are irreversible from the run's
17
+ point of view, so the destructive path must be confirmed deliberately rather than
18
+ reached by a command that merely looked like a removal.
19
+
20
+ .NOTES
21
+ Compatible with PowerShell 7+. No external module dependencies. Tool-input retrieval
22
+ goes through an injectable wrapper function so tests can mock the boundary with
23
+ literal JSON without writing temporary files, following the read-seam pattern of
24
+ .claude/hooks/enforce-epic-worktree-removal-gate.ps1.
25
+
26
+ The two token values are declared ONCE EACH below and every match in this file reads
27
+ those variables rather than repeating a literal. The producer side of the same pair is
28
+ scripts/dev_tools/parallel_mutation_abandon_cli.py, and
29
+ tests/scripts/dev_tools/test_parallel_abandon_token_seam.py parses both sides at run
30
+ time so a rename on one side without the other fails.
31
+ #>
32
+ [CmdletBinding()]
33
+ param()
34
+
35
+ # The two tokens this gate matches on. These are the ONLY places either token literal
36
+ # appears in this file; the seam test extracts the consumer-side values from exactly
37
+ # these two named assignments.
38
+ $script:AbandonDispositionToken = '--disposition abandon'
39
+ $script:AbandonConfirmToken = '--confirm-abandon'
40
+
41
+ # Literal prefix on the deny reason, so the reason code is greppable in transcripts.
42
+ $script:AbandonBlockedReasonCode = 'PARALLEL_ABANDON_BLOCKED'
43
+
44
+ function Get-ParallelAbandonGateToolInput {
45
+ <#
46
+ .SYNOPSIS
47
+ Read the raw JSON tool payload supplied by Claude Code. Tests mock this
48
+ function (read seam).
49
+ .OUTPUTS
50
+ System.String or $null
51
+ #>
52
+ [CmdletBinding()]
53
+ [OutputType([string])]
54
+ param()
55
+
56
+ return $env:CLAUDE_TOOL_INPUT
57
+ }
58
+
59
+ function Get-ParallelAbandonNormalizedCommand {
60
+ <#
61
+ .SYNOPSIS
62
+ Collapse whitespace runs in a command so token matching is not defeated by
63
+ extra spacing or a line continuation.
64
+ .PARAMETER CommandText
65
+ The Bash command text under evaluation.
66
+ .OUTPUTS
67
+ System.String
68
+ #>
69
+ [CmdletBinding()]
70
+ [OutputType([string])]
71
+ param(
72
+ [AllowNull()]
73
+ [AllowEmptyString()]
74
+ [string] $CommandText
75
+ )
76
+
77
+ if ([string]::IsNullOrWhiteSpace($CommandText)) {
78
+ return ''
79
+ }
80
+ # A single space between tokens is the shape the declared tokens are written in, so
81
+ # normalizing here lets the tokens stay exactly as the producer declares them.
82
+ return ($CommandText -replace '\s+', ' ').Trim()
83
+ }
84
+
85
+ function Test-ParallelAbandonCommandInScope {
86
+ <#
87
+ .SYNOPSIS
88
+ Report whether a command carries the abandon disposition token at all.
89
+ .PARAMETER NormalizedCommand
90
+ The whitespace-normalized command text.
91
+ .OUTPUTS
92
+ System.Boolean
93
+ #>
94
+ [CmdletBinding()]
95
+ [OutputType([bool])]
96
+ param(
97
+ [AllowNull()]
98
+ [AllowEmptyString()]
99
+ [string] $NormalizedCommand
100
+ )
101
+
102
+ if ([string]::IsNullOrWhiteSpace($NormalizedCommand)) {
103
+ return $false
104
+ }
105
+ return $NormalizedCommand.Contains(
106
+ $script:AbandonDispositionToken,
107
+ [System.StringComparison]::OrdinalIgnoreCase)
108
+ }
109
+
110
+ function Test-ParallelAbandonCommandConfirmed {
111
+ <#
112
+ .SYNOPSIS
113
+ Report whether a command carries the confirmation marker.
114
+ .PARAMETER NormalizedCommand
115
+ The whitespace-normalized command text.
116
+ .OUTPUTS
117
+ System.Boolean
118
+ #>
119
+ [CmdletBinding()]
120
+ [OutputType([bool])]
121
+ param(
122
+ [AllowNull()]
123
+ [AllowEmptyString()]
124
+ [string] $NormalizedCommand
125
+ )
126
+
127
+ if ([string]::IsNullOrWhiteSpace($NormalizedCommand)) {
128
+ return $false
129
+ }
130
+ return $NormalizedCommand.Contains(
131
+ $script:AbandonConfirmToken,
132
+ [System.StringComparison]::OrdinalIgnoreCase)
133
+ }
134
+
135
+ function Get-ParallelAbandonGateAllowDecision {
136
+ <#
137
+ .SYNOPSIS
138
+ Build the allow decision payload.
139
+ .OUTPUTS
140
+ System.Collections.Specialized.OrderedDictionary
141
+ #>
142
+ [CmdletBinding()]
143
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
144
+ param()
145
+
146
+ return [ordered]@{
147
+ hookSpecificOutput = [ordered]@{
148
+ hookEventName = 'PreToolUse'
149
+ permissionDecision = 'allow'
150
+ }
151
+ }
152
+ }
153
+
154
+ function Get-ParallelAbandonGateBlockDecision {
155
+ <#
156
+ .SYNOPSIS
157
+ Build the deny decision payload carrying the supplied reason.
158
+ .PARAMETER Reason
159
+ The deny reason surfaced to the caller.
160
+ .OUTPUTS
161
+ System.Collections.Specialized.OrderedDictionary
162
+ #>
163
+ [CmdletBinding()]
164
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
165
+ param(
166
+ [Parameter(Mandatory)]
167
+ [string] $Reason
168
+ )
169
+
170
+ return [ordered]@{
171
+ hookSpecificOutput = [ordered]@{
172
+ hookEventName = 'PreToolUse'
173
+ permissionDecision = 'deny'
174
+ permissionDecisionReason = $Reason
175
+ }
176
+ }
177
+ }
178
+
179
+ function Get-ParallelAbandonGateBlockReason {
180
+ <#
181
+ .SYNOPSIS
182
+ Build the deny reason text from the two declared tokens.
183
+ .OUTPUTS
184
+ System.String
185
+ #>
186
+ [CmdletBinding()]
187
+ [OutputType([string])]
188
+ param()
189
+
190
+ return @(
191
+ "$($script:AbandonBlockedReasonCode): this command carries"
192
+ "'$($script:AbandonDispositionToken)' without the explicit"
193
+ "'$($script:AbandonConfirmToken)' confirmation marker in the same command."
194
+ 'The abandon disposition closes the item pull request and removes its worktree,'
195
+ 'so it must be confirmed deliberately. Add the confirmation marker to the same'
196
+ 'command, or use the detach disposition instead. Do not reformulate the command'
197
+ 'to evade this gate.'
198
+ ) -join ' '
199
+ }
200
+
201
+ function Invoke-ParallelAbandonGateDecision {
202
+ <#
203
+ .SYNOPSIS
204
+ Parses CLAUDE_TOOL_INPUT and returns an allow-or-block decision.
205
+ .PARAMETER ToolInputRaw
206
+ The raw JSON tool payload supplied by Claude Code.
207
+ .OUTPUTS
208
+ System.Collections.Specialized.OrderedDictionary
209
+ #>
210
+ [CmdletBinding()]
211
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
212
+ param(
213
+ [AllowNull()]
214
+ [AllowEmptyString()]
215
+ [string] $ToolInputRaw
216
+ )
217
+
218
+ # An absent payload carries no command to gate, so there is nothing in scope. This is
219
+ # allow rather than deny because the gate constrains one specific destructive command
220
+ # shape and must not become a blanket Bash block.
221
+ if (-not $ToolInputRaw) {
222
+ return Get-ParallelAbandonGateAllowDecision
223
+ }
224
+
225
+ try {
226
+ $toolInput = $ToolInputRaw | ConvertFrom-Json -ErrorAction Stop
227
+ } catch {
228
+ throw "enforce-parallel-abandon-gate hook received malformed JSON in CLAUDE_TOOL_INPUT: $_"
229
+ }
230
+
231
+ $normalizedCommand = Get-ParallelAbandonNormalizedCommand -CommandText ([string]$toolInput.command)
232
+ if (-not (Test-ParallelAbandonCommandInScope -NormalizedCommand $normalizedCommand)) {
233
+ return Get-ParallelAbandonGateAllowDecision
234
+ }
235
+
236
+ # In scope: the command asks for the destructive disposition, so the confirmation
237
+ # marker decides. Its presence is the caller's explicit acknowledgement.
238
+ if (Test-ParallelAbandonCommandConfirmed -NormalizedCommand $normalizedCommand) {
239
+ return Get-ParallelAbandonGateAllowDecision
240
+ }
241
+
242
+ return Get-ParallelAbandonGateBlockDecision -Reason (Get-ParallelAbandonGateBlockReason)
243
+ }
244
+
245
+ # Guard allows dot-sourcing in tests without executing the entrypoint.
246
+ if ($MyInvocation.InvocationName -eq '.') {
247
+ return
248
+ }
249
+
250
+ try {
251
+ $decision = Invoke-ParallelAbandonGateDecision -ToolInputRaw (Get-ParallelAbandonGateToolInput)
252
+ } catch {
253
+ Write-Error $_
254
+ exit 1
255
+ }
256
+
257
+ $decision | ConvertTo-Json -Compress -Depth 5 | Write-Output
258
+
259
+ exit 0