|
|
@@ -0,0 +1,117 @@
|
|
|
+# OpenClaw Skill Deploy Script v1.3.0
|
|
|
+# Flatten 41 skills into ~/.openclaw/skills/
|
|
|
+# 批量将voc技能部署在龙虾skills目录下脚本
|
|
|
+# 需要将.openclaw的路径更换后使用
|
|
|
+# Usage:
|
|
|
+# .\deploy-to-openclaw.ps1 -DryRun # Preview only
|
|
|
+# .\deploy-to-openclaw.ps1 # Actual deploy
|
|
|
+# .\deploy-to-openclaw.ps1 -SkillsRoot "D:\custom\skills"
|
|
|
+
|
|
|
+param(
|
|
|
+ [string]$SkillsRoot = "$env:USERPROFILE\.openclaw\skills",
|
|
|
+ [string]$SourceRoot = $PSScriptRoot,
|
|
|
+ [switch]$DryRun
|
|
|
+)
|
|
|
+
|
|
|
+$ErrorActionPreference = "Stop"
|
|
|
+
|
|
|
+$categories = @(
|
|
|
+ "voc",
|
|
|
+ "social-media",
|
|
|
+ "competitor-analysis",
|
|
|
+ "review-analysis",
|
|
|
+ "synthesis",
|
|
|
+ "social-voc"
|
|
|
+)
|
|
|
+
|
|
|
+Write-Host "========================================"
|
|
|
+Write-Host " OpenClaw Skill Deploy v1.3.0"
|
|
|
+Write-Host "========================================"
|
|
|
+Write-Host ""
|
|
|
+Write-Host "Source: $SourceRoot"
|
|
|
+Write-Host "Target: $SkillsRoot"
|
|
|
+if ($DryRun) { Write-Host "[DRY RUN] Preview only, no files copied" -ForegroundColor Yellow }
|
|
|
+Write-Host ""
|
|
|
+
|
|
|
+if (-not $DryRun) {
|
|
|
+ if (-not (Test-Path $SkillsRoot)) {
|
|
|
+ New-Item -ItemType Directory -Path $SkillsRoot -Force | Out-Null
|
|
|
+ Write-Host "Created target dir: $SkillsRoot" -ForegroundColor Green
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+$deployed = 0
|
|
|
+$skipped = 0
|
|
|
+$errors = 0
|
|
|
+
|
|
|
+foreach ($cat in $categories) {
|
|
|
+ $catPath = Join-Path $SourceRoot $cat
|
|
|
+ if (-not (Test-Path $catPath)) {
|
|
|
+ Write-Host "SKIP category (not found): $cat" -ForegroundColor DarkGray
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ Write-Host "--- $cat ---" -ForegroundColor Cyan
|
|
|
+ $skillDirs = Get-ChildItem -Directory -Path $catPath
|
|
|
+ foreach ($skillDir in $skillDirs) {
|
|
|
+ $skillName = $skillDir.Name
|
|
|
+ $skillMd = Join-Path $skillDir.FullName "SKILL.md"
|
|
|
+ $apiConfig = Join-Path $skillDir.FullName "api-config.json"
|
|
|
+
|
|
|
+ if (-not (Test-Path $skillMd)) {
|
|
|
+ Write-Host " [SKIP] $skillName - missing SKILL.md" -ForegroundColor DarkYellow
|
|
|
+ $skipped++
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if (-not (Test-Path $apiConfig)) {
|
|
|
+ Write-Host " [SKIP] $skillName - missing api-config.json" -ForegroundColor DarkYellow
|
|
|
+ $skipped++
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ $mdContent = Get-Content $skillMd -Raw -Encoding UTF8
|
|
|
+ if ($mdContent -notmatch "^---\s*\r?\n") {
|
|
|
+ Write-Host " [WARN] $skillName - SKILL.md missing YAML frontmatter" -ForegroundColor Yellow
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ $null = Get-Content $apiConfig -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
|
+ } catch {
|
|
|
+ Write-Host " [ERROR] $skillName - invalid JSON in api-config.json" -ForegroundColor Red
|
|
|
+ $errors++
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ $destDir = Join-Path $SkillsRoot $skillName
|
|
|
+
|
|
|
+ if ($DryRun) {
|
|
|
+ $tag = if (Test-Path $destDir) { "UPDATE" } else { "NEW" }
|
|
|
+ Write-Host " [$tag] $skillName" -ForegroundColor White
|
|
|
+ } else {
|
|
|
+ if (Test-Path $destDir) {
|
|
|
+ Remove-Item -Recurse -Force $destDir
|
|
|
+ }
|
|
|
+ New-Item -ItemType Directory -Path $destDir -Force | Out-Null
|
|
|
+
|
|
|
+ Get-ChildItem -File -Path $skillDir.FullName | ForEach-Object {
|
|
|
+ Copy-Item $_.FullName -Destination $destDir
|
|
|
+ }
|
|
|
+
|
|
|
+ Write-Host " [OK] $skillName" -ForegroundColor Green
|
|
|
+ }
|
|
|
+
|
|
|
+ $deployed++
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+Write-Host ""
|
|
|
+Write-Host "========================================"
|
|
|
+Write-Host " Result: $deployed deployed, $skipped skipped, $errors errors"
|
|
|
+Write-Host "========================================"
|
|
|
+
|
|
|
+if ($DryRun) {
|
|
|
+ Write-Host "Remove -DryRun to execute actual deployment." -ForegroundColor Yellow
|
|
|
+} else {
|
|
|
+ Write-Host "Done! Refresh OpenClaw skill list to verify." -ForegroundColor Green
|
|
|
+ Write-Host " openclaw skills list"
|
|
|
+}
|