-
Notifications
You must be signed in to change notification settings - Fork 0
V0.9.0/finalization #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
gimlichael
wants to merge
22
commits into
main
Choose a base branch
from
v0.9.0/finalization
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
a1526d9
♻️ refactor skill documentation and evaluation framework
aicia-bot 3fef81e
✅ add comprehensive testing and validation for skill
aicia-bot 7cf3543
♻️ enhance runner selection and error handling in remote-test
aicia-bot 47f4a56
💬 update repository documentation for skill changes
aicia-bot c54b526
♻️ document build-tooling preparation in dotnet-remote-testing skill
aicia-bot 6618d7f
✨ add image provisioning to dotnet-remote-testing runner
aicia-bot 5b4213e
💬 update changelog with build-tooling preparation details
aicia-bot b3f9b30
🔨 add sync-skill-install.ps1 script for skill synchronization
aicia-bot ad660c1
📚 update repo governance for skill synchronization
aicia-bot 8d8003f
📝 clarify skill synchronization process in README
aicia-bot c5dd446
✨ make dotnet-remote-testing results faithful to local environment
aicia-bot f133ba7
💬 update changelog for v0.9.0
aicia-bot 1352427
♻️ refactor sync-skill-install for host-tool distinction
aicia-bot db92094
🐛 preserve configured user in docker prepared images
aicia-bot e3e2bdc
📚 expand git-visual-squash-summary catalog entry
aicia-bot 87f4a9d
♻️ clarify immediate-action contract in squash-summary skill
aicia-bot 699dbaa
♻️ clarify immediate-action contract in squash-summary skill
aicia-bot 6a2738f
🔨 add kebab-case validation to sync script
aicia-bot 5ecc791
🔧 strengthen dotnet-test validator contract
aicia-bot d130f08
♻️ refactor dotnet-test skill with immediate-action lockdown
aicia-bot 5318085
💬 update README for dotnet-test availability
aicia-bot adf42bf
🔀 merge branch 'v0.9.0/finalization' of https://github.com/codebeltne…
aicia-bot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,178 @@ | ||
| param( | ||
| [string[]]$Skill, | ||
| [switch]$VerifyOnly, | ||
| [switch]$Prune | ||
| ) | ||
|
|
||
| $ErrorActionPreference = 'Stop' | ||
|
|
||
| Set-StrictMode -Version Latest | ||
|
|
||
| $utf8NoBom = [System.Text.UTF8Encoding]::new($false) | ||
| [Console]::InputEncoding = $utf8NoBom | ||
| [Console]::OutputEncoding = $utf8NoBom | ||
| $OutputEncoding = $utf8NoBom | ||
|
|
||
| # Build output is regenerated per location, so its hashes never match across installs. Comparing it | ||
| # would bury real drift under noise and push agents back to fragile per-file copying. | ||
| $excludePattern = '(^|/)(bin|obj)/' | ||
|
|
||
| function Get-RepoRoot { | ||
| return (Resolve-Path (Join-Path $PSScriptRoot '..')).Path | ||
| } | ||
|
|
||
| # HostRoot is the tool's own directory. Its absence means the tool is not installed on this machine and | ||
| # there is genuinely nothing to sync; a missing skill directory *under* an installed tool is drift. | ||
| function Get-InstallRoot { | ||
| param([string]$SkillName) | ||
|
|
||
| $home_ = [Environment]::GetFolderPath('UserProfile') | ||
| return @( | ||
| [pscustomobject]@{ HostRoot = (Join-Path $home_ '.claude'); Path = (Join-Path $home_ ".claude/skills/$SkillName") }, | ||
| [pscustomobject]@{ HostRoot = (Join-Path $home_ '.agents'); Path = (Join-Path $home_ ".agents/skills/$SkillName") }, | ||
| [pscustomobject]@{ HostRoot = (Join-Path $home_ '.gemini/antigravity-cli'); Path = (Join-Path $home_ ".gemini/antigravity-cli/skills/$SkillName") } | ||
| ) | ||
| } | ||
|
|
||
| function Get-RelativeFile { | ||
| param([string]$Root) | ||
|
|
||
| if (-not (Test-Path $Root)) { | ||
| return @() | ||
| } | ||
|
|
||
| $base = (Resolve-Path $Root).Path.TrimEnd('\', '/') | ||
| return @(Get-ChildItem -LiteralPath $Root -Recurse -File -Force | | ||
| ForEach-Object { $_.FullName.Substring($base.Length + 1).Replace('\', '/') } | | ||
| Where-Object { $_ -notmatch $excludePattern }) | ||
| } | ||
|
|
||
| function Sync-SkillTree { | ||
| param( | ||
| [string]$SourceRoot, | ||
| [string]$InstallRoot, | ||
| [string[]]$RelativeFile | ||
| ) | ||
|
|
||
| foreach ($rel in $RelativeFile) { | ||
| $destination = Join-Path $InstallRoot $rel | ||
| $destinationDir = Split-Path -Parent $destination | ||
| if (-not (Test-Path $destinationDir)) { | ||
| New-Item -ItemType Directory -Force -Path $destinationDir | Out-Null | ||
| } | ||
|
|
||
| Copy-Item -LiteralPath (Join-Path $SourceRoot $rel) -Destination $destination -Force | ||
| } | ||
| } | ||
|
|
||
| function Test-SkillTree { | ||
| param( | ||
| [string]$SourceRoot, | ||
| [string]$InstallRoot, | ||
| [string[]]$RelativeFile | ||
| ) | ||
|
|
||
| $drift = @() | ||
|
|
||
| foreach ($rel in $RelativeFile) { | ||
| $expected = (Get-FileHash -LiteralPath (Join-Path $SourceRoot $rel) -Algorithm SHA256).Hash | ||
| $destination = Join-Path $InstallRoot $rel | ||
| $actual = if (Test-Path -LiteralPath $destination) { | ||
| (Get-FileHash -LiteralPath $destination -Algorithm SHA256).Hash | ||
| } | ||
| else { | ||
| 'MISSING' | ||
| } | ||
|
|
||
| if ($actual -ne $expected) { | ||
| $drift += " DRIFT $rel" | ||
| } | ||
| } | ||
|
|
||
| # A rename or deletion in the repository leaves the old file behind in an install, where a stale | ||
| # skill keeps loading it. Extras are drift too, not cosmetic residue. | ||
| foreach ($rel in (Get-RelativeFile -Root $InstallRoot)) { | ||
| if ($RelativeFile -notcontains $rel) { | ||
| if ($Prune) { | ||
| Remove-Item -LiteralPath (Join-Path $InstallRoot $rel) -Force | ||
| } | ||
| else { | ||
| $drift += " EXTRA $rel" | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return $drift | ||
| } | ||
|
|
||
| $repoRoot = Get-RepoRoot | ||
| $skillsRoot = Join-Path $repoRoot 'skills' | ||
|
|
||
| if (-not $Skill -or $Skill.Count -eq 0) { | ||
| $Skill = @(Get-ChildItem -LiteralPath $skillsRoot -Directory | ForEach-Object { $_.Name }) | ||
| } | ||
|
|
||
| $totalDrift = 0 | ||
|
|
||
| foreach ($name in $Skill) { | ||
| # Both roots are built by joining this name onto a trusted prefix, so a separator or `..` in it walks | ||
| # the sync out of the skill tree: the source becomes the repo and the install becomes the skills root, | ||
| # where -Prune would delete every other installed skill. Skill directories are kebab-case by | ||
| # convention, so anything else is malformed input rather than a skill that is merely missing. | ||
| if ($name -notmatch '^[a-z0-9]+(-[a-z0-9]+)*$') { | ||
| throw "Invalid skill name: '$name'. Expected a kebab-case skill directory name." | ||
| } | ||
|
|
||
| $sourceRoot = Join-Path $skillsRoot $name | ||
| if (-not (Test-Path -LiteralPath $sourceRoot)) { | ||
| Write-Host "[SKIP] $name (not a repo-managed skill)" | ||
| continue | ||
| } | ||
|
|
||
| $relativeFile = Get-RelativeFile -Root $sourceRoot | ||
|
|
||
| foreach ($install in (Get-InstallRoot -SkillName $name)) { | ||
| $installRoot = $install.Path | ||
|
|
||
| if (-not (Test-Path -LiteralPath $install.HostRoot)) { | ||
| Write-Host "[SKIP] $name -> $installRoot (host tool not installed)" | ||
| continue | ||
| } | ||
|
greptile-apps[bot] marked this conversation as resolved.
|
||
|
|
||
| # An installed host with no copy of the skill used to be skipped, which let a run where nothing | ||
| # was ever installed still report "verified, 0 drift". A sync creates the install; a verify fails. | ||
| if (-not (Test-Path -LiteralPath $installRoot)) { | ||
| if ($VerifyOnly) { | ||
| Write-Host "[FAIL] $name -> $installRoot (not installed)" | ||
| $totalDrift += 1 | ||
| continue | ||
| } | ||
|
|
||
| New-Item -ItemType Directory -Force -Path $installRoot | Out-Null | ||
| } | ||
|
|
||
| if (-not $VerifyOnly) { | ||
| Sync-SkillTree -SourceRoot $sourceRoot -InstallRoot $installRoot -RelativeFile $relativeFile | ||
| } | ||
|
|
||
| $drift = @(Test-SkillTree -SourceRoot $sourceRoot -InstallRoot $installRoot -RelativeFile $relativeFile) | ||
| $totalDrift += $drift.Count | ||
|
|
||
| if ($drift.Count -eq 0) { | ||
| Write-Host "[PASS] $name -> $installRoot ($($relativeFile.Count) files identical)" | ||
| } | ||
| else { | ||
| Write-Host "[FAIL] $name -> $installRoot ($($drift.Count) drifted)" | ||
| $drift | ForEach-Object { Write-Host $_ } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Write-Host '' | ||
| if ($totalDrift -eq 0) { | ||
| Write-Host "Install sync: verified, 0 drift." | ||
| exit 0 | ||
| } | ||
|
|
||
| Write-Host "Install sync: $totalDrift drifted entr$(if ($totalDrift -eq 1) { 'y' } else { 'ies' })." | ||
| exit 1 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.