@danmoisan/drm-copilot-mcp 1.1.18 → 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.
- package/out/mcp-server.js +989 -662
- package/package.json +3 -2
- package/resources/claude-customizations/.claude/agents/atomic-executor.md +11 -0
- package/resources/claude-customizations/.claude/agents/atomic-planner.md +10 -0
- package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +12 -4
- package/resources/claude-customizations/.claude/agents/epic-planner.md +5 -4
- package/resources/claude-customizations/.claude/agents/feature-review.md +6 -4
- package/resources/claude-customizations/.claude/agents/orchestrator.md +5 -4
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +31 -13
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +9 -6
- package/resources/claude-customizations/.claude/agents/pr-author.md +15 -2
- package/resources/claude-customizations/.claude/agents/prd-feature.md +1 -1
- package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +111 -46
- package/resources/claude-customizations/.claude/hooks/enforce-completion-helpers.ps1 +105 -0
- package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +8 -1
- package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-resolution.ps1 +116 -59
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +55 -23
- package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +74 -75
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +127 -35
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +61 -57
- package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +129 -39
- package/resources/claude-customizations/.claude/hooks/enforce-mermaid-validation.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +39 -51
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +17 -12
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +65 -50
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +49 -42
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +54 -72
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +8 -2
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +279 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +129 -75
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.artifact-root.ps1 +233 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +224 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +69 -24
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1 +29 -18
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +10 -4
- package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +14 -5
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +8 -2
- package/resources/claude-customizations/.claude/hooks/feature-folder-resolution.ps1 +373 -0
- package/resources/claude-customizations/.claude/hooks/feature-review-coverage-thresholds.ps1 +85 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-heredoc.ps1 +119 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-invocation-operands.ps1 +198 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-invocation.ps1 +254 -255
- package/resources/claude-customizations/.claude/hooks/hook-command-payload-powershell.ps1 +201 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-payload.ps1 +484 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-scanner.ps1 +27 -110
- package/resources/claude-customizations/.claude/hooks/hook-dependency-guard.ps1 +114 -0
- package/resources/claude-customizations/.claude/hooks/hook-docs-only-diff.ps1 +493 -0
- package/resources/claude-customizations/.claude/hooks/subagentstop-envelope.ps1 +192 -0
- package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +40 -42
- package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +66 -38
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-metrics.ps1 +180 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +195 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +141 -395
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-resolution.ps1 +311 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-routing.ps1 +170 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +115 -190
- package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +64 -32
- package/resources/claude-customizations/.claude/hooks/validate-pr-author-output.ps1 +39 -44
- package/resources/claude-customizations/.claude/hooks/validate-prd-feature-output.ps1 +43 -14
- package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +66 -36
- package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +31 -34
- package/resources/claude-customizations/.claude/lib/bash/mutate-parallel-run.sh +191 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-cohorts.sh +13 -3
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-cli.sh +152 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-ops.sh +193 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation.sh +322 -0
- package/resources/claude-customizations/.claude/lib/bash/remove-parallel-item.sh +146 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +23 -33
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +86 -6
- package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-CiGateParser.ps1 +91 -19
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateEpicWaveBarrier.psm1 +346 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +24 -3
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +79 -2
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +3 -3
- package/resources/claude-customizations/.claude/rules/architecture-boundaries.md +5 -5
- package/resources/claude-customizations/.claude/rules/csharp.md +2 -2
- package/resources/claude-customizations/.claude/rules/general-code-change.md +1 -1
- package/resources/claude-customizations/.claude/rules/general-unit-test.md +3 -2
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +37 -4
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +50 -5
- package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +47 -8
- package/resources/claude-customizations/.claude/rules/quality-tiers.md +11 -7
- package/resources/claude-customizations/.claude/rules/shell.md +10 -8
- package/resources/claude-customizations/.claude/rules/typescript.md +1 -1
- package/resources/claude-customizations/.claude/settings.json +3 -4
- package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +5 -1
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_detached_lib.sh +1 -1
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_enumerate_lib.sh +2 -0
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh +2 -0
- package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +33 -6
- package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +4 -3
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +14 -6
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +52 -14
- package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +22 -9
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +79 -16
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +63 -7
- package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +35 -12
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +3 -1
- package/resources/claude-customizations/.claude/skills/quota-throttling/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +2 -2
- package/resources/claude-customizations/pack-manifests/core.json +23 -0
- package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/architecture-boundaries/SKILL.md +5 -5
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +11 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +4 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +10 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +8 -0
- package/resources/codex-and-agents-customizations/.agents/skills/epic-plan/SKILL.md +17 -1
- package/resources/codex-and-agents-customizations/.agents/skills/epic-run/SKILL.md +2 -1
- package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +13 -5
- package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/general-unit-test/SKILL.md +3 -2
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +15 -6
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +11 -7
- package/resources/codex-and-agents-customizations/.agents/skills/translate-claude-to-codex/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/epic-orchestrator.toml +2 -1
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +318 -273
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/codex-epic-child-launch-attestation.ps1 +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +97 -44
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-helpers.ps1 +105 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-child-worktree-binding.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +37 -5
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +6 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-root-invocation.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-wave-barrier.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-worktree-removal-gate.ps1 +54 -41
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +35 -14
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +24 -11
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +13 -4
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/feature-folder-resolution.ps1 +373 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/feature-review-coverage-thresholds.ps1 +85 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-heredoc.ps1 +119 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation-operands.ps1 +198 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation.ps1 +254 -255
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload-powershell.ps1 +201 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload.ps1 +484 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-scanner.ps1 +27 -110
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-dependency-guard.ps1 +114 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-docs-only-diff.ps1 +493 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +24 -8
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +9 -0
- package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +2 -2
- package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +4 -4
- package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +2 -2
- package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +4 -0
- package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +1 -1
- package/resources/powershell/PoshQC/PoshQC.Coverage.psm1 +314 -0
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +25 -28
- package/resources/powershell/PoshQC/PoshQC.psm1 +1 -0
- package/resources/powershell/PoshQC/README.md +8 -2
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +2 -319
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Heredoc header and body readers for the Bash command-line segment scanner.
|
|
4
|
+
.DESCRIPTION
|
|
5
|
+
Holds Read-CommandLineHeredocHeader and Read-CommandLineHeredocBody, moved verbatim
|
|
6
|
+
from hook-command-scanner.ps1 (issue #824) so the scanner stays under the 500-line
|
|
7
|
+
limit once it records each segment's Delimiter and TokenText. The functions read
|
|
8
|
+
$script:CommandLineSegmentDelimiters, which the scanner declares before it
|
|
9
|
+
dot-sources this file.
|
|
10
|
+
|
|
11
|
+
Pure string logic only: no disk, process, network, clock, or environment access. It is
|
|
12
|
+
dot-sourced by hook-command-scanner.ps1 as:
|
|
13
|
+
. (Join-Path $PSScriptRoot 'hook-command-heredoc.ps1')
|
|
14
|
+
#>
|
|
15
|
+
|
|
16
|
+
function Read-CommandLineHeredocHeader {
|
|
17
|
+
<#
|
|
18
|
+
.SYNOPSIS
|
|
19
|
+
Read a heredoc header beginning at a '<<' operator and report its delimiter.
|
|
20
|
+
.DESCRIPTION
|
|
21
|
+
Handles the plain '<<' form, the tab-stripping '<<-' form, and an optionally quoted
|
|
22
|
+
delimiter word. A delimiter produced by expansion is reported as non-literal, which
|
|
23
|
+
makes the segment unresolvable under R3. Returns NextIndex, Delimiter, StripTabs,
|
|
24
|
+
and IsLiteral.
|
|
25
|
+
.OUTPUTS
|
|
26
|
+
System.Management.Automation.PSCustomObject
|
|
27
|
+
#>
|
|
28
|
+
[CmdletBinding()]
|
|
29
|
+
[OutputType([pscustomobject])]
|
|
30
|
+
param(
|
|
31
|
+
[Parameter(Mandatory)][string] $Text,
|
|
32
|
+
[Parameter(Mandatory)][int] $StartIndex
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
$cursor = $StartIndex + 2
|
|
36
|
+
$stripTabs = $false
|
|
37
|
+
if ($cursor -lt $Text.Length -and $Text[$cursor] -eq '-') {
|
|
38
|
+
$stripTabs = $true
|
|
39
|
+
$cursor++
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
while ($cursor -lt $Text.Length -and ($Text[$cursor] -eq ' ' -or $Text[$cursor] -eq "`t")) { $cursor++ }
|
|
43
|
+
|
|
44
|
+
$word = [System.Text.StringBuilder]::new()
|
|
45
|
+
$isLiteral = $true
|
|
46
|
+
$openQuote = [char]0
|
|
47
|
+
while ($cursor -lt $Text.Length) {
|
|
48
|
+
$character = $Text[$cursor]
|
|
49
|
+
if ($openQuote -ne [char]0) {
|
|
50
|
+
if ($character -eq $openQuote) {
|
|
51
|
+
$openQuote = [char]0
|
|
52
|
+
} else {
|
|
53
|
+
if ($openQuote -eq '"' -and ($character -eq '$' -or $character -eq '`')) { $isLiteral = $false }
|
|
54
|
+
[void]$word.Append($character)
|
|
55
|
+
}
|
|
56
|
+
$cursor++
|
|
57
|
+
continue
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if ($character -eq '"' -or $character -eq "'") {
|
|
61
|
+
$openQuote = $character
|
|
62
|
+
$cursor++
|
|
63
|
+
continue
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if ([char]::IsWhiteSpace($character) -or $script:CommandLineSegmentDelimiters -contains $character) { break }
|
|
67
|
+
if ($character -eq '$' -or $character -eq '`') { $isLiteral = $false }
|
|
68
|
+
[void]$word.Append($character)
|
|
69
|
+
$cursor++
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
$delimiter = $word.ToString()
|
|
73
|
+
if ($openQuote -ne [char]0 -or [string]::IsNullOrEmpty($delimiter)) { $isLiteral = $false }
|
|
74
|
+
|
|
75
|
+
return [pscustomobject]@{
|
|
76
|
+
NextIndex = $cursor
|
|
77
|
+
Delimiter = $delimiter
|
|
78
|
+
StripTabs = $stripTabs
|
|
79
|
+
IsLiteral = $isLiteral
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function Read-CommandLineHeredocBody {
|
|
84
|
+
<#
|
|
85
|
+
.SYNOPSIS
|
|
86
|
+
Consume one heredoc body from a start index and report where it ends.
|
|
87
|
+
.DESCRIPTION
|
|
88
|
+
Consumes lines until a line whose content - after optional leading tabs for the
|
|
89
|
+
'<<-' form - equals the delimiter exactly, case-sensitively as in the shell. An
|
|
90
|
+
unterminated body is consumed to end of text and reported through Unbalanced.
|
|
91
|
+
.OUTPUTS
|
|
92
|
+
System.Management.Automation.PSCustomObject
|
|
93
|
+
#>
|
|
94
|
+
[CmdletBinding()]
|
|
95
|
+
[OutputType([pscustomobject])]
|
|
96
|
+
param(
|
|
97
|
+
[Parameter(Mandatory)][string] $Text,
|
|
98
|
+
[Parameter(Mandatory)][int] $StartIndex,
|
|
99
|
+
[Parameter(Mandatory)][AllowEmptyString()][string] $Delimiter,
|
|
100
|
+
[Parameter(Mandatory)][bool] $StripTabs
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
$cursor = $StartIndex
|
|
104
|
+
$length = $Text.Length
|
|
105
|
+
while ($cursor -lt $length) {
|
|
106
|
+
$lineEnd = $Text.IndexOf("`n", $cursor)
|
|
107
|
+
if ($lineEnd -lt 0) { $lineEnd = $length }
|
|
108
|
+
|
|
109
|
+
$line = $Text.Substring($cursor, $lineEnd - $cursor).TrimEnd("`r")
|
|
110
|
+
if ($StripTabs) { $line = $line.TrimStart("`t") }
|
|
111
|
+
|
|
112
|
+
$cursor = if ($lineEnd -lt $length) { $lineEnd + 1 } else { $length }
|
|
113
|
+
if ($line -ceq $Delimiter) {
|
|
114
|
+
return [pscustomobject]@{ NextIndex = $cursor; Terminated = $true }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return [pscustomobject]@{ NextIndex = $length; Terminated = $false }
|
|
119
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Operand, flag, and removal-target readers over the structural invocation matcher.
|
|
4
|
+
.DESCRIPTION
|
|
5
|
+
Issue #824. Holds Get-CommandLineOperand, Get-CommandLineFlagValue, and
|
|
6
|
+
Test-CommandLineFlag, moved out of hook-command-invocation.ps1 to keep that file under the
|
|
7
|
+
500-line limit, and Resolve-CommandLineInvocationTarget, the target resolver the
|
|
8
|
+
worktree-removal gates consume. Every reader takes its tokens from the FIRST Structural
|
|
9
|
+
match Get-CommandLineInvocation returns; inside a wrapper payload that is the payload
|
|
10
|
+
record's tokens. An Indeterminate match never yields an operand or a flag.
|
|
11
|
+
|
|
12
|
+
Pure string logic only: no disk, process, network, clock, or environment access. It is
|
|
13
|
+
dot-sourced by hook-command-invocation.ps1.
|
|
14
|
+
#>
|
|
15
|
+
|
|
16
|
+
function Get-CommandLineStructuralMatch {
|
|
17
|
+
<#
|
|
18
|
+
.SYNOPSIS
|
|
19
|
+
Return the first Structural match for a command word and subcommand path, or $null.
|
|
20
|
+
.OUTPUTS
|
|
21
|
+
System.Management.Automation.PSCustomObject or $null
|
|
22
|
+
#>
|
|
23
|
+
[CmdletBinding()]
|
|
24
|
+
[OutputType([pscustomobject])]
|
|
25
|
+
param(
|
|
26
|
+
[Parameter(Mandatory)][AllowEmptyString()][AllowNull()][string] $CommandText,
|
|
27
|
+
[Parameter(Mandatory)][string] $CommandWord,
|
|
28
|
+
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string[]] $SubcommandPath
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
foreach ($match in @(Get-CommandLineInvocation -CommandText $CommandText -CommandWord $CommandWord -SubcommandPath $SubcommandPath)) {
|
|
32
|
+
if ($match.Status -eq 'Structural') { return $match }
|
|
33
|
+
}
|
|
34
|
+
return $null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function Get-CommandLineOperand {
|
|
38
|
+
<#
|
|
39
|
+
.SYNOPSIS
|
|
40
|
+
Return the positional operands of the first Structural match, in source order.
|
|
41
|
+
.DESCRIPTION
|
|
42
|
+
Operand collection follows the issue #545 rules: a modeled option-with-argument pair
|
|
43
|
+
is consumed, a known zero-argument flag such as '--force' contributes nothing, a token
|
|
44
|
+
after a bare '--' is always an operand, a redirection is not an operand, and an
|
|
45
|
+
unmodeled dash token ends collection. The operands come from the matched record only,
|
|
46
|
+
so a chained 'cd <path> &&' segment contributes nothing (issue #591). With no
|
|
47
|
+
Structural match the result is an empty array.
|
|
48
|
+
.PARAMETER CommandText
|
|
49
|
+
The raw Bash command text.
|
|
50
|
+
.PARAMETER CommandWord
|
|
51
|
+
The command name.
|
|
52
|
+
.PARAMETER SubcommandPath
|
|
53
|
+
The ordered subcommand tokens.
|
|
54
|
+
.OUTPUTS
|
|
55
|
+
System.String[] - operands with balanced quotes already stripped, in source order.
|
|
56
|
+
#>
|
|
57
|
+
[CmdletBinding()]
|
|
58
|
+
[OutputType([string[]])]
|
|
59
|
+
param(
|
|
60
|
+
[Parameter(Mandatory)][AllowEmptyString()][AllowNull()][string] $CommandText,
|
|
61
|
+
[Parameter(Mandatory)][string] $CommandWord,
|
|
62
|
+
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string[]] $SubcommandPath
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
$match = Get-CommandLineStructuralMatch -CommandText $CommandText -CommandWord $CommandWord -SubcommandPath $SubcommandPath
|
|
66
|
+
if ($null -eq $match) { return [string[]]@() }
|
|
67
|
+
return [string[]]@($match.Operands)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function Get-CommandLineFlagValue {
|
|
71
|
+
<#
|
|
72
|
+
.SYNOPSIS
|
|
73
|
+
Return the value of a named flag belonging to the first Structural match.
|
|
74
|
+
.DESCRIPTION
|
|
75
|
+
Recognizes the separated form ('--merge 688') and the equals form ('--merge=688').
|
|
76
|
+
Returns $null when no Structural match exists, when the flag is absent, when it has no
|
|
77
|
+
following value token, and when the following token is itself dash-leading. The
|
|
78
|
+
$null-on-missing-value contract is pinned by issue #591: a bare 'gh pr merge --merge'
|
|
79
|
+
must yield $null, never 0 and never ''.
|
|
80
|
+
.PARAMETER CommandText
|
|
81
|
+
The raw Bash command text.
|
|
82
|
+
.PARAMETER CommandWord
|
|
83
|
+
The command name.
|
|
84
|
+
.PARAMETER SubcommandPath
|
|
85
|
+
The ordered subcommand tokens.
|
|
86
|
+
.PARAMETER FlagName
|
|
87
|
+
The flag as written, including leading dashes, e.g. '--merge' or '--body-file'.
|
|
88
|
+
.OUTPUTS
|
|
89
|
+
System.String or $null. Quotes are already stripped.
|
|
90
|
+
#>
|
|
91
|
+
[CmdletBinding()]
|
|
92
|
+
[OutputType([string])]
|
|
93
|
+
param(
|
|
94
|
+
[Parameter(Mandatory)][AllowEmptyString()][AllowNull()][string] $CommandText,
|
|
95
|
+
[Parameter(Mandatory)][string] $CommandWord,
|
|
96
|
+
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string[]] $SubcommandPath,
|
|
97
|
+
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string] $FlagName
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
$match = Get-CommandLineStructuralMatch -CommandText $CommandText -CommandWord $CommandWord -SubcommandPath $SubcommandPath
|
|
101
|
+
if ($null -eq $match) { return $null }
|
|
102
|
+
|
|
103
|
+
$tokens = @($match.Segment.Tokens)
|
|
104
|
+
$prefix = $FlagName + '='
|
|
105
|
+
for ($index = 0; $index -lt $tokens.Count; $index++) {
|
|
106
|
+
$current = $tokens[$index]
|
|
107
|
+
|
|
108
|
+
if ($current -eq $FlagName) {
|
|
109
|
+
if ($index + 1 -ge $tokens.Count) { return $null }
|
|
110
|
+
$value = $tokens[$index + 1]
|
|
111
|
+
if ($value.StartsWith('-') -and $value.Length -gt 1) { return $null }
|
|
112
|
+
return $value
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if ($current.StartsWith($prefix, [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
116
|
+
$value = $current.Substring($prefix.Length)
|
|
117
|
+
if ([string]::IsNullOrEmpty($value)) { return $null }
|
|
118
|
+
return $value
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return $null
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function Test-CommandLineFlag {
|
|
126
|
+
<#
|
|
127
|
+
.SYNOPSIS
|
|
128
|
+
Report whether a named flag is present on the first Structural match, with or without
|
|
129
|
+
a value.
|
|
130
|
+
.DESCRIPTION
|
|
131
|
+
Matches both '--flag' and '--flag=value' by exact token comparison after quote
|
|
132
|
+
stripping, so '--body' does not match '--body-file'. With no Structural match the
|
|
133
|
+
result is $false.
|
|
134
|
+
.OUTPUTS
|
|
135
|
+
System.Boolean
|
|
136
|
+
#>
|
|
137
|
+
[CmdletBinding()]
|
|
138
|
+
[OutputType([bool])]
|
|
139
|
+
param(
|
|
140
|
+
[Parameter(Mandatory)][AllowEmptyString()][AllowNull()][string] $CommandText,
|
|
141
|
+
[Parameter(Mandatory)][string] $CommandWord,
|
|
142
|
+
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string[]] $SubcommandPath,
|
|
143
|
+
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string] $FlagName
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
$match = Get-CommandLineStructuralMatch -CommandText $CommandText -CommandWord $CommandWord -SubcommandPath $SubcommandPath
|
|
147
|
+
if ($null -eq $match) { return $false }
|
|
148
|
+
|
|
149
|
+
$prefix = $FlagName + '='
|
|
150
|
+
foreach ($current in @($match.Segment.Tokens)) {
|
|
151
|
+
if ($current -eq $FlagName) { return $true }
|
|
152
|
+
if ($current.StartsWith($prefix, [System.StringComparison]::OrdinalIgnoreCase)) { return $true }
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return $false
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function Resolve-CommandLineInvocationTarget {
|
|
159
|
+
<#
|
|
160
|
+
.SYNOPSIS
|
|
161
|
+
Resolve the targets of every invocation of a command word and subcommand path.
|
|
162
|
+
.DESCRIPTION
|
|
163
|
+
Returns Status and Targets:
|
|
164
|
+
NoMatch no invocation; Targets is empty.
|
|
165
|
+
Indeterminate any match is Indeterminate, has OperandsComplete = $false, or has
|
|
166
|
+
other than exactly one literal operand; Targets is empty.
|
|
167
|
+
Targets every match is Structural with exactly one literal operand; Targets
|
|
168
|
+
holds the distinct operands (ordinal comparison) in source order and
|
|
169
|
+
is never empty.
|
|
170
|
+
The worktree-removal gates authorize each target and deny on Indeterminate, so no
|
|
171
|
+
unreadable operand routes to an allow.
|
|
172
|
+
.OUTPUTS
|
|
173
|
+
System.Management.Automation.PSCustomObject
|
|
174
|
+
#>
|
|
175
|
+
[CmdletBinding()]
|
|
176
|
+
[OutputType([pscustomobject])]
|
|
177
|
+
param(
|
|
178
|
+
[Parameter(Mandatory)][AllowEmptyString()][AllowNull()][string] $CommandText,
|
|
179
|
+
[Parameter(Mandatory)][string] $CommandWord,
|
|
180
|
+
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string[]] $SubcommandPath
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
$matchList = @(Get-CommandLineInvocation -CommandText $CommandText -CommandWord $CommandWord -SubcommandPath $SubcommandPath)
|
|
184
|
+
if ($matchList.Count -eq 0) {
|
|
185
|
+
return [pscustomobject]@{ Status = 'NoMatch'; Targets = [string[]]@() }
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
$targets = [System.Collections.Generic.List[string]]::new()
|
|
189
|
+
foreach ($match in $matchList) {
|
|
190
|
+
$operands = @($match.Operands)
|
|
191
|
+
if ($match.Status -ne 'Structural' -or -not $match.OperandsComplete -or $operands.Count -ne 1 -or
|
|
192
|
+
-not (Test-CommandLineTokenLiteral -Token $operands[0])) {
|
|
193
|
+
return [pscustomobject]@{ Status = 'Indeterminate'; Targets = [string[]]@() }
|
|
194
|
+
}
|
|
195
|
+
if (-not $targets.Contains($operands[0])) { $targets.Add($operands[0]) }
|
|
196
|
+
}
|
|
197
|
+
return [pscustomobject]@{ Status = 'Targets'; Targets = [string[]]$targets.ToArray() }
|
|
198
|
+
}
|