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 = 'preview0001' ReleaseNotes = '## [4.0.0-preview0001] - 2026-08-12 ### Changed - **`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 - **`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 sweep now goes through `Invoke-ShpBatch`, which dispatches items concurrently in a bounded runspace pool. Measured on the identical pinned 69-call sweep: **26.3 s batched at `-ThrottleLimit 4` against 103.9 s sequential, for the same money** (0.7623 USD against 0.7659 USD). `-Dispatch Sequential` is kept, and documented, so an older run stays reproducible and a ShellPilot without `Invoke-ShpBatch` still works. Three consequences of the batch contract are now enforced rather than assumed. Every item is dispatched with `-History @()`, so the batch neither reads nor writes a session conversation and the `Clear-ShpChat` reset the sequential path depends on is gone from it — a test asserts zero resets under batch and exactly one per prompt under sequential. A failed item arrives as data with `Success` false instead of aborting the sweep, so the harness''s hand-rolled `try`/`catch` is no longer what provides isolation. And results arrive in **completion** order, so replies are correlated on the item `Id`: the test stub returns results reversed on purpose and asserts the content of every reply file, because a position-correlated harness would file every answer under the wrong query and still look successful. The `-Temperature` guard now probes the command that will actually dispatch, so a ShellPilot whose `Invoke-ShpBatch` predates the parameter is named as such rather than passing because `Invoke-Shp` happens to have it. **Concurrency did not change what is measured, and the control proves it.** Batched and sequential sweeps of the same description graded train 15/15 both ways and validation 7/8 batched against 6/8 sequential. The difference is not dispatch: two *sequential* runs of that same description disagreed with each other by just as much, scoring `pos-09` at 1/3 and then 2/3, and `pos-06` at 3/3 and then 1/3. `-Temperature 0` reduces the judge''s run-to-run variance but does not remove it, so any query sitting near the 0.5 trigger threshold moves between runs whichever way it is dispatched. - **Two conformance guards the audit found missing** (2026-08-11). [`tests/PluginManifest.Tests.ps1`](tests/PluginManifest.Tests.ps1) validates [`plugin.json`](plugin.json), which until now nothing in the build or the test suite read at all. It asserts a loadable `name`, that both declared component paths resolve to directories holding the artifacts they claim, that `version` equals the most recent released `CHANGELOG.md` section — the field is hand-maintained while GitVersion sets everything else, and both VS Code and the CLI detect a plugin update from it — and that the Agent Plugins `$schema` is not declared while the skills folder is capitalised. That last one guards a silent failure rather than a present defect: without `$schema` the manifest loads in the legacy Copilot format, where `"skills": "Skills/"` overrides the default component path and is the only reason a capital-S folder is discovered. Agent Plugins 1.0 ignores those fields and reads skills solely from a lowercase `./skills`, so adding the schema without renaming the folder would drop all 44 Skills with no error. The manifest also gained the `license`, `repository`, `homepage`, and `keywords` fields the format supports and it had left empty. [`tests/SkillFrontmatter.Tests.ps1`](tests/SkillFrontmatter.Tests.ps1) turns the over-budget baseline from a list into a map of Skill to current body length. The list could already never grow, and a Skill could never leave it silently, but a Skill already on it could grow without limit — `pester-patterns` at 796 lines could have reached 1,200 unchallenged. Each entry is now a high-water mark, so the only ways forward are splitting into references or a deliberate, reviewed increase. The same file gained the equivalent ratchet for descriptions, where the failure is worse: the GitHub Copilot CLI drops a Skill whose description passes 1024 characters and reports nothing. Eight descriptions were already past a 1000-character soft cap and `authenticated-web-extraction` stood at exactly 1024 — one added character from a silent drop, with only the hard cap to catch it and nothing to warn on the way up. Each is pinned to its current length, so crossing the soft cap is now a deliberate baseline edit rather than an accident during trigger-eval optimisation, which is precisely when descriptions grow. - **`run-trigger-evals.ps1 -Temperature`, and the measurement it unblocked** (2026-08-11). The harness had no way to pin the judge, so a query that scored 1 of 3 could not be told apart from a reliable trigger that got unlucky, and every partial score was uninterpretable. `-Temperature` is omit-or-send —' } } } |