feat: add browser AI connection guide and calculator instructions
Publish GitHub Pages output / publish (push) Successful in 43s
Publish GitHub Pages output / publish (push) Successful in 43s
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$taskRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..'))
|
||||
$pluginRoot = Join-Path $taskRoot 'plugins\holodori-web-assistant'
|
||||
$skillRoot = Join-Path $pluginRoot 'skills\holodori-web-assistant'
|
||||
$outputRoot = Join-Path $taskRoot 'plugin-dist'
|
||||
$manifest = Get-Content -LiteralPath (Join-Path $pluginRoot 'plugin.json') -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
if ($manifest.name -ne 'holodori-web-assistant' -or $manifest.version -notmatch '^\d+\.\d+\.\d+$') { throw 'Invalid plugin identity.' }
|
||||
if ($manifest.extensions.'com.openai'.interface.shortDescription.Length -gt 30) { throw 'Plugin subtitle is too long.' }
|
||||
$allowed = @('plugin.json', 'assets/icon.svg', 'skills/holodori-web-assistant/SKILL.md', 'skills/holodori-web-assistant/agents/openai.yaml', 'skills/holodori-web-assistant/references/requests.md', 'skills/holodori-web-assistant/references/browser-workflow.md')
|
||||
$sourceFiles = @(Get-ChildItem -LiteralPath $pluginRoot -Recurse -File)
|
||||
$paths = @($sourceFiles | ForEach-Object { [System.IO.Path]::GetRelativePath($pluginRoot, $_.FullName).Replace('\', '/') })
|
||||
if ($paths.Count -ne $allowed.Count -or (Compare-Object $paths $allowed)) { throw 'The instruction package must contain only its declared files.' }
|
||||
$skill = Get-Content -LiteralPath (Join-Path $skillRoot 'SKILL.md') -Raw -Encoding UTF8
|
||||
if ($skill -notmatch '^---\r?\nname: holodori-web-assistant\r?\ndescription: [^\r\n]+\r?\n---') { throw 'Invalid skill frontmatter.' }
|
||||
New-Item -ItemType Directory -Path $outputRoot -Force | Out-Null
|
||||
$pluginZip = Join-Path $outputRoot 'holodori-web-assistant-plugin.zip'
|
||||
$skillZip = Join-Path $outputRoot 'holodori-web-assistant-skill.zip'
|
||||
Compress-Archive -Path (Join-Path $pluginRoot '*') -DestinationPath $pluginZip -Force
|
||||
Compress-Archive -LiteralPath $skillRoot -DestinationPath $skillZip -Force
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
foreach ($archive in @($pluginZip, $skillZip)) {
|
||||
$zip = [System.IO.Compression.ZipFile]::OpenRead($archive)
|
||||
try {
|
||||
$expected = if ($archive -eq $pluginZip) { $allowed } else { @('holodori-web-assistant/SKILL.md', 'holodori-web-assistant/agents/openai.yaml', 'holodori-web-assistant/references/requests.md', 'holodori-web-assistant/references/browser-workflow.md') }
|
||||
$actual = @($zip.Entries | Where-Object { -not $_.FullName.EndsWith('/') } | ForEach-Object { $_.FullName })
|
||||
if (Compare-Object $actual $expected) { throw 'Unexpected ZIP contents.' }
|
||||
foreach ($entry in $zip.Entries) {
|
||||
if ($entry.FullName.EndsWith('/')) { continue }
|
||||
$relative = if ($archive -eq $pluginZip) { $entry.FullName } else { 'skills/' + $entry.FullName }
|
||||
$source = Join-Path $pluginRoot $relative
|
||||
$stream = $entry.Open()
|
||||
$hasher = [System.Security.Cryptography.SHA256]::Create()
|
||||
try { $archiveHash = [Convert]::ToHexString($hasher.ComputeHash($stream)) }
|
||||
finally { $stream.Dispose(); $hasher.Dispose() }
|
||||
if ($archiveHash -ne (Get-FileHash -LiteralPath $source -Algorithm SHA256).Hash) { throw 'Archive hash mismatch.' }
|
||||
}
|
||||
Write-Output "Verified $archive ($($actual.Count) files; $((Get-Item -LiteralPath $archive).Length) bytes)."
|
||||
} finally { $zip.Dispose() }
|
||||
}
|
||||
$downloadRoot = Join-Path $taskRoot 'static\downloads'
|
||||
New-Item -ItemType Directory -Path $downloadRoot -Force | Out-Null
|
||||
foreach ($archive in @($pluginZip, $skillZip)) {
|
||||
$destination = Join-Path $downloadRoot ([System.IO.Path]::GetFileName($archive))
|
||||
Copy-Item -LiteralPath $archive -Destination $destination -Force
|
||||
if ((Get-FileHash -LiteralPath $archive).Hash -ne (Get-FileHash -LiteralPath $destination).Hash) { throw 'Download copy hash mismatch.' }
|
||||
Write-Output "Prepared website download: $destination"
|
||||
}
|
||||
$guideRoot = Join-Path $taskRoot 'static\ai'
|
||||
New-Item -ItemType Directory -Path $guideRoot -Force | Out-Null
|
||||
$guide = $skill.Replace('[references/browser-workflow.md](references/browser-workflow.md)', '[Browser calculation workflow](#browser-calculation-workflow)').Replace('[references/requests.md](references/requests.md)', '[Analysis requests](#analysis-requests)')
|
||||
foreach ($reference in @('browser-workflow.md', 'requests.md')) {
|
||||
$guide += "`n`n" + (Get-Content -LiteralPath (Join-Path $skillRoot "references\$reference") -Raw -Encoding UTF8)
|
||||
}
|
||||
if ($guide -match '\]\(references/') { throw 'The standalone guide must not require separate reference files.' }
|
||||
$guidePath = Join-Path $guideRoot 'SKILL.md'
|
||||
[System.IO.File]::WriteAllText($guidePath, $guide, [System.Text.UTF8Encoding]::new($false))
|
||||
$escapedGuide = [System.Net.WebUtility]::HtmlEncode($guide)
|
||||
$html = @"
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>SKILL.md · HolodoriCalc AI usage guide</title>
|
||||
<style>body{max-width:960px;margin:32px auto;padding:0 24px;background:#11151b;color:#e5e7eb;font:16px/1.7 system-ui,sans-serif}a{color:#f3a5c5}pre{white-space:pre-wrap;overflow-wrap:anywhere;font:14px/1.7 ui-monospace,monospace}</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>HolodoriCalc · SKILL.md</h1>
|
||||
<p>GPT용 사용 안내입니다. 아래 내용을 읽고 원래 계산기 탭에서 작업하세요. <a href="./SKILL.md" download>SKILL.md 다운로드</a></p>
|
||||
<pre aria-label="SKILL.md">$escapedGuide</pre>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
[System.IO.File]::WriteAllText((Join-Path $guideRoot 'SKILL.html'), $html, [System.Text.UTF8Encoding]::new($false))
|
||||
if ((Get-Content -LiteralPath $guidePath -Raw -Encoding UTF8) -ne $guide) { throw 'Standalone guide content mismatch.' }
|
||||
Write-Output "Prepared standalone AI guide: $guidePath"
|
||||
Reference in New Issue
Block a user