Files
broodcicada-glitch 7154ed7fa5 Add Cursor generator plugin with slash commands and installers. (#417)
Ship a first-class Cursor adaptation (commands, skill, rules, marketplace manifest, CI installer tests) and document generator vs Hub consumer install paths in README/README_CN.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 15:25:52 +08:00

125 lines
5.6 KiB
PowerShell

# Install the CLI-Anything Cursor plugin with vendored methodology resources.
param(
[switch]$Force,
[switch]$Help
)
$ErrorActionPreference = "Stop"
if ($Help) {
Write-Host "Usage: .\install.ps1 [-Force]"
Write-Host "Install the CLI-Anything Cursor plugin with vendored methodology resources."
Write-Host "Destination: `$env:CURSOR_PLUGINS_HOME\local\cli-anything (default: %USERPROFILE%\.cursor\plugins\local\cli-anything)"
exit 0
}
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
. (Join-Path $scriptDir "lib.ps1")
$pluginSrc = Split-Path -Parent $scriptDir
$repoRoot = Split-Path -Parent $pluginSrc
$canonicalPlugin = Join-Path $repoRoot "cli-anything-plugin"
$previewProtocol = Join-Path $repoRoot "docs\PREVIEW_PROTOCOL.md"
if ($env:CURSOR_PLUGINS_HOME) {
$pluginsHome = Resolve-CliAnythingPluginsHome -Raw $env:CURSOR_PLUGINS_HOME -Create
} elseif ($env:USERPROFILE) {
$pluginsHome = Resolve-CliAnythingPluginsHome -Raw (Join-Path $env:USERPROFILE ".cursor\plugins") -Create
} else {
throw "CURSOR_PLUGINS_HOME is not set and USERPROFILE is unavailable."
}
$discoveryPointer = Get-CliAnythingDiscoveryPointerPath
$userCursor = Split-Path -Parent $discoveryPointer
$destRoot = Join-Path $pluginsHome "local"
$destDir = Join-Path $destRoot "cli-anything"
$stagingDir = $null
$backupDir = $null
if (-not (Test-Path (Join-Path $canonicalPlugin "HARNESS.md"))) {
throw "Cannot find canonical CLI-Anything resources at: $canonicalPlugin`nRun this installer from a full CLI-Anything repository checkout."
}
if (-not (Test-Path $previewProtocol)) {
throw "Cannot find preview protocol at: $previewProtocol`nRun this installer from a full CLI-Anything repository checkout."
}
if (-not (Test-Path (Join-Path $pluginSrc ".cursor-plugin\plugin.json"))) {
throw "Cannot find Cursor plugin manifest at: $(Join-Path $pluginSrc '.cursor-plugin\plugin.json')"
}
New-Item -ItemType Directory -Path $destRoot -Force | Out-Null
New-Item -ItemType Directory -Path $userCursor -Force | Out-Null
if (Test-Path $destDir) {
if (-not $Force) {
throw "Refusing to overwrite existing plugin: $destDir`nRe-run with -Force to upgrade, or remove it manually."
}
}
try {
$stagingDir = Join-Path $destRoot (".cli-anything.tmp." + [System.Guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Path $stagingDir | Out-Null
Get-ChildItem -LiteralPath $pluginSrc -Force | ForEach-Object {
if ($_.Name -in @("tests", "references", ".git")) {
return
}
Copy-Item -LiteralPath $_.FullName -Destination (Join-Path $stagingDir $_.Name) -Recurse -Force
}
$referenceDir = Join-Path $stagingDir "references"
$referenceCommands = Join-Path $referenceDir "commands"
$referenceDocs = Join-Path $referenceDir "docs"
$referenceGuides = Join-Path $referenceDir "guides"
$resourceScripts = Join-Path $stagingDir "scripts"
$scriptTemplates = Join-Path $resourceScripts "templates"
New-Item -ItemType Directory -Path $referenceCommands, $referenceDocs, $referenceGuides, $scriptTemplates -Force | Out-Null
Copy-Item -Path (Join-Path $canonicalPlugin "HARNESS.md") -Destination (Join-Path $referenceDir "HARNESS.md")
Copy-Item -Path (Join-Path $canonicalPlugin "commands\*.md") -Destination $referenceCommands
Copy-Item -Path (Join-Path $canonicalPlugin "guides\*.md") -Destination $referenceGuides
Copy-Item -Path (Join-Path $canonicalPlugin "repl_skin.py") -Destination (Join-Path $resourceScripts "repl_skin.py")
Copy-Item -Path (Join-Path $canonicalPlugin "preview_bundle.py") -Destination (Join-Path $resourceScripts "preview_bundle.py")
Copy-Item -Path (Join-Path $canonicalPlugin "skill_generator.py") -Destination (Join-Path $resourceScripts "skill_generator.py")
Copy-Item -Path (Join-Path $canonicalPlugin "templates\*") -Destination $scriptTemplates
Copy-Item -Path $previewProtocol -Destination (Join-Path $referenceDocs "PREVIEW_PROTOCOL.md")
# If interrupted after moving the old install aside, look for
# $destRoot\.cli-anything.bak.* and restore it manually.
if (Test-Path $destDir) {
$backupDir = Join-Path $destRoot (".cli-anything.bak." + [System.Guid]::NewGuid().ToString("N"))
Move-Item -LiteralPath $destDir -Destination $backupDir
try {
Move-Item -LiteralPath $stagingDir -Destination $destDir
$stagingDir = $null
Remove-Item -LiteralPath $backupDir -Recurse -Force
$backupDir = $null
} catch {
if ($backupDir -and (Test-Path $backupDir)) {
Move-Item -LiteralPath $backupDir -Destination $destDir -Force
}
throw
}
} else {
Move-Item -LiteralPath $stagingDir -Destination $destDir
$stagingDir = $null
}
} finally {
if ($stagingDir -and (Test-Path $stagingDir)) {
Remove-Item -LiteralPath $stagingDir -Recurse -Force
}
}
$pluginRoot = [System.IO.Path]::GetFullPath($destDir)
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
[System.IO.File]::WriteAllText((Join-Path $pluginRoot "PLUGIN_ROOT.txt"), ($pluginRoot + [Environment]::NewLine), $utf8NoBom)
[System.IO.File]::WriteAllText($discoveryPointer, ($pluginRoot + [Environment]::NewLine), $utf8NoBom)
Write-Host "Installed Cursor plugin to: $pluginRoot"
Write-Host "Wrote PLUGIN_ROOT stamp and discovery pointer: $discoveryPointer"
Write-Host "Vendored CLI-Anything methodology resources into the installed plugin."
Write-Host "Reload the Cursor window (Developer: Reload Window) to pick up commands."
Write-Host "Consumer Hub/skills are separate: npx skills add HKUDS/CLI-Anything --skill cli-hub-meta-skill -g -y"