CopilotAtelier.psd1
|
@{ RootModule = 'CopilotAtelier.psm1' # Replaced at build time by GitVersion. ModuleVersion = '4.0.0' GUID = '67bbef0b-f4de-4c1b-bb5a-b34104beb5b7' Author = 'raandree' CompanyName = 'raandree' Copyright = '(c) raandree. All rights reserved.' Description = 'Portable GitHub Copilot customization library. Ships custom agents, auto-applied instructions, on-demand skills, prompt templates, and lifecycle hooks, and installs them into the well-known ~/.copilot discovery folders that VS Code, the GitHub Copilot CLI, and Claude Code read.' PowerShellVersion = '5.1' FunctionsToExport = @('Get-CopilotAtelierVersion','Install-CopilotAtelier','Update-CopilotAtelier') CmdletsToExport = @() VariablesToExport = @() AliasesToExport = @() PrivateData = @{ PSData = @{ Tags = @( 'Copilot' 'GitHubCopilot' 'VSCode' 'Agents' 'Skills' 'Prompts' 'Instructions' 'Hooks' 'AI' 'Windows' 'Linux' 'MacOS' ) LicenseUri = 'https://github.com/raandree/CopilotAtelier/blob/main/LICENSE' ProjectUri = 'https://github.com/raandree/CopilotAtelier' IconUri = 'https://raw.githubusercontent.com/raandree/CopilotAtelier/main/assets/CA-glyph-on-light.png' Prerelease = 'preview0002' ReleaseNotes = '## [4.0.0-preview0002] - 2026-08-12 ### Changed - **`AGENTS.md` states the atomic change set for a Skill and a Custom agent** (2026-08-12). A Customization is never one file, and a half-added one leaves the catalogue, the trigger coverage, and the changelog disagreeing with each other. The new *Atomic change sets* section names every artifact that has to move in the same commit for each, and tables which test catches which kind of drift — so the answer to "what else does this change need?" is in the house rules rather than in a reviewer''s memory. - **`pester-patterns` split into a body plus two references** (2026-08-11). The body was 796 lines against the 500-line progressive-disclosure budget and had been carried on the `SkillFrontmatter` over-budget baseline rather than fixed. It is now 149 lines. What stayed is what an agent needs on *every* Pester run: pattern 0, run tests through the fully detached launcher, and pattern 14, helpers used inside `It` must live in `BeforeAll`. What moved is what it needs *sometimes* — patterns 1 to 3 into [`references/mocking-external-dependencies.md`](Skills/pester-patterns/references/mocking-external-dependencies.md) and patterns 4 to 13 into [`references/testing-powershell-constructs.md`](Skills/pester-patterns/references/testing-powershell-constructs.md), both one level deep, both keeping their original numbers so existing references still resolve. The frontmatter `description` is untouched, so the trigger surface is unchanged and no eval re-run is owed. Its baseline entry is removed in the same change, so the gate proves the fix rather than recording the intent; nine Skills remain baselined, `german-legal-research` at 780 lines the worst of them. - **`.memory-bank/systemPatterns.md` curated from 106 lines to 86** (2026-08-11). It sat 4 lines under its 110-line budget and warned on every build, while the Decision index that must stay grows by a line per record. The repository tree at the top is what went: a changing inventory of the working tree, duplicating `techContext.md`''s module layout, deployment boundary, and discovery model, and contradicting the file''s own closing rule to index durable relationships only. The build warning is gone and the routing reduction improved from 55.69 % to 56.11 % against its 50 % floor — curation moves that gate the right way, which is the direction to check before any Memory Bank edit. Two recorded premises did not survive inspection and are corrected here: `techContext.md`''s per-test-file inventory had already been curated away, and the routing gate is not at 49.57 % with roughly 1 KB of headroom. ### Fixed - **CI resolves the `uv` install step again** (2026-08-12). Every test leg failed before it ran a single job step, at *Prepare all required actions*: `Unable to resolve action astral-sh/setup-uv@v9, unable to find version v9`. `astral-sh/setup-uv` stopped publishing a floating major alias after `v7` — `v8.3.2` and `v9.0.0` exist as full release tags, `refs/tags/v8` and `refs/tags/v9` do not — so the reference had never been resolvable. The step is now pinned to `v9.0.0`, which the workflow comment explains, and the step takes no inputs so the major bump carries no configuration risk. The three `actions/*` references in the same workflow were checked against the tag API and all resolve. - **`Set-CustomizationLink` no longer prompts, discards, or follows a link out of the tree** (2026-08-11). Three review findings had been recorded and deferred; all three still reproduced, and the reproductions are now regression tests. The `Read-Host` before replacing a non-empty discovery folder is gone. The function is reachable unattended through the shipped `Update-CopilotAtelier -Force` path, where a prompt does not fail — it waits forever on a host with no console. The opt-in is now `-Force`, surfaced on `Install-CopilotAtelier` and on [`Setup-CopilotSettings.ps1`](Setup-CopilotSettings.ps1); without it a populated folder is left alone and the message names the switch. Interactive users who previously answered `y` in-flight now re-run with `-Force`. A child present in both the folder and the target used to be skipped and then destroyed by the `Remove-Item -Recurse` that followed. Measured against the previous implementation: a file holding `deployed copy, 126 lines` was gone after the merge, leaving only `repository copy, 106 lines` — the same shape as the drift `.memory-bank` already recorded in the wild, where the deployed copy was the newer one. And `Copy-Item -Recurse` followed a junction inside the folder, materialising content from outside the tree inside the target. Both are closed by one rule, recorded as [decision 0020](.memory-bank/decisions/0020-refuse-lossy-customization-merges.md): anything that cannot be merged without losing content stops the merge, and nothing is copied or removed. A child already in the target is dropped only when both sides are files with the same length and the same SHA-256; a directory on either side, a differing file, a child that is a reparse point, and a child containing one at any depth all stop the merge and are named in the report. *Newest wins* was rejected because a timestamp is not evidence, and *source always wins* was rejected because it is the defect. The seven new tests create real junctions on Windows and real symbolic links elsewhere, neither of which needs elevation, so the reparse-point cases are exercised rather than skipped. ### Added - **Pester 4 to 5 migration tooling in `pester-patterns`** (2026-08-12). A v4 suite does not fail loudly on v5, it fails quietly: setup that ran per test now runs once during Discovery, a mock that covered a `Describe` now covers only where it sits, and `Should -Throw` matches with `-like`. A migrated test can pass while asserting less than it did before, so the work needs a detection sweep and a baseline count rather than a careful read of the diff. [`scripts/Find-PesterV4Pattern.ps1`](Skills/pester-patterns/scripts/Find-PesterV4Pattern.ps1) parses each file''s AST and reports legacy `Should`, `Assert-MockCalled` and `Assert-VerifiableMock(s)`, `Describe`/`Context`/`It` wrapped in `InModuleScope`, `$MyInvocation.MyCommand.Path`, commands running at file top level or in a block body, and retired `Invoke-Pester` parameters. The replacements, mock scoping rules, runner parameter map, and completion checklist are in [`references/migrating-pester-v4-to-v5.md`](Skills/pester-patterns/references/migrating-pester-v4-to-v5.md). The script reports and never rewrites, because two of its finding classes are legal Pester 5. Against this repository''s own suite it returns zero `BlockBodyCommand` findings and 18 `TopLevelCommand` findings, every one of them a deliberate discovery-time assignment feeding `-ForEach`. That ratio is the point: a detector that called those defects would be ignored within a day. The `description` is deliberately untouched, so the trigger surface is unchanged and no eval sweep is owed — which also means a bare *"migrate my Pester 4 tests"* still routes on the old wording, where `sampler-migration` also claims Pester 4 to 5. That boundary is recorded in both new query sets rather than papered over, and the first sweep settles it. - **Trigger coverage gate and a first cluster of query sets** (2026-08-12). One Skill of forty-four had labelled trigger queries, so forty-three descriptions had never been measured for discovery at all. [`tests/SkillTriggerCoverage.Tests.ps1`](tests/SkillTriggerCoverage.Tests.ps1) makes that a tracked debt instead of an invisible one: every Skill needs a query set or an entry on a documented uncovered baseline, the baseline may only shrink, a Skill that gains a set fails until its entry is removed, and a query set that outlives its Skill is caught as an orphan. Each set is checked for unique ids, valid splits, and at least three positives and three negatives with both halves populated. Five sets ship with it — `pester-patterns`, `test-driven-development`, `sampler-build-debug`, `sampler-framework`, `sampler-migration` — chosen because they are the cluster most likely to collide with each other. Every negative is a near miss lifted from a sibling Skill rather than an unrelated topic, so a description edit that widens the net is penalised instead of rewarded. Thirty-eight Skills remain on the baseline; none of the five sets has been run yet, so the gate claims only that the queries exist, not that the descriptions pass. - **A secret scan and frontmatter gates for the other three Customization types** (2026-08-12). [`tests/SecretScan.Tests.ps1`](tests/SecretScan.Tests.ps1) scans the payload, the module source, the build, and the Memory Bank for six high-signal credential shapes — private key blocks, GitHub classic and fine-grained tokens, AWS access key ids, Azure storage account keys, and Slack tokens. Generic `password = "..."` matching was rejected: it fires on placeholders and parameter names throughout the Skills, and a scanner that cries wolf gets suppressed rather than fixed. It carries a planted-credential test, because a gate never shown to reject a bad input is a green build with nothing behind it. [`tests/CustomizationFrontmatter.Tests.ps1`](tests/CustomizationFrontmatter.Tests.ps1) closes the gap left by `SkillFrontmatter`, which only ever covered Skills: Custom agents need a slug `name`, a `description`, and a `model` array with at least two entries so a model retirement degrades instead of breaking every agent; Instructions need a non-empty `applyTo`, without which they never auto-apply; Prompts need the `description` the picker shows. - **`run-trigger-evals.ps1 -Dispatch Batch`, now the default** (2026-08-11). Execute mode was a sequential `foreach` over N queries by R repetitions, which turned pure network latency into wall-clock time for no benefit; the run the harness actually wants is N by R by M model tiers, and 20 x 3 x 3 = 180 sequential calls is not practical. The s' } } } |