aidevops 3.1.269 → 3.1.271
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/VERSION +1 -1
- package/aidevops.sh +1 -1
- package/package.json +1 -1
- package/setup-modules/agent-deploy.sh +133 -14
- package/setup-modules/config.sh +269 -39
- package/setup-modules/plugins.sh +3 -2
- package/setup-modules/tool-install.sh +144 -0
- package/setup.sh +188 -150
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.1.
|
|
1
|
+
3.1.271
|
package/aidevops.sh
CHANGED
package/package.json
CHANGED
|
@@ -324,14 +324,33 @@ deploy_aidevops_agents() {
|
|
|
324
324
|
inject_agents_reference() {
|
|
325
325
|
print_info "Adding aidevops reference to AI assistant configurations..."
|
|
326
326
|
|
|
327
|
+
# Delegate to prompt-injection-adapter.sh (t1665.3) which handles all runtimes.
|
|
328
|
+
# The adapter deploys AGENTS.md references via each runtime's native mechanism:
|
|
329
|
+
# OpenCode (json-instructions), Claude (AGENTS.md autodiscovery), Codex, Cursor,
|
|
330
|
+
# Droid, Gemini, Windsurf, Continue, Kilo, Kiro, Aider.
|
|
331
|
+
local adapter_script="${INSTALL_DIR}/.agents/scripts/prompt-injection-adapter.sh"
|
|
332
|
+
|
|
333
|
+
if [[ -f "$adapter_script" ]]; then
|
|
334
|
+
# shellcheck source=/dev/null
|
|
335
|
+
source "$adapter_script"
|
|
336
|
+
deploy_prompts_for_all_runtimes
|
|
337
|
+
else
|
|
338
|
+
# Fallback: adapter not yet deployed — use legacy inline logic
|
|
339
|
+
# This path is only hit during initial setup before .agents/ is deployed.
|
|
340
|
+
print_warning "prompt-injection-adapter.sh not found — using legacy deployment"
|
|
341
|
+
_inject_agents_reference_legacy
|
|
342
|
+
fi
|
|
343
|
+
|
|
344
|
+
return 0
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
# Legacy fallback for inject_agents_reference — used only when the adapter
|
|
348
|
+
# script is not yet available (e.g., during initial setup before .agents/ deploy).
|
|
349
|
+
# Will be removed once t1665 migration is complete.
|
|
350
|
+
_inject_agents_reference_legacy() {
|
|
327
351
|
local reference_line='Add ~/.aidevops/agents/AGENTS.md to context for AI DevOps capabilities.'
|
|
328
352
|
|
|
329
353
|
# AI assistant agent directories - these receive AGENTS.md reference
|
|
330
|
-
# Format: "config_dir:agents_subdir" where agents_subdir is the folder containing agent files
|
|
331
|
-
# Only Claude Code (companion CLI) and .opencode are included here.
|
|
332
|
-
# OpenCode excluded: its agent/ dir treats every .md as a subagent, so AGENTS.md
|
|
333
|
-
# would show as a mode. OpenCode gets the reference via opencode.json instructions
|
|
334
|
-
# field and the config-root AGENTS.md (deployed by deploy_opencode_greeting below).
|
|
335
354
|
local ai_agent_dirs=(
|
|
336
355
|
"$HOME/.claude:commands"
|
|
337
356
|
"$HOME/.opencode:."
|
|
@@ -347,16 +366,12 @@ inject_agents_reference() {
|
|
|
347
366
|
|
|
348
367
|
# Only process if the config directory exists (tool is installed)
|
|
349
368
|
if [[ -d "$config_dir" ]]; then
|
|
350
|
-
# Create agents subdirectory if needed
|
|
351
369
|
mkdir -p "$agents_dir"
|
|
352
370
|
|
|
353
|
-
# Check if AGENTS.md exists and has our reference
|
|
354
371
|
if [[ -f "$agents_file" ]]; then
|
|
355
|
-
# Check first line for our reference
|
|
356
372
|
local first_line
|
|
357
373
|
first_line=$(head -1 "$agents_file" 2>/dev/null || echo "")
|
|
358
|
-
if [[ "$first_line" != *"
|
|
359
|
-
# Prepend reference to existing file
|
|
374
|
+
if [[ "$first_line" != *"aidevops/agents/AGENTS.md"* ]]; then
|
|
360
375
|
local temp_file
|
|
361
376
|
temp_file=$(mktemp)
|
|
362
377
|
trap 'rm -f "${temp_file:-}"' RETURN
|
|
@@ -370,7 +385,6 @@ inject_agents_reference() {
|
|
|
370
385
|
print_info "Reference already exists in $agents_file"
|
|
371
386
|
fi
|
|
372
387
|
else
|
|
373
|
-
# Create new file with just the reference
|
|
374
388
|
echo "$reference_line" >"$agents_file"
|
|
375
389
|
print_success "Created $agents_file with aidevops reference"
|
|
376
390
|
((++updated_count))
|
|
@@ -384,17 +398,15 @@ inject_agents_reference() {
|
|
|
384
398
|
print_success "Updated $updated_count AI assistant configuration(s)"
|
|
385
399
|
fi
|
|
386
400
|
|
|
387
|
-
# Clean up stale AGENTS.md from OpenCode agent dir
|
|
401
|
+
# Clean up stale AGENTS.md from OpenCode agent dir
|
|
388
402
|
rm -f "$HOME/.config/opencode/agent/AGENTS.md"
|
|
389
403
|
|
|
390
404
|
# Deploy OpenCode config-level AGENTS.md from managed template
|
|
391
|
-
# This controls the session greeting (auto-loaded by OpenCode from config root)
|
|
392
405
|
local opencode_config_dir="$HOME/.config/opencode"
|
|
393
406
|
local opencode_config_agents="$opencode_config_dir/AGENTS.md"
|
|
394
407
|
local template_source="$INSTALL_DIR/templates/opencode-config-agents.md"
|
|
395
408
|
|
|
396
409
|
if [[ -d "$opencode_config_dir" && -f "$template_source" ]]; then
|
|
397
|
-
# Backup if file exists and differs from template
|
|
398
410
|
if [[ -f "$opencode_config_agents" ]]; then
|
|
399
411
|
if ! diff -q "$template_source" "$opencode_config_agents" &>/dev/null; then
|
|
400
412
|
create_backup_with_rotation "$opencode_config_agents" "opencode-agents"
|
|
@@ -407,6 +419,113 @@ inject_agents_reference() {
|
|
|
407
419
|
fi
|
|
408
420
|
fi
|
|
409
421
|
|
|
422
|
+
# Deploy Codex instructions.md (Codex reads ~/.codex/instructions.md as system prompt)
|
|
423
|
+
_deploy_codex_instructions
|
|
424
|
+
|
|
425
|
+
# Deploy Cursor AGENTS.md (Cursor reads ~/.cursor/rules/*.md as context)
|
|
426
|
+
_deploy_cursor_agents_reference
|
|
427
|
+
|
|
428
|
+
# Deploy Droid AGENTS.md (Droid reads ~/.factory/skills/*.md as context)
|
|
429
|
+
_deploy_droid_agents_reference
|
|
430
|
+
|
|
431
|
+
return 0
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
# Deploy instructions.md to Codex config directory.
|
|
435
|
+
# Codex reads ~/.codex/instructions.md as its system-level instructions.
|
|
436
|
+
_deploy_codex_instructions() {
|
|
437
|
+
local codex_dir="$HOME/.codex"
|
|
438
|
+
local instructions_file="$codex_dir/instructions.md"
|
|
439
|
+
|
|
440
|
+
# Only deploy if Codex is installed or config dir exists
|
|
441
|
+
if [[ ! -d "$codex_dir" ]] && ! command -v codex >/dev/null 2>&1; then
|
|
442
|
+
return 0
|
|
443
|
+
fi
|
|
444
|
+
|
|
445
|
+
mkdir -p "$codex_dir"
|
|
446
|
+
|
|
447
|
+
local reference_content
|
|
448
|
+
reference_content="Add ~/.aidevops/agents/AGENTS.md to context for AI DevOps capabilities."
|
|
449
|
+
|
|
450
|
+
if [[ -f "$instructions_file" ]]; then
|
|
451
|
+
# Check if our reference is already present
|
|
452
|
+
# shellcheck disable=SC2088 # Tilde is a literal grep pattern, not a path
|
|
453
|
+
if grep -q '~/.aidevops/agents/AGENTS.md' "$instructions_file" 2>/dev/null; then
|
|
454
|
+
print_info "Codex instructions.md already has aidevops reference"
|
|
455
|
+
return 0
|
|
456
|
+
fi
|
|
457
|
+
# Prepend reference to existing instructions
|
|
458
|
+
local temp_file
|
|
459
|
+
temp_file=$(mktemp)
|
|
460
|
+
echo "$reference_content" >"$temp_file"
|
|
461
|
+
echo "" >>"$temp_file"
|
|
462
|
+
cat "$instructions_file" >>"$temp_file"
|
|
463
|
+
mv "$temp_file" "$instructions_file"
|
|
464
|
+
print_success "Added aidevops reference to $instructions_file"
|
|
465
|
+
else
|
|
466
|
+
echo "$reference_content" >"$instructions_file"
|
|
467
|
+
print_success "Created $instructions_file with aidevops reference"
|
|
468
|
+
fi
|
|
469
|
+
return 0
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
# Deploy AGENTS.md reference to Cursor rules directory.
|
|
473
|
+
# Cursor reads ~/.cursor/rules/*.md files as additional context.
|
|
474
|
+
_deploy_cursor_agents_reference() {
|
|
475
|
+
local cursor_dir="$HOME/.cursor"
|
|
476
|
+
local rules_dir="$cursor_dir/rules"
|
|
477
|
+
local agents_file="$rules_dir/aidevops.md"
|
|
478
|
+
|
|
479
|
+
# Only deploy if Cursor is installed or config dir exists
|
|
480
|
+
if [[ ! -d "$cursor_dir" ]] && ! command -v cursor >/dev/null 2>&1 && ! command -v agent >/dev/null 2>&1; then
|
|
481
|
+
return 0
|
|
482
|
+
fi
|
|
483
|
+
|
|
484
|
+
mkdir -p "$rules_dir"
|
|
485
|
+
|
|
486
|
+
local reference_content
|
|
487
|
+
reference_content="Add ~/.aidevops/agents/AGENTS.md to context for AI DevOps capabilities."
|
|
488
|
+
|
|
489
|
+
if [[ -f "$agents_file" ]]; then
|
|
490
|
+
# shellcheck disable=SC2088 # Tilde is a literal grep pattern, not a path
|
|
491
|
+
if grep -q '~/.aidevops/agents/AGENTS.md' "$agents_file" 2>/dev/null; then
|
|
492
|
+
print_info "Cursor rules/aidevops.md already has aidevops reference"
|
|
493
|
+
return 0
|
|
494
|
+
fi
|
|
495
|
+
fi
|
|
496
|
+
|
|
497
|
+
echo "$reference_content" >"$agents_file"
|
|
498
|
+
print_success "Deployed aidevops reference to $agents_file"
|
|
499
|
+
return 0
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
# Deploy AGENTS.md reference to Droid skills directory.
|
|
503
|
+
# Droid reads ~/.factory/skills/*.md files as additional context.
|
|
504
|
+
_deploy_droid_agents_reference() {
|
|
505
|
+
local factory_dir="$HOME/.factory"
|
|
506
|
+
local skills_dir="$factory_dir/skills"
|
|
507
|
+
local agents_file="$skills_dir/aidevops.md"
|
|
508
|
+
|
|
509
|
+
# Only deploy if Droid is installed or config dir exists
|
|
510
|
+
if [[ ! -d "$factory_dir" ]] && ! command -v droid >/dev/null 2>&1; then
|
|
511
|
+
return 0
|
|
512
|
+
fi
|
|
513
|
+
|
|
514
|
+
mkdir -p "$skills_dir"
|
|
515
|
+
|
|
516
|
+
local reference_content
|
|
517
|
+
reference_content="Add ~/.aidevops/agents/AGENTS.md to context for AI DevOps capabilities."
|
|
518
|
+
|
|
519
|
+
if [[ -f "$agents_file" ]]; then
|
|
520
|
+
# shellcheck disable=SC2088 # Tilde is a literal grep pattern, not a path
|
|
521
|
+
if grep -q '~/.aidevops/agents/AGENTS.md' "$agents_file" 2>/dev/null; then
|
|
522
|
+
print_info "Droid skills/aidevops.md already has aidevops reference"
|
|
523
|
+
return 0
|
|
524
|
+
fi
|
|
525
|
+
fi
|
|
526
|
+
|
|
527
|
+
echo "$reference_content" >"$agents_file"
|
|
528
|
+
print_success "Deployed aidevops reference to $agents_file"
|
|
410
529
|
return 0
|
|
411
530
|
}
|
|
412
531
|
|
package/setup-modules/config.sh
CHANGED
|
@@ -108,26 +108,31 @@ update_opencode_config() {
|
|
|
108
108
|
|
|
109
109
|
print_info "Updating OpenCode configuration..."
|
|
110
110
|
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
111
|
+
# Use unified generator (t1665.4) if available, fall back to legacy scripts
|
|
112
|
+
if [[ -f ".agents/scripts/generate-runtime-config.sh" ]]; then
|
|
113
|
+
_run_generator ".agents/scripts/generate-runtime-config.sh" \
|
|
114
|
+
"Generating OpenCode configuration (unified)..." \
|
|
115
|
+
"OpenCode configuration complete (agents, commands, MCPs, prompts)" \
|
|
116
|
+
"OpenCode configuration encountered issues" \
|
|
117
|
+
all --runtime opencode
|
|
118
|
+
else
|
|
119
|
+
# Legacy fallback — remove after one release cycle
|
|
120
|
+
_run_generator ".agents/scripts/generate-opencode-commands.sh" \
|
|
121
|
+
"Generating OpenCode commands..." \
|
|
122
|
+
"OpenCode commands configured" \
|
|
123
|
+
"OpenCode command generation encountered issues"
|
|
124
|
+
|
|
125
|
+
_run_generator ".agents/scripts/generate-opencode-agents.sh" \
|
|
126
|
+
"Generating OpenCode agent configuration..." \
|
|
127
|
+
"OpenCode agents configured (11 primary in JSON, subagents as markdown)" \
|
|
128
|
+
"OpenCode agent generation encountered issues"
|
|
129
|
+
|
|
130
|
+
_run_generator ".agents/scripts/subagent-index-helper.sh" \
|
|
131
|
+
"Regenerating subagent index..." \
|
|
132
|
+
"Subagent index regenerated" \
|
|
133
|
+
"Subagent index generation encountered issues" \
|
|
134
|
+
generate
|
|
135
|
+
fi
|
|
131
136
|
|
|
132
137
|
return 0
|
|
133
138
|
}
|
|
@@ -141,25 +146,250 @@ update_claude_config() {
|
|
|
141
146
|
|
|
142
147
|
print_info "Updating Claude Code configuration..."
|
|
143
148
|
|
|
144
|
-
#
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
149
|
+
# Use unified generator (t1665.4) if available, fall back to legacy scripts
|
|
150
|
+
if [[ -f ".agents/scripts/generate-runtime-config.sh" ]]; then
|
|
151
|
+
_run_generator ".agents/scripts/generate-runtime-config.sh" \
|
|
152
|
+
"Generating Claude Code configuration (unified)..." \
|
|
153
|
+
"Claude Code configuration complete (agents, commands, MCPs, prompts)" \
|
|
154
|
+
"Claude Code configuration encountered issues" \
|
|
155
|
+
all --runtime claude-code
|
|
156
|
+
else
|
|
157
|
+
# Legacy fallback — remove after one release cycle
|
|
158
|
+
_run_generator ".agents/scripts/generate-claude-commands.sh" \
|
|
159
|
+
"Generating Claude Code commands..." \
|
|
160
|
+
"Claude Code commands configured" \
|
|
161
|
+
"Claude Code command generation encountered issues"
|
|
162
|
+
|
|
163
|
+
_run_generator ".agents/scripts/generate-claude-agents.sh" \
|
|
164
|
+
"Generating Claude Code agent configuration..." \
|
|
165
|
+
"Claude Code agents configured (MCPs, settings, commands)" \
|
|
166
|
+
"Claude Code agent generation encountered issues"
|
|
167
|
+
|
|
168
|
+
_run_generator ".agents/scripts/subagent-index-helper.sh" \
|
|
169
|
+
"Regenerating subagent index..." \
|
|
170
|
+
"Subagent index regenerated" \
|
|
171
|
+
"Subagent index generation encountered issues" \
|
|
172
|
+
generate
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
return 0
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
# Unified runtime config update (t1665.4)
|
|
179
|
+
# Generates config for all installed runtimes in a single pass.
|
|
180
|
+
# Called by setup.sh as an alternative to separate update_opencode_config + update_claude_config.
|
|
181
|
+
# Respects per-runtime opt-outs (manage_opencode_config, manage_claude_config).
|
|
182
|
+
update_runtime_configs() {
|
|
183
|
+
print_info "Updating runtime configurations..."
|
|
184
|
+
|
|
185
|
+
if [[ ! -f ".agents/scripts/generate-runtime-config.sh" ]]; then
|
|
186
|
+
# Legacy fallback — use per-runtime update functions
|
|
187
|
+
print_info "Unified generator not found — falling back to per-runtime updates"
|
|
188
|
+
update_opencode_config
|
|
189
|
+
update_claude_config
|
|
190
|
+
return 0
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
# Build list of runtimes to generate, respecting opt-outs
|
|
194
|
+
local runtimes_to_generate=()
|
|
195
|
+
|
|
196
|
+
if is_feature_enabled manage_opencode_config 2>/dev/null; then
|
|
197
|
+
runtimes_to_generate+=("opencode")
|
|
198
|
+
else
|
|
199
|
+
print_info "OpenCode config management disabled via config"
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
if is_feature_enabled manage_claude_config 2>/dev/null; then
|
|
203
|
+
runtimes_to_generate+=("claude-code")
|
|
204
|
+
else
|
|
205
|
+
print_info "Claude Code config management disabled via config"
|
|
206
|
+
fi
|
|
207
|
+
|
|
208
|
+
# Generate for each enabled runtime
|
|
209
|
+
local runtime
|
|
210
|
+
for runtime in "${runtimes_to_generate[@]}"; do
|
|
211
|
+
_run_generator ".agents/scripts/generate-runtime-config.sh" \
|
|
212
|
+
"Generating configuration for $runtime..." \
|
|
213
|
+
"$runtime configuration updated" \
|
|
214
|
+
"$runtime configuration encountered issues" \
|
|
215
|
+
all --runtime "$runtime"
|
|
216
|
+
done
|
|
217
|
+
|
|
218
|
+
return 0
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
update_codex_config() {
|
|
222
|
+
# Only run if Codex is installed or config dir exists
|
|
223
|
+
if [[ ! -d "$HOME/.codex" ]] && ! command -v codex >/dev/null 2>&1; then
|
|
224
|
+
return 0
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
print_info "Updating Codex configuration..."
|
|
228
|
+
|
|
229
|
+
# Fix broken MCP_DOCKER entry (P0 — OrbStack/Colima don't support docker mcp)
|
|
230
|
+
if type _fix_codex_docker_mcp &>/dev/null; then
|
|
231
|
+
_fix_codex_docker_mcp
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
# Deploy aidevops MCP servers to Codex config.toml
|
|
235
|
+
_deploy_codex_mcps
|
|
236
|
+
|
|
237
|
+
print_success "Codex configuration updated"
|
|
238
|
+
return 0
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
# Deploy standard aidevops MCP servers to ~/.codex/config.toml
|
|
242
|
+
# Codex uses TOML format: [mcp_servers.NAME] sections
|
|
243
|
+
_deploy_codex_mcps() {
|
|
244
|
+
local config="$HOME/.codex/config.toml"
|
|
245
|
+
mkdir -p "$HOME/.codex"
|
|
246
|
+
|
|
247
|
+
# Touch config if it doesn't exist
|
|
248
|
+
[[ -f "$config" ]] || touch "$config"
|
|
249
|
+
|
|
250
|
+
local mcp_count=0
|
|
251
|
+
|
|
252
|
+
# Helper: add a TOML MCP section if not already present
|
|
253
|
+
# Args: $1=name, $2=type (stdio|url), $3=command_or_url, $4=args (optional, comma-separated)
|
|
254
|
+
_add_codex_mcp() {
|
|
255
|
+
local name="$1"
|
|
256
|
+
local mcp_type="$2"
|
|
257
|
+
local cmd_or_url="$3"
|
|
258
|
+
local args="${4:-}"
|
|
259
|
+
|
|
260
|
+
if grep -q "\\[mcp_servers\\.${name}\\]" "$config" 2>/dev/null; then
|
|
261
|
+
echo -e " ${BLUE:-}=${NC:-} $name (already configured)"
|
|
262
|
+
return 0
|
|
263
|
+
fi
|
|
264
|
+
|
|
265
|
+
{
|
|
266
|
+
echo ""
|
|
267
|
+
echo "[mcp_servers.${name}]"
|
|
268
|
+
if [[ "$mcp_type" == "stdio" ]]; then
|
|
269
|
+
echo "command = '${cmd_or_url}'"
|
|
270
|
+
if [[ -n "$args" ]]; then
|
|
271
|
+
echo "args = [${args}]"
|
|
272
|
+
fi
|
|
273
|
+
else
|
|
274
|
+
echo "type = 'url'"
|
|
275
|
+
echo "url = '${cmd_or_url}'"
|
|
276
|
+
fi
|
|
277
|
+
} >>"$config"
|
|
278
|
+
((++mcp_count))
|
|
279
|
+
echo -e " ${GREEN:-}+${NC:-} $name"
|
|
280
|
+
return 0
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
# --- context7 (library docs) ---
|
|
284
|
+
_add_codex_mcp "context7" "stdio" "npx" "'-y', '@upstash/context7-mcp@latest'"
|
|
285
|
+
|
|
286
|
+
# --- Playwright MCP ---
|
|
287
|
+
_add_codex_mcp "playwright" "stdio" "npx" "'-y', '@anthropic-ai/mcp-server-playwright@latest'"
|
|
288
|
+
|
|
289
|
+
# --- shadcn UI ---
|
|
290
|
+
_add_codex_mcp "shadcn" "stdio" "npx" "'shadcn@latest', 'mcp'"
|
|
291
|
+
|
|
292
|
+
# --- OpenAPI Search (remote, zero install) ---
|
|
293
|
+
_add_codex_mcp "openapi-search" "url" "https://openapi-mcp.openapisearch.com/mcp"
|
|
294
|
+
|
|
295
|
+
# --- Cloudflare API (remote) ---
|
|
296
|
+
_add_codex_mcp "cloudflare-api" "url" "https://mcp.cloudflare.com/mcp"
|
|
297
|
+
|
|
298
|
+
echo -e " ${GREEN:-}Done${NC:-} -- $mcp_count new MCP servers added to Codex config"
|
|
299
|
+
return 0
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
update_cursor_config() {
|
|
303
|
+
# Only run if Cursor is installed or config dir exists
|
|
304
|
+
if [[ ! -d "$HOME/.cursor" ]] && ! command -v cursor >/dev/null 2>&1 && ! command -v agent >/dev/null 2>&1; then
|
|
305
|
+
return 0
|
|
306
|
+
fi
|
|
307
|
+
|
|
308
|
+
print_info "Updating Cursor configuration..."
|
|
309
|
+
|
|
310
|
+
# Deploy aidevops MCP servers to Cursor mcp.json
|
|
311
|
+
_deploy_cursor_mcps
|
|
312
|
+
|
|
313
|
+
print_success "Cursor configuration updated"
|
|
314
|
+
return 0
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
# Deploy standard aidevops MCP servers to ~/.cursor/mcp.json
|
|
318
|
+
# Cursor uses JSON format: { "mcpServers": { "name": { ... } } }
|
|
319
|
+
_deploy_cursor_mcps() {
|
|
320
|
+
local config="$HOME/.cursor/mcp.json"
|
|
321
|
+
mkdir -p "$HOME/.cursor"
|
|
322
|
+
|
|
323
|
+
# Ensure config file exists with valid JSON
|
|
324
|
+
if [[ ! -f "$config" ]]; then
|
|
325
|
+
echo '{}' >"$config"
|
|
326
|
+
fi
|
|
327
|
+
|
|
328
|
+
# Use the json_set_nested helper from ai-cli-config.sh if available,
|
|
329
|
+
# otherwise use python3 directly
|
|
330
|
+
local mcp_count=0
|
|
331
|
+
|
|
332
|
+
# Helper: add a JSON MCP entry if not already present
|
|
333
|
+
# Increments mcp_count only when a new entry is actually added.
|
|
334
|
+
_add_cursor_mcp() {
|
|
335
|
+
local name="$1"
|
|
336
|
+
local json_value="$2"
|
|
337
|
+
|
|
338
|
+
if ! command -v python3 >/dev/null 2>&1; then
|
|
339
|
+
print_warning "python3 not found - cannot update Cursor config"
|
|
340
|
+
return 0
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
local py_output
|
|
344
|
+
py_output=$(
|
|
345
|
+
python3 - "$config" "$name" "$json_value" <<'PYEOF'
|
|
346
|
+
import json, sys
|
|
347
|
+
|
|
348
|
+
file_path = sys.argv[1]
|
|
349
|
+
name = sys.argv[2]
|
|
350
|
+
value_json = sys.argv[3]
|
|
351
|
+
|
|
352
|
+
try:
|
|
353
|
+
with open(file_path, 'r') as f:
|
|
354
|
+
cfg = json.load(f)
|
|
355
|
+
except (FileNotFoundError, json.JSONDecodeError):
|
|
356
|
+
cfg = {}
|
|
357
|
+
|
|
358
|
+
if "mcpServers" not in cfg or not isinstance(cfg["mcpServers"], dict):
|
|
359
|
+
cfg["mcpServers"] = {}
|
|
360
|
+
|
|
361
|
+
if name in cfg["mcpServers"]:
|
|
362
|
+
print(f"SKIP = {name} (already configured)")
|
|
363
|
+
else:
|
|
364
|
+
cfg["mcpServers"][name] = json.loads(value_json)
|
|
365
|
+
with open(file_path, 'w') as f:
|
|
366
|
+
json.dump(cfg, f, indent=2)
|
|
367
|
+
f.write('\n')
|
|
368
|
+
print(f"ADDED + {name}")
|
|
369
|
+
PYEOF
|
|
370
|
+
) || true
|
|
371
|
+
echo " ${py_output#* }"
|
|
372
|
+
if [[ "$py_output" == ADDED* ]]; then
|
|
373
|
+
((++mcp_count))
|
|
374
|
+
fi
|
|
375
|
+
return 0
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
# --- context7 (library docs) ---
|
|
379
|
+
_add_cursor_mcp "context7" '{"command":"npx","args":["-y","@upstash/context7-mcp@latest"]}'
|
|
380
|
+
|
|
381
|
+
# --- Playwright MCP ---
|
|
382
|
+
_add_cursor_mcp "playwright" '{"command":"npx","args":["-y","@anthropic-ai/mcp-server-playwright@latest"]}'
|
|
383
|
+
|
|
384
|
+
# --- shadcn UI ---
|
|
385
|
+
_add_cursor_mcp "shadcn" '{"command":"npx","args":["shadcn@latest","mcp"]}'
|
|
386
|
+
|
|
387
|
+
# --- OpenAPI Search (remote, zero install) ---
|
|
388
|
+
_add_cursor_mcp "openapi-search" '{"url":"https://openapi-mcp.openapisearch.com/mcp"}'
|
|
389
|
+
|
|
390
|
+
# --- Cloudflare API (remote) ---
|
|
391
|
+
_add_cursor_mcp "cloudflare-api" '{"url":"https://mcp.cloudflare.com/mcp"}'
|
|
163
392
|
|
|
393
|
+
echo " Done -- $mcp_count new MCP servers added to Cursor config"
|
|
164
394
|
return 0
|
|
165
395
|
}
|
package/setup-modules/plugins.sh
CHANGED
|
@@ -222,14 +222,15 @@ generate_agent_skills() {
|
|
|
222
222
|
if [[ -f "$skills_script" ]]; then
|
|
223
223
|
if bash "$skills_script" 2>/dev/null; then
|
|
224
224
|
print_success "Agent Skills SKILL.md files generated"
|
|
225
|
+
return 0
|
|
225
226
|
else
|
|
226
227
|
print_warning "Agent Skills generation encountered issues (non-critical)"
|
|
228
|
+
return 1
|
|
227
229
|
fi
|
|
228
230
|
else
|
|
229
231
|
print_warning "Agent Skills generator not found at $skills_script"
|
|
232
|
+
return 1
|
|
230
233
|
fi
|
|
231
|
-
|
|
232
|
-
return 0
|
|
233
234
|
}
|
|
234
235
|
|
|
235
236
|
create_skill_symlinks() {
|
|
@@ -1535,6 +1535,150 @@ setup_opencode_cli() {
|
|
|
1535
1535
|
return 0
|
|
1536
1536
|
}
|
|
1537
1537
|
|
|
1538
|
+
setup_codex_cli() {
|
|
1539
|
+
print_info "Setting up OpenAI Codex CLI..."
|
|
1540
|
+
|
|
1541
|
+
# Check if Codex is already installed
|
|
1542
|
+
if command -v codex >/dev/null 2>&1; then
|
|
1543
|
+
local codex_version
|
|
1544
|
+
codex_version=$(codex --version 2>/dev/null | head -1 || echo "unknown")
|
|
1545
|
+
print_success "Codex already installed: $codex_version"
|
|
1546
|
+
# Fix broken MCP_DOCKER if present
|
|
1547
|
+
_fix_codex_docker_mcp
|
|
1548
|
+
return 0
|
|
1549
|
+
fi
|
|
1550
|
+
|
|
1551
|
+
# Need either bun or npm to install
|
|
1552
|
+
local installer=""
|
|
1553
|
+
local install_pkg="@openai/codex@latest"
|
|
1554
|
+
|
|
1555
|
+
if command -v bun >/dev/null 2>&1; then
|
|
1556
|
+
installer="bun"
|
|
1557
|
+
elif command -v npm >/dev/null 2>&1; then
|
|
1558
|
+
installer="npm"
|
|
1559
|
+
else
|
|
1560
|
+
print_warning "Neither bun nor npm found - cannot install Codex"
|
|
1561
|
+
print_info "Install Node.js first, then re-run setup"
|
|
1562
|
+
return 0
|
|
1563
|
+
fi
|
|
1564
|
+
|
|
1565
|
+
print_info "Codex is OpenAI's AI coding CLI (terminal-based, agentic)"
|
|
1566
|
+
echo " It provides an AI-powered terminal interface using OpenAI models."
|
|
1567
|
+
echo ""
|
|
1568
|
+
|
|
1569
|
+
local install_codex="Y"
|
|
1570
|
+
if [[ "${NON_INTERACTIVE:-}" != "true" ]]; then
|
|
1571
|
+
read -r -p "Install Codex via $installer? [Y/n]: " install_codex || install_codex="Y"
|
|
1572
|
+
fi
|
|
1573
|
+
if [[ "$install_codex" =~ ^[Yy]?$ ]]; then
|
|
1574
|
+
if run_with_spinner "Installing Codex" npm_global_install "$install_pkg"; then
|
|
1575
|
+
print_success "Codex installed"
|
|
1576
|
+
echo ""
|
|
1577
|
+
print_info "Codex needs OpenAI authentication."
|
|
1578
|
+
print_info "Run 'codex' and follow the auth prompts."
|
|
1579
|
+
echo ""
|
|
1580
|
+
# Fix broken MCP_DOCKER if Codex created a default config
|
|
1581
|
+
_fix_codex_docker_mcp
|
|
1582
|
+
else
|
|
1583
|
+
print_warning "Codex installation failed"
|
|
1584
|
+
print_info "Try manually: npm install -g $install_pkg"
|
|
1585
|
+
fi
|
|
1586
|
+
else
|
|
1587
|
+
print_info "Skipped Codex installation"
|
|
1588
|
+
print_info "Install later: $installer install -g $install_pkg"
|
|
1589
|
+
fi
|
|
1590
|
+
|
|
1591
|
+
return 0
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
# P0 fix: Remove broken MCP_DOCKER from Codex config.toml
|
|
1595
|
+
# Docker Desktop 4.40+ with MCP Toolkit extension is required for `docker mcp`.
|
|
1596
|
+
# OrbStack, Colima, Rancher Desktop do not support it.
|
|
1597
|
+
_fix_codex_docker_mcp() {
|
|
1598
|
+
local config="$HOME/.codex/config.toml"
|
|
1599
|
+
[[ -f "$config" ]] || return 0
|
|
1600
|
+
|
|
1601
|
+
# Check if MCP_DOCKER section exists
|
|
1602
|
+
if ! grep -q '^\[mcp_servers\.MCP_DOCKER\]' "$config" 2>/dev/null; then
|
|
1603
|
+
return 0
|
|
1604
|
+
fi
|
|
1605
|
+
|
|
1606
|
+
# Check if `docker mcp` subcommand is actually available
|
|
1607
|
+
if docker mcp --help >/dev/null 2>&1; then
|
|
1608
|
+
return 0
|
|
1609
|
+
fi
|
|
1610
|
+
|
|
1611
|
+
# Comment out the MCP_DOCKER section (from header to next section or EOF)
|
|
1612
|
+
# Use sed to comment out lines from [mcp_servers.MCP_DOCKER] to the next
|
|
1613
|
+
# section header or end of file. Portable sed (no -i on macOS without ext).
|
|
1614
|
+
local tmp_config
|
|
1615
|
+
tmp_config=$(mktemp)
|
|
1616
|
+
local in_mcp_docker=false
|
|
1617
|
+
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
1618
|
+
if [[ "$line" == "[mcp_servers.MCP_DOCKER]" ]]; then
|
|
1619
|
+
in_mcp_docker=true
|
|
1620
|
+
printf '# %s # Disabled by aidevops: docker mcp not available\n' "$line" >>"$tmp_config"
|
|
1621
|
+
continue
|
|
1622
|
+
fi
|
|
1623
|
+
# If we hit another section header, stop commenting
|
|
1624
|
+
if [[ "$in_mcp_docker" == "true" ]] && [[ "$line" == "["* ]]; then
|
|
1625
|
+
in_mcp_docker=false
|
|
1626
|
+
fi
|
|
1627
|
+
if [[ "$in_mcp_docker" == "true" ]]; then
|
|
1628
|
+
printf '# %s\n' "$line" >>"$tmp_config"
|
|
1629
|
+
else
|
|
1630
|
+
printf '%s\n' "$line" >>"$tmp_config"
|
|
1631
|
+
fi
|
|
1632
|
+
done <"$config"
|
|
1633
|
+
mv "$tmp_config" "$config"
|
|
1634
|
+
print_info "Disabled MCP_DOCKER in Codex config (docker mcp not available on this system)"
|
|
1635
|
+
return 0
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
setup_droid_cli() {
|
|
1639
|
+
print_info "Setting up Factory.AI Droid CLI..."
|
|
1640
|
+
|
|
1641
|
+
# Check if Droid is already installed
|
|
1642
|
+
if command -v droid >/dev/null 2>&1; then
|
|
1643
|
+
local droid_version
|
|
1644
|
+
droid_version=$(droid --version 2>/dev/null | head -1 || echo "unknown")
|
|
1645
|
+
print_success "Droid already installed: $droid_version"
|
|
1646
|
+
return 0
|
|
1647
|
+
fi
|
|
1648
|
+
|
|
1649
|
+
# Droid uses its own installer — not available via npm/brew
|
|
1650
|
+
print_info "Droid (Factory.AI) is an AI coding agent CLI"
|
|
1651
|
+
echo " It provides autonomous coding capabilities with Factory.AI models."
|
|
1652
|
+
echo ""
|
|
1653
|
+
|
|
1654
|
+
local install_droid="Y"
|
|
1655
|
+
if [[ "${NON_INTERACTIVE:-}" != "true" ]]; then
|
|
1656
|
+
read -r -p "Install Droid CLI? [Y/n]: " install_droid || install_droid="Y"
|
|
1657
|
+
fi
|
|
1658
|
+
if [[ "$install_droid" =~ ^[Yy]?$ ]]; then
|
|
1659
|
+
print_info "Installing Droid CLI..."
|
|
1660
|
+
if command -v curl >/dev/null 2>&1; then
|
|
1661
|
+
if curl -fsSL https://app.factory.ai/install.sh | bash 2>/dev/null; then
|
|
1662
|
+
print_success "Droid installed"
|
|
1663
|
+
echo ""
|
|
1664
|
+
print_info "Run 'droid auth login' to authenticate with Factory.AI."
|
|
1665
|
+
echo ""
|
|
1666
|
+
else
|
|
1667
|
+
print_warning "Droid installation failed"
|
|
1668
|
+
print_info "Install manually from: https://docs.factory.ai/cli/installation"
|
|
1669
|
+
fi
|
|
1670
|
+
else
|
|
1671
|
+
print_warning "curl not found - cannot install Droid"
|
|
1672
|
+
print_info "Install manually from: https://docs.factory.ai/cli/installation"
|
|
1673
|
+
fi
|
|
1674
|
+
else
|
|
1675
|
+
print_info "Skipped Droid installation"
|
|
1676
|
+
print_info "Install later: curl -fsSL https://app.factory.ai/install.sh | bash"
|
|
1677
|
+
fi
|
|
1678
|
+
|
|
1679
|
+
return 0
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1538
1682
|
setup_google_workspace_cli() {
|
|
1539
1683
|
print_info "Setting up Google Workspace CLI (gws)..."
|
|
1540
1684
|
|
package/setup.sh
CHANGED
|
@@ -10,7 +10,7 @@ shopt -s inherit_errexit 2>/dev/null || true
|
|
|
10
10
|
# AI Assistant Server Access Framework Setup Script
|
|
11
11
|
# Helps developers set up the framework for their infrastructure
|
|
12
12
|
#
|
|
13
|
-
# Version: 3.1.
|
|
13
|
+
# Version: 3.1.271
|
|
14
14
|
#
|
|
15
15
|
# Quick Install:
|
|
16
16
|
# npm install -g aidevops && aidevops update (recommended)
|
|
@@ -689,27 +689,8 @@ init_settings_json() {
|
|
|
689
689
|
return 0
|
|
690
690
|
}
|
|
691
691
|
|
|
692
|
-
#
|
|
693
|
-
|
|
694
|
-
# Bootstrap first (handles curl install)
|
|
695
|
-
bootstrap_repo "$@"
|
|
696
|
-
|
|
697
|
-
parse_args "$@"
|
|
698
|
-
local _os
|
|
699
|
-
_os="$(uname -s)"
|
|
700
|
-
|
|
701
|
-
# Auto-detect non-interactive terminals (CI/CD, agent shells, piped stdin)
|
|
702
|
-
# Must run after parse_args so explicit --interactive flag takes precedence
|
|
703
|
-
if [[ "$INTERACTIVE_MODE" != "true" && ! -t 0 ]]; then
|
|
704
|
-
NON_INTERACTIVE=true
|
|
705
|
-
fi
|
|
706
|
-
|
|
707
|
-
# Guard: --interactive and --non-interactive are mutually exclusive
|
|
708
|
-
if [[ "$INTERACTIVE_MODE" == "true" && "$NON_INTERACTIVE" == "true" ]]; then
|
|
709
|
-
print_error "--interactive and --non-interactive cannot be used together"
|
|
710
|
-
exit 1
|
|
711
|
-
fi
|
|
712
|
-
|
|
692
|
+
# Print the setup header based on active mode flags.
|
|
693
|
+
_setup_print_header() {
|
|
713
694
|
echo "🤖 AI DevOps Framework Setup"
|
|
714
695
|
echo "============================="
|
|
715
696
|
if [[ "$CLEAN_MODE" == "true" ]]; then
|
|
@@ -726,139 +707,157 @@ main() {
|
|
|
726
707
|
echo "Mode: Update (will check for tool updates after setup)"
|
|
727
708
|
fi
|
|
728
709
|
echo ""
|
|
710
|
+
return 0
|
|
711
|
+
}
|
|
729
712
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
713
|
+
# Non-interactive path: deploy agents and run safe migrations only (no prompts).
|
|
714
|
+
_setup_run_non_interactive() {
|
|
715
|
+
print_info "Non-interactive mode: deploying agents and running safe migrations only"
|
|
716
|
+
verify_location
|
|
717
|
+
check_requirements
|
|
718
|
+
check_python_upgrade_available
|
|
719
|
+
set_permissions
|
|
720
|
+
migrate_old_backups
|
|
721
|
+
migrate_loop_state_directories
|
|
722
|
+
migrate_agent_to_agents_folder
|
|
723
|
+
migrate_mcp_env_to_credentials
|
|
724
|
+
migrate_pulse_repos_to_repos_json
|
|
725
|
+
cleanup_deprecated_paths
|
|
726
|
+
migrate_orphaned_supervisor
|
|
727
|
+
cleanup_deprecated_mcps
|
|
728
|
+
cleanup_stale_bun_opencode
|
|
729
|
+
validate_opencode_config
|
|
730
|
+
deploy_aidevops_agents
|
|
731
|
+
sync_agent_sources
|
|
732
|
+
setup_shellcheck_wrapper
|
|
733
|
+
if is_feature_enabled safety_hooks 2>/dev/null; then
|
|
734
|
+
setup_safety_hooks
|
|
735
|
+
fi
|
|
736
|
+
init_settings_json
|
|
754
737
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
738
|
+
# Parallelise independent skill operations (t1356: ~84s serial -> ~18s parallel)
|
|
739
|
+
# generate_agent_skills must complete before create_skill_symlinks (symlinks
|
|
740
|
+
# depend on generated SKILL.md files). scan_imported_skills is independent.
|
|
741
|
+
local _pid_symlinks=""
|
|
742
|
+
if generate_agent_skills; then
|
|
760
743
|
create_skill_symlinks &
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
744
|
+
_pid_symlinks=$!
|
|
745
|
+
else
|
|
746
|
+
print_warning "Agent skills generation failed — skipping skill symlinks"
|
|
747
|
+
fi
|
|
748
|
+
|
|
749
|
+
scan_imported_skills &
|
|
750
|
+
local _pid_scan=$!
|
|
751
|
+
|
|
752
|
+
if [[ -n "$_pid_symlinks" ]]; then
|
|
765
753
|
wait "$_pid_symlinks" 2>/dev/null || print_warning "Skill symlink creation encountered issues (non-critical)"
|
|
766
|
-
|
|
754
|
+
fi
|
|
755
|
+
wait "$_pid_scan" 2>/dev/null || print_warning "Skill security scan encountered issues (non-critical)"
|
|
756
|
+
|
|
757
|
+
inject_agents_reference
|
|
758
|
+
update_opencode_config
|
|
759
|
+
update_claude_config
|
|
760
|
+
update_codex_config
|
|
761
|
+
update_cursor_config
|
|
762
|
+
disable_ondemand_mcps
|
|
763
|
+
return 0
|
|
764
|
+
}
|
|
767
765
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
# Optional steps with confirmation in interactive mode
|
|
799
|
-
confirm_step "Check optional dependencies (bun, node, python)" && check_optional_deps
|
|
800
|
-
confirm_step "Check Python version (recommend upgrade if outdated)" && check_python_upgrade_available
|
|
801
|
-
confirm_step "Setup recommended tools (Tabby, Zed, etc.)" && setup_recommended_tools
|
|
802
|
-
confirm_step "Setup MiniSim (iOS/Android emulator launcher)" && setup_minisim
|
|
803
|
-
confirm_step "Setup ClaudeBar (AI quota monitor in menu bar)" && setup_claudebar
|
|
804
|
-
confirm_step "Setup Git CLIs (gh, glab, tea)" && setup_git_clis
|
|
805
|
-
confirm_step "Setup file discovery tools (fd, ripgrep, ripgrep-all)" && setup_file_discovery_tools
|
|
806
|
-
confirm_step "Setup rtk (token-optimized CLI output, 60-90% savings)" && setup_rtk
|
|
807
|
-
confirm_step "Setup shell linting tools (shellcheck, shfmt)" && setup_shell_linting_tools
|
|
766
|
+
# Interactive path: all optional steps gated behind confirm_step prompts.
|
|
767
|
+
_setup_run_interactive() {
|
|
768
|
+
# Required steps (always run)
|
|
769
|
+
verify_location
|
|
770
|
+
check_requirements
|
|
771
|
+
|
|
772
|
+
# Quality tools check (optional but recommended)
|
|
773
|
+
confirm_step "Check quality tools (shellcheck, shfmt)" && check_quality_tools
|
|
774
|
+
|
|
775
|
+
# Core runtime setup (early - many later steps depend on these)
|
|
776
|
+
confirm_step "Setup Node.js runtime (required for OpenCode and tools)" && setup_nodejs
|
|
777
|
+
|
|
778
|
+
# Shell environment setup (early, so later tools benefit from zsh/Oh My Zsh)
|
|
779
|
+
confirm_step "Setup Oh My Zsh (optional, enhances zsh)" && setup_oh_my_zsh
|
|
780
|
+
confirm_step "Setup cross-shell compatibility (preserve bash config in zsh)" && setup_shell_compatibility
|
|
781
|
+
|
|
782
|
+
# OrbStack (macOS only - offer VM option early)
|
|
783
|
+
confirm_step "Setup OrbStack (lightweight Linux VMs on macOS)" && setup_orbstack_vm
|
|
784
|
+
|
|
785
|
+
# Optional steps with confirmation in interactive mode
|
|
786
|
+
confirm_step "Check optional dependencies (bun, node, python)" && check_optional_deps
|
|
787
|
+
confirm_step "Check Python version (recommend upgrade if outdated)" && check_python_upgrade_available
|
|
788
|
+
confirm_step "Setup recommended tools (Tabby, Zed, etc.)" && setup_recommended_tools
|
|
789
|
+
confirm_step "Setup MiniSim (iOS/Android emulator launcher)" && setup_minisim
|
|
790
|
+
confirm_step "Setup ClaudeBar (AI quota monitor in menu bar)" && setup_claudebar
|
|
791
|
+
confirm_step "Setup Git CLIs (gh, glab, tea)" && setup_git_clis
|
|
792
|
+
confirm_step "Setup file discovery tools (fd, ripgrep, ripgrep-all)" && setup_file_discovery_tools
|
|
793
|
+
confirm_step "Setup rtk (token-optimized CLI output, 60-90% savings)" && setup_rtk
|
|
794
|
+
confirm_step "Setup shell linting tools (shellcheck, shfmt)" && {
|
|
795
|
+
setup_shell_linting_tools
|
|
808
796
|
setup_shellcheck_wrapper
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
797
|
+
}
|
|
798
|
+
confirm_step "Setup Qlty CLI (multi-linter code quality)" && setup_qlty_cli
|
|
799
|
+
confirm_step "Rosetta audit (Apple Silicon x86 migration)" && setup_rosetta_audit
|
|
800
|
+
confirm_step "Setup Worktrunk (git worktree management)" && setup_worktrunk
|
|
801
|
+
confirm_step "Setup SSH key" && setup_ssh_key
|
|
802
|
+
confirm_step "Setup configuration files" && setup_configs
|
|
803
|
+
confirm_step "Set secure permissions on config files" && set_permissions
|
|
804
|
+
confirm_step "Install aidevops CLI command" && install_aidevops_cli
|
|
805
|
+
confirm_step "Setup shell aliases" && setup_aliases
|
|
806
|
+
confirm_step "Setup terminal title integration" && setup_terminal_title
|
|
807
|
+
confirm_step "Deploy AI templates to home directories" && deploy_ai_templates
|
|
808
|
+
confirm_step "Migrate old backups to new structure" && migrate_old_backups
|
|
809
|
+
confirm_step "Migrate loop state from .claude/.agent/ to .agents/loop-state/" && migrate_loop_state_directories
|
|
810
|
+
confirm_step "Migrate .agent -> .agents in user projects" && migrate_agent_to_agents_folder
|
|
811
|
+
confirm_step "Migrate mcp-env.sh -> credentials.sh" && migrate_mcp_env_to_credentials
|
|
812
|
+
confirm_step "Migrate pulse-repos.json into repos.json" && migrate_pulse_repos_to_repos_json
|
|
813
|
+
confirm_step "Cleanup deprecated agent paths" && cleanup_deprecated_paths
|
|
814
|
+
confirm_step "Migrate orphaned supervisor to pulse-wrapper" && migrate_orphaned_supervisor
|
|
815
|
+
confirm_step "Cleanup deprecated MCP entries (hetzner, serper, etc.)" && cleanup_deprecated_mcps
|
|
816
|
+
confirm_step "Cleanup stale bun opencode install" && cleanup_stale_bun_opencode
|
|
817
|
+
confirm_step "Validate and repair OpenCode config schema" && validate_opencode_config
|
|
818
|
+
confirm_step "Extract OpenCode prompts" && extract_opencode_prompts
|
|
819
|
+
confirm_step "Check OpenCode prompt drift" && check_opencode_prompt_drift
|
|
820
|
+
confirm_step "Deploy aidevops agents to ~/.aidevops/agents/" && deploy_aidevops_agents
|
|
821
|
+
confirm_step "Sync agents from private repositories" && sync_agent_sources
|
|
822
|
+
is_feature_enabled safety_hooks 2>/dev/null && confirm_step "Install Claude Code safety hooks (block destructive commands)" && setup_safety_hooks
|
|
823
|
+
confirm_step "Initialize settings.json (canonical config file)" && init_settings_json
|
|
824
|
+
confirm_step "Setup multi-tenant credential storage" && setup_multi_tenant_credentials
|
|
825
|
+
confirm_step "Generate agent skills (SKILL.md files)" && generate_agent_skills
|
|
826
|
+
confirm_step "Create symlinks for imported skills" && create_skill_symlinks
|
|
827
|
+
confirm_step "Check for skill updates from upstream" && check_skill_updates
|
|
828
|
+
confirm_step "Security scan imported skills" && scan_imported_skills
|
|
829
|
+
confirm_step "Inject agents reference into AI configs" && inject_agents_reference
|
|
830
|
+
confirm_step "Setup Python environment (DSPy, crawl4ai)" && setup_python_env
|
|
831
|
+
confirm_step "Setup Node.js environment" && setup_nodejs_env
|
|
832
|
+
confirm_step "Install MCP packages globally (fast startup)" && install_mcp_packages
|
|
833
|
+
confirm_step "Setup LocalWP MCP server" && setup_localwp_mcp
|
|
834
|
+
confirm_step "Setup Augment Context Engine MCP" && setup_augment_context_engine
|
|
835
|
+
confirm_step "Setup Beads task management" && setup_beads
|
|
836
|
+
confirm_step "Setup SEO integrations (curl subagents)" && setup_seo_mcps
|
|
837
|
+
confirm_step "Setup Google Analytics MCP" && setup_google_analytics_mcp
|
|
838
|
+
confirm_step "Setup QuickFile MCP (UK accounting)" && setup_quickfile_mcp
|
|
839
|
+
confirm_step "Setup browser automation tools" && setup_browser_tools
|
|
840
|
+
confirm_step "Setup AI orchestration frameworks info" && setup_ai_orchestration
|
|
841
|
+
confirm_step "Setup Google Workspace CLI (Gmail, Calendar, Drive)" && setup_google_workspace_cli
|
|
842
|
+
confirm_step "Setup OpenCode CLI (AI coding tool)" && setup_opencode_cli
|
|
843
|
+
confirm_step "Setup OpenCode plugins" && setup_opencode_plugins
|
|
844
|
+
confirm_step "Setup Codex CLI (OpenAI AI coding tool)" && setup_codex_cli
|
|
845
|
+
confirm_step "Setup Droid CLI (Factory.AI coding tool)" && setup_droid_cli
|
|
846
|
+
# Run AFTER CLI installs so config dirs may exist for agent config
|
|
847
|
+
confirm_step "Update OpenCode configuration" && update_opencode_config
|
|
848
|
+
# Run AFTER OpenCode config so Claude Code gets equivalent setup
|
|
849
|
+
confirm_step "Update Claude Code configuration (slash commands, MCPs, settings)" && update_claude_config
|
|
850
|
+
# Run AFTER Claude Code config so Codex/Cursor get equivalent setup
|
|
851
|
+
confirm_step "Update Codex configuration (MCPs, instructions)" && update_codex_config
|
|
852
|
+
confirm_step "Update Cursor configuration (MCPs)" && update_cursor_config
|
|
853
|
+
# Run AFTER all MCP setup functions to ensure disabled state persists
|
|
854
|
+
confirm_step "Disable on-demand MCPs globally" && disable_ondemand_mcps
|
|
855
|
+
return 0
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
# Post-setup steps: schedulers, final instructions, optional tool update check.
|
|
859
|
+
_setup_post_setup_steps() {
|
|
860
|
+
local os="$1"
|
|
862
861
|
|
|
863
862
|
# Print setup summary before final success message (GH#5240)
|
|
864
863
|
print_setup_summary
|
|
@@ -866,9 +865,15 @@ main() {
|
|
|
866
865
|
echo ""
|
|
867
866
|
print_success "Setup complete!"
|
|
868
867
|
|
|
868
|
+
# Non-interactive mode: deploy + migrations only — skip schedulers,
|
|
869
|
+
# services, and optional post-setup work (CI/agent shells don't need them).
|
|
870
|
+
if [[ "$NON_INTERACTIVE" == "true" ]]; then
|
|
871
|
+
return 0
|
|
872
|
+
fi
|
|
873
|
+
|
|
869
874
|
# Post-setup: auto-update, schedulers, final instructions (GH#5793)
|
|
870
875
|
setup_auto_update
|
|
871
|
-
setup_supervisor_pulse "$
|
|
876
|
+
setup_supervisor_pulse "$os"
|
|
872
877
|
setup_stats_wrapper "${PULSE_ENABLED:-}"
|
|
873
878
|
setup_repo_sync
|
|
874
879
|
setup_process_guard
|
|
@@ -887,6 +892,39 @@ main() {
|
|
|
887
892
|
fi
|
|
888
893
|
|
|
889
894
|
setup_onboarding_prompt
|
|
895
|
+
return 0
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
# Main setup function — orchestrates init, mode dispatch, and post-setup.
|
|
899
|
+
main() {
|
|
900
|
+
# Bootstrap first (handles curl install)
|
|
901
|
+
bootstrap_repo "$@"
|
|
902
|
+
|
|
903
|
+
parse_args "$@"
|
|
904
|
+
local _os
|
|
905
|
+
_os="$(uname -s)"
|
|
906
|
+
|
|
907
|
+
# Auto-detect non-interactive terminals (CI/CD, agent shells, piped stdin)
|
|
908
|
+
# Must run after parse_args so explicit --interactive flag takes precedence
|
|
909
|
+
if [[ "$INTERACTIVE_MODE" != "true" && ! -t 0 ]]; then
|
|
910
|
+
NON_INTERACTIVE=true
|
|
911
|
+
fi
|
|
912
|
+
|
|
913
|
+
# Guard: --interactive and --non-interactive are mutually exclusive
|
|
914
|
+
if [[ "$INTERACTIVE_MODE" == "true" && "$NON_INTERACTIVE" == "true" ]]; then
|
|
915
|
+
print_error "--interactive and --non-interactive cannot be used together"
|
|
916
|
+
exit 1
|
|
917
|
+
fi
|
|
918
|
+
|
|
919
|
+
_setup_print_header
|
|
920
|
+
|
|
921
|
+
if [[ "$NON_INTERACTIVE" == "true" ]]; then
|
|
922
|
+
_setup_run_non_interactive
|
|
923
|
+
else
|
|
924
|
+
_setup_run_interactive
|
|
925
|
+
fi
|
|
926
|
+
|
|
927
|
+
_setup_post_setup_steps "$_os"
|
|
890
928
|
|
|
891
929
|
return 0
|
|
892
930
|
}
|