@laitszkin/apollo-toolkit 3.2.2 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -4
- package/CHANGELOG.md +15 -2
- package/README.md +35 -8
- package/analyse-app-logs/scripts/__pycache__/filter_logs_by_time.cpython-312.pyc +0 -0
- package/analyse-app-logs/scripts/__pycache__/log_cli_utils.cpython-312.pyc +0 -0
- package/analyse-app-logs/scripts/__pycache__/search_logs.cpython-312.pyc +0 -0
- package/docs-to-voice/scripts/__pycache__/docs_to_voice.cpython-312.pyc +0 -0
- package/generate-spec/scripts/__pycache__/create-specscpython-312.pyc +0 -0
- package/katex/scripts/__pycache__/render_katex.cpython-312.pyc +0 -0
- package/lib/cli.js +190 -9
- package/lib/installer.js +147 -8
- package/open-github-issue/scripts/__pycache__/open_github_issue.cpython-312.pyc +0 -0
- package/package.json +1 -1
- package/read-github-issue/scripts/__pycache__/find_issues.cpython-312.pyc +0 -0
- package/read-github-issue/scripts/__pycache__/read_issue.cpython-312.pyc +0 -0
- package/resolve-review-comments/scripts/__pycache__/review_threads.cpython-312.pyc +0 -0
- package/scripts/install_skills.ps1 +488 -108
- package/scripts/install_skills.sh +429 -15
- package/text-to-short-video/scripts/__pycache__/enforce_video_aspect_ratio.cpython-312.pyc +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
param(
|
|
2
2
|
[Parameter(ValueFromRemainingArguments = $true)]
|
|
3
|
-
[string[]]$
|
|
3
|
+
[string[]]$RawArgs
|
|
4
4
|
)
|
|
5
5
|
|
|
6
6
|
Set-StrictMode -Version Latest
|
|
@@ -9,7 +9,8 @@ $ErrorActionPreference = "Stop"
|
|
|
9
9
|
function Show-Usage {
|
|
10
10
|
@"
|
|
11
11
|
Usage:
|
|
12
|
-
./scripts/install_skills.ps1 [codex|openclaw|trae|agents|claude-code|all]...
|
|
12
|
+
./scripts/install_skills.ps1 [install] [codex|openclaw|trae|agents|claude-code|all]...
|
|
13
|
+
./scripts/install_skills.ps1 uninstall [codex|openclaw|trae|agents|claude-code|all]...
|
|
13
14
|
|
|
14
15
|
Modes:
|
|
15
16
|
codex Copy skills into ~/.codex/skills (includes ./codex/ agent-specific skills)
|
|
@@ -19,6 +20,10 @@ Modes:
|
|
|
19
20
|
claude-code Copy skills into ~/.claude/skills
|
|
20
21
|
all Install all supported targets
|
|
21
22
|
|
|
23
|
+
Options:
|
|
24
|
+
--symlink Install skills as symlinks (recommended; auto-update via git pull)
|
|
25
|
+
--copy Install skills as file copies (manual reinstall for updates)
|
|
26
|
+
|
|
22
27
|
Optional environment overrides:
|
|
23
28
|
CODEX_SKILLS_DIR Override codex skills destination path
|
|
24
29
|
OPENCLAW_HOME Override openclaw home path
|
|
@@ -30,7 +35,8 @@ Optional environment overrides:
|
|
|
30
35
|
"@
|
|
31
36
|
}
|
|
32
37
|
|
|
33
|
-
$ToolkitRepoUrl = if ($env:APOLLO_TOOLKIT_REPO_URL) { $env:APOLLO_TOOLKIT_REPO_URL } else { "https://github.com/LaiTszKin/apollo-toolkit.git" }
|
|
38
|
+
$Script:ToolkitRepoUrl = if ($env:APOLLO_TOOLKIT_REPO_URL) { $env:APOLLO_TOOLKIT_REPO_URL } else { "https://github.com/LaiTszKin/apollo-toolkit.git" }
|
|
39
|
+
$Script:ManifestFilename = ".apollo-toolkit-manifest.json"
|
|
34
40
|
|
|
35
41
|
function Expand-UserPath {
|
|
36
42
|
param([string]$Path)
|
|
@@ -51,7 +57,7 @@ function Expand-UserPath {
|
|
|
51
57
|
return $Path
|
|
52
58
|
}
|
|
53
59
|
|
|
54
|
-
$ToolkitHome = if ($env:APOLLO_TOOLKIT_HOME) { Expand-UserPath $env:APOLLO_TOOLKIT_HOME } else { Join-Path $HOME ".apollo-toolkit" }
|
|
60
|
+
$Script:ToolkitHome = if ($env:APOLLO_TOOLKIT_HOME) { Expand-UserPath $env:APOLLO_TOOLKIT_HOME } else { Join-Path $HOME ".apollo-toolkit" }
|
|
55
61
|
|
|
56
62
|
function Show-Banner {
|
|
57
63
|
@"
|
|
@@ -80,40 +86,43 @@ function Test-RepoRoot {
|
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
function Bootstrap-RepoIfNeeded {
|
|
83
|
-
if (Test-Path -LiteralPath (Join-Path $ToolkitHome ".git") -PathType Container) {
|
|
84
|
-
git -C $ToolkitHome pull --ff-only | Out-Null
|
|
89
|
+
if (Test-Path -LiteralPath (Join-Path $Script:ToolkitHome ".git") -PathType Container) {
|
|
90
|
+
git -C $Script:ToolkitHome pull --ff-only | Out-Null
|
|
85
91
|
}
|
|
86
92
|
else {
|
|
87
|
-
if (Test-Path -LiteralPath $ToolkitHome) {
|
|
88
|
-
Remove-Item -LiteralPath $ToolkitHome -Force -Recurse
|
|
93
|
+
if (Test-Path -LiteralPath $Script:ToolkitHome) {
|
|
94
|
+
Remove-Item -LiteralPath $Script:ToolkitHome -Force -Recurse
|
|
89
95
|
}
|
|
90
|
-
git clone --depth 1 $ToolkitRepoUrl $ToolkitHome | Out-Null
|
|
96
|
+
git clone --depth 1 $Script:ToolkitRepoUrl $Script:ToolkitHome | Out-Null
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
99
|
|
|
94
|
-
$
|
|
100
|
+
$Script:LinkMode = ""
|
|
101
|
+
$Script:ScriptPath = $MyInvocation.MyCommand.Path
|
|
95
102
|
$candidateRepoRoot = $null
|
|
96
103
|
|
|
97
|
-
if (-not [string]::IsNullOrWhiteSpace($
|
|
98
|
-
$scriptDir = Split-Path -Parent $
|
|
104
|
+
if (-not [string]::IsNullOrWhiteSpace($Script:ScriptPath)) {
|
|
105
|
+
$scriptDir = Split-Path -Parent $Script:ScriptPath
|
|
99
106
|
$candidateRepoRoot = Split-Path -Parent $scriptDir
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
if (Test-RepoRoot -Path $candidateRepoRoot) {
|
|
103
|
-
$RepoRoot = $candidateRepoRoot
|
|
110
|
+
$Script:RepoRoot = $candidateRepoRoot
|
|
104
111
|
}
|
|
105
112
|
elseif (Test-RepoRoot -Path (Get-Location).Path) {
|
|
106
|
-
$RepoRoot = (Get-Location).Path
|
|
113
|
+
$Script:RepoRoot = (Get-Location).Path
|
|
107
114
|
}
|
|
108
115
|
else {
|
|
109
116
|
Bootstrap-RepoIfNeeded
|
|
110
|
-
$RepoRoot = $ToolkitHome
|
|
117
|
+
$Script:RepoRoot = $Script:ToolkitHome
|
|
111
118
|
}
|
|
112
119
|
|
|
120
|
+
# ---- Skill collection ----
|
|
121
|
+
|
|
113
122
|
function Get-SkillPathGroups {
|
|
114
123
|
param([string[]]$SelectedModes)
|
|
115
124
|
|
|
116
|
-
$dirs = Get-ChildItem -Path $RepoRoot -Directory | Sort-Object Name
|
|
125
|
+
$dirs = Get-ChildItem -Path $Script:RepoRoot -Directory | Sort-Object Name
|
|
117
126
|
$sharedSkills = @()
|
|
118
127
|
$codexSkills = @()
|
|
119
128
|
|
|
@@ -123,9 +132,8 @@ function Get-SkillPathGroups {
|
|
|
123
132
|
}
|
|
124
133
|
}
|
|
125
134
|
|
|
126
|
-
# For codex mode, also include codex-specific skills
|
|
127
135
|
if ($SelectedModes -contains "codex") {
|
|
128
|
-
$codexDir = Join-Path $RepoRoot "codex"
|
|
136
|
+
$codexDir = Join-Path $Script:RepoRoot "codex"
|
|
129
137
|
if (Test-Path -LiteralPath $codexDir -PathType Container) {
|
|
130
138
|
$codexDirs = Get-ChildItem -Path $codexDir -Directory | Sort-Object Name
|
|
131
139
|
foreach ($dir in $codexDirs) {
|
|
@@ -137,102 +145,84 @@ function Get-SkillPathGroups {
|
|
|
137
145
|
}
|
|
138
146
|
|
|
139
147
|
if ($sharedSkills.Count -eq 0) {
|
|
140
|
-
throw "No skill folders found in: $RepoRoot"
|
|
148
|
+
throw "No skill folders found in: $($Script:RepoRoot)"
|
|
141
149
|
}
|
|
142
150
|
|
|
143
151
|
[PSCustomObject]@{
|
|
144
152
|
Shared = $sharedSkills
|
|
145
|
-
Codex
|
|
153
|
+
Codex = $codexSkills
|
|
146
154
|
}
|
|
147
155
|
}
|
|
148
156
|
|
|
149
|
-
function
|
|
150
|
-
param(
|
|
151
|
-
[System.Collections.Generic.List[string]]$Selected,
|
|
152
|
-
[string]$Mode
|
|
153
|
-
)
|
|
157
|
+
function Get-SkillNames {
|
|
158
|
+
param([string[]]$Paths)
|
|
154
159
|
|
|
155
|
-
|
|
156
|
-
|
|
160
|
+
$names = @()
|
|
161
|
+
foreach ($p in $Paths) {
|
|
162
|
+
$names += Split-Path -Path $p -Leaf
|
|
157
163
|
}
|
|
164
|
+
return ($names | Sort-Object -Unique)
|
|
158
165
|
}
|
|
159
166
|
|
|
160
|
-
|
|
161
|
-
param([string[]]$Requested)
|
|
167
|
+
# ---- Manifest management ----
|
|
162
168
|
|
|
163
|
-
|
|
169
|
+
function Read-ManifestSkills {
|
|
170
|
+
param([string]$TargetRoot)
|
|
164
171
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Write-Host "1) codex (~/.codex/skills, includes ./codex/ agent-specific skills)"
|
|
170
|
-
Write-Host "2) openclaw (~/.openclaw/workspace*/skills)"
|
|
171
|
-
Write-Host "3) trae (~/.trae/skills)"
|
|
172
|
-
Write-Host "4) agents (~/.agents/skills)"
|
|
173
|
-
Write-Host "5) claude-code (~/.claude/skills)"
|
|
174
|
-
Write-Host "6) all"
|
|
175
|
-
$inputValue = Read-Host "Enter choice(s) [1-6]"
|
|
172
|
+
$manifestPath = Join-Path $TargetRoot $Script:ManifestFilename
|
|
173
|
+
if (-not (Test-Path -LiteralPath $manifestPath -PathType Leaf)) {
|
|
174
|
+
return @()
|
|
175
|
+
}
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
"3" { Add-ModeOnce -Selected $selected -Mode "trae" }
|
|
183
|
-
"4" { Add-ModeOnce -Selected $selected -Mode "agents" }
|
|
184
|
-
"5" { Add-ModeOnce -Selected $selected -Mode "claude-code" }
|
|
185
|
-
"6" {
|
|
186
|
-
Add-ModeOnce -Selected $selected -Mode "codex"
|
|
187
|
-
Add-ModeOnce -Selected $selected -Mode "openclaw"
|
|
188
|
-
Add-ModeOnce -Selected $selected -Mode "trae"
|
|
189
|
-
Add-ModeOnce -Selected $selected -Mode "agents"
|
|
190
|
-
Add-ModeOnce -Selected $selected -Mode "claude-code"
|
|
191
|
-
}
|
|
192
|
-
default {
|
|
193
|
-
throw "Invalid choice: $choice"
|
|
194
|
-
}
|
|
195
|
-
}
|
|
177
|
+
try {
|
|
178
|
+
$manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json
|
|
179
|
+
$skills = @()
|
|
180
|
+
if ($manifest.historicalSkills) {
|
|
181
|
+
$skills += $manifest.historicalSkills
|
|
196
182
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
foreach ($mode in $Requested) {
|
|
200
|
-
switch ($mode.ToLowerInvariant()) {
|
|
201
|
-
"codex" { Add-ModeOnce -Selected $selected -Mode "codex" }
|
|
202
|
-
"openclaw" { Add-ModeOnce -Selected $selected -Mode "openclaw" }
|
|
203
|
-
"trae" { Add-ModeOnce -Selected $selected -Mode "trae" }
|
|
204
|
-
"agents" { Add-ModeOnce -Selected $selected -Mode "agents" }
|
|
205
|
-
"claude-code" { Add-ModeOnce -Selected $selected -Mode "claude-code" }
|
|
206
|
-
"all" {
|
|
207
|
-
Add-ModeOnce -Selected $selected -Mode "codex"
|
|
208
|
-
Add-ModeOnce -Selected $selected -Mode "openclaw"
|
|
209
|
-
Add-ModeOnce -Selected $selected -Mode "trae"
|
|
210
|
-
Add-ModeOnce -Selected $selected -Mode "agents"
|
|
211
|
-
Add-ModeOnce -Selected $selected -Mode "claude-code"
|
|
212
|
-
}
|
|
213
|
-
default {
|
|
214
|
-
Show-Usage
|
|
215
|
-
throw "Invalid mode: $mode"
|
|
216
|
-
}
|
|
217
|
-
}
|
|
183
|
+
if ($manifest.skills) {
|
|
184
|
+
$skills += $manifest.skills
|
|
218
185
|
}
|
|
186
|
+
return ($skills | Sort-Object -Unique)
|
|
219
187
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
throw "No install option selected."
|
|
188
|
+
catch {
|
|
189
|
+
return @()
|
|
223
190
|
}
|
|
224
|
-
|
|
225
|
-
return $selected
|
|
226
191
|
}
|
|
227
192
|
|
|
228
|
-
function
|
|
229
|
-
param(
|
|
193
|
+
function Write-Manifest {
|
|
194
|
+
param(
|
|
195
|
+
[string]$TargetRoot,
|
|
196
|
+
[string]$Version,
|
|
197
|
+
[string]$LinkMode,
|
|
198
|
+
[string[]]$SkillNames
|
|
199
|
+
)
|
|
230
200
|
|
|
231
|
-
|
|
232
|
-
|
|
201
|
+
$manifestPath = Join-Path $TargetRoot $Script:ManifestFilename
|
|
202
|
+
$historicalSkills = @()
|
|
203
|
+
if (Test-Path -LiteralPath $manifestPath -PathType Leaf) {
|
|
204
|
+
$historicalSkills = Read-ManifestSkills -TargetRoot $TargetRoot
|
|
233
205
|
}
|
|
206
|
+
|
|
207
|
+
$merged = @()
|
|
208
|
+
$merged += $historicalSkills
|
|
209
|
+
$merged += $SkillNames
|
|
210
|
+
$allSkills = ($merged | Sort-Object -Unique)
|
|
211
|
+
|
|
212
|
+
$manifest = [PSCustomObject]@{
|
|
213
|
+
version = $Version
|
|
214
|
+
installedAt = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")
|
|
215
|
+
linkMode = $LinkMode
|
|
216
|
+
skills = ($SkillNames | Sort-Object -Unique)
|
|
217
|
+
historicalSkills = $allSkills
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
New-Item -ItemType Directory -Path $TargetRoot -Force | Out-Null
|
|
221
|
+
$manifest | ConvertTo-Json -Depth 3 | Set-Content -LiteralPath $manifestPath -Encoding UTF8
|
|
234
222
|
}
|
|
235
223
|
|
|
224
|
+
# ---- Install operations ----
|
|
225
|
+
|
|
236
226
|
function Copy-Skill {
|
|
237
227
|
param(
|
|
238
228
|
[string]$Source,
|
|
@@ -249,6 +239,171 @@ function Copy-Skill {
|
|
|
249
239
|
Write-Host "[copied] $Source -> $target"
|
|
250
240
|
}
|
|
251
241
|
|
|
242
|
+
function Symlink-Skill {
|
|
243
|
+
param(
|
|
244
|
+
[string]$Source,
|
|
245
|
+
[string]$TargetRoot
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
$name = Split-Path -Path $Source -Leaf
|
|
249
|
+
$target = Join-Path $TargetRoot $name
|
|
250
|
+
|
|
251
|
+
New-Item -ItemType Directory -Path $TargetRoot -Force | Out-Null
|
|
252
|
+
Remove-PathForce -Target $target
|
|
253
|
+
|
|
254
|
+
New-Item -ItemType SymbolicLink -Path $target -Target $Source -Force | Out-Null
|
|
255
|
+
Write-Host "[symlink] $Source -> $target"
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function Do-Replace {
|
|
259
|
+
param(
|
|
260
|
+
[string]$Source,
|
|
261
|
+
[string]$TargetRoot
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
if ($Script:LinkMode -eq "symlink") {
|
|
265
|
+
Symlink-Skill -Source $Source -TargetRoot $TargetRoot
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
Copy-Skill -Source $Source -TargetRoot $TargetRoot
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function Remove-PathForce {
|
|
273
|
+
param([string]$Target)
|
|
274
|
+
|
|
275
|
+
if (Test-Path -LiteralPath $Target) {
|
|
276
|
+
Remove-Item -LiteralPath $Target -Force -Recurse
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
# ---- Uninstall operations ----
|
|
281
|
+
|
|
282
|
+
function Uninstall-Target {
|
|
283
|
+
param(
|
|
284
|
+
[string]$TargetRoot,
|
|
285
|
+
[string]$TargetLabel
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
$manifestPath = Join-Path $TargetRoot $Script:ManifestFilename
|
|
289
|
+
if (-not (Test-Path -LiteralPath $manifestPath -PathType Leaf)) {
|
|
290
|
+
Write-Host "[skip] No manifest found in: $TargetRoot"
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
$skills = Read-ManifestSkills -TargetRoot $TargetRoot
|
|
295
|
+
if ($skills.Count -eq 0) {
|
|
296
|
+
Write-Host "[skip] No skills in manifest: $TargetRoot"
|
|
297
|
+
Remove-Item -LiteralPath $manifestPath -Force -ErrorAction SilentlyContinue
|
|
298
|
+
return
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
Write-Host "Uninstalling from $($TargetLabel): $TargetRoot"
|
|
302
|
+
foreach ($name in $skills) {
|
|
303
|
+
$skillPath = Join-Path $TargetRoot $name
|
|
304
|
+
if (Test-Path -LiteralPath $skillPath) {
|
|
305
|
+
Remove-Item -LiteralPath $skillPath -Force -Recurse
|
|
306
|
+
Write-Host " [removed] $skillPath"
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
Remove-Item -LiteralPath $manifestPath -Force -ErrorAction SilentlyContinue
|
|
311
|
+
Write-Host " [removed manifest] $manifestPath"
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function Invoke-Uninstall {
|
|
315
|
+
param([string[]]$SelectedModes)
|
|
316
|
+
|
|
317
|
+
if ($SelectedModes.Count -eq 0) {
|
|
318
|
+
$SelectedModes = @("codex", "openclaw", "trae", "agents", "claude-code")
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
Write-Host "Uninstalling Apollo Toolkit skills..."
|
|
322
|
+
Write-Host "Target modes: $($SelectedModes -join ', ')"
|
|
323
|
+
Write-Host ""
|
|
324
|
+
|
|
325
|
+
# Show all known skills
|
|
326
|
+
$skillGroups = Get-SkillPathGroups -SelectedModes $SelectedModes
|
|
327
|
+
$currentNames = Get-SkillNames -Paths ($skillGroups.Shared + $skillGroups.Codex)
|
|
328
|
+
$allNames = @()
|
|
329
|
+
$allNames += $currentNames
|
|
330
|
+
|
|
331
|
+
# Collect historical from manifests
|
|
332
|
+
$targetDirs = @()
|
|
333
|
+
foreach ($m in $SelectedModes) {
|
|
334
|
+
switch ($m) {
|
|
335
|
+
"codex" {
|
|
336
|
+
$d = if ($env:CODEX_SKILLS_DIR) { Expand-UserPath $env:CODEX_SKILLS_DIR } else { Join-Path $HOME ".codex/skills" }
|
|
337
|
+
$targetDirs += $d
|
|
338
|
+
}
|
|
339
|
+
"openclaw" {
|
|
340
|
+
$oh = if ($env:OPENCLAW_HOME) { Expand-UserPath $env:OPENCLAW_HOME } else { Join-Path $HOME ".openclaw" }
|
|
341
|
+
if (Test-Path -LiteralPath $oh) {
|
|
342
|
+
foreach ($ws in (Get-ChildItem -Path $oh -Directory -Filter "workspace*")) {
|
|
343
|
+
$targetDirs += (Join-Path $ws.FullName "skills")
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
"trae" {
|
|
348
|
+
$d = if ($env:TRAE_SKILLS_DIR) { Expand-UserPath $env:TRAE_SKILLS_DIR } else { Join-Path $HOME ".trae/skills" }
|
|
349
|
+
$targetDirs += $d
|
|
350
|
+
}
|
|
351
|
+
"agents" {
|
|
352
|
+
$d = if ($env:AGENTS_SKILLS_DIR) { Expand-UserPath $env:AGENTS_SKILLS_DIR } else { Join-Path $HOME ".agents/skills" }
|
|
353
|
+
$targetDirs += $d
|
|
354
|
+
}
|
|
355
|
+
"claude-code" {
|
|
356
|
+
$d = if ($env:CLAUDE_CODE_SKILLS_DIR) { Expand-UserPath $env:CLAUDE_CODE_SKILLS_DIR } else { Join-Path $HOME ".claude/skills" }
|
|
357
|
+
$targetDirs += $d
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
foreach ($td in $targetDirs) {
|
|
363
|
+
$allNames += (Read-ManifestSkills -TargetRoot $td)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
$allKnown = ($allNames | Sort-Object -Unique)
|
|
367
|
+
Write-Host "All known skills (current + historical):"
|
|
368
|
+
foreach ($n in $allKnown) {
|
|
369
|
+
Write-Host " - $n"
|
|
370
|
+
}
|
|
371
|
+
Write-Host ""
|
|
372
|
+
|
|
373
|
+
foreach ($m in $SelectedModes) {
|
|
374
|
+
switch ($m) {
|
|
375
|
+
"codex" {
|
|
376
|
+
$d = if ($env:CODEX_SKILLS_DIR) { Expand-UserPath $env:CODEX_SKILLS_DIR } else { Join-Path $HOME ".codex/skills" }
|
|
377
|
+
Uninstall-Target -TargetRoot $d -TargetLabel "codex"
|
|
378
|
+
}
|
|
379
|
+
"trae" {
|
|
380
|
+
$d = if ($env:TRAE_SKILLS_DIR) { Expand-UserPath $env:TRAE_SKILLS_DIR } else { Join-Path $HOME ".trae/skills" }
|
|
381
|
+
Uninstall-Target -TargetRoot $d -TargetLabel "trae"
|
|
382
|
+
}
|
|
383
|
+
"agents" {
|
|
384
|
+
$d = if ($env:AGENTS_SKILLS_DIR) { Expand-UserPath $env:AGENTS_SKILLS_DIR } else { Join-Path $HOME ".agents/skills" }
|
|
385
|
+
Uninstall-Target -TargetRoot $d -TargetLabel "agents"
|
|
386
|
+
}
|
|
387
|
+
"claude-code" {
|
|
388
|
+
$d = if ($env:CLAUDE_CODE_SKILLS_DIR) { Expand-UserPath $env:CLAUDE_CODE_SKILLS_DIR } else { Join-Path $HOME ".claude/skills" }
|
|
389
|
+
Uninstall-Target -TargetRoot $d -TargetLabel "claude-code"
|
|
390
|
+
}
|
|
391
|
+
"openclaw" {
|
|
392
|
+
$oh = if ($env:OPENCLAW_HOME) { Expand-UserPath $env:OPENCLAW_HOME } else { Join-Path $HOME ".openclaw" }
|
|
393
|
+
if (Test-Path -LiteralPath $oh) {
|
|
394
|
+
foreach ($ws in (Get-ChildItem -Path $oh -Directory -Filter "workspace*")) {
|
|
395
|
+
Uninstall-Target -TargetRoot (Join-Path $ws.FullName "skills") -TargetLabel "openclaw"
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
Write-Host "Done."
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
# ---- Install functions ----
|
|
406
|
+
|
|
252
407
|
function Install-Codex {
|
|
253
408
|
param([string[]]$SkillPaths)
|
|
254
409
|
|
|
@@ -259,10 +414,13 @@ function Install-Codex {
|
|
|
259
414
|
Join-Path $HOME ".codex/skills"
|
|
260
415
|
}
|
|
261
416
|
|
|
262
|
-
Write-Host "Installing to codex: $target"
|
|
417
|
+
Write-Host "Installing to codex: $target (mode: $Script:LinkMode)"
|
|
418
|
+
$skillNames = @()
|
|
263
419
|
foreach ($src in $SkillPaths) {
|
|
264
|
-
|
|
420
|
+
Do-Replace -Source $src -TargetRoot $target
|
|
421
|
+
$skillNames += (Split-Path -Path $src -Leaf)
|
|
265
422
|
}
|
|
423
|
+
Write-Manifest -TargetRoot $target -Version $Script:Version -LinkMode $Script:LinkMode -SkillNames $skillNames
|
|
266
424
|
}
|
|
267
425
|
|
|
268
426
|
function Install-OpenClaw {
|
|
@@ -286,10 +444,13 @@ function Install-OpenClaw {
|
|
|
286
444
|
|
|
287
445
|
foreach ($workspace in $workspaces) {
|
|
288
446
|
$skillsDir = Join-Path $workspace.FullName "skills"
|
|
289
|
-
Write-Host "Installing to openclaw workspace: $skillsDir"
|
|
447
|
+
Write-Host "Installing to openclaw workspace: $skillsDir (mode: $Script:LinkMode)"
|
|
448
|
+
$skillNames = @()
|
|
290
449
|
foreach ($src in $SkillPaths) {
|
|
291
|
-
|
|
450
|
+
Do-Replace -Source $src -TargetRoot $skillsDir
|
|
451
|
+
$skillNames += (Split-Path -Path $src -Leaf)
|
|
292
452
|
}
|
|
453
|
+
Write-Manifest -TargetRoot $skillsDir -Version $Script:Version -LinkMode $Script:LinkMode -SkillNames $skillNames
|
|
293
454
|
}
|
|
294
455
|
}
|
|
295
456
|
|
|
@@ -303,10 +464,13 @@ function Install-Trae {
|
|
|
303
464
|
Join-Path $HOME ".trae/skills"
|
|
304
465
|
}
|
|
305
466
|
|
|
306
|
-
Write-Host "Installing to trae: $target"
|
|
467
|
+
Write-Host "Installing to trae: $target (mode: $Script:LinkMode)"
|
|
468
|
+
$skillNames = @()
|
|
307
469
|
foreach ($src in $SkillPaths) {
|
|
308
|
-
|
|
470
|
+
Do-Replace -Source $src -TargetRoot $target
|
|
471
|
+
$skillNames += (Split-Path -Path $src -Leaf)
|
|
309
472
|
}
|
|
473
|
+
Write-Manifest -TargetRoot $target -Version $Script:Version -LinkMode $Script:LinkMode -SkillNames $skillNames
|
|
310
474
|
}
|
|
311
475
|
|
|
312
476
|
function Install-Agents {
|
|
@@ -319,10 +483,13 @@ function Install-Agents {
|
|
|
319
483
|
Join-Path $HOME ".agents/skills"
|
|
320
484
|
}
|
|
321
485
|
|
|
322
|
-
Write-Host "Installing to agents: $target"
|
|
486
|
+
Write-Host "Installing to agents: $target (mode: $Script:LinkMode)"
|
|
487
|
+
$skillNames = @()
|
|
323
488
|
foreach ($src in $SkillPaths) {
|
|
324
|
-
|
|
489
|
+
Do-Replace -Source $src -TargetRoot $target
|
|
490
|
+
$skillNames += (Split-Path -Path $src -Leaf)
|
|
325
491
|
}
|
|
492
|
+
Write-Manifest -TargetRoot $target -Version $Script:Version -LinkMode $Script:LinkMode -SkillNames $skillNames
|
|
326
493
|
}
|
|
327
494
|
|
|
328
495
|
function Install-ClaudeCode {
|
|
@@ -335,27 +502,240 @@ function Install-ClaudeCode {
|
|
|
335
502
|
Join-Path $HOME ".claude/skills"
|
|
336
503
|
}
|
|
337
504
|
|
|
338
|
-
Write-Host "Installing to claude-code: $target"
|
|
505
|
+
Write-Host "Installing to claude-code: $target (mode: $Script:LinkMode)"
|
|
506
|
+
$skillNames = @()
|
|
339
507
|
foreach ($src in $SkillPaths) {
|
|
340
|
-
|
|
508
|
+
Do-Replace -Source $src -TargetRoot $target
|
|
509
|
+
$skillNames += (Split-Path -Path $src -Leaf)
|
|
510
|
+
}
|
|
511
|
+
Write-Manifest -TargetRoot $target -Version $Script:Version -LinkMode $Script:LinkMode -SkillNames $skillNames
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
# ---- Mode management ----
|
|
515
|
+
|
|
516
|
+
function Add-ModeOnce {
|
|
517
|
+
param(
|
|
518
|
+
[System.Collections.Generic.List[string]]$Selected,
|
|
519
|
+
[string]$Mode
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
if (-not $Selected.Contains($Mode)) {
|
|
523
|
+
$Selected.Add($Mode)
|
|
341
524
|
}
|
|
342
525
|
}
|
|
343
526
|
|
|
344
|
-
|
|
345
|
-
|
|
527
|
+
function Resolve-Modes {
|
|
528
|
+
param([string[]]$Requested)
|
|
529
|
+
|
|
530
|
+
$selected = [System.Collections.Generic.List[string]]::new()
|
|
531
|
+
|
|
532
|
+
if ($Requested.Count -eq 0) {
|
|
533
|
+
Show-Banner
|
|
534
|
+
Write-Host ""
|
|
535
|
+
Write-Host "Select install options (comma-separated):"
|
|
536
|
+
Write-Host "1) codex (~/.codex/skills, includes ./codex/ agent-specific skills)"
|
|
537
|
+
Write-Host "2) openclaw (~/.openclaw/workspace*/skills)"
|
|
538
|
+
Write-Host "3) trae (~/.trae/skills)"
|
|
539
|
+
Write-Host "4) agents (~/.agents/skills)"
|
|
540
|
+
Write-Host "5) claude-code (~/.claude/skills)"
|
|
541
|
+
Write-Host "6) all"
|
|
542
|
+
$inputValue = Read-Host "Enter choice(s) [1-6]"
|
|
543
|
+
|
|
544
|
+
foreach ($rawChoice in ($inputValue -split ",")) {
|
|
545
|
+
$choice = $rawChoice.Trim()
|
|
546
|
+
switch ($choice) {
|
|
547
|
+
"1" { Add-ModeOnce -Selected $selected -Mode "codex" }
|
|
548
|
+
"2" { Add-ModeOnce -Selected $selected -Mode "openclaw" }
|
|
549
|
+
"3" { Add-ModeOnce -Selected $selected -Mode "trae" }
|
|
550
|
+
"4" { Add-ModeOnce -Selected $selected -Mode "agents" }
|
|
551
|
+
"5" { Add-ModeOnce -Selected $selected -Mode "claude-code" }
|
|
552
|
+
"6" {
|
|
553
|
+
Add-ModeOnce -Selected $selected -Mode "codex"
|
|
554
|
+
Add-ModeOnce -Selected $selected -Mode "openclaw"
|
|
555
|
+
Add-ModeOnce -Selected $selected -Mode "trae"
|
|
556
|
+
Add-ModeOnce -Selected $selected -Mode "agents"
|
|
557
|
+
Add-ModeOnce -Selected $selected -Mode "claude-code"
|
|
558
|
+
}
|
|
559
|
+
default {
|
|
560
|
+
throw "Invalid choice: $choice"
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
foreach ($mode in $Requested) {
|
|
567
|
+
switch ($mode.ToLowerInvariant()) {
|
|
568
|
+
"codex" { Add-ModeOnce -Selected $selected -Mode "codex" }
|
|
569
|
+
"openclaw" { Add-ModeOnce -Selected $selected -Mode "openclaw" }
|
|
570
|
+
"trae" { Add-ModeOnce -Selected $selected -Mode "trae" }
|
|
571
|
+
"agents" { Add-ModeOnce -Selected $selected -Mode "agents" }
|
|
572
|
+
"claude-code" { Add-ModeOnce -Selected $selected -Mode "claude-code" }
|
|
573
|
+
"all" {
|
|
574
|
+
Add-ModeOnce -Selected $selected -Mode "codex"
|
|
575
|
+
Add-ModeOnce -Selected $selected -Mode "openclaw"
|
|
576
|
+
Add-ModeOnce -Selected $selected -Mode "trae"
|
|
577
|
+
Add-ModeOnce -Selected $selected -Mode "agents"
|
|
578
|
+
Add-ModeOnce -Selected $selected -Mode "claude-code"
|
|
579
|
+
}
|
|
580
|
+
default {
|
|
581
|
+
Show-Usage
|
|
582
|
+
throw "Invalid mode: $mode"
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if ($selected.Count -eq 0) {
|
|
589
|
+
throw "No install option selected."
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return $selected
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function Read-YesNo {
|
|
596
|
+
param(
|
|
597
|
+
[string]$Prompt,
|
|
598
|
+
[bool]$DefaultYes = $true
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
$hint = if ($DefaultYes) { "[Y/n]" } else { "[y/N]" }
|
|
602
|
+
$result = Read-Host "$Prompt $hint"
|
|
603
|
+
if ([string]::IsNullOrWhiteSpace($result)) {
|
|
604
|
+
return $DefaultYes
|
|
605
|
+
}
|
|
606
|
+
$trimmed = $result.Trim().ToLowerInvariant()
|
|
607
|
+
return ($trimmed -eq "y" -or $trimmed -eq "yes")
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function Prompt-LinkMode {
|
|
611
|
+
Write-Host ""
|
|
612
|
+
Write-Host "Symlink mode:"
|
|
613
|
+
Write-Host " Pro: Skills auto-update when you 'git pull' in ~/.apollo-toolkit"
|
|
614
|
+
Write-Host " Pro: No need to re-run installer after patch updates"
|
|
615
|
+
Write-Host " Con: Changes pushed to the repo automatically reflect in your skills -"
|
|
616
|
+
Write-Host " you may receive updates you did not intend to accept"
|
|
617
|
+
Write-Host ""
|
|
618
|
+
|
|
619
|
+
if (Read-YesNo -Prompt "Install skills as symlinks (recommended)?" -DefaultYes $true) {
|
|
620
|
+
$Script:LinkMode = "symlink"
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
$Script:LinkMode = "copy"
|
|
624
|
+
}
|
|
625
|
+
Write-Host "Using: $Script:LinkMode"
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
function Prompt-IncludeExclusive {
|
|
629
|
+
param(
|
|
630
|
+
[string[]]$SelectedModes,
|
|
631
|
+
[string[]]$CodexSkillPaths
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
if ($CodexSkillPaths.Count -eq 0) {
|
|
635
|
+
return
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
$hasNonCodex = $false
|
|
639
|
+
foreach ($m in $SelectedModes) {
|
|
640
|
+
if ($m -ne "codex") {
|
|
641
|
+
$hasNonCodex = $true
|
|
642
|
+
break
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (-not $hasNonCodex) {
|
|
647
|
+
return
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
$codexOnlyNames = @()
|
|
651
|
+
foreach ($cp in $CodexSkillPaths) {
|
|
652
|
+
$codexOnlyNames += (Split-Path -Path $cp -Leaf)
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
Write-Host ""
|
|
656
|
+
Write-Host "Exclusive skills detected:"
|
|
657
|
+
Write-Host " The following skills are exclusive to codex: $($codexOnlyNames -join ', ')"
|
|
658
|
+
Write-Host " Your selected non-codex targets: $(($SelectedModes | Where-Object { $_ -ne 'codex' }) -join ', ')"
|
|
659
|
+
|
|
660
|
+
if (Read-YesNo -Prompt "Install codex-exclusive skills to non-codex targets as well?" -DefaultYes $false) {
|
|
661
|
+
return $true
|
|
662
|
+
}
|
|
663
|
+
return $false
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
# ---- Version detection ----
|
|
667
|
+
$Script:Version = "unknown"
|
|
668
|
+
$pkgJsonPath = Join-Path $Script:RepoRoot "package.json"
|
|
669
|
+
if (Test-Path -LiteralPath $pkgJsonPath -PathType Leaf) {
|
|
670
|
+
try {
|
|
671
|
+
$pkg = Get-Content -LiteralPath $pkgJsonPath -Raw | ConvertFrom-Json
|
|
672
|
+
if ($pkg.version) {
|
|
673
|
+
$Script:Version = $pkg.version
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
catch { }
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
# ---- Main ----
|
|
680
|
+
|
|
681
|
+
# Parse arguments
|
|
682
|
+
$Args = @()
|
|
683
|
+
$Command = "install"
|
|
684
|
+
foreach ($arg in $RawArgs) {
|
|
685
|
+
switch ($arg) {
|
|
686
|
+
"-h" { Show-Usage; exit 0 }
|
|
687
|
+
"--help" { Show-Usage; exit 0 }
|
|
688
|
+
"--symlink" { $Script:LinkMode = "symlink" }
|
|
689
|
+
"--copy" { $Script:LinkMode = "copy" }
|
|
690
|
+
default { $Args += $arg }
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
if ($Args.Count -gt 0 -and $Args[0] -eq "uninstall") {
|
|
695
|
+
$Command = "uninstall"
|
|
696
|
+
$Args = $Args[1..($Args.Count - 1)]
|
|
697
|
+
}
|
|
698
|
+
elseif ($Args.Count -gt 0 -and $Args[0] -eq "install") {
|
|
699
|
+
$Args = $Args[1..($Args.Count - 1)]
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
# Resolve modes
|
|
703
|
+
$selectedModes = Resolve-Modes -Requested $Args
|
|
704
|
+
|
|
705
|
+
if ($Command -eq "uninstall") {
|
|
706
|
+
Invoke-Uninstall -SelectedModes $selectedModes
|
|
346
707
|
exit 0
|
|
347
708
|
}
|
|
348
709
|
|
|
349
|
-
|
|
710
|
+
# Install flow
|
|
350
711
|
$skillPathGroups = Get-SkillPathGroups -SelectedModes $selectedModes
|
|
351
712
|
|
|
713
|
+
# Prompt for link mode if not set
|
|
714
|
+
if ([string]::IsNullOrEmpty($Script:LinkMode)) {
|
|
715
|
+
Prompt-LinkMode
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
# Prompt for exclusive skills inclusion
|
|
719
|
+
$includeExclusive = Prompt-IncludeExclusive -SelectedModes $selectedModes -CodexSkillPaths $skillPathGroups.Codex
|
|
720
|
+
$effectiveShared = $skillPathGroups.Shared
|
|
721
|
+
if ($includeExclusive) {
|
|
722
|
+
$effectiveShared += $skillPathGroups.Codex
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
# Summarize and install
|
|
726
|
+
Write-Host ""
|
|
727
|
+
Write-Host "Apollo Toolkit repo: $($Script:RepoRoot)"
|
|
728
|
+
Write-Host "Install mode: $Script:LinkMode"
|
|
729
|
+
Write-Host "Targets: $($selectedModes -join ', ')"
|
|
730
|
+
Write-Host ""
|
|
731
|
+
|
|
352
732
|
foreach ($mode in $selectedModes) {
|
|
353
733
|
switch ($mode) {
|
|
354
|
-
"codex" { Install-Codex -SkillPaths ($
|
|
355
|
-
"openclaw" { Install-OpenClaw -SkillPaths $
|
|
356
|
-
"trae" { Install-Trae -SkillPaths $
|
|
357
|
-
"agents" { Install-Agents -SkillPaths $
|
|
358
|
-
"claude-code" { Install-ClaudeCode -SkillPaths $
|
|
734
|
+
"codex" { Install-Codex -SkillPaths ($effectiveShared + $skillPathGroups.Codex) }
|
|
735
|
+
"openclaw" { Install-OpenClaw -SkillPaths $effectiveShared }
|
|
736
|
+
"trae" { Install-Trae -SkillPaths $effectiveShared }
|
|
737
|
+
"agents" { Install-Agents -SkillPaths $effectiveShared }
|
|
738
|
+
"claude-code" { Install-ClaudeCode -SkillPaths $effectiveShared }
|
|
359
739
|
default { throw "Unknown mode: $mode" }
|
|
360
740
|
}
|
|
361
741
|
}
|