aidevops 3.13.95 → 3.14.1
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/README.md +0 -1
- package/VERSION +1 -1
- package/aidevops.sh +44 -26
- package/package.json +1 -1
- package/setup.sh +25 -21
- package/aidevops-init-lib.sh +0 -1411
- package/aidevops-repos-lib.sh +0 -700
- package/aidevops-skills-plugin-lib.sh +0 -697
- package/aidevops-status-lib.sh +0 -141
- package/aidevops-update-lib.sh +0 -512
- package/aidevops-upgrade-planning-lib.sh +0 -370
- package/setup-modules/agent-deploy.sh +0 -1035
- package/setup-modules/agent-runtime.sh +0 -287
- package/setup-modules/config.sh +0 -478
- package/setup-modules/core.sh +0 -736
- package/setup-modules/mcp-setup.sh +0 -947
- package/setup-modules/migrations.sh +0 -1688
- package/setup-modules/plugins.sh +0 -728
- package/setup-modules/post-setup.sh +0 -301
- package/setup-modules/schedulers-linux.sh +0 -386
- package/setup-modules/schedulers-platform.sh +0 -1072
- package/setup-modules/schedulers-pulse.sh +0 -978
- package/setup-modules/schedulers.sh +0 -565
- package/setup-modules/shell-env.sh +0 -1240
- package/setup-modules/tool-beads.sh +0 -324
- package/setup-modules/tool-install.sh +0 -2134
|
@@ -1,697 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# SPDX-FileCopyrightText: 2025-2026 Marcus Quinn
|
|
4
|
-
# =============================================================================
|
|
5
|
-
# aidevops Skills and Plugin Library
|
|
6
|
-
# =============================================================================
|
|
7
|
-
# Skill and plugin management functions extracted from aidevops.sh to keep
|
|
8
|
-
# the orchestrator under the 2000-line file-size threshold.
|
|
9
|
-
#
|
|
10
|
-
# Covers:
|
|
11
|
-
# 1. Skills: _skill_help, _skill_add_usage, cmd_skill, cmd_skills
|
|
12
|
-
# 2. Plugins: _plugin_validate_ns, _plugin_field, _plugin_add, _plugin_list,
|
|
13
|
-
# _plugin_update, _plugin_toggle, _plugin_remove, _plugin_scaffold,
|
|
14
|
-
# _plugin_help, cmd_plugin
|
|
15
|
-
#
|
|
16
|
-
# Usage: source "${SCRIPT_DIR}/aidevops-skills-plugin-lib.sh"
|
|
17
|
-
#
|
|
18
|
-
# Dependencies:
|
|
19
|
-
# - INSTALL_DIR, AGENTS_DIR, CONFIG_DIR (set by aidevops.sh)
|
|
20
|
-
# - print_* helpers and utility functions (defined in aidevops.sh before sourcing)
|
|
21
|
-
#
|
|
22
|
-
# Part of aidevops framework: https://aidevops.sh
|
|
23
|
-
|
|
24
|
-
# Apply strict mode only when executed directly (not when sourced)
|
|
25
|
-
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && set -euo pipefail
|
|
26
|
-
|
|
27
|
-
# Include guard
|
|
28
|
-
[[ -n "${_AIDEVOPS_SKILLS_PLUGIN_LIB_LOADED:-}" ]] && return 0
|
|
29
|
-
_AIDEVOPS_SKILLS_PLUGIN_LIB_LOADED=1
|
|
30
|
-
|
|
31
|
-
# Skill help text (extracted for complexity reduction)
|
|
32
|
-
_skill_help() {
|
|
33
|
-
print_header "Agent Skills Management"
|
|
34
|
-
echo ""
|
|
35
|
-
echo "Import and manage reusable AI agent skills from the community."
|
|
36
|
-
echo "Skills are converted to aidevops format with upstream tracking."
|
|
37
|
-
echo "Telemetry is disabled - no data sent to third parties."
|
|
38
|
-
echo ""
|
|
39
|
-
echo "Usage: aidevops skill <command> [options]"
|
|
40
|
-
echo ""
|
|
41
|
-
echo "Commands:"
|
|
42
|
-
echo " add <source> Import a skill from GitHub (saved as *-skill.md)"
|
|
43
|
-
echo " list List all imported skills"
|
|
44
|
-
echo " check Check for upstream updates"
|
|
45
|
-
echo " update [name] Update specific or all skills"
|
|
46
|
-
echo " remove <name> Remove an imported skill"
|
|
47
|
-
echo " scan [name] Security scan imported skills (Cisco Skill Scanner)"
|
|
48
|
-
echo " status Show detailed skill status"
|
|
49
|
-
echo " generate Generate SKILL.md stubs for cross-tool discovery"
|
|
50
|
-
echo " clean Remove generated SKILL.md stubs"
|
|
51
|
-
echo ""
|
|
52
|
-
echo "Source formats:"
|
|
53
|
-
echo " owner/repo GitHub shorthand"
|
|
54
|
-
echo " owner/repo/path/to/skill Specific skill in multi-skill repo"
|
|
55
|
-
echo " https://github.com/owner/repo Full URL"
|
|
56
|
-
echo ""
|
|
57
|
-
echo "Examples:"
|
|
58
|
-
echo " aidevops skill add vercel-labs/agent-skills"
|
|
59
|
-
echo " aidevops skill add anthropics/skills/pdf"
|
|
60
|
-
echo " aidevops skill add expo/skills --name expo-dev"
|
|
61
|
-
echo " aidevops skill check"
|
|
62
|
-
echo " aidevops skill update"
|
|
63
|
-
echo " aidevops skill scan"
|
|
64
|
-
echo " aidevops skill scan cloudflare-platform"
|
|
65
|
-
echo " aidevops skill generate --dry-run"
|
|
66
|
-
echo ""
|
|
67
|
-
echo "Imported skills are saved with a -skill suffix to distinguish"
|
|
68
|
-
echo "from native aidevops subagents (e.g., playwright-skill.md vs playwright.md)."
|
|
69
|
-
echo ""
|
|
70
|
-
echo "Browse community skills: https://skills.sh"
|
|
71
|
-
echo "Agent Skills specification: https://agentskills.io"
|
|
72
|
-
return 0
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
_skill_add_usage() {
|
|
76
|
-
print_error "Source required (owner/repo or URL)"
|
|
77
|
-
echo ""
|
|
78
|
-
echo "Usage: aidevops skill add <source> [options]"
|
|
79
|
-
echo ""
|
|
80
|
-
echo "Examples:"
|
|
81
|
-
echo " aidevops skill add vercel-labs/agent-skills"
|
|
82
|
-
echo " aidevops skill add anthropics/skills/pdf"
|
|
83
|
-
echo " aidevops skill add https://github.com/owner/repo"
|
|
84
|
-
echo ""
|
|
85
|
-
echo "Options:"
|
|
86
|
-
echo " --name <name> Override the skill name"
|
|
87
|
-
echo " --force Overwrite existing skill"
|
|
88
|
-
echo " --dry-run Preview without making changes"
|
|
89
|
-
echo ""
|
|
90
|
-
echo "Browse skills: https://skills.sh"
|
|
91
|
-
return 0
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
# Skill management command
|
|
95
|
-
cmd_skill() {
|
|
96
|
-
local action="${1:-help}"
|
|
97
|
-
shift || true
|
|
98
|
-
export DISABLE_TELEMETRY=1 DO_NOT_TRACK=1 SKILLS_NO_TELEMETRY=1
|
|
99
|
-
local add_skill_script="$AGENTS_DIR/scripts/add-skill-helper.sh"
|
|
100
|
-
local update_skill_script="$AGENTS_DIR/scripts/skill-update-helper.sh"
|
|
101
|
-
case "$action" in
|
|
102
|
-
add | a)
|
|
103
|
-
if [[ $# -lt 1 ]]; then
|
|
104
|
-
_skill_add_usage
|
|
105
|
-
return 1
|
|
106
|
-
fi
|
|
107
|
-
[[ ! -f "$add_skill_script" ]] && {
|
|
108
|
-
print_error "add-skill-helper.sh not found"
|
|
109
|
-
print_info "Run 'aidevops update' to get the latest scripts"
|
|
110
|
-
return 1
|
|
111
|
-
}
|
|
112
|
-
bash "$add_skill_script" add "$@"
|
|
113
|
-
;;
|
|
114
|
-
list | ls | l)
|
|
115
|
-
[[ ! -f "$add_skill_script" ]] && {
|
|
116
|
-
print_error "add-skill-helper.sh not found"
|
|
117
|
-
return 1
|
|
118
|
-
}
|
|
119
|
-
bash "$add_skill_script" list
|
|
120
|
-
;;
|
|
121
|
-
check | c)
|
|
122
|
-
[[ ! -f "$update_skill_script" ]] && {
|
|
123
|
-
print_error "skill-update-helper.sh not found"
|
|
124
|
-
return 1
|
|
125
|
-
}
|
|
126
|
-
bash "$update_skill_script" check "$@"
|
|
127
|
-
;;
|
|
128
|
-
update | u)
|
|
129
|
-
[[ ! -f "$update_skill_script" ]] && {
|
|
130
|
-
print_error "skill-update-helper.sh not found"
|
|
131
|
-
return 1
|
|
132
|
-
}
|
|
133
|
-
bash "$update_skill_script" update "$@"
|
|
134
|
-
;;
|
|
135
|
-
remove | rm)
|
|
136
|
-
[[ $# -lt 1 ]] && {
|
|
137
|
-
print_error "Skill name required"
|
|
138
|
-
echo "Usage: aidevops skill remove <name>"
|
|
139
|
-
return 1
|
|
140
|
-
}
|
|
141
|
-
[[ ! -f "$add_skill_script" ]] && {
|
|
142
|
-
print_error "add-skill-helper.sh not found"
|
|
143
|
-
return 1
|
|
144
|
-
}
|
|
145
|
-
bash "$add_skill_script" remove "$@"
|
|
146
|
-
;;
|
|
147
|
-
status | s)
|
|
148
|
-
[[ ! -f "$update_skill_script" ]] && {
|
|
149
|
-
print_error "skill-update-helper.sh not found"
|
|
150
|
-
return 1
|
|
151
|
-
}
|
|
152
|
-
bash "$update_skill_script" status "$@"
|
|
153
|
-
;;
|
|
154
|
-
generate | gen | g)
|
|
155
|
-
local gs="$AGENTS_DIR/scripts/generate-skills.sh"
|
|
156
|
-
[[ ! -f "$gs" ]] && {
|
|
157
|
-
print_error "generate-skills.sh not found"
|
|
158
|
-
print_info "Run 'aidevops update' to get the latest scripts"
|
|
159
|
-
return 1
|
|
160
|
-
}
|
|
161
|
-
print_info "Generating SKILL.md stubs for cross-tool discovery..."
|
|
162
|
-
bash "$gs" "$@"
|
|
163
|
-
;;
|
|
164
|
-
scan)
|
|
165
|
-
local ss="$AGENTS_DIR/scripts/security-helper.sh"
|
|
166
|
-
[[ ! -f "$ss" ]] && {
|
|
167
|
-
print_error "security-helper.sh not found"
|
|
168
|
-
print_info "Run 'aidevops update' to get the latest scripts"
|
|
169
|
-
return 1
|
|
170
|
-
}
|
|
171
|
-
bash "$ss" skill-scan "$@"
|
|
172
|
-
;;
|
|
173
|
-
clean)
|
|
174
|
-
local gs="$AGENTS_DIR/scripts/generate-skills.sh"
|
|
175
|
-
[[ ! -f "$gs" ]] && {
|
|
176
|
-
print_error "generate-skills.sh not found"
|
|
177
|
-
return 1
|
|
178
|
-
}
|
|
179
|
-
bash "$gs" --clean "$@"
|
|
180
|
-
;;
|
|
181
|
-
help | --help | -h) _skill_help ;;
|
|
182
|
-
*)
|
|
183
|
-
print_error "Unknown skill command: $action"
|
|
184
|
-
echo "Run 'aidevops skill help' for usage information."
|
|
185
|
-
return 1
|
|
186
|
-
;;
|
|
187
|
-
esac
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
# Plugin management helpers (extracted for complexity reduction)
|
|
191
|
-
_PLUGIN_RESERVED="custom draft scripts tools services workflows templates memory plugins seo wordpress aidevops"
|
|
192
|
-
|
|
193
|
-
_plugin_validate_ns() {
|
|
194
|
-
local ns="$1"
|
|
195
|
-
if [[ ! "$ns" =~ ^[a-z][a-z0-9-]*$ ]]; then
|
|
196
|
-
print_error "Invalid namespace '$ns': must be lowercase alphanumeric with hyphens, starting with a letter"
|
|
197
|
-
return 1
|
|
198
|
-
fi
|
|
199
|
-
local r
|
|
200
|
-
for r in $_PLUGIN_RESERVED; do [[ "$ns" == "$r" ]] && {
|
|
201
|
-
print_error "Namespace '$ns' is reserved."
|
|
202
|
-
return 1
|
|
203
|
-
}; done
|
|
204
|
-
return 0
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
_plugin_field() {
|
|
208
|
-
local pf="$1" n="$2" f="$3"
|
|
209
|
-
jq -r --arg n "$n" --arg f "$f" '.plugins[] | select(.name == $n) | .[$f] // empty' "$pf" 2>/dev/null || echo ""
|
|
210
|
-
return 0
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
_plugin_regenerate_discovery_index() {
|
|
214
|
-
local ad="$1"
|
|
215
|
-
local runtime_generator="$ad/scripts/generate-runtime-config.sh"
|
|
216
|
-
local index_helper="$ad/scripts/subagent-index-helper.sh"
|
|
217
|
-
|
|
218
|
-
if [[ -x "$runtime_generator" ]]; then
|
|
219
|
-
if bash "$runtime_generator" all >/dev/null 2>&1; then
|
|
220
|
-
print_success "Runtime config and subagent index regenerated"
|
|
221
|
-
return 0
|
|
222
|
-
fi
|
|
223
|
-
print_warning "Runtime config regeneration encountered issues; trying subagent index only"
|
|
224
|
-
fi
|
|
225
|
-
|
|
226
|
-
if [[ -x "$index_helper" ]]; then
|
|
227
|
-
if bash "$index_helper" generate >/dev/null 2>&1; then
|
|
228
|
-
print_success "Subagent index regenerated"
|
|
229
|
-
return 0
|
|
230
|
-
fi
|
|
231
|
-
print_warning "Subagent index regeneration encountered issues"
|
|
232
|
-
return 1
|
|
233
|
-
fi
|
|
234
|
-
|
|
235
|
-
print_warning "Subagent index helper not found; run 'aidevops update' to regenerate discovery"
|
|
236
|
-
return 1
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
_plugin_add() {
|
|
240
|
-
local pf="$1" ad="$2"
|
|
241
|
-
shift 2
|
|
242
|
-
if [[ $# -lt 1 ]]; then
|
|
243
|
-
print_error "Repository URL required"
|
|
244
|
-
echo ""
|
|
245
|
-
echo "Usage: aidevops plugin add <repo-url> [options]"
|
|
246
|
-
echo ""
|
|
247
|
-
echo "Options:"
|
|
248
|
-
echo " --namespace <name> Namespace directory (default: derived from repo name)"
|
|
249
|
-
echo " --branch <branch> Branch to track (default: main)"
|
|
250
|
-
echo " --name <name> Human-readable name (default: derived from repo)"
|
|
251
|
-
echo ""
|
|
252
|
-
echo "Examples:"
|
|
253
|
-
echo " aidevops plugin add https://github.com/marcusquinn/aidevops-pro.git --namespace pro"
|
|
254
|
-
echo " aidevops plugin add https://github.com/marcusquinn/aidevops-anon.git --namespace anon"
|
|
255
|
-
return 1
|
|
256
|
-
fi
|
|
257
|
-
local repo_url="$1"
|
|
258
|
-
shift
|
|
259
|
-
local namespace="" branch="main" plugin_name=""
|
|
260
|
-
while [[ $# -gt 0 ]]; do
|
|
261
|
-
local _opt="$1" _val="${2:-}"
|
|
262
|
-
case "$_opt" in
|
|
263
|
-
--namespace | --ns)
|
|
264
|
-
namespace="$_val"
|
|
265
|
-
shift 2
|
|
266
|
-
;;
|
|
267
|
-
--branch | -b)
|
|
268
|
-
branch="$_val"
|
|
269
|
-
shift 2
|
|
270
|
-
;;
|
|
271
|
-
--name | -n)
|
|
272
|
-
plugin_name="$_val"
|
|
273
|
-
shift 2
|
|
274
|
-
;;
|
|
275
|
-
*)
|
|
276
|
-
print_error "Unknown option: $_opt"
|
|
277
|
-
return 1
|
|
278
|
-
;;
|
|
279
|
-
esac
|
|
280
|
-
done
|
|
281
|
-
[[ -z "$namespace" ]] && {
|
|
282
|
-
namespace=$(basename "$repo_url" .git | sed 's/^aidevops-//')
|
|
283
|
-
namespace=$(echo "$namespace" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g')
|
|
284
|
-
}
|
|
285
|
-
[[ -z "$plugin_name" ]] && plugin_name="$namespace"
|
|
286
|
-
_plugin_validate_ns "$namespace" || return 1
|
|
287
|
-
local existing
|
|
288
|
-
existing=$(jq -r --arg n "$plugin_name" '.plugins[] | select(.name == $n) | .name' "$pf" 2>/dev/null || echo "")
|
|
289
|
-
[[ -n "$existing" ]] && {
|
|
290
|
-
print_error "Plugin '$plugin_name' already exists. Use 'aidevops plugin update $plugin_name' to update."
|
|
291
|
-
return 1
|
|
292
|
-
}
|
|
293
|
-
if [[ -d "$ad/$namespace" ]]; then
|
|
294
|
-
local ns_owner
|
|
295
|
-
ns_owner=$(jq -r --arg ns "$namespace" '.plugins[] | select(.namespace == $ns) | .name' "$pf" 2>/dev/null || echo "")
|
|
296
|
-
[[ -n "$ns_owner" ]] && print_error "Namespace '$namespace' is already used by plugin '$ns_owner'" || {
|
|
297
|
-
print_error "Directory '$ad/$namespace/' already exists"
|
|
298
|
-
echo " Choose a different namespace with --namespace <name>"
|
|
299
|
-
}
|
|
300
|
-
return 1
|
|
301
|
-
fi
|
|
302
|
-
print_info "Adding plugin '$plugin_name' from $repo_url..."
|
|
303
|
-
print_info " Namespace: $namespace"
|
|
304
|
-
print_info " Branch: $branch"
|
|
305
|
-
local clone_dir="$ad/$namespace"
|
|
306
|
-
if ! git clone --branch "$branch" --depth 1 "$repo_url" "$clone_dir" 2>&1; then
|
|
307
|
-
print_error "Failed to clone repository"
|
|
308
|
-
rm -rf "$clone_dir" 2>/dev/null || true
|
|
309
|
-
return 1
|
|
310
|
-
fi
|
|
311
|
-
rm -rf "$clone_dir/.git"
|
|
312
|
-
local tmp="${pf}.tmp"
|
|
313
|
-
jq --arg name "$plugin_name" --arg repo "$repo_url" --arg branch "$branch" --arg ns "$namespace" \
|
|
314
|
-
'.plugins += [{"name": $name, "repo": $repo, "branch": $branch, "namespace": $ns, "enabled": true}]' "$pf" >"$tmp" && mv "$tmp" "$pf"
|
|
315
|
-
local loader="$ad/scripts/plugin-loader-helper.sh"
|
|
316
|
-
[[ -f "$loader" ]] && bash "$loader" hooks "$namespace" init 2>/dev/null || true
|
|
317
|
-
_plugin_regenerate_discovery_index "$ad" || true
|
|
318
|
-
print_success "Plugin '$plugin_name' installed to $clone_dir"
|
|
319
|
-
echo ""
|
|
320
|
-
echo " Agents available at: ~/.aidevops/agents/$namespace/"
|
|
321
|
-
echo " Update: aidevops plugin update $plugin_name"
|
|
322
|
-
echo " Remove: aidevops plugin remove $plugin_name"
|
|
323
|
-
return 0
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
_plugin_list() {
|
|
327
|
-
local pf="$1"
|
|
328
|
-
local count
|
|
329
|
-
count=$(jq '.plugins | length' "$pf" 2>/dev/null || echo "0")
|
|
330
|
-
if [[ "$count" == "0" ]]; then
|
|
331
|
-
echo "No plugins installed."
|
|
332
|
-
echo ""
|
|
333
|
-
echo "Add a plugin: aidevops plugin add <repo-url> --namespace <name>"
|
|
334
|
-
return 0
|
|
335
|
-
fi
|
|
336
|
-
echo "Installed plugins ($count):"
|
|
337
|
-
echo ""
|
|
338
|
-
printf " %-15s %-10s %-8s %s\n" "NAME" "NAMESPACE" "ENABLED" "REPO"
|
|
339
|
-
printf " %-15s %-10s %-8s %s\n" "----" "---------" "-------" "----"
|
|
340
|
-
jq -r '.plugins[] | " \(.name)\t\(.namespace)\t\(.enabled // true)\t\(.repo)"' "$pf" 2>/dev/null |
|
|
341
|
-
while IFS=$'\t' read -r name ns enabled repo; do
|
|
342
|
-
local si="yes"
|
|
343
|
-
[[ "$enabled" == "false" ]] && si="no"
|
|
344
|
-
printf " %-15s %-10s %-8s %s\n" "$name" "$ns" "$si" "$repo"
|
|
345
|
-
done
|
|
346
|
-
return 0
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
_plugin_update() {
|
|
350
|
-
local pf="$1" ad="$2" target="${3:-}"
|
|
351
|
-
if [[ -n "$target" ]]; then
|
|
352
|
-
local repo ns bn
|
|
353
|
-
repo=$(_plugin_field "$pf" "$target" "repo")
|
|
354
|
-
ns=$(_plugin_field "$pf" "$target" "namespace")
|
|
355
|
-
bn=$(_plugin_field "$pf" "$target" "branch")
|
|
356
|
-
bn="${bn:-main}"
|
|
357
|
-
[[ -z "$repo" ]] && {
|
|
358
|
-
print_error "Plugin '$target' not found"
|
|
359
|
-
return 1
|
|
360
|
-
}
|
|
361
|
-
print_info "Updating plugin '$target'..."
|
|
362
|
-
local cd2="$ad/$ns"
|
|
363
|
-
rm -rf "$cd2"
|
|
364
|
-
if git clone --branch "$bn" --depth 1 "$repo" "$cd2" 2>&1; then
|
|
365
|
-
rm -rf "$cd2/.git"
|
|
366
|
-
print_success "Plugin '$target' updated"
|
|
367
|
-
_plugin_regenerate_discovery_index "$ad" || true
|
|
368
|
-
else
|
|
369
|
-
print_error "Failed to update plugin '$target'"
|
|
370
|
-
return 1
|
|
371
|
-
fi
|
|
372
|
-
else
|
|
373
|
-
local names
|
|
374
|
-
names=$(jq -r '.plugins[] | select(.enabled != false) | .name' "$pf" 2>/dev/null || echo "")
|
|
375
|
-
[[ -z "$names" ]] && {
|
|
376
|
-
echo "No enabled plugins to update."
|
|
377
|
-
return 0
|
|
378
|
-
}
|
|
379
|
-
local failed=0
|
|
380
|
-
while IFS= read -r pn; do
|
|
381
|
-
[[ -z "$pn" ]] && continue
|
|
382
|
-
local pr pns pb
|
|
383
|
-
pr=$(_plugin_field "$pf" "$pn" "repo")
|
|
384
|
-
pns=$(_plugin_field "$pf" "$pn" "namespace")
|
|
385
|
-
pb=$(_plugin_field "$pf" "$pn" "branch")
|
|
386
|
-
pb="${pb:-main}"
|
|
387
|
-
print_info "Updating '$pn'..."
|
|
388
|
-
local pd="$ad/$pns"
|
|
389
|
-
rm -rf "$pd"
|
|
390
|
-
if git clone --branch "$pb" --depth 1 "$pr" "$pd" 2>/dev/null; then
|
|
391
|
-
rm -rf "$pd/.git"
|
|
392
|
-
print_success " '$pn' updated"
|
|
393
|
-
else
|
|
394
|
-
print_error " '$pn' failed to update"
|
|
395
|
-
failed=$((failed + 1))
|
|
396
|
-
fi
|
|
397
|
-
done <<<"$names"
|
|
398
|
-
[[ "$failed" -gt 0 ]] && {
|
|
399
|
-
print_warning "$failed plugin(s) failed to update"
|
|
400
|
-
return 1
|
|
401
|
-
}
|
|
402
|
-
print_success "All plugins updated"
|
|
403
|
-
_plugin_regenerate_discovery_index "$ad" || true
|
|
404
|
-
fi
|
|
405
|
-
return 0
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
_plugin_toggle() {
|
|
409
|
-
local pf="$1" ad="$2" tn="$3" action="$4"
|
|
410
|
-
if [[ "$action" == "enable" ]]; then
|
|
411
|
-
local tr
|
|
412
|
-
tr=$(_plugin_field "$pf" "$tn" "repo")
|
|
413
|
-
[[ -z "$tr" ]] && {
|
|
414
|
-
print_error "Plugin '$tn' not found"
|
|
415
|
-
return 1
|
|
416
|
-
}
|
|
417
|
-
local tns
|
|
418
|
-
tns=$(_plugin_field "$pf" "$tn" "namespace")
|
|
419
|
-
local tb
|
|
420
|
-
tb=$(_plugin_field "$pf" "$tn" "branch")
|
|
421
|
-
tb="${tb:-main}"
|
|
422
|
-
local tmp="${pf}.tmp"
|
|
423
|
-
jq --arg n "$tn" '(.plugins[] | select(.name == $n)).enabled = true' "$pf" >"$tmp" && mv "$tmp" "$pf"
|
|
424
|
-
[[ ! -d "$ad/$tns" ]] && {
|
|
425
|
-
print_info "Deploying plugin '$tn'..."
|
|
426
|
-
git clone --branch "$tb" --depth 1 "$tr" "$ad/$tns" 2>/dev/null && rm -rf "$ad/$tns/.git"
|
|
427
|
-
}
|
|
428
|
-
local loader="$ad/scripts/plugin-loader-helper.sh"
|
|
429
|
-
[[ -f "$loader" ]] && bash "$loader" hooks "$tns" init 2>/dev/null || true
|
|
430
|
-
_plugin_regenerate_discovery_index "$ad" || true
|
|
431
|
-
print_success "Plugin '$tn' enabled"
|
|
432
|
-
else
|
|
433
|
-
local tns
|
|
434
|
-
tns=$(_plugin_field "$pf" "$tn" "namespace")
|
|
435
|
-
[[ -z "$tns" ]] && {
|
|
436
|
-
print_error "Plugin '$tn' not found"
|
|
437
|
-
return 1
|
|
438
|
-
}
|
|
439
|
-
local loader="$ad/scripts/plugin-loader-helper.sh"
|
|
440
|
-
[[ -f "$loader" && -d "$ad/$tns" ]] && bash "$loader" hooks "$tns" unload 2>/dev/null || true
|
|
441
|
-
local tmp="${pf}.tmp"
|
|
442
|
-
jq --arg n "$tn" '(.plugins[] | select(.name == $n)).enabled = false' "$pf" >"$tmp" && mv "$tmp" "$pf"
|
|
443
|
-
[[ -d "$ad/${tns:?}" ]] && rm -rf "$ad/${tns:?}"
|
|
444
|
-
_plugin_regenerate_discovery_index "$ad" || true
|
|
445
|
-
print_success "Plugin '$tn' disabled (config preserved)"
|
|
446
|
-
fi
|
|
447
|
-
return 0
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
_plugin_remove() {
|
|
451
|
-
local pf="$1" ad="$2" tn="$3"
|
|
452
|
-
local tns
|
|
453
|
-
tns=$(_plugin_field "$pf" "$tn" "namespace")
|
|
454
|
-
[[ -z "$tns" ]] && {
|
|
455
|
-
print_error "Plugin '$tn' not found"
|
|
456
|
-
return 1
|
|
457
|
-
}
|
|
458
|
-
local loader="$ad/scripts/plugin-loader-helper.sh"
|
|
459
|
-
[[ -f "$loader" && -d "$ad/$tns" ]] && bash "$loader" hooks "$tns" unload 2>/dev/null || true
|
|
460
|
-
[[ -d "$ad/${tns:?}" ]] && {
|
|
461
|
-
rm -rf "$ad/${tns:?}"
|
|
462
|
-
print_info "Removed $ad/$tns/"
|
|
463
|
-
}
|
|
464
|
-
local tmp="${pf}.tmp"
|
|
465
|
-
jq --arg n "$tn" '.plugins = [.plugins[] | select(.name != $n)]' "$pf" >"$tmp" && mv "$tmp" "$pf"
|
|
466
|
-
print_success "Plugin '$tn' removed"
|
|
467
|
-
return 0
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
_plugin_scaffold() {
|
|
471
|
-
local ad="$1" td="${2:-.}" pn="${3:-my-plugin}"
|
|
472
|
-
local ns="${4:-$pn}"
|
|
473
|
-
if [[ "$td" != "." && -d "$td" ]]; then
|
|
474
|
-
local ec
|
|
475
|
-
ec=$(find "$td" -maxdepth 1 -type f | wc -l | tr -d ' ')
|
|
476
|
-
[[ "$ec" -gt 0 ]] && {
|
|
477
|
-
print_error "Directory '$td' already has files. Use an empty directory."
|
|
478
|
-
return 1
|
|
479
|
-
}
|
|
480
|
-
fi
|
|
481
|
-
mkdir -p "$td"
|
|
482
|
-
local tpl="$ad/templates/plugin-template"
|
|
483
|
-
[[ ! -d "$tpl" ]] && {
|
|
484
|
-
print_error "Plugin template not found at $tpl"
|
|
485
|
-
print_info "Run 'aidevops update' to get the latest templates."
|
|
486
|
-
return 1
|
|
487
|
-
}
|
|
488
|
-
local pnu
|
|
489
|
-
pnu=$(echo "$pn" | tr '[:lower:]' '[:upper:]' | tr '-' '_')
|
|
490
|
-
sed -e "s|{{PLUGIN_NAME}}|$pn|g" -e "s|{{PLUGIN_NAME_UPPER}}|$pnu|g" -e "s|{{NAMESPACE}}|$ns|g" -e "s|{{REPO_URL}}|https://github.com/user/aidevops-$ns.git|g" "$tpl/AGENTS.md" >"$td/AGENTS.md"
|
|
491
|
-
sed -e "s|{{PLUGIN_NAME}}|$pn|g" -e "s|{{PLUGIN_DESCRIPTION}}|$pn plugin for aidevops|g" -e "s|{{NAMESPACE}}|$ns|g" "$tpl/main-agent.md" >"$td/$ns.md"
|
|
492
|
-
mkdir -p "$td/$ns"
|
|
493
|
-
sed -e "s|{{PLUGIN_NAME}}|$pn|g" -e "s|{{NAMESPACE}}|$ns|g" "$tpl/example-subagent.md" >"$td/$ns/example.md"
|
|
494
|
-
mkdir -p "$td/scripts"
|
|
495
|
-
if [[ -d "$tpl/scripts" ]]; then
|
|
496
|
-
for hf in "$tpl/scripts"/on-*.sh; do
|
|
497
|
-
[[ -f "$hf" ]] || continue
|
|
498
|
-
local hb
|
|
499
|
-
hb=$(basename "$hf")
|
|
500
|
-
sed -e "s|{{PLUGIN_NAME}}|$pn|g" -e "s|{{NAMESPACE}}|$ns|g" "$hf" >"$td/scripts/$hb"
|
|
501
|
-
chmod +x "$td/scripts/$hb"
|
|
502
|
-
done
|
|
503
|
-
fi
|
|
504
|
-
[[ -f "$tpl/plugin.json" ]] && sed -e "s|{{PLUGIN_NAME}}|$pn|g" -e "s|{{PLUGIN_DESCRIPTION}}|$pn plugin for aidevops|g" -e "s|{{NAMESPACE}}|$ns|g" "$tpl/plugin.json" >"$td/plugin.json"
|
|
505
|
-
print_success "Plugin scaffolded in $td/"
|
|
506
|
-
echo ""
|
|
507
|
-
echo "Structure:"
|
|
508
|
-
echo " $td/"
|
|
509
|
-
echo " ├── AGENTS.md # Plugin documentation"
|
|
510
|
-
echo " ├── plugin.json # Plugin manifest"
|
|
511
|
-
echo " ├── $ns.md # Main agent"
|
|
512
|
-
echo " ├── $ns/"
|
|
513
|
-
echo " │ └── example.md # Example subagent"
|
|
514
|
-
echo " └── scripts/"
|
|
515
|
-
echo " ├── on-init.sh # Init lifecycle hook"
|
|
516
|
-
echo " ├── on-load.sh # Load lifecycle hook"
|
|
517
|
-
echo " └── on-unload.sh # Unload lifecycle hook"
|
|
518
|
-
echo ""
|
|
519
|
-
echo "Next steps:"
|
|
520
|
-
echo " 1. Edit plugin.json with your plugin metadata"
|
|
521
|
-
echo " 2. Edit $ns.md with your agent instructions"
|
|
522
|
-
echo " 3. Add subagents to $ns/"
|
|
523
|
-
echo " 4. Push to a git repo"
|
|
524
|
-
echo " 5. Install: aidevops plugin add <repo-url> --namespace $ns"
|
|
525
|
-
return 0
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
_plugin_help() {
|
|
529
|
-
print_header "Plugin Management"
|
|
530
|
-
echo ""
|
|
531
|
-
echo "Manage third-party agent plugins that extend aidevops."
|
|
532
|
-
echo "Plugins deploy to ~/.aidevops/agents/<namespace>/ (isolated from core)."
|
|
533
|
-
echo ""
|
|
534
|
-
echo "Usage: aidevops plugin <command> [options]"
|
|
535
|
-
echo ""
|
|
536
|
-
echo "Commands:"
|
|
537
|
-
echo " add <repo-url> Install a plugin from a git repository"
|
|
538
|
-
echo " list List installed plugins"
|
|
539
|
-
echo " update [name] Update specific or all plugins"
|
|
540
|
-
echo " enable <name> Enable a disabled plugin (redeploys files)"
|
|
541
|
-
echo " disable <name> Disable a plugin (removes files, keeps config)"
|
|
542
|
-
echo " remove <name> Remove a plugin entirely"
|
|
543
|
-
echo " init [dir] [name] [namespace] Scaffold a new plugin from template"
|
|
544
|
-
echo ""
|
|
545
|
-
echo "Options for 'add':"
|
|
546
|
-
echo " --namespace <name> Directory name under ~/.aidevops/agents/"
|
|
547
|
-
echo " --branch <branch> Branch to track (default: main)"
|
|
548
|
-
echo " --name <name> Human-readable plugin name"
|
|
549
|
-
echo ""
|
|
550
|
-
echo "Examples:"
|
|
551
|
-
echo " aidevops plugin add https://github.com/marcusquinn/aidevops-pro.git --namespace pro"
|
|
552
|
-
echo " aidevops plugin add https://github.com/marcusquinn/aidevops-anon.git --namespace anon"
|
|
553
|
-
echo " aidevops plugin list"
|
|
554
|
-
echo " aidevops plugin update"
|
|
555
|
-
echo " aidevops plugin update pro"
|
|
556
|
-
echo " aidevops plugin disable pro"
|
|
557
|
-
echo " aidevops plugin enable pro"
|
|
558
|
-
echo " aidevops plugin remove pro"
|
|
559
|
-
echo " aidevops plugin init ./my-plugin my-plugin my-plugin"
|
|
560
|
-
echo ""
|
|
561
|
-
echo "Plugin docs: ~/.aidevops/agents/aidevops/plugins.md"
|
|
562
|
-
return 0
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
# Plugin management command
|
|
566
|
-
cmd_plugin() {
|
|
567
|
-
local action="${1:-help}"
|
|
568
|
-
shift || true
|
|
569
|
-
local pf="$CONFIG_DIR/plugins.json" ad="$AGENTS_DIR"
|
|
570
|
-
mkdir -p "$CONFIG_DIR"
|
|
571
|
-
[[ ! -f "$pf" ]] && echo '{"plugins":[]}' >"$pf"
|
|
572
|
-
case "$action" in
|
|
573
|
-
add | a) _plugin_add "$pf" "$ad" "$@" ;;
|
|
574
|
-
list | ls | l) _plugin_list "$pf" ;;
|
|
575
|
-
update | u) _plugin_update "$pf" "$ad" "$@" ;;
|
|
576
|
-
enable)
|
|
577
|
-
[[ $# -lt 1 ]] && {
|
|
578
|
-
print_error "Plugin name required"
|
|
579
|
-
echo "Usage: aidevops plugin enable <name>"
|
|
580
|
-
return 1
|
|
581
|
-
}
|
|
582
|
-
local _enable_name="$1"
|
|
583
|
-
_plugin_toggle "$pf" "$ad" "$_enable_name" enable
|
|
584
|
-
;;
|
|
585
|
-
disable)
|
|
586
|
-
[[ $# -lt 1 ]] && {
|
|
587
|
-
print_error "Plugin name required"
|
|
588
|
-
echo "Usage: aidevops plugin disable <name>"
|
|
589
|
-
return 1
|
|
590
|
-
}
|
|
591
|
-
local _disable_name="$1"
|
|
592
|
-
_plugin_toggle "$pf" "$ad" "$_disable_name" disable
|
|
593
|
-
;;
|
|
594
|
-
remove | rm)
|
|
595
|
-
[[ $# -lt 1 ]] && {
|
|
596
|
-
print_error "Plugin name required"
|
|
597
|
-
echo "Usage: aidevops plugin remove <name>"
|
|
598
|
-
return 1
|
|
599
|
-
}
|
|
600
|
-
local _remove_name="$1"
|
|
601
|
-
_plugin_remove "$pf" "$ad" "$_remove_name"
|
|
602
|
-
;;
|
|
603
|
-
init) _plugin_scaffold "$ad" "$@" ;;
|
|
604
|
-
help | --help | -h) _plugin_help ;;
|
|
605
|
-
*)
|
|
606
|
-
print_error "Unknown plugin command: $action"
|
|
607
|
-
echo "Run 'aidevops plugin help' for usage information."
|
|
608
|
-
return 1
|
|
609
|
-
;;
|
|
610
|
-
esac
|
|
611
|
-
return 0
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
# Skills discovery command - search, browse, describe installed skills
|
|
615
|
-
cmd_skills() {
|
|
616
|
-
local action="${1:-help}"
|
|
617
|
-
shift || true
|
|
618
|
-
|
|
619
|
-
local skills_helper="$AGENTS_DIR/scripts/skills-helper.sh"
|
|
620
|
-
|
|
621
|
-
if [[ ! -f "$skills_helper" ]]; then
|
|
622
|
-
print_error "skills-helper.sh not found"
|
|
623
|
-
print_info "Run 'aidevops update' to get the latest scripts"
|
|
624
|
-
return 1
|
|
625
|
-
fi
|
|
626
|
-
|
|
627
|
-
case "$action" in
|
|
628
|
-
search | s | find | f)
|
|
629
|
-
bash "$skills_helper" search "$@"
|
|
630
|
-
;;
|
|
631
|
-
browse | b)
|
|
632
|
-
bash "$skills_helper" browse "$@"
|
|
633
|
-
;;
|
|
634
|
-
describe | desc | d | show)
|
|
635
|
-
bash "$skills_helper" describe "$@"
|
|
636
|
-
;;
|
|
637
|
-
info | i | meta)
|
|
638
|
-
bash "$skills_helper" info "$@"
|
|
639
|
-
;;
|
|
640
|
-
list | ls | l)
|
|
641
|
-
bash "$skills_helper" list "$@"
|
|
642
|
-
;;
|
|
643
|
-
categories | cats | cat)
|
|
644
|
-
bash "$skills_helper" categories "$@"
|
|
645
|
-
;;
|
|
646
|
-
recommend | rec | suggest)
|
|
647
|
-
bash "$skills_helper" recommend "$@"
|
|
648
|
-
;;
|
|
649
|
-
install | add)
|
|
650
|
-
bash "$skills_helper" install "$@"
|
|
651
|
-
;;
|
|
652
|
-
registry | online)
|
|
653
|
-
bash "$skills_helper" registry "$@"
|
|
654
|
-
;;
|
|
655
|
-
help | --help | -h)
|
|
656
|
-
print_header "Skill Discovery & Exploration"
|
|
657
|
-
echo ""
|
|
658
|
-
echo "Discover, explore, and get recommendations for installed skills."
|
|
659
|
-
echo "For importing/managing skills, use: aidevops skill <cmd>"
|
|
660
|
-
echo ""
|
|
661
|
-
echo "Usage: aidevops skills <command> [options]"
|
|
662
|
-
echo ""
|
|
663
|
-
echo "Commands:"
|
|
664
|
-
echo " search <query> Search installed skills by keyword"
|
|
665
|
-
echo " search --registry <q> Search the public skills.sh registry (online)"
|
|
666
|
-
echo " browse [category] Browse skills by category"
|
|
667
|
-
echo " describe <name> Show detailed skill description"
|
|
668
|
-
echo " info <name> Show skill metadata (path, source, model tier)"
|
|
669
|
-
echo " list [filter] List skills (--imported, --native, --all)"
|
|
670
|
-
echo " categories List all categories with skill counts"
|
|
671
|
-
echo " recommend <task> Suggest skills for a task description"
|
|
672
|
-
echo " install <owner/repo@s> Install a skill from the public registry"
|
|
673
|
-
echo ""
|
|
674
|
-
echo "Options:"
|
|
675
|
-
echo " --json Output in JSON format (for scripting)"
|
|
676
|
-
echo " --registry, --online Search the public skills.sh registry"
|
|
677
|
-
echo ""
|
|
678
|
-
echo "Examples:"
|
|
679
|
-
echo " aidevops skills search \"browser automation\""
|
|
680
|
-
echo " aidevops skills search --registry \"seo\""
|
|
681
|
-
echo " aidevops skills browse tools"
|
|
682
|
-
echo " aidevops skills browse tools/browser"
|
|
683
|
-
echo " aidevops skills describe playwright"
|
|
684
|
-
echo " aidevops skills info seo-audit-skill"
|
|
685
|
-
echo " aidevops skills list --imported"
|
|
686
|
-
echo " aidevops skills categories"
|
|
687
|
-
echo " aidevops skills recommend \"deploy a Next.js app\""
|
|
688
|
-
echo " aidevops skills install vercel-labs/agent-browser@agent-browser"
|
|
689
|
-
echo ""
|
|
690
|
-
echo "See also: aidevops skill help (import/manage skills)"
|
|
691
|
-
;;
|
|
692
|
-
*)
|
|
693
|
-
# Treat unknown action as a search query
|
|
694
|
-
bash "$skills_helper" search "$action $*"
|
|
695
|
-
;;
|
|
696
|
-
esac
|
|
697
|
-
}
|