137 lines
3.9 KiB
PowerShell
137 lines
3.9 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[string]$Source,
|
|
[string]$Dest,
|
|
[string]$SkillsDir,
|
|
[string]$Agent = $(if ($env:HTSY_SKILL_AGENT) { $env:HTSY_SKILL_AGENT } else { "" }),
|
|
[string]$Repo = $(if ($env:HTSY_SKILL_REPO_URL) { $env:HTSY_SKILL_REPO_URL } else { "https://git.ikuban.com/server/htsy-skill.git" })
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Resolve-Dest {
|
|
param(
|
|
[string]$ExactDest,
|
|
[string]$ParentSkillsDir,
|
|
[string]$TargetAgent
|
|
)
|
|
|
|
if ($ExactDest) {
|
|
return $ExactDest
|
|
}
|
|
|
|
if ($env:HTSY_SKILL_DEST) {
|
|
return $env:HTSY_SKILL_DEST
|
|
}
|
|
|
|
if (-not $ParentSkillsDir -and $env:AGENT_SKILLS_DIR) {
|
|
$ParentSkillsDir = $env:AGENT_SKILLS_DIR
|
|
}
|
|
|
|
if ($ParentSkillsDir) {
|
|
return Join-Path $ParentSkillsDir "htsy"
|
|
}
|
|
|
|
switch ($TargetAgent) {
|
|
"claude" {
|
|
$claudeHome = $env:CLAUDE_HOME
|
|
if (-not $claudeHome) {
|
|
$claudeHome = Join-Path $HOME ".claude"
|
|
}
|
|
return Join-Path (Join-Path $claudeHome "skills") "htsy"
|
|
}
|
|
"claude-user" {
|
|
$claudeHome = $env:CLAUDE_HOME
|
|
if (-not $claudeHome) {
|
|
$claudeHome = Join-Path $HOME ".claude"
|
|
}
|
|
return Join-Path (Join-Path $claudeHome "skills") "htsy"
|
|
}
|
|
"claude-project" {
|
|
return Join-Path (Join-Path (Join-Path (Get-Location).Path ".claude") "skills") "htsy"
|
|
}
|
|
"codex" {
|
|
$codexHome = $env:CODEX_HOME
|
|
if (-not $codexHome) {
|
|
$codexHome = Join-Path $HOME ".codex"
|
|
}
|
|
return Join-Path (Join-Path $codexHome "skills") "htsy"
|
|
}
|
|
"" {
|
|
throw "Specify -Agent claude|claude-project|codex, -SkillsDir, or -Dest."
|
|
}
|
|
default {
|
|
throw "Unknown agent: $TargetAgent"
|
|
}
|
|
}
|
|
}
|
|
|
|
function Copy-Skill {
|
|
param(
|
|
[Parameter(Mandatory = $true)][string]$From,
|
|
[Parameter(Mandatory = $true)][string]$To
|
|
)
|
|
|
|
if (-not (Test-Path (Join-Path $From "SKILL.md"))) {
|
|
throw "Invalid source: $From does not contain SKILL.md"
|
|
}
|
|
|
|
$destParent = Split-Path -Parent $To
|
|
if (-not (Test-Path $destParent)) {
|
|
New-Item -ItemType Directory -Force $destParent | Out-Null
|
|
}
|
|
|
|
$tmpDest = Join-Path $destParent (".htsy-install-{0}" -f ([guid]::NewGuid().ToString("N")))
|
|
New-Item -ItemType Directory -Force $tmpDest | Out-Null
|
|
|
|
try {
|
|
Get-ChildItem -LiteralPath $From -Force | Copy-Item -Destination $tmpDest -Recurse -Force
|
|
|
|
if (Test-Path $To) {
|
|
Remove-Item -Path $To -Recurse -Force
|
|
}
|
|
|
|
Move-Item -Path $tmpDest -Destination $To
|
|
}
|
|
catch {
|
|
if (Test-Path $tmpDest) {
|
|
Remove-Item -Path $tmpDest -Recurse -Force
|
|
}
|
|
throw
|
|
}
|
|
}
|
|
|
|
$Dest = Resolve-Dest -ExactDest $Dest -ParentSkillsDir $SkillsDir -TargetAgent $Agent
|
|
|
|
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$repoRoot = (Resolve-Path (Join-Path $scriptDir "..")).Path
|
|
$tempRoot = $null
|
|
|
|
try {
|
|
if (-not $Source) {
|
|
$localSkill = Join-Path $repoRoot "htsy"
|
|
if (Test-Path (Join-Path $localSkill "SKILL.md")) {
|
|
$Source = $localSkill
|
|
}
|
|
else {
|
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
|
throw "git is required when the local htsy/ directory is unavailable."
|
|
}
|
|
|
|
$tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("htsy-skill-{0}" -f ([guid]::NewGuid().ToString("N")))
|
|
git clone --depth 1 $Repo $tempRoot
|
|
$Source = Join-Path $tempRoot "htsy"
|
|
}
|
|
}
|
|
|
|
Copy-Skill -From $Source -To $Dest
|
|
|
|
Write-Host "Installed htsy skill to: $Dest"
|
|
Write-Host "Verify: $(Join-Path $Dest 'SKILL.md')"
|
|
}
|
|
finally {
|
|
if ($tempRoot -and (Test-Path $tempRoot)) {
|
|
Remove-Item -Path $tempRoot -Recurse -Force
|
|
}
|
|
}
|