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
package/setup-modules/config.sh
DELETED
|
@@ -1,478 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# SPDX-FileCopyrightText: 2025-2026 Marcus Quinn
|
|
4
|
-
# Configuration functions: setup_configs, set_permissions, ssh, aidevops-cli, opencode-config, claude-config, validate, extract-prompts, drift-check
|
|
5
|
-
# Part of aidevops setup.sh modularization (t316.3)
|
|
6
|
-
|
|
7
|
-
# Shell safety baseline
|
|
8
|
-
set -Eeuo pipefail
|
|
9
|
-
IFS=$'\n\t'
|
|
10
|
-
# shellcheck disable=SC2154 # rc is assigned by $? in the trap string
|
|
11
|
-
trap 'rc=$?; echo "[ERROR] ${BASH_SOURCE[0]}:${LINENO} exit $rc" >&2' ERR
|
|
12
|
-
shopt -s inherit_errexit 2>/dev/null || true
|
|
13
|
-
|
|
14
|
-
setup_configs() {
|
|
15
|
-
print_info "Setting up configuration files..."
|
|
16
|
-
|
|
17
|
-
# Create configs directory if it doesn't exist
|
|
18
|
-
mkdir -p configs
|
|
19
|
-
|
|
20
|
-
# Copy template configs if they don't exist
|
|
21
|
-
for template in configs/*.txt; do
|
|
22
|
-
if [[ -f "$template" ]]; then
|
|
23
|
-
config_file="${template%.txt}"
|
|
24
|
-
if [[ ! -f "$config_file" ]]; then
|
|
25
|
-
cp "$template" "$config_file"
|
|
26
|
-
print_success "Created $(basename "$config_file")"
|
|
27
|
-
print_warning "Please edit $(basename "$config_file") with your actual credentials"
|
|
28
|
-
else
|
|
29
|
-
print_info "Found existing config: $(basename "$config_file") - Skipping"
|
|
30
|
-
fi
|
|
31
|
-
fi
|
|
32
|
-
done
|
|
33
|
-
|
|
34
|
-
return 0
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
install_aidevops_cli() {
|
|
38
|
-
print_info "Installing aidevops CLI command..."
|
|
39
|
-
|
|
40
|
-
# Use INSTALL_DIR (repo root, exported by setup.sh) — not BASH_SOURCE[0]
|
|
41
|
-
# which resolves to setup-modules/ when sourced from setup.sh.
|
|
42
|
-
local cli_source="${INSTALL_DIR:?INSTALL_DIR not set}/aidevops.sh"
|
|
43
|
-
local cli_target="/usr/local/bin/aidevops"
|
|
44
|
-
|
|
45
|
-
if [[ ! -f "$cli_source" ]]; then
|
|
46
|
-
print_warning "aidevops.sh not found at $cli_source - skipping CLI installation"
|
|
47
|
-
return 0
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
# Check if we can write to /usr/local/bin
|
|
51
|
-
if [[ -w "/usr/local/bin" ]]; then
|
|
52
|
-
# Direct symlink
|
|
53
|
-
ln -sf "$cli_source" "$cli_target"
|
|
54
|
-
print_success "Installed aidevops command to $cli_target"
|
|
55
|
-
elif [[ -w "$HOME/.local/bin" ]] || mkdir -p "$HOME/.local/bin" 2>/dev/null; then
|
|
56
|
-
# Use ~/.local/bin instead
|
|
57
|
-
cli_target="$HOME/.local/bin/aidevops"
|
|
58
|
-
ln -sf "$cli_source" "$cli_target"
|
|
59
|
-
print_success "Installed aidevops command to $cli_target"
|
|
60
|
-
|
|
61
|
-
# Check if ~/.local/bin is in PATH and add it if not
|
|
62
|
-
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
|
63
|
-
add_local_bin_to_path
|
|
64
|
-
fi
|
|
65
|
-
else
|
|
66
|
-
# Need sudo
|
|
67
|
-
print_info "Installing aidevops command requires sudo..."
|
|
68
|
-
if sudo ln -sf "$cli_source" "$cli_target"; then
|
|
69
|
-
print_success "Installed aidevops command to $cli_target"
|
|
70
|
-
else
|
|
71
|
-
print_warning "Could not install aidevops command globally"
|
|
72
|
-
print_info "You can run it directly: $cli_source"
|
|
73
|
-
fi
|
|
74
|
-
fi
|
|
75
|
-
|
|
76
|
-
return 0
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
# Helper: check for a generator script, run it, report result consistently
|
|
80
|
-
_run_generator() {
|
|
81
|
-
local script_path="$1"
|
|
82
|
-
local info_msg="$2"
|
|
83
|
-
local success_msg="$3"
|
|
84
|
-
local failure_msg="$4"
|
|
85
|
-
shift 4
|
|
86
|
-
local script_args=("$@")
|
|
87
|
-
|
|
88
|
-
if [[ ! -f "$script_path" ]]; then
|
|
89
|
-
print_warning "Generator script not found: $script_path"
|
|
90
|
-
return 0
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
print_info "$info_msg"
|
|
94
|
-
# Use ${arr[@]+"${arr[@]}"} pattern for safe expansion under set -u when array may be empty
|
|
95
|
-
if bash "$script_path" ${script_args[@]+"${script_args[@]}"}; then
|
|
96
|
-
print_success "$success_msg"
|
|
97
|
-
else
|
|
98
|
-
print_warning "$failure_msg"
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
return 0
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
update_opencode_config() {
|
|
105
|
-
# Respect config (env var or config file)
|
|
106
|
-
if ! is_feature_enabled manage_opencode_config 2>/dev/null; then
|
|
107
|
-
print_info "OpenCode config management disabled via config (integrations.manage_opencode_config)"
|
|
108
|
-
return 0
|
|
109
|
-
fi
|
|
110
|
-
|
|
111
|
-
print_info "Updating OpenCode configuration..."
|
|
112
|
-
|
|
113
|
-
# Use unified generator (t1665.4) if available, fall back to legacy scripts
|
|
114
|
-
if [[ -f ".agents/scripts/generate-runtime-config.sh" ]]; then
|
|
115
|
-
_run_generator ".agents/scripts/generate-runtime-config.sh" \
|
|
116
|
-
"Generating OpenCode configuration (unified)..." \
|
|
117
|
-
"OpenCode configuration complete (agents, commands, MCPs, prompts)" \
|
|
118
|
-
"OpenCode configuration encountered issues" \
|
|
119
|
-
all --runtime opencode
|
|
120
|
-
else
|
|
121
|
-
# Legacy fallback — remove after one release cycle
|
|
122
|
-
_run_generator ".agents/scripts/generate-opencode-commands.sh" \
|
|
123
|
-
"Generating OpenCode commands..." \
|
|
124
|
-
"OpenCode commands configured" \
|
|
125
|
-
"OpenCode command generation encountered issues"
|
|
126
|
-
|
|
127
|
-
_run_generator ".agents/scripts/generate-opencode-agents.sh" \
|
|
128
|
-
"Generating OpenCode agent configuration..." \
|
|
129
|
-
"OpenCode agents configured (11 primary in JSON, subagents as markdown)" \
|
|
130
|
-
"OpenCode agent generation encountered issues"
|
|
131
|
-
|
|
132
|
-
_run_generator ".agents/scripts/subagent-index-helper.sh" \
|
|
133
|
-
"Regenerating subagent index..." \
|
|
134
|
-
"Subagent index regenerated" \
|
|
135
|
-
"Subagent index generation encountered issues" \
|
|
136
|
-
generate
|
|
137
|
-
fi
|
|
138
|
-
|
|
139
|
-
return 0
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
update_claude_config() {
|
|
143
|
-
# Respect config (env var or config file)
|
|
144
|
-
if ! is_feature_enabled manage_claude_config 2>/dev/null; then
|
|
145
|
-
print_info "Claude config management disabled via config (integrations.manage_claude_config)"
|
|
146
|
-
return 0
|
|
147
|
-
fi
|
|
148
|
-
|
|
149
|
-
print_info "Updating Claude Code configuration..."
|
|
150
|
-
|
|
151
|
-
# Use unified generator (t1665.4) if available, fall back to legacy scripts
|
|
152
|
-
if [[ -f ".agents/scripts/generate-runtime-config.sh" ]]; then
|
|
153
|
-
_run_generator ".agents/scripts/generate-runtime-config.sh" \
|
|
154
|
-
"Generating Claude Code configuration (unified)..." \
|
|
155
|
-
"Claude Code configuration complete (agents, commands, MCPs, prompts)" \
|
|
156
|
-
"Claude Code configuration encountered issues" \
|
|
157
|
-
all --runtime claude-code
|
|
158
|
-
else
|
|
159
|
-
# Legacy fallback — remove after one release cycle
|
|
160
|
-
_run_generator ".agents/scripts/generate-claude-commands.sh" \
|
|
161
|
-
"Generating Claude Code commands..." \
|
|
162
|
-
"Claude Code commands configured" \
|
|
163
|
-
"Claude Code command generation encountered issues"
|
|
164
|
-
|
|
165
|
-
_run_generator ".agents/scripts/generate-claude-agents.sh" \
|
|
166
|
-
"Generating Claude Code agent configuration..." \
|
|
167
|
-
"Claude Code agents configured (MCPs, settings, commands)" \
|
|
168
|
-
"Claude Code agent generation encountered issues"
|
|
169
|
-
|
|
170
|
-
_run_generator ".agents/scripts/subagent-index-helper.sh" \
|
|
171
|
-
"Regenerating subagent index..." \
|
|
172
|
-
"Subagent index regenerated" \
|
|
173
|
-
"Subagent index generation encountered issues" \
|
|
174
|
-
generate
|
|
175
|
-
fi
|
|
176
|
-
|
|
177
|
-
return 0
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
# Unified runtime config update (t1665.4)
|
|
181
|
-
# Generates config for all installed runtimes in a single pass.
|
|
182
|
-
# Called by setup.sh as an alternative to separate update_opencode_config + update_claude_config.
|
|
183
|
-
# Respects per-runtime opt-outs (manage_opencode_config, manage_claude_config).
|
|
184
|
-
update_runtime_configs() {
|
|
185
|
-
print_info "Updating runtime configurations..."
|
|
186
|
-
|
|
187
|
-
if [[ ! -f ".agents/scripts/generate-runtime-config.sh" ]]; then
|
|
188
|
-
# Legacy fallback — use per-runtime update functions
|
|
189
|
-
print_info "Unified generator not found — falling back to per-runtime updates"
|
|
190
|
-
update_opencode_config
|
|
191
|
-
update_claude_config
|
|
192
|
-
return 0
|
|
193
|
-
fi
|
|
194
|
-
|
|
195
|
-
# Build list of runtimes to generate, respecting opt-outs
|
|
196
|
-
local runtimes_to_generate=()
|
|
197
|
-
|
|
198
|
-
if is_feature_enabled manage_opencode_config 2>/dev/null; then
|
|
199
|
-
runtimes_to_generate+=("opencode")
|
|
200
|
-
else
|
|
201
|
-
print_info "OpenCode config management disabled via config"
|
|
202
|
-
fi
|
|
203
|
-
|
|
204
|
-
if is_feature_enabled manage_claude_config 2>/dev/null; then
|
|
205
|
-
runtimes_to_generate+=("claude-code")
|
|
206
|
-
else
|
|
207
|
-
print_info "Claude Code config management disabled via config"
|
|
208
|
-
fi
|
|
209
|
-
|
|
210
|
-
# Generate for each enabled runtime
|
|
211
|
-
local runtime
|
|
212
|
-
for runtime in "${runtimes_to_generate[@]}"; do
|
|
213
|
-
_run_generator ".agents/scripts/generate-runtime-config.sh" \
|
|
214
|
-
"Generating configuration for $runtime..." \
|
|
215
|
-
"$runtime configuration updated" \
|
|
216
|
-
"$runtime configuration encountered issues" \
|
|
217
|
-
all --runtime "$runtime"
|
|
218
|
-
done
|
|
219
|
-
|
|
220
|
-
return 0
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
update_codex_config() {
|
|
224
|
-
# Only run if Codex is installed or config dir exists
|
|
225
|
-
if [[ ! -d "$HOME/.codex" ]] && ! command -v codex >/dev/null 2>&1; then
|
|
226
|
-
return 0
|
|
227
|
-
fi
|
|
228
|
-
|
|
229
|
-
print_info "Updating Codex configuration..."
|
|
230
|
-
|
|
231
|
-
# Fix broken MCP_DOCKER entry (P0 — OrbStack/Colima don't support docker mcp)
|
|
232
|
-
if type _fix_codex_docker_mcp &>/dev/null; then
|
|
233
|
-
_fix_codex_docker_mcp
|
|
234
|
-
fi
|
|
235
|
-
|
|
236
|
-
# Deploy aidevops MCP servers to Codex config.toml
|
|
237
|
-
_deploy_codex_mcps
|
|
238
|
-
|
|
239
|
-
print_success "Codex configuration updated"
|
|
240
|
-
return 0
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
# Deploy standard aidevops MCP servers to ~/.codex/config.toml
|
|
244
|
-
# Codex uses TOML format: [mcp_servers.NAME] sections
|
|
245
|
-
_deploy_codex_mcps() {
|
|
246
|
-
local config="$HOME/.codex/config.toml"
|
|
247
|
-
mkdir -p "$HOME/.codex"
|
|
248
|
-
|
|
249
|
-
# Touch config if it doesn't exist
|
|
250
|
-
[[ -f "$config" ]] || touch "$config"
|
|
251
|
-
|
|
252
|
-
local mcp_count=0
|
|
253
|
-
|
|
254
|
-
# Helper: add a TOML MCP section if not already present
|
|
255
|
-
# Args: $1=name, $2=type (stdio|url), $3=command_or_url, $4=args (optional, comma-separated)
|
|
256
|
-
_add_codex_mcp() {
|
|
257
|
-
local name="$1"
|
|
258
|
-
local mcp_type="$2"
|
|
259
|
-
local cmd_or_url="$3"
|
|
260
|
-
local args="${4:-}"
|
|
261
|
-
|
|
262
|
-
if grep -q "\\[mcp_servers\\.${name}\\]" "$config" 2>/dev/null; then
|
|
263
|
-
echo -e " ${BLUE:-}=${NC:-} $name (already configured)"
|
|
264
|
-
return 0
|
|
265
|
-
fi
|
|
266
|
-
|
|
267
|
-
{
|
|
268
|
-
echo ""
|
|
269
|
-
echo "[mcp_servers.${name}]"
|
|
270
|
-
if [[ "$mcp_type" == "stdio" ]]; then
|
|
271
|
-
echo "command = '${cmd_or_url}'"
|
|
272
|
-
if [[ -n "$args" ]]; then
|
|
273
|
-
echo "args = [${args}]"
|
|
274
|
-
fi
|
|
275
|
-
else
|
|
276
|
-
echo "type = 'url'"
|
|
277
|
-
echo "url = '${cmd_or_url}'"
|
|
278
|
-
fi
|
|
279
|
-
} >>"$config"
|
|
280
|
-
((++mcp_count))
|
|
281
|
-
echo -e " ${GREEN:-}+${NC:-} $name"
|
|
282
|
-
return 0
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
# --- context7 (library docs) ---
|
|
286
|
-
_add_codex_mcp "context7" "stdio" "npx" "'-y', '@upstash/context7-mcp@latest'"
|
|
287
|
-
|
|
288
|
-
# --- Playwright MCP ---
|
|
289
|
-
_add_codex_mcp "playwright" "stdio" "npx" "'-y', '@anthropic-ai/mcp-server-playwright@latest'"
|
|
290
|
-
|
|
291
|
-
# --- shadcn UI ---
|
|
292
|
-
_add_codex_mcp "shadcn" "stdio" "npx" "'shadcn@latest', 'mcp'"
|
|
293
|
-
|
|
294
|
-
# --- OpenAPI Search (remote, zero install) ---
|
|
295
|
-
_add_codex_mcp "openapi-search" "url" "https://openapi-mcp.openapisearch.com/mcp"
|
|
296
|
-
|
|
297
|
-
# --- Cloudflare API (remote) ---
|
|
298
|
-
_add_codex_mcp "cloudflare-api" "url" "https://mcp.cloudflare.com/mcp"
|
|
299
|
-
|
|
300
|
-
echo -e " ${GREEN:-}Done${NC:-} -- $mcp_count new MCP servers added to Codex config"
|
|
301
|
-
return 0
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
update_cursor_config() {
|
|
305
|
-
# Only run if Cursor is installed or config dir exists
|
|
306
|
-
if [[ ! -d "$HOME/.cursor" ]] && ! command -v cursor >/dev/null 2>&1 && ! command -v agent >/dev/null 2>&1; then
|
|
307
|
-
return 0
|
|
308
|
-
fi
|
|
309
|
-
|
|
310
|
-
print_info "Updating Cursor configuration..."
|
|
311
|
-
|
|
312
|
-
# Deploy aidevops MCP servers to Cursor mcp.json
|
|
313
|
-
_deploy_cursor_mcps
|
|
314
|
-
|
|
315
|
-
print_success "Cursor configuration updated"
|
|
316
|
-
return 0
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
# Deploy standard aidevops MCP servers to ~/.cursor/mcp.json
|
|
320
|
-
# Cursor uses JSON format: { "mcpServers": { "name": { ... } } }
|
|
321
|
-
_deploy_cursor_mcps() {
|
|
322
|
-
local config="$HOME/.cursor/mcp.json"
|
|
323
|
-
mkdir -p "$HOME/.cursor"
|
|
324
|
-
|
|
325
|
-
# Ensure config file exists with valid JSON
|
|
326
|
-
if [[ ! -f "$config" ]]; then
|
|
327
|
-
echo '{}' >"$config"
|
|
328
|
-
fi
|
|
329
|
-
|
|
330
|
-
# Use the json_set_nested helper from ai-cli-config.sh if available,
|
|
331
|
-
# otherwise use python3 directly
|
|
332
|
-
local mcp_count=0
|
|
333
|
-
|
|
334
|
-
# Helper: add a JSON MCP entry if not already present
|
|
335
|
-
# Increments mcp_count only when a new entry is actually added.
|
|
336
|
-
_add_cursor_mcp() {
|
|
337
|
-
local name="$1"
|
|
338
|
-
local json_value="$2"
|
|
339
|
-
|
|
340
|
-
if ! command -v python3 >/dev/null 2>&1; then
|
|
341
|
-
print_warning "python3 not found - cannot update Cursor config"
|
|
342
|
-
return 0
|
|
343
|
-
fi
|
|
344
|
-
|
|
345
|
-
local py_output
|
|
346
|
-
py_output=$(
|
|
347
|
-
python3 - "$config" "$name" "$json_value" <<'PYEOF'
|
|
348
|
-
import json, sys
|
|
349
|
-
|
|
350
|
-
file_path = sys.argv[1]
|
|
351
|
-
name = sys.argv[2]
|
|
352
|
-
value_json = sys.argv[3]
|
|
353
|
-
|
|
354
|
-
try:
|
|
355
|
-
with open(file_path, 'r') as f:
|
|
356
|
-
cfg = json.load(f)
|
|
357
|
-
except (FileNotFoundError, json.JSONDecodeError):
|
|
358
|
-
cfg = {}
|
|
359
|
-
|
|
360
|
-
if "mcpServers" not in cfg or not isinstance(cfg["mcpServers"], dict):
|
|
361
|
-
cfg["mcpServers"] = {}
|
|
362
|
-
|
|
363
|
-
if name in cfg["mcpServers"]:
|
|
364
|
-
print(f"SKIP = {name} (already configured)")
|
|
365
|
-
else:
|
|
366
|
-
cfg["mcpServers"][name] = json.loads(value_json)
|
|
367
|
-
with open(file_path, 'w') as f:
|
|
368
|
-
json.dump(cfg, f, indent=2)
|
|
369
|
-
f.write('\n')
|
|
370
|
-
print(f"ADDED + {name}")
|
|
371
|
-
PYEOF
|
|
372
|
-
) || true
|
|
373
|
-
echo " ${py_output#* }"
|
|
374
|
-
if [[ "$py_output" == ADDED* ]]; then
|
|
375
|
-
((++mcp_count))
|
|
376
|
-
fi
|
|
377
|
-
return 0
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
# --- context7 (library docs) ---
|
|
381
|
-
_add_cursor_mcp "context7" '{"command":"npx","args":["-y","@upstash/context7-mcp@latest"]}'
|
|
382
|
-
|
|
383
|
-
# --- Playwright MCP ---
|
|
384
|
-
_add_cursor_mcp "playwright" '{"command":"npx","args":["-y","@anthropic-ai/mcp-server-playwright@latest"]}'
|
|
385
|
-
|
|
386
|
-
# --- shadcn UI ---
|
|
387
|
-
_add_cursor_mcp "shadcn" '{"command":"npx","args":["shadcn@latest","mcp"]}'
|
|
388
|
-
|
|
389
|
-
# --- OpenAPI Search (remote, zero install) ---
|
|
390
|
-
_add_cursor_mcp "openapi-search" '{"url":"https://openapi-mcp.openapisearch.com/mcp"}'
|
|
391
|
-
|
|
392
|
-
# --- Cloudflare API (remote) ---
|
|
393
|
-
_add_cursor_mcp "cloudflare-api" '{"url":"https://mcp.cloudflare.com/mcp"}'
|
|
394
|
-
|
|
395
|
-
echo " Done -- $mcp_count new MCP servers added to Cursor config"
|
|
396
|
-
return 0
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
# Deploy slash commands to every installed runtime that supports them.
|
|
400
|
-
#
|
|
401
|
-
# Background: update_opencode_config and update_claude_config already invoke
|
|
402
|
-
# the unified generator (.agents/scripts/generate-runtime-config.sh) for
|
|
403
|
-
# their runtimes. The other per-client update_*_config functions (Codex,
|
|
404
|
-
# Cursor, Droid, etc.) were written before the unified generator existed
|
|
405
|
-
# and only handle MCP registration. This function closes that gap by
|
|
406
|
-
# invoking the generator for every other installed client.
|
|
407
|
-
#
|
|
408
|
-
# Gated on rt_feature_commands so users can disable command installation
|
|
409
|
-
# per-runtime via AIDEVOPS_FEATURE_COMMANDS_<SUFFIX>=no. Clients with no
|
|
410
|
-
# _RT_COMMAND_DIR (windsurf, amp, kilo, aider) are skipped automatically.
|
|
411
|
-
#
|
|
412
|
-
# Fixes GH#18106 / t15474.
|
|
413
|
-
deploy_commands_to_all_runtimes() {
|
|
414
|
-
local registry_script="${INSTALL_DIR:-.}/.agents/scripts/runtime-registry.sh"
|
|
415
|
-
local generator_script="${INSTALL_DIR:-.}/.agents/scripts/generate-runtime-config.sh"
|
|
416
|
-
|
|
417
|
-
if [[ ! -f "$registry_script" ]]; then
|
|
418
|
-
print_info "Runtime registry not found — skipping unified command deployment"
|
|
419
|
-
return 0
|
|
420
|
-
fi
|
|
421
|
-
if [[ ! -x "$generator_script" ]]; then
|
|
422
|
-
print_info "Runtime config generator not executable — skipping unified command deployment"
|
|
423
|
-
return 0
|
|
424
|
-
fi
|
|
425
|
-
|
|
426
|
-
# Source registry if not already loaded
|
|
427
|
-
if [[ -z "${_RUNTIME_REGISTRY_LOADED:-}" ]]; then
|
|
428
|
-
# shellcheck source=/dev/null
|
|
429
|
-
source "$registry_script"
|
|
430
|
-
fi
|
|
431
|
-
|
|
432
|
-
local runtime_id cmd_dir feature_flag display_name
|
|
433
|
-
local deployed_count=0 skipped_count=0
|
|
434
|
-
|
|
435
|
-
while IFS= read -r runtime_id; do
|
|
436
|
-
# OpenCode and Claude Code are already handled by their dedicated
|
|
437
|
-
# update_*_config functions above — skip to avoid double-deploy
|
|
438
|
-
# and keep the log output clean.
|
|
439
|
-
case "$runtime_id" in
|
|
440
|
-
opencode | claude-code) continue ;;
|
|
441
|
-
esac
|
|
442
|
-
|
|
443
|
-
# Skip runtimes with no command directory in the registry (repo-only
|
|
444
|
-
# clients like Windsurf/Amp, and clients without native slash command
|
|
445
|
-
# support like Kilo/Aider).
|
|
446
|
-
cmd_dir=$(rt_command_dir "$runtime_id" 2>/dev/null || echo "")
|
|
447
|
-
[[ -z "$cmd_dir" ]] && continue
|
|
448
|
-
|
|
449
|
-
# Honour the rt_feature_commands flag.
|
|
450
|
-
feature_flag=$(rt_feature_commands "$runtime_id" 2>/dev/null || echo "yes")
|
|
451
|
-
if [[ "$feature_flag" != "yes" ]]; then
|
|
452
|
-
display_name=$(rt_display_name "$runtime_id" 2>/dev/null || echo "$runtime_id")
|
|
453
|
-
print_info "Commands installation disabled for $display_name (feature flag)"
|
|
454
|
-
skipped_count=$((skipped_count + 1))
|
|
455
|
-
continue
|
|
456
|
-
fi
|
|
457
|
-
|
|
458
|
-
# Invoke the unified generator — it prints its own success/failure.
|
|
459
|
-
# Redirect stdin from /dev/null so the generator cannot accidentally
|
|
460
|
-
# read from the `while read` loop's process-substitution pipe and
|
|
461
|
-
# steal the remaining runtime IDs — a classic bash pitfall.
|
|
462
|
-
if "$generator_script" commands --runtime "$runtime_id" </dev/null; then
|
|
463
|
-
deployed_count=$((deployed_count + 1))
|
|
464
|
-
else
|
|
465
|
-
display_name=$(rt_display_name "$runtime_id" 2>/dev/null || echo "$runtime_id")
|
|
466
|
-
print_warning "Failed to deploy commands for $display_name"
|
|
467
|
-
fi
|
|
468
|
-
done < <(rt_detect_installed 2>/dev/null)
|
|
469
|
-
|
|
470
|
-
if [[ $deployed_count -gt 0 ]]; then
|
|
471
|
-
print_success "Deployed slash commands to $deployed_count additional runtime(s)"
|
|
472
|
-
elif [[ $skipped_count -gt 0 ]]; then
|
|
473
|
-
print_info "All remaining runtimes had commands installation disabled via feature flags"
|
|
474
|
-
else
|
|
475
|
-
print_info "No additional runtimes needed command deployment"
|
|
476
|
-
fi
|
|
477
|
-
return 0
|
|
478
|
-
}
|