aidevops 2.100.7 → 2.100.9

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.
Files changed (4) hide show
  1. package/VERSION +1 -1
  2. package/aidevops.sh +1 -1
  3. package/package.json +1 -1
  4. package/setup.sh +111 -17
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.100.7
1
+ 2.100.9
package/aidevops.sh CHANGED
@@ -3,7 +3,7 @@
3
3
  # AI DevOps Framework CLI
4
4
  # Usage: aidevops <command> [options]
5
5
  #
6
- # Version: 2.100.7
6
+ # Version: 2.100.9
7
7
 
8
8
  set -euo pipefail
9
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidevops",
3
- "version": "2.100.7",
3
+ "version": "2.100.9",
4
4
  "description": "AI DevOps Framework - AI-assisted development workflows, code quality, and deployment automation",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/setup.sh CHANGED
@@ -3,7 +3,7 @@
3
3
  # AI Assistant Server Access Framework Setup Script
4
4
  # Helps developers set up the framework for their infrastructure
5
5
  #
6
- # Version: 2.100.7
6
+ # Version: 2.100.9
7
7
  #
8
8
  # Quick Install (one-liner):
9
9
  # bash <(curl -fsSL https://aidevops.dev/install)
@@ -412,6 +412,85 @@ disable_ondemand_mcps() {
412
412
  return 0
413
413
  }
414
414
 
415
+ # Validate and repair OpenCode config schema
416
+ # Fixes common issues from manual editing or AI-generated configs:
417
+ # - MCP entries missing "type": "local" field
418
+ # - tools entries as objects {} instead of booleans
419
+ # If invalid, backs up and regenerates using the generator script
420
+ validate_opencode_config() {
421
+ local opencode_config
422
+ opencode_config=$(find_opencode_config) || return 0
423
+
424
+ if [[ ! -f "$opencode_config" ]]; then
425
+ return 0
426
+ fi
427
+
428
+ if ! command -v jq &> /dev/null; then
429
+ return 0
430
+ fi
431
+
432
+ local needs_repair=false
433
+ local issues=""
434
+
435
+ # Check 1: MCP entries must have "type" field (usually "local")
436
+ # Invalid: {"mcp": {"foo": {"command": "..."}}}
437
+ # Valid: {"mcp": {"foo": {"type": "local", "command": "..."}}}
438
+ local mcps_without_type
439
+ mcps_without_type=$(jq -r '.mcp // {} | to_entries[] | select(.value.type == null and .value.command != null) | .key' "$opencode_config" 2>/dev/null | head -5)
440
+ if [[ -n "$mcps_without_type" ]]; then
441
+ needs_repair=true
442
+ issues="${issues}\n - MCP entries missing 'type' field: $(echo "$mcps_without_type" | tr '\n' ', ' | sed 's/,$//')"
443
+ fi
444
+
445
+ # Check 2: tools entries must be booleans, not objects
446
+ # Invalid: {"tools": {"gh_grep": {}}}
447
+ # Valid: {"tools": {"gh_grep": true}}
448
+ local tools_as_objects
449
+ tools_as_objects=$(jq -r '.tools // {} | to_entries[] | select(.value | type == "object") | .key' "$opencode_config" 2>/dev/null | head -5)
450
+ if [[ -n "$tools_as_objects" ]]; then
451
+ needs_repair=true
452
+ issues="${issues}\n - tools entries as objects instead of booleans: $(echo "$tools_as_objects" | tr '\n' ', ' | sed 's/,$//')"
453
+ fi
454
+
455
+ # Check 3: Try to parse with opencode (if available) to catch other schema issues
456
+ if command -v opencode &> /dev/null; then
457
+ local validation_output
458
+ if ! validation_output=$(opencode --version 2>&1); then
459
+ # If opencode fails to start, config might be invalid
460
+ if echo "$validation_output" | grep -q "Configuration is invalid"; then
461
+ needs_repair=true
462
+ issues="${issues}\n - OpenCode reports invalid configuration"
463
+ fi
464
+ fi
465
+ fi
466
+
467
+ if [[ "$needs_repair" == "true" ]]; then
468
+ print_warning "OpenCode config has schema issues:$issues"
469
+
470
+ # Backup the invalid config
471
+ create_backup_with_rotation "$opencode_config" "opencode"
472
+ print_info "Backed up invalid config"
473
+
474
+ # Remove the invalid config so generator creates fresh one
475
+ rm -f "$opencode_config"
476
+
477
+ # Regenerate using the generator script
478
+ local generator_script="$HOME/.aidevops/agents/scripts/generate-opencode-agents.sh"
479
+ if [[ -x "$generator_script" ]]; then
480
+ print_info "Regenerating OpenCode config with correct schema..."
481
+ if "$generator_script" > /dev/null 2>&1; then
482
+ print_success "OpenCode config regenerated successfully"
483
+ else
484
+ print_warning "Config regeneration failed - run manually: $generator_script"
485
+ fi
486
+ else
487
+ print_warning "Generator script not found - run setup.sh again after agents are deployed"
488
+ fi
489
+ fi
490
+
491
+ return 0
492
+ }
493
+
415
494
  # Migrate old config-backups to new per-type backup structure
416
495
  # This runs once to clean up the legacy backup directory
