@danmoisan/drm-copilot-mcp 1.1.25 → 1.1.27
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 +170 -52
- package/package.json +1 -1
- package/resources/claude-customizations/.claude/agents/atomic-executor.md +3 -3
- package/resources/claude-customizations/.claude/agents/atomic-planner.md +2 -2
- package/resources/claude-customizations/.claude/agents/csharp-typed-engineer.md +7 -7
- package/resources/claude-customizations/.claude/agents/feature-review.md +6 -3
- package/resources/claude-customizations/.claude/agents/orchestrator.md +11 -7
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +7 -3
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +6 -2
- package/resources/claude-customizations/.claude/agents/powershell-typed-engineer.md +7 -7
- package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +6 -6
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-review.ps1 +699 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +16 -1
- package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +41 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1 +481 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +3 -1
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier-helpers.ps1 +69 -3
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +2 -2
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.cleanup.ps1 +246 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +1 -0
- package/resources/claude-customizations/.claude/hooks/hook-cleanup-context.ps1 +343 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +50 -16
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1 +6 -1
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCompletion.psm1 +4 -2
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCompletionChecks.psm1 +51 -2
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateReceipts.psm1 +5 -2
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRemediationAccounting.psm1 +116 -4
- package/resources/claude-customizations/.claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 +626 -0
- package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmission.psm1 +508 -0
- package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmissionJson.psm1 +141 -0
- package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmissionPrecedence.psm1 +508 -0
- package/resources/claude-customizations/.claude/rules/csharp.md +8 -8
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +28 -2
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +17 -1
- package/resources/claude-customizations/.claude/rules/powershell.md +2 -2
- package/resources/claude-customizations/.claude/settings.json +1 -0
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +9 -13
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +93 -14
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup-worktrees.sh +23 -10
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_lib.sh +54 -46
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_merge_lib.sh +234 -0
- package/resources/claude-customizations/.claude/skills/csharp-qa-gate/SKILL.md +14 -15
- package/resources/claude-customizations/.claude/skills/epic-progress-report/SKILL.md +338 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.Logic.ps1 +248 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.Metrics.ps1 +232 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.Render.ps1 +196 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.State.ps1 +286 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.ps1 +475 -0
- package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +31 -16
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +21 -9
- package/resources/claude-customizations/.claude/skills/invoke-csharp-engineer/SKILL.md +5 -5
- package/resources/claude-customizations/.claude/skills/invoke-powershell-engineer/SKILL.md +4 -4
- package/resources/claude-customizations/.claude/skills/invoke-python-engineer/SKILL.md +4 -4
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +24 -2
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +71 -7
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +34 -2
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +82 -12
- package/resources/claude-customizations/.claude/skills/powershell-qa-gate/SKILL.md +16 -17
- package/resources/claude-customizations/.claude/skills/python-qa-gate/SKILL.md +15 -16
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +1 -1
- package/resources/claude-customizations/.claude-variants/csharp-legacy/agents/csharp-typed-engineer.md +6 -6
- package/resources/claude-customizations/.claude-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +13 -14
- package/resources/claude-customizations/.claude-variants/csharp-legacy/skills/invoke-csharp-engineer/SKILL.md +4 -4
- package/resources/claude-customizations/pack-manifests/core.json +15 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +8 -12
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +13 -14
- package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +31 -16
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +5 -1
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +18 -5
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-csharp-engineer/SKILL.md +4 -4
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-powershell-engineer/SKILL.md +4 -4
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-python-engineer/SKILL.md +4 -4
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +24 -2
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-state/SKILL.md +16 -1
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +3 -3
- package/resources/codex-and-agents-customizations/.agents/skills/powershell/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-qa-gate/SKILL.md +15 -16
- package/resources/codex-and-agents-customizations/.agents/skills/python-qa-gate/SKILL.md +14 -15
- package/resources/codex-and-agents-customizations/.agents/skills/repo-automation-adapter/SKILL.md +2 -0
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +13 -14
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/invoke-csharp-engineer/SKILL.md +4 -4
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-executor.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-orchestrator.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c1.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c2.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3-elevated.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c4.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-executor.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-di-unit-test-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-orchestrator.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c1.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c2.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3-elevated.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c4.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/pytest-unit-test-coding.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-executor.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-execution-only-typed.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-orchestrator.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c1.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c2.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3-elevated.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c4.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate-review.ps1 +699 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +29 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1 +481 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +4 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-cleanup-context.ps1 +343 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +51 -4
- package/resources/codex-and-agents-customizations/.codex-variants/csharp-legacy/agents/csharp-typed-engineer.toml +6 -6
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +3 -0
- package/resources/customizations/.github/agents/5.1-Beast-adjusted.agent.md +1 -1
- package/resources/customizations/.github/agents/Powershell DI Unit Test Engineer.agent.md +20 -26
- package/resources/customizations/.github/agents/atomic_executor.agent.md +4 -4
- package/resources/customizations/.github/agents/atomic_planning.agent.md +4 -4
- package/resources/customizations/.github/agents/commentary-remediation.agent.md +1 -1
- package/resources/customizations/.github/agents/commit-steward.agent.md +1 -1
- package/resources/customizations/.github/agents/csharp-atomic-executor.agent.md +14 -14
- package/resources/customizations/.github/agents/csharp-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/csharp-orchestrator.agent.md +4 -4
- package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +19 -22
- package/resources/customizations/.github/agents/epic-review.agent.md +1 -1
- package/resources/customizations/.github/agents/gpt-5-beast-mode.agent.md +3 -3
- package/resources/customizations/.github/agents/orchestrator.agent.md +8 -8
- package/resources/customizations/.github/agents/powershell-atomic-executor.agent.md +12 -12
- package/resources/customizations/.github/agents/powershell-atomic-planning.agent.md +4 -4
- package/resources/customizations/.github/agents/powershell-orchestrator.agent.md +6 -6
- package/resources/customizations/.github/agents/powershell-typed-engineer.agent.md +21 -24
- package/resources/customizations/.github/agents/pytest-unit-test-coding.agent.md +13 -17
- package/resources/customizations/.github/agents/python-atomic-executor.agent.md +11 -11
- package/resources/customizations/.github/agents/python-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/python-execution-only-typed.agent.md +14 -17
- package/resources/customizations/.github/agents/python-orchestrator.agent.md +7 -7
- package/resources/customizations/.github/agents/python-typed-engineer.agent.md +17 -20
- package/resources/customizations/.github/agents/staged-review.agent.md +2 -2
- package/resources/customizations/.github/agents/tdd-green.agent.md +1 -1
- package/resources/customizations/.github/agents/tdd-red.agent.md +3 -3
- package/resources/customizations/.github/agents/tdd-refactor.agent.md +2 -2
- package/resources/customizations/.github/agents/typescript-engineer.agent.md +3 -3
- package/resources/customizations/.github/codex/execute-hard-lock.prompt.md +3 -3
- package/resources/customizations/.github/instructions/general-code-change.instructions.md +1 -1
- package/resources/customizations/.github/instructions/powershell-unit-test.instructions.md +1 -1
- package/resources/customizations/.github/instructions/python-code-change.instructions.md +5 -5
- package/resources/customizations/.github/instructions/python-suppressions.instructions.md +3 -3
- package/resources/customizations/.github/instructions/python-unit-test.instructions.md +1 -1
- package/resources/customizations/.github/prompts/execute-hard-lock.prompt.md +2 -2
- package/resources/customizations/.github/prompts/generate-commit-message-repo.prompt.md +2 -2
- package/resources/customizations/.github/prompts/remediate-comments.prompt.md +2 -2
- package/resources/customizations/.github/prompts/review-feature.prompt.md +1 -1
- package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +8 -12
- package/resources/customizations/.github/skills/execution-environment/SKILL.md +31 -16
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +15 -2
- package/resources/feature-templates/bug/plan.yyyy-MM-ddTHH-mm.md +4 -4
- package/resources/feature-templates/feature/plan.yyyy-MM-ddTHH-mm.md +3 -3
- package/resources/feature-templates/refactor/plan.yyyy-MM-ddTHH-mm.md +2 -2
- package/resources/powershell/PoshQC/PoshQC.ScanConfig.psm1 +3 -1
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +14 -12
- package/resources/powershell/PoshQC/PoshQC.psm1 +3 -3
- package/resources/powershell/PoshQC/README.md +8 -8
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +2 -2
- package/resources/templates/policy_audit/AGENTS.md +9 -10
- package/resources/templates/policy_audit/policy-audit.yyyy-MM-ddTHH-mm.md +19 -20
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Setting, state-file, baseline, and sample functions for Get-EpicProgressReport.ps1.
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
Pure functions: each takes data in and returns data, and none reads a file, starts a
|
|
7
|
+
process, calls the network, or reads the clock. The entry script reads and writes the
|
|
8
|
+
state file through its I/O seams. Get-EpicProgressReport.Logic.ps1 dot-sources this file,
|
|
9
|
+
so a consumer dot-sources the Logic hub, not this file.
|
|
10
|
+
#>
|
|
11
|
+
|
|
12
|
+
function Select-EpicProgressSample {
|
|
13
|
+
<#
|
|
14
|
+
.SYNOPSIS
|
|
15
|
+
Apply the sample-retention rule for one check-in; return Sample and Changed.
|
|
16
|
+
.DESCRIPTION
|
|
17
|
+
A sample (ts, done) is added only when there is no previous sample, the previous
|
|
18
|
+
sample has no 'ts', or it is at least 90 seconds older than now. On add, samples
|
|
19
|
+
without 'ts' are dropped and only the last SampleCap samples are kept.
|
|
20
|
+
.PARAMETER Sample
|
|
21
|
+
The samples read from the state file.
|
|
22
|
+
.PARAMETER NowUnixSeconds
|
|
23
|
+
The current instant in Unix seconds.
|
|
24
|
+
.PARAMETER Done
|
|
25
|
+
The checked task count now.
|
|
26
|
+
.PARAMETER SampleCap
|
|
27
|
+
The maximum number of samples kept.
|
|
28
|
+
#>
|
|
29
|
+
[CmdletBinding()]
|
|
30
|
+
[OutputType([pscustomobject])]
|
|
31
|
+
param(
|
|
32
|
+
[Parameter(Mandatory = $true)] [AllowEmptyCollection()] [object[]] $Sample,
|
|
33
|
+
[Parameter(Mandatory = $true)] [long] $NowUnixSeconds,
|
|
34
|
+
[Parameter(Mandatory = $true)] [int] $Done,
|
|
35
|
+
[Parameter(Mandatory = $true)] [ValidateRange(1, 100000)] [int] $SampleCap
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
$last = $null
|
|
39
|
+
if ($Sample.Count -gt 0) { $last = $Sample[$Sample.Count - 1] }
|
|
40
|
+
$add = ($null -eq $last) -or -not ($last.PSObject.Properties.Name -contains 'ts') -or (($NowUnixSeconds - [long] $last.ts) -ge 90)
|
|
41
|
+
if (-not $add) { return [pscustomobject]@{ Sample = $Sample; Changed = $false } }
|
|
42
|
+
$kept = [System.Collections.Generic.List[object]]::new()
|
|
43
|
+
foreach ($entry in $Sample) {
|
|
44
|
+
if ($null -ne $entry -and $entry.PSObject.Properties.Name -contains 'ts') { $kept.Add($entry) }
|
|
45
|
+
}
|
|
46
|
+
$kept.Add([pscustomobject]@{ ts = $NowUnixSeconds; done = $Done })
|
|
47
|
+
$retained = [object[]] @($kept | Select-Object -Skip ([math]::Max(0, $kept.Count - $SampleCap)))
|
|
48
|
+
return [pscustomobject]@{ Sample = $retained; Changed = $true }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function Resolve-EpicProgressSetting {
|
|
52
|
+
<#
|
|
53
|
+
.SYNOPSIS
|
|
54
|
+
Apply the parameter defaults of the report; pure, with the current location passed in.
|
|
55
|
+
.DESCRIPTION
|
|
56
|
+
A blank value takes its default and an explicit value is kept. The kickoff path is a
|
|
57
|
+
git object path with '/' separators; filesystem paths are built with Join-Path. The
|
|
58
|
+
default state file is .claude/state/epic-progress-<EpicFolder>.json under the
|
|
59
|
+
repository root, which is gitignored and survives a container stop with the checkout.
|
|
60
|
+
.PARAMETER EpicFolder
|
|
61
|
+
The epic folder name.
|
|
62
|
+
.PARAMETER EpicIssue
|
|
63
|
+
The explicit epic issue number, or blank.
|
|
64
|
+
.PARAMETER IntegrationBranch
|
|
65
|
+
The explicit integration branch, or blank.
|
|
66
|
+
.PARAMETER KickoffPath
|
|
67
|
+
The explicit kickoff path, or blank.
|
|
68
|
+
.PARAMETER RepositoryRoot
|
|
69
|
+
The explicit repository root, or blank.
|
|
70
|
+
.PARAMETER CheckpointPath
|
|
71
|
+
The explicit checkpoint path, or blank.
|
|
72
|
+
.PARAMETER StatePath
|
|
73
|
+
The explicit state file path, or blank.
|
|
74
|
+
.PARAMETER CurrentLocation
|
|
75
|
+
The current location.
|
|
76
|
+
#>
|
|
77
|
+
[CmdletBinding()]
|
|
78
|
+
[OutputType([pscustomobject])]
|
|
79
|
+
param(
|
|
80
|
+
[Parameter(Mandatory = $true)] [string] $EpicFolder,
|
|
81
|
+
[AllowEmptyString()] [string] $EpicIssue = '',
|
|
82
|
+
[AllowEmptyString()] [string] $IntegrationBranch = '',
|
|
83
|
+
[AllowEmptyString()] [string] $KickoffPath = '',
|
|
84
|
+
[AllowEmptyString()] [string] $RepositoryRoot = '',
|
|
85
|
+
[AllowEmptyString()] [string] $CheckpointPath = '',
|
|
86
|
+
[AllowEmptyString()] [string] $StatePath = '',
|
|
87
|
+
[Parameter(Mandatory = $true)] [string] $CurrentLocation
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
$root = $RepositoryRoot
|
|
91
|
+
if ([string]::IsNullOrWhiteSpace($root)) { $root = $CurrentLocation }
|
|
92
|
+
$branch = $IntegrationBranch
|
|
93
|
+
if ([string]::IsNullOrWhiteSpace($branch)) { $branch = "origin/epic/$EpicFolder-integration" }
|
|
94
|
+
$kickoff = $KickoffPath
|
|
95
|
+
if ([string]::IsNullOrWhiteSpace($kickoff)) { $kickoff = "docs/features/epics/$EpicFolder/epic-kickoff.md" }
|
|
96
|
+
$checkpoint = $CheckpointPath
|
|
97
|
+
if ([string]::IsNullOrWhiteSpace($checkpoint)) {
|
|
98
|
+
$checkpoint = Join-Path -Path $root -ChildPath 'artifacts' -AdditionalChildPath 'orchestration', 'epic-orchestrator-state.json'
|
|
99
|
+
}
|
|
100
|
+
$state = $StatePath
|
|
101
|
+
if ([string]::IsNullOrWhiteSpace($state)) {
|
|
102
|
+
$state = Join-Path -Path $root -ChildPath '.claude' -AdditionalChildPath 'state', "epic-progress-$EpicFolder.json"
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return [pscustomobject]@{
|
|
106
|
+
EpicIssue = $EpicIssue
|
|
107
|
+
IntegrationBranch = $branch
|
|
108
|
+
KickoffPath = $kickoff.Replace('\', '/')
|
|
109
|
+
RepositoryRoot = $root
|
|
110
|
+
CheckpointPath = $checkpoint
|
|
111
|
+
StatePath = $state
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function ConvertFrom-EpicProgressStateText {
|
|
116
|
+
<#
|
|
117
|
+
.SYNOPSIS
|
|
118
|
+
Parse the state file text into StartUnixSeconds, BaselineDone, BaselineWeeklyPct, and Samples.
|
|
119
|
+
.DESCRIPTION
|
|
120
|
+
Accepts the version-1 object written by ConvertTo-EpicProgressStateJson and the legacy
|
|
121
|
+
JSON array of samples written by the issue #1080 tool (samples only, no baseline).
|
|
122
|
+
Blank text, unparseable text, any other JSON value, and an object whose version is
|
|
123
|
+
not 1 give the empty state. A version-1 field that is missing, null, or not a number
|
|
124
|
+
is absent: its value is $null. Samples is always an array.
|
|
125
|
+
.PARAMETER Text
|
|
126
|
+
The raw state file text; blank or null for no state file.
|
|
127
|
+
#>
|
|
128
|
+
[CmdletBinding()]
|
|
129
|
+
[OutputType([pscustomobject])]
|
|
130
|
+
param([Parameter(Mandatory = $true)] [AllowEmptyString()] [AllowNull()] [string] $Text)
|
|
131
|
+
|
|
132
|
+
$state = [pscustomobject]@{ StartUnixSeconds = $null; BaselineDone = $null; BaselineWeeklyPct = $null; Samples = [object[]] @() }
|
|
133
|
+
if (-not (Test-EpicProgressJsonText -Json $Text)) { return $state }
|
|
134
|
+
$parsed = ConvertFrom-Json -InputObject $Text -NoEnumerate
|
|
135
|
+
if ($parsed -is [array]) {
|
|
136
|
+
$state.Samples = [object[]] @($parsed | Where-Object { $null -ne $_ })
|
|
137
|
+
return $state
|
|
138
|
+
}
|
|
139
|
+
if ($parsed -isnot [System.Management.Automation.PSCustomObject]) { return $state }
|
|
140
|
+
$names = $parsed.PSObject.Properties.Name
|
|
141
|
+
if (-not ($names -contains 'version') -or [string] $parsed.version -ne '1') { return $state }
|
|
142
|
+
if ($names -contains 'startUnixSeconds' -and $null -ne $parsed.startUnixSeconds) { $state.StartUnixSeconds = $parsed.startUnixSeconds -as [long] }
|
|
143
|
+
if ($names -contains 'baselineDone' -and $null -ne $parsed.baselineDone) { $state.BaselineDone = $parsed.baselineDone -as [int] }
|
|
144
|
+
if ($names -contains 'baselineWeeklyPct' -and $null -ne $parsed.baselineWeeklyPct) { $state.BaselineWeeklyPct = $parsed.baselineWeeklyPct -as [double] }
|
|
145
|
+
if ($names -contains 'samples' -and $null -ne $parsed.samples) {
|
|
146
|
+
$state.Samples = [object[]] @($parsed.samples | Where-Object { $null -ne $_ })
|
|
147
|
+
}
|
|
148
|
+
return $state
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function ConvertTo-EpicProgressStateJson {
|
|
152
|
+
<#
|
|
153
|
+
.SYNOPSIS
|
|
154
|
+
Return the version-1 state document as JSON text.
|
|
155
|
+
.DESCRIPTION
|
|
156
|
+
The document holds version 1, startUnixSeconds, baselineDone, baselineWeeklyPct, and
|
|
157
|
+
samples, each sample with an integer 'ts' (Unix epoch seconds) and a 'done' count.
|
|
158
|
+
A sample without 'ts' is not written. Epoch seconds are used because ConvertFrom-Json
|
|
159
|
+
converts ISO date strings into local-time DateTime values.
|
|
160
|
+
.PARAMETER StartUnixSeconds
|
|
161
|
+
The start instant in Unix epoch seconds.
|
|
162
|
+
.PARAMETER BaselineDone
|
|
163
|
+
The checked task count at the start instant.
|
|
164
|
+
.PARAMETER BaselineWeeklyPct
|
|
165
|
+
The weekly quota percentage at the start instant.
|
|
166
|
+
.PARAMETER Sample
|
|
167
|
+
The retained samples (ts, done).
|
|
168
|
+
#>
|
|
169
|
+
[CmdletBinding()]
|
|
170
|
+
[OutputType([string])]
|
|
171
|
+
param(
|
|
172
|
+
[Parameter(Mandatory = $true)] [long] $StartUnixSeconds,
|
|
173
|
+
[Parameter(Mandatory = $true)] [int] $BaselineDone,
|
|
174
|
+
[Parameter(Mandatory = $true)] [double] $BaselineWeeklyPct,
|
|
175
|
+
[Parameter(Mandatory = $true)] [AllowEmptyCollection()] [object[]] $Sample
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
$written = [System.Collections.Generic.List[object]]::new()
|
|
179
|
+
foreach ($entry in $Sample) {
|
|
180
|
+
if ($null -eq $entry -or -not ($entry.PSObject.Properties.Name -contains 'ts')) { continue }
|
|
181
|
+
$written.Add([ordered]@{ ts = [long] $entry.ts; done = [int] $entry.done })
|
|
182
|
+
}
|
|
183
|
+
$document = [ordered]@{
|
|
184
|
+
version = 1
|
|
185
|
+
startUnixSeconds = $StartUnixSeconds
|
|
186
|
+
baselineDone = $BaselineDone
|
|
187
|
+
baselineWeeklyPct = $BaselineWeeklyPct
|
|
188
|
+
samples = [object[]] $written.ToArray()
|
|
189
|
+
}
|
|
190
|
+
return ConvertTo-Json -InputObject $document -Depth 4
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function Resolve-EpicProgressBaseline {
|
|
194
|
+
<#
|
|
195
|
+
.SYNOPSIS
|
|
196
|
+
Resolve the start instant and the baseline values from the passed values, the stored state, and the reset switch.
|
|
197
|
+
.DESCRIPTION
|
|
198
|
+
Start: the passed value, else (with ResetBaseline) NowUtc, else the stored value; with
|
|
199
|
+
none of these a terminating error names -StartUtc and -ResetBaseline. Baseline done:
|
|
200
|
+
the passed value, else (with ResetBaseline) the current done count, else the stored
|
|
201
|
+
value, else 0. Weekly baseline: the passed value, else the stored value, else 0; a
|
|
202
|
+
reset does not capture it. The current done count is not known before the git calls,
|
|
203
|
+
so UseCurrentDone is $true when the caller must substitute it for BaselineDone.
|
|
204
|
+
.PARAMETER StartUtc
|
|
205
|
+
The passed start instant; read only when StartUtcPassed is set.
|
|
206
|
+
.PARAMETER StartUtcPassed
|
|
207
|
+
Whether -StartUtc was passed to the report.
|
|
208
|
+
.PARAMETER BaselineDone
|
|
209
|
+
The passed baseline done count; read only when BaselineDonePassed is set.
|
|
210
|
+
.PARAMETER BaselineDonePassed
|
|
211
|
+
Whether -BaselineDone was passed to the report.
|
|
212
|
+
.PARAMETER BaselineWeeklyPct
|
|
213
|
+
The passed weekly baseline; read only when BaselineWeeklyPctPassed is set.
|
|
214
|
+
.PARAMETER BaselineWeeklyPctPassed
|
|
215
|
+
Whether -BaselineWeeklyPct was passed to the report.
|
|
216
|
+
.PARAMETER State
|
|
217
|
+
The parsed state from ConvertFrom-EpicProgressStateText.
|
|
218
|
+
.PARAMETER ResetBaseline
|
|
219
|
+
Whether the run resets the baseline.
|
|
220
|
+
.PARAMETER NowUtc
|
|
221
|
+
The current instant (UTC).
|
|
222
|
+
#>
|
|
223
|
+
[CmdletBinding()]
|
|
224
|
+
[OutputType([pscustomobject])]
|
|
225
|
+
param(
|
|
226
|
+
[datetime] $StartUtc,
|
|
227
|
+
[switch] $StartUtcPassed,
|
|
228
|
+
[int] $BaselineDone,
|
|
229
|
+
[switch] $BaselineDonePassed,
|
|
230
|
+
[double] $BaselineWeeklyPct,
|
|
231
|
+
[switch] $BaselineWeeklyPctPassed,
|
|
232
|
+
[Parameter(Mandatory = $true)] [pscustomobject] $State,
|
|
233
|
+
[switch] $ResetBaseline,
|
|
234
|
+
[Parameter(Mandatory = $true)] [datetime] $NowUtc
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
if ($StartUtcPassed) {
|
|
238
|
+
$start = $StartUtc.ToUniversalTime()
|
|
239
|
+
} elseif ($ResetBaseline) {
|
|
240
|
+
$start = $NowUtc.ToUniversalTime()
|
|
241
|
+
} elseif ($null -ne $State.StartUnixSeconds) {
|
|
242
|
+
$start = [DateTimeOffset]::FromUnixTimeSeconds([long] $State.StartUnixSeconds).UtcDateTime
|
|
243
|
+
} else {
|
|
244
|
+
throw 'The start instant could not be resolved: pass -StartUtc, or pass -ResetBaseline to start the measurement now; the state file holds no start.'
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
$useCurrentDone = $false
|
|
248
|
+
$done = 0
|
|
249
|
+
if ($BaselineDonePassed) {
|
|
250
|
+
$done = $BaselineDone
|
|
251
|
+
} elseif ($ResetBaseline) {
|
|
252
|
+
$useCurrentDone = $true
|
|
253
|
+
} elseif ($null -ne $State.BaselineDone) {
|
|
254
|
+
$done = [int] $State.BaselineDone
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
$weekly = 0.0
|
|
258
|
+
if ($BaselineWeeklyPctPassed) {
|
|
259
|
+
$weekly = $BaselineWeeklyPct
|
|
260
|
+
} elseif ($null -ne $State.BaselineWeeklyPct) {
|
|
261
|
+
$weekly = [double] $State.BaselineWeeklyPct
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return [pscustomobject]@{ StartUtc = $start; BaselineDone = $done; BaselineWeeklyPct = $weekly; UseCurrentDone = $useCurrentDone }
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function Merge-EpicProgressSamplePair {
|
|
268
|
+
<#
|
|
269
|
+
.SYNOPSIS
|
|
270
|
+
Keep the newest sample and every second older sample (indices n-1, n-3, ...), in chronological order.
|
|
271
|
+
.DESCRIPTION
|
|
272
|
+
With k intervals the result has floor(k/2) intervals, each spanning two original
|
|
273
|
+
intervals; when k is odd the oldest interval is discarded. 14 samples become 7, 13
|
|
274
|
+
become 7, 2 become 1, and 1 or 0 samples are returned unchanged. Each application
|
|
275
|
+
doubles the spacing again, so the function is not idempotent.
|
|
276
|
+
.PARAMETER Sample
|
|
277
|
+
The samples in chronological order.
|
|
278
|
+
#>
|
|
279
|
+
[CmdletBinding()]
|
|
280
|
+
[OutputType([object[]])]
|
|
281
|
+
param([Parameter(Mandatory = $true)] [AllowEmptyCollection()] [object[]] $Sample)
|
|
282
|
+
|
|
283
|
+
$kept = [System.Collections.Generic.List[object]]::new()
|
|
284
|
+
for ($index = $Sample.Count - 1; $index -ge 0; $index -= 2) { $kept.Insert(0, $Sample[$index]) }
|
|
285
|
+
return [object[]] $kept.ToArray()
|
|
286
|
+
}
|