Sync third-party and MCP marketplace plugins
Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources. Confidence: high Scope-risk: narrow Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history. Tested: Marketplace validation passed.
This commit is contained in:
1 parent
e4ce1effaf
commit
ebe8c7d892
171 files changed
+9766
-499
No files matched your search
@@ -677,6 +677,65 @@ function Apply-LocalOverrides {
|
||||
}
|
||||
}
|
||||
|
||||
function Get-GiteaArchive {
|
||||
param(
|
||||
[object]$Source,
|
||||
[string]$CloneRoot,
|
||||
[string]$ClonePath,
|
||||
[object[]]$SparseCheckout
|
||||
)
|
||||
$archivePath = Join-Path $CloneRoot "$($Source.id)-release.zip"
|
||||
$extractPath = Join-Path $CloneRoot "$($Source.id)-release-extract"
|
||||
Remove-PathIfExists -Path $archivePath -Within $CloneRoot
|
||||
Remove-PathIfExists -Path $extractPath -Within $CloneRoot
|
||||
Remove-PathIfExists -Path $ClonePath -Within $CloneRoot
|
||||
try {
|
||||
Invoke-WebRequest -Uri ([string]$Source._releaseArchiveUrl) -OutFile $archivePath -UseBasicParsing -TimeoutSec 60
|
||||
Expand-Archive -LiteralPath $archivePath -DestinationPath $extractPath -Force
|
||||
$entries = @(Get-ChildItem -LiteralPath $extractPath -Force)
|
||||
$sourceRoot = $extractPath
|
||||
if ($entries.Count -eq 1 -and $entries[0].PSIsContainer) {
|
||||
$sourceRoot = $entries[0].FullName
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path $ClonePath | Out-Null
|
||||
if ($SparseCheckout.Count -gt 0) {
|
||||
foreach ($path in $SparseCheckout) {
|
||||
$relative = [string]$path
|
||||
Assert-RelativePathValue -Path $relative
|
||||
$sourcePath = Join-Path $sourceRoot $relative
|
||||
if (-not (Test-Path -LiteralPath $sourcePath)) {
|
||||
continue
|
||||
}
|
||||
$destination = Join-Path $ClonePath $relative
|
||||
$parent = Split-Path -Path $destination -Parent
|
||||
New-Item -ItemType Directory -Force -Path $parent | Out-Null
|
||||
Copy-Item -LiteralPath $sourcePath -Destination $destination -Recurse -Force
|
||||
}
|
||||
} else {
|
||||
Copy-DirectoryFiltered -Source $sourceRoot -Destination $ClonePath -Within $CloneRoot
|
||||
}
|
||||
$selectedFiles = @(Get-ChildItem -LiteralPath $ClonePath -Recurse -File)
|
||||
if ($selectedFiles.Count -eq 0) {
|
||||
throw "Gitea archive contained no selected files for $($Source.id)"
|
||||
}
|
||||
$commit = [string]$Source._releaseCommit
|
||||
if ($commit -notmatch '^[0-9a-fA-F]{40}$') {
|
||||
$commitInfo = Invoke-RestMethod -Uri ([string]$Source._releaseCommitApiUrl) -Headers @{ Accept = "application/json"; "User-Agent" = "skill-market" } -TimeoutSec 30
|
||||
$commit = [string]$commitInfo.sha
|
||||
}
|
||||
if ($commit -notmatch '^[0-9a-fA-F]{40}$') {
|
||||
throw "Invalid Gitea commit for $($Source.id): $commit"
|
||||
}
|
||||
return [ordered]@{
|
||||
path = $ClonePath
|
||||
commit = $commit.ToLowerInvariant()
|
||||
}
|
||||
} finally {
|
||||
Remove-PathIfExists -Path $archivePath -Within $CloneRoot
|
||||
Remove-PathIfExists -Path $extractPath -Within $CloneRoot
|
||||
}
|
||||
}
|
||||
|
||||
function Get-Clone {
|
||||
param(
|
||||
[object]$Source,
|
||||
@@ -701,6 +760,28 @@ function Get-Clone {
|
||||
$Source | Add-Member -NotePropertyName manifestOverrides -NotePropertyValue ([pscustomobject]@{}) -Force
|
||||
}
|
||||
$Source.manifestOverrides | Add-Member -NotePropertyName version -NotePropertyValue $tag.TrimStart('v') -Force
|
||||
if ($provider -eq "gitea") {
|
||||
$escapedTag = [uri]::EscapeDataString($tag)
|
||||
$archiveUrl = [string]$release.zipball_url
|
||||
if (-not $archiveUrl) { $archiveUrl = "https://$repoHost/$owner/$repoName/archive/$escapedTag.zip" }
|
||||
$Source | Add-Member -NotePropertyName _releaseArchiveUrl -NotePropertyValue $archiveUrl -Force
|
||||
$Source | Add-Member -NotePropertyName _releaseCommitApiUrl -NotePropertyValue "$apiRoot/repos/$owner/$repoName/git/commits/$escapedTag" -Force
|
||||
$targetCommit = [string]$release.target_commitish
|
||||
if ($targetCommit -match '^[0-9a-fA-F]{40}$') {
|
||||
$Source | Add-Member -NotePropertyName _releaseCommit -NotePropertyValue $targetCommit.ToLowerInvariant() -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
$repoProvider = ""
|
||||
if ($Source.PSObject.Properties.Name -contains "repoProvider") { $repoProvider = [string]$Source.repoProvider }
|
||||
if ($repoProvider -eq "gitea" -and -not $Source._releaseArchiveUrl) {
|
||||
if ($Source.repo -notmatch '^https://([A-Za-z0-9.-]+(?::[0-9]+)?)/([\w-]+)/([\w.-]+?)(?:\.git)?$' -or -not $Source.ref) {
|
||||
throw "Gitea archive fallback requires an HTTPS repository and ref: $($Source.id)"
|
||||
}
|
||||
$repoHost, $owner, $repoName = $Matches[1], $Matches[2], $Matches[3]
|
||||
$escapedRef = [uri]::EscapeDataString([string]$Source.ref)
|
||||
$Source | Add-Member -NotePropertyName _releaseArchiveUrl -NotePropertyValue "https://$repoHost/$owner/$repoName/archive/$escapedRef.zip" -Force
|
||||
$Source | Add-Member -NotePropertyName _releaseCommitApiUrl -NotePropertyValue "https://$repoHost/api/v1/repos/$owner/$repoName/git/commits/$escapedRef" -Force
|
||||
}
|
||||
$clonePath = Join-Path $CloneRoot $Source.id
|
||||
Remove-PathIfExists -Path $clonePath -Within $CloneRoot
|
||||
@@ -730,6 +811,10 @@ function Get-Clone {
|
||||
}
|
||||
break
|
||||
} catch {
|
||||
if (($Source.releaseProvider -eq "gitea" -or $Source.repoProvider -eq "gitea") -and $Source._releaseArchiveUrl) {
|
||||
Write-Warning "Git clone failed for $($Source.id); using Gitea archive."
|
||||
return Get-GiteaArchive -Source $Source -CloneRoot $CloneRoot -ClonePath $clonePath -SparseCheckout $sparseCheckout
|
||||
}
|
||||
if ($attempt -eq $maxAttempts) {
|
||||
throw "Third-party source $($Source.id) clone failed after $maxAttempts attempts: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user