417
496
  migrate_old_backups() {
@@ -996,7 +1075,8 @@ setup_worktrunk() {
996
1075
  print_info "Shell integration not detected"
997
1076
  read -r -p "Install Worktrunk shell integration (enables 'wt switch' to change directories)? [Y/n]: " install_shell
998
1077
  if [[ "$install_shell" =~ ^[Yy]?$ ]]; then
999
- if wt config shell install 2>/dev/null; then
1078
+ print_info "Installing shell integration..."
1079
+ if wt config shell install; then
1000
1080
  print_success "Shell integration installed"
1001
1081
  print_info "Restart your terminal or run: source $shell_rc"
1002
1082
  else
@@ -1028,8 +1108,10 @@ setup_worktrunk() {
1028
1108
 
1029
1109
  if [[ "$install_wt" =~ ^[Yy]?$ ]]; then
1030
1110
  if run_with_spinner "Installing Worktrunk via Homebrew" brew install max-sixty/worktrunk/wt; then
1031
- # Install shell integration
1032
- if run_with_spinner "Installing shell integration" wt config shell install; then
1111
+ # Install shell integration (don't use spinner - command is fast and may need interaction)
1112
+ print_info "Installing shell integration..."
1113
+ if wt config shell install; then
1114
+ print_success "Shell integration installed"
1033
1115
  print_info "Restart your terminal or source your shell config"
1034
1116
  else
1035
1117
  print_warning "Shell integration failed - run manually: wt config shell install"
@@ -1056,8 +1138,10 @@ setup_worktrunk() {
1056
1138
 
1057
1139
  if [[ "$install_wt" =~ ^[Yy]?$ ]]; then
1058
1140
  if run_with_spinner "Installing Worktrunk via Cargo" cargo install worktrunk; then
1059
- # Install shell integration
1060
- if run_with_spinner "Installing shell integration" wt config shell install; then
1141
+ # Install shell integration (don't use spinner - command is fast and may need interaction)
1142
+ print_info "Installing shell integration..."
1143
+ if wt config shell install; then
1144
+ print_success "Shell integration installed"
1061
1145
  print_info "Restart your terminal or source your shell config"
1062
1146
  else
1063
1147
  print_warning "Shell integration failed - run manually: wt config shell install"
@@ -1813,15 +1897,24 @@ deploy_aidevops_agents() {
1813
1897
  if [[ -f "$plan_reminder" && -f "$plan_plus" ]]; then
1814
1898
  # Check if plan-plus.md has the placeholder marker
1815
1899
  if grep -q "OPENCODE-PLAN-REMINDER-INJECT" "$plan_plus"; then
1816
- # Replace placeholder with extracted content
1817
- local reminder_content
1818
- reminder_content=$(cat "$plan_reminder")
1819
- # Use awk to replace the placeholder section
1820
- awk -v content="$reminder_content" '
1821
- /<!-- OPENCODE-PLAN-REMINDER-INJECT-START -->/ { print; print content; skip=1; next }
1822
- /<!-- OPENCODE-PLAN-REMINDER-INJECT-END -->/ { skip=0 }
1823
- !skip { print }
1824
- ' "$plan_plus" > "$plan_plus.tmp" && mv "$plan_plus.tmp" "$plan_plus"
1900
+ # Replace placeholder with extracted content using sed
1901
+ # (awk -v doesn't handle multi-line content with special chars well)
1902
+ local tmp_file
1903
+ tmp_file=$(mktemp)
1904
+ local in_placeholder=false
1905
+ while IFS= read -r line || [[ -n "$line" ]]; do
1906
+ if [[ "$line" == *"OPENCODE-PLAN-REMINDER-INJECT-START"* ]]; then
1907
+ echo "$line" >> "$tmp_file"
1908
+ cat "$plan_reminder" >> "$tmp_file"
1909
+ in_placeholder=true
1910
+ elif [[ "$line" == *"OPENCODE-PLAN-REMINDER-INJECT-END"* ]]; then
1911
+ echo "$line" >> "$tmp_file"
1912
+ in_placeholder=false
1913
+ elif [[ "$in_placeholder" == false ]]; then
1914
+ echo "$line" >> "$tmp_file"
1915
+ fi
1916
+ done < "$plan_plus"
1917
+ mv "$tmp_file" "$plan_plus"
1825
1918
  print_info "Injected OpenCode plan-reminder into Plan+"
1826
1919
  fi
1827
1920
  fi
@@ -3418,6 +3511,7 @@ main() {
3418
3511
  confirm_step "Migrate loop state from .claude/ to .agent/loop-state/" && migrate_loop_state_directories
3419
3512
  confirm_step "Cleanup deprecated agent paths" && cleanup_deprecated_paths
3420
3513
  confirm_step "Cleanup deprecated MCP entries (hetzner, serper, etc.)" && cleanup_deprecated_mcps
3514
+ confirm_step "Validate and repair OpenCode config schema" && validate_opencode_config
3421
3515
  confirm_step "Extract OpenCode prompts" && extract_opencode_prompts
3422
3516
  confirm_step "Check OpenCode prompt drift" && check_opencode_prompt_drift
3423
3517
  confirm_step "Deploy aidevops agents to ~/.aidevops/agents/" && deploy_aidevops_agents
@@ -3532,8 +3626,8 @@ echo " aidevops uninstall - Remove aidevops"
3532
3626
  read -r -p "Launch OpenCode with /onboarding now? [Y/n]: " launch_onboarding
3533
3627
  if [[ "$launch_onboarding" =~ ^[Yy]?$ || "$launch_onboarding" == "Y" ]]; then
3534
3628
  echo ""
3535
- echo "Starting OpenCode..."
3536
- opencode --prompt "/onboarding"
3629
+ echo "Starting OpenCode with Onboarding agent..."
3630
+ opencode --agent Onboarding --prompt "/onboarding"
3537
3631
  else
3538
3632
  echo ""
3539
3633
  echo "You can run /onboarding anytime in OpenCode to configure services."