aidevops 3.5.568 → 3.5.569

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 CHANGED
@@ -1 +1 @@
1
- 3.5.568
1
+ 3.5.569
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidevops",
3
- "version": "3.5.568",
3
+ "version": "3.5.569",
4
4
  "description": "AI DevOps Framework - AI-assisted development workflows, code quality, and deployment automation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -530,6 +530,235 @@ _deploy_droid_agents_reference() {
530
530
  return 0
531
531
  }
532
532
 
533
+ # =============================================================================
534
+ # Deploy aidevops main agents to runtime-native agent directories
535
+ # =============================================================================
536
+ # Converts aidevops agents from ~/.aidevops/agents/*.md into each runtime's
537
+ # native agent format and copies them to the runtime's agent directory.
538
+ # Only deploys to installed runtimes that support agent directories.
539
+ #
540
+ # aidevops frontmatter fields stripped (not understood by target runtimes):
541
+ # mode, subagents
542
+ #
543
+ # Kept/mapped fields (compatible with Claude Code, Cursor, Amp):
544
+ # name, description, tools, model, permissionMode, hooks, mcpServers,
545
+ # maxTurns, initialPrompt, memory, background, isolation
546
+
547
+ # _convert_agent_frontmatter: strips aidevops-only fields from agent markdown.
548
+ # Reads from stdin, writes converted content to stdout.
549
+ # Tracks whether we're inside an indented block (subagents list) to correctly
550
+ # skip its child lines without stripping other indented YAML fields.
551
+ _convert_agent_frontmatter() {
552
+ local in_frontmatter=false
553
+ local frontmatter_started=false
554
+ local in_skip_block=false
555
+ local line_num=0
556
+
557
+ while IFS= read -r line || [[ -n "$line" ]]; do
558
+ line_num=$((line_num + 1))
559
+ if [[ $line_num -eq 1 && "$line" == "---" ]]; then
560
+ in_frontmatter=true
561
+ frontmatter_started=true
562
+ echo "$line"
563
+ continue
564
+ fi
565
+ if [[ "$frontmatter_started" == "true" && "$in_frontmatter" == "true" && "$line" == "---" ]]; then
566
+ in_frontmatter=false
567
+ echo "$line"
568
+ continue
569
+ fi
570
+ if [[ "$in_frontmatter" == "true" ]]; then
571
+ # Detect top-level keys (no leading whitespace)
572
+ case "$line" in
573
+ mode:*)
574
+ in_skip_block=false
575
+ continue
576
+ ;;
577
+ subagents:*)
578
+ in_skip_block=true
579
+ continue
580
+ ;;
581
+ esac
582
+ # If inside a skipped block, consume indented continuation lines
583
+ if [[ "$in_skip_block" == "true" ]]; then
584
+ case "$line" in
585
+ [[:space:]]*)
586
+ # Indented line under a skipped key — skip it
587
+ continue
588
+ ;;
589
+ *)
590
+ # Non-indented line — we've left the skip block
591
+ in_skip_block=false
592
+ echo "$line"
593
+ ;;
594
+ esac
595
+ else
596
+ echo "$line"
597
+ fi
598
+ else
599
+ echo "$line"
600
+ fi
601
+ done
602
+ return 0
603
+ }
604
+
605
+ # _is_agent_definition: check if a markdown file has agent frontmatter (name: field).
606
+ # Returns 0 if the file is an agent definition, 1 otherwise.
607
+ _is_agent_definition() {
608
+ local file="$1"
609
+ # Check first 30 lines for name: in YAML frontmatter (fast path)
610
+ head -30 "$file" 2>/dev/null | grep -q '^name:' 2>/dev/null
611
+ return $?
612
+ }
613
+
614
+ # _agent_source_dirs: list directories under agents_source that contain subagents.
615
+ # Excludes framework infrastructure directories that are not agent definitions.
616
+ # Prints directory paths, one per line.
617
+ _agent_source_dirs() {
618
+ local agents_source="$1"
619
+ local dir
620
+ for dir in "$agents_source"/*/; do
621
+ [[ -d "$dir" ]] || continue
622
+ local dirname
623
+ dirname=$(basename "$dir")
624
+ # Skip framework infrastructure directories
625
+ case "$dirname" in
626
+ scripts | reference | prompts | templates | configs | hooks | \
627
+ plugins | bundles | loop-state | advisories | aidevops | \
628
+ custom | draft | tests | rules)
629
+ continue
630
+ ;;
631
+ *)
632
+ echo "$dir"
633
+ ;;
634
+ esac
635
+ done
636
+ return 0
637
+ }
638
+
639
+ # deploy_agents_to_runtimes: main entry point called by setup.sh.
640
+ # Iterates all installed runtimes with agent directory support, converts and
641
+ # deploys aidevops agents (top-level and subagent directories) to each runtime's
642
+ # native agent directory. Only files with name: frontmatter are deployed.
643
+ # SKILL.md stubs (directory indexes) are excluded.
644
+ deploy_agents_to_runtimes() {
645
+ # Source runtime registry if not already loaded
646
+ local registry_script="${INSTALL_DIR:-.}/.agents/scripts/runtime-registry.sh"
647
+ if [[ -z "${_RUNTIME_REGISTRY_LOADED:-}" ]]; then
648
+ if [[ -f "$registry_script" ]]; then
649
+ # shellcheck source=/dev/null
650
+ source "$registry_script"
651
+ else
652
+ print_warning "Runtime registry not found — skipping agent deployment to runtimes"
653
+ return 0
654
+ fi
655
+ fi
656
+
657
+ local agents_source="${HOME}/.aidevops/agents"
658
+ if [[ ! -d "$agents_source" ]]; then
659
+ print_warning "No deployed agents found at $agents_source — skipping"
660
+ return 0
661
+ fi
662
+
663
+ # Build the list of agent files to deploy (once, shared across runtimes).
664
+ # Includes top-level *.md and all *.md in subagent directories that:
665
+ # 1. Have name: in frontmatter (actual agent definitions)
666
+ # 2. Are not SKILL.md stubs (directory index files)
667
+ local -a agent_files=()
668
+ local -a agent_relpaths=()
669
+
670
+ # Top-level agents
671
+ local f bn
672
+ for f in "$agents_source"/*.md; do
673
+ [[ -f "$f" ]] || continue
674
+ bn=$(basename "$f")
675
+ [[ "$bn" == "AGENTS.md" ]] && continue
676
+ if _is_agent_definition "$f"; then
677
+ agent_files+=("$f")
678
+ agent_relpaths+=("$bn")
679
+ fi
680
+ done
681
+
682
+ # Subagent directories (recursive)
683
+ local subdir
684
+ while IFS= read -r subdir; do
685
+ while IFS= read -r f; do
686
+ [[ -f "$f" ]] || continue
687
+ bn=$(basename "$f")
688
+ # Skip SKILL.md stubs — they're directory indexes, not real agents
689
+ [[ "$bn" == "SKILL.md" ]] && continue
690
+ if _is_agent_definition "$f"; then
691
+ # Compute path relative to agents_source
692
+ local relpath="${f#"$agents_source"/}"
693
+ agent_files+=("$f")
694
+ agent_relpaths+=("$relpath")
695
+ fi
696
+ done < <(find "$subdir" -name '*.md' -type f 2>/dev/null)
697
+ done < <(_agent_source_dirs "$agents_source")
698
+
699
+ local total_agents=${#agent_files[@]}
700
+ if [[ $total_agents -eq 0 ]]; then
701
+ print_warning "No agent definitions found in $agents_source"
702
+ return 0
703
+ fi
704
+
705
+ local deployed_count=0
706
+ local runtime_count=0
707
+
708
+ # Deploy to each installed runtime
709
+ local runtime_id agent_dir
710
+ while IFS= read -r runtime_id; do
711
+ agent_dir=$(rt_agent_dir "$runtime_id")
712
+ [[ -z "$agent_dir" ]] && continue
713
+
714
+ # Only deploy if the runtime is actually installed
715
+ local binary
716
+ binary=$(rt_binary "$runtime_id")
717
+ local config_path
718
+ config_path=$(rt_config_path "$runtime_id")
719
+ local config_dir
720
+ config_dir="$(dirname "$config_path" 2>/dev/null)"
721
+
722
+ if ! type -P "$binary" >/dev/null 2>&1 && [[ ! -d "$config_dir" ]]; then
723
+ continue
724
+ fi
725
+
726
+ mkdir -p "$agent_dir"
727
+ runtime_count=$((runtime_count + 1))
728
+ local agent_count=0
729
+ local i=0
730
+
731
+ while [[ $i -lt $total_agents ]]; do
732
+ local src="${agent_files[$i]}"
733
+ local rel="${agent_relpaths[$i]}"
734
+ local target="$agent_dir/$rel"
735
+
736
+ # Ensure target subdirectory exists
737
+ local target_parent
738
+ target_parent=$(dirname "$target")
739
+ [[ -d "$target_parent" ]] || mkdir -p "$target_parent"
740
+
741
+ if _convert_agent_frontmatter <"$src" >"$target"; then
742
+ agent_count=$((agent_count + 1))
743
+ fi
744
+ i=$((i + 1))
745
+ done
746
+
747
+ local display_name
748
+ display_name=$(rt_display_name "$runtime_id")
749
+ print_info "Deployed $agent_count agents to $display_name ($agent_dir)"
750
+ deployed_count=$((deployed_count + agent_count))
751
+ done < <(rt_list_with_agents)
752
+
753
+ if [[ $runtime_count -eq 0 ]]; then
754
+ print_info "No runtimes with agent directory support detected — skipping"
755
+ else
756
+ print_success "Deployed $deployed_count agent(s) across $runtime_count runtime(s)"
757
+ fi
758
+
759
+ return 0
760
+ }
761
+
533
762
  install_beads_binary() {
534
763
  local os arch tarball_name
535
764
  os=$(uname -s | tr '[:upper:]' '[:lower:]')
package/setup.sh CHANGED
@@ -794,6 +794,7 @@ _setup_run_non_interactive() {
794
794
  wait "$_pid_scan" 2>/dev/null || print_warning "Skill security scan encountered issues (non-critical)"
795
795
 
796
796
  inject_agents_reference
797
+ deploy_agents_to_runtimes
797
798
  update_opencode_config
798
799
  update_claude_config
799
800
  update_codex_config
@@ -866,6 +867,7 @@ _setup_run_interactive() {
866
867
  confirm_step "Check for skill updates from upstream" && check_skill_updates
867
868
  confirm_step "Security scan imported skills" && scan_imported_skills
868
869
  confirm_step "Inject agents reference into AI configs" && inject_agents_reference
870
+ confirm_step "Deploy aidevops agents to runtime agent directories" && deploy_agents_to_runtimes
869
871
  confirm_step "Setup Python environment (DSPy, crawl4ai)" && setup_python_env
870
872
  confirm_step "Setup Node.js environment" && setup_nodejs_env
871
873
  confirm_step "Install MCP packages globally (fast startup)" && install_mcp_packages