From f8813a5f6398612573129c496e49cf7c22aa777b Mon Sep 17 00:00:00 2001 From: Ron Tiso Date: Mon, 3 Nov 2025 12:04:49 +0100 Subject: [PATCH] Implement Factory AI droids support in configuration and scripts. Updated config.yml to include factory_ai_droids option, modified common functions and installation scripts to handle droid creation and installation based on this new setting. --- config.yml | 11 +- profiles/default/factory-ai-droid-template.md | 8 + scripts/common-functions.sh | 272 +++++++++++++++++- scripts/project-install.sh | 22 +- scripts/project-update.sh | 34 ++- 5 files changed, 342 insertions(+), 5 deletions(-) create mode 100644 profiles/default/factory-ai-droid-template.md diff --git a/config.yml b/config.yml index b93c982d..23ac6bd6 100644 --- a/config.yml +++ b/config.yml @@ -31,7 +31,7 @@ agent_os_commands: false # # Override this default when running project-install.sh by using the flag --use-claude-code-subagents true/false # ================================================ -use_claude_code_subagents: true +use_claude_code_subagents: false # ================================================ @@ -45,6 +45,15 @@ use_claude_code_subagents: true standards_as_claude_code_skills: false +# ================================================ +# Do you use Factory AI? +# Set to true to install droids in your project's .factory/droids/ folder +# +# Override this default when running project-install.sh by using the flag --factory-ai-droids true/false +# ================================================ +factory_ai_droids: true + + # ================================================ # PROFILE # diff --git a/profiles/default/factory-ai-droid-template.md b/profiles/default/factory-ai-droid-template.md new file mode 100644 index 00000000..7f929de3 --- /dev/null +++ b/profiles/default/factory-ai-droid-template.md @@ -0,0 +1,8 @@ +--- +name: {{agent_name}} +description: {{agent_description}} +model: inherit +tools: {{agent_tools}} +--- + +{{agent_content}} diff --git a/scripts/common-functions.sh b/scripts/common-functions.sh index 3474bfc0..42c0e0d2 100755 --- a/scripts/common-functions.sh +++ b/scripts/common-functions.sh @@ -1186,6 +1186,7 @@ load_base_config() { BASE_USE_CLAUDE_CODE_SUBAGENTS=$(get_yaml_value "$BASE_DIR/config.yml" "use_claude_code_subagents" "true") BASE_AGENT_OS_COMMANDS=$(get_yaml_value "$BASE_DIR/config.yml" "agent_os_commands" "false") BASE_STANDARDS_AS_CLAUDE_CODE_SKILLS=$(get_yaml_value "$BASE_DIR/config.yml" "standards_as_claude_code_skills" "true") + BASE_FACTORY_AI_DROIDS=$(get_yaml_value "$BASE_DIR/config.yml" "factory_ai_droids" "false") # Check for old config flags to set variables for validation MULTI_AGENT_MODE=$(get_yaml_value "$BASE_DIR/config.yml" "multi_agent_mode" "") @@ -1201,6 +1202,7 @@ load_project_config() { PROJECT_USE_CLAUDE_CODE_SUBAGENTS=$(get_project_config "$PROJECT_DIR" "use_claude_code_subagents") PROJECT_AGENT_OS_COMMANDS=$(get_project_config "$PROJECT_DIR" "agent_os_commands") PROJECT_STANDARDS_AS_CLAUDE_CODE_SKILLS=$(get_project_config "$PROJECT_DIR" "standards_as_claude_code_skills") + PROJECT_FACTORY_AI_DROIDS=$(get_project_config "$PROJECT_DIR" "factory_ai_droids") # Check for old config flags to set variables for validation MULTI_AGENT_MODE=$(get_project_config "$PROJECT_DIR" "multi_agent_mode") @@ -1256,6 +1258,7 @@ write_project_config() { local use_claude_code_subagents=$4 local agent_os_commands=$5 local standards_as_claude_code_skills=$6 + local factory_ai_droids=$7 local dest="$PROJECT_DIR/agent-os/config.yml" local config_content="version: $version @@ -1270,7 +1273,8 @@ profile: $profile claude_code_commands: $claude_code_commands use_claude_code_subagents: $use_claude_code_subagents agent_os_commands: $agent_os_commands -standards_as_claude_code_skills: $standards_as_claude_code_skills" +standards_as_claude_code_skills: $standards_as_claude_code_skills +factory_ai_droids: $factory_ai_droids" local result=$(write_file "$config_content" "$dest") if [[ "$DRY_RUN" == "true" ]]; then @@ -1466,3 +1470,269 @@ install_improve_skills_command() { fi fi } + +# ----------------------------------------------------------------------------- +# Factory AI Droid Functions +# ----------------------------------------------------------------------------- + +# Map agent-os tool names to Factory AI tool names +map_tools_to_factory() { + local tools=$1 + # Remove the brackets and split by comma + local tools_array=$(echo "$tools" | sed 's/\[//g' | sed 's/\]//g' | sed 's/, */ /g') + local factory_tools=() + + for tool in $tools_array; do + case "$tool" in + "Write") + # Map Write to standard Factory edit tools + exploration tools + factory_tools+=("Read" "LS" "Grep" "Glob" "Create" "Edit" "MultiEdit") + ;; + "Read") + # Map Read to Factory read-only tools + factory_tools+=("Read" "LS" "Grep" "Glob") + ;; + "Bash") + # Map Bash to Factory Execute + factory_tools+=("Execute") + ;; + "WebFetch") + # Map WebFetch to Factory web tools (but exclude for most droids) + # Don't add by default - let droids that need it specify explicitly + ;; + "Playwright") + # Don't include Playwright tools - not standard Factory tools + # Browsers should be used via WebSearch/FetchUrl instead + ;; + *) + # Pass through any other tool names as-is + factory_tools+=("$tool") + ;; + esac + done + + # Remove duplicates and format as JSON array + local unique_tools=($(echo "${factory_tools[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) + local json_tools="[" + local first=true + for tool in "${unique_tools[@]}"; do + if [[ "$first" == "true" ]]; then + json_tools+="\"$tool\"" + first=false + else + json_tools+=", \"$tool\"" + fi + done + json_tools+="]" + echo "$json_tools" +} + +# Create a Factory AI droid from an agent file +# Args: $1=agent file path (relative to profile, e.g., "agents/implementer.md") +# $2=dest base directory (project directory) +# $3=base directory (~/agent-os) +# $4=profile name +create_factory_droid() { + local agent_file=$1 + local dest_base=$2 + local base_dir=$3 + local profile=$4 + + # Get the full path to the agent file + local source_file=$(get_profile_file "$profile" "$agent_file" "$base_dir") + if [[ ! -f "$source_file" ]]; then + print_error "Agent file not found: $source_file" + return 1 + fi + + # Extract agent name from filename + local agent_name=$(basename "$agent_file" .md) + + # Read the agent file and extract frontmatter + local agent_content=$(cat "$source_file") + local description="" + local tools="" + local model="inherit" + + # Extract frontmatter using awk - extract everything between first and second --- + description=$(awk 'BEGIN{count=0} /^---$/{count++; next} count==1 && /^description:/{sub(/^description:[[:space:]]*/, ""); print; exit}' "$source_file") + tools=$(awk 'BEGIN{count=0} /^---$/{count++; next} count==1 && /^tools:/{sub(/^tools:[[:space:]]*/, ""); print; exit}' "$source_file") + + # Extract content after frontmatter (everything after second ---) + local droid_content=$(echo "$agent_content" | awk '/^---$/ {count++; next} count >= 2 {print}') + + # Compile the droid content (process workflows, standards, conditionals) + # First write to a temp file + local temp_file=$(mktemp) + echo "$droid_content" > "$temp_file" + + # Now compile it + local compiled_content=$(compile_agent "$temp_file" "$temp_file.compiled" "$base_dir" "$profile" "" "") + compiled_content=$(cat "$temp_file.compiled" 2>/dev/null || echo "$droid_content") + rm -f "$temp_file" "$temp_file.compiled" + + # Map tools to Factory AI tool names + local factory_tools=$(map_tools_to_factory "$tools") + + # Get the droid template + local template_file=$(get_profile_file "$profile" "factory-ai-droid-template.md" "$base_dir") + if [[ ! -f "$template_file" ]]; then + print_error "Factory AI droid template not found: $template_file" + return 1 + fi + + # Read template and replace placeholders + local droid_file_content=$(cat "$template_file") + droid_file_content=$(echo "$droid_file_content" | sed "s|{{agent_name}}|$agent_name|g") + droid_file_content=$(echo "$droid_file_content" | sed "s|{{agent_description}}|$description|g") + droid_file_content=$(echo "$droid_file_content" | sed "s|{{agent_tools}}|$factory_tools|g") + + # Replace content placeholder (handle multiline) + local temp_template=$(mktemp) + local temp_content=$(mktemp) + echo "$droid_file_content" > "$temp_template" + echo "$compiled_content" > "$temp_content" + + droid_file_content=$(perl -e ' + use strict; + use warnings; + + my $content_file = $ARGV[0]; + my $template_file = $ARGV[1]; + + # Read compiled content + open(my $fh, "<", $content_file) or die $!; + my $content = do { local $/; <$fh> }; + close($fh); + chomp $content; + + # Read template + open($fh, "<", $template_file) or die $!; + my $template = do { local $/; <$fh> }; + close($fh); + + # Replace placeholder + $template =~ s/\{\{agent_content\}\}/$content/g; + + print $template; + ' "$temp_content" "$temp_template") + + rm -f "$temp_template" "$temp_content" + + # Create droid directory + local droid_dir="$dest_base/.factory/droids" + ensure_dir "$droid_dir" + + # Write droid file + local droid_file="$droid_dir/$agent_name.md" + if [[ "$DRY_RUN" == "true" ]]; then + echo "$droid_file" + else + echo "$droid_file_content" > "$droid_file" + print_verbose "Created Factory AI droid: $droid_file" + fi +} + +# Create a Factory AI command that delegates to a droid +# Args: $1=command file path (relative to profile) +# $2=dest base directory (project directory) +# $3=base directory (~/agent-os) +# $4=profile name +create_factory_command() { + local command_file=$1 + local dest_base=$2 + local base_dir=$3 + local profile=$4 + + # Get the full path to the command file + local source_file=$(get_profile_file "$profile" "$command_file" "$base_dir") + if [[ ! -f "$source_file" ]]; then + print_verbose "Command file not found: $source_file" + return 0 + fi + + # Extract command name from path + # e.g., commands/plan-product/multi-agent/plan-product.md -> plan-product + local command_name=$(echo "$command_file" | cut -d'/' -f2) + + # Create command directory + local command_dir="$dest_base/.factory/commands" + ensure_dir "$command_dir" + + # Compile the command content (process workflows, standards, conditionals) + local temp_file=$(mktemp) + compile_command "$source_file" "$temp_file" "$base_dir" "$profile" "" + local command_content=$(cat "$temp_file") + rm -f "$temp_file" + + # Generate description from command name + local description=$(echo "$command_name" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1') + + # Add YAML frontmatter for Factory AI slash command + local dest_file="$command_dir/$command_name.md" + if [[ "$DRY_RUN" == "true" ]]; then + echo "$dest_file" + else + cat > "$dest_file" << EOF +--- +name: $command_name +description: $description +--- + +$command_content +EOF + print_verbose "Created Factory AI command: $dest_file" + fi +} + +# Install Factory AI droids and commands +install_factory_droids() { + # Only install droids if Factory AI is enabled + if [[ "$EFFECTIVE_FACTORY_AI_DROIDS" != "true" ]]; then + return 0 + fi + + if [[ "$DRY_RUN" != "true" ]]; then + print_status "Installing Factory AI droids and commands..." + fi + + local droids_count=0 + local commands_count=0 + + # Install droids from agent files + while read file; do + if [[ "$file" == agents/* ]] && [[ "$file" == *.md ]]; then + # Create droid from this agent file + create_factory_droid "$file" "$PROJECT_DIR" "$BASE_DIR" "$EFFECTIVE_PROFILE" + + # Track the droid file for dry run + local agent_name=$(basename "$file" .md) + local droid_file="$PROJECT_DIR/.factory/droids/$agent_name.md" + if [[ "$DRY_RUN" == "true" ]]; then + INSTALLED_FILES+=("$droid_file") + fi + ((droids_count++)) || true + fi + done < <(get_profile_files "$EFFECTIVE_PROFILE" "$BASE_DIR" "agents") + + # Install commands (slash commands that delegate to droids) + while read file; do + # Use multi-agent commands for Factory AI (they use Task tool delegation) + if [[ "$file" == commands/*/multi-agent/* ]] || [[ "$file" == commands/orchestrate-tasks/orchestrate-tasks.md ]]; then + create_factory_command "$file" "$PROJECT_DIR" "$BASE_DIR" "$EFFECTIVE_PROFILE" + + if [[ "$DRY_RUN" == "true" ]]; then + local command_name=$(echo "$file" | cut -d'/' -f2) + INSTALLED_FILES+=("$PROJECT_DIR/.factory/commands/$command_name.md") + fi + ((commands_count++)) || true + fi + done < <(get_profile_files "$EFFECTIVE_PROFILE" "$BASE_DIR" "commands") + + if [[ "$DRY_RUN" != "true" ]]; then + if [[ $droids_count -gt 0 ]] || [[ $commands_count -gt 0 ]]; then + echo "✓ Installed $droids_count Factory AI droids and $commands_count commands" + echo -e "${YELLOW} 👉 Enable Custom Droids in Factory AI settings, then use slash commands like /plan-product${NC}" + fi + fi +} diff --git a/scripts/project-install.sh b/scripts/project-install.sh index 295dfae3..b1dbb219 100755 --- a/scripts/project-install.sh +++ b/scripts/project-install.sh @@ -26,6 +26,7 @@ CLAUDE_CODE_COMMANDS="" USE_CLAUDE_CODE_SUBAGENTS="" AGENT_OS_COMMANDS="" STANDARDS_AS_CLAUDE_CODE_SKILLS="" +FACTORY_AI_DROIDS="" RE_INSTALL="false" OVERWRITE_ALL="false" OVERWRITE_STANDARDS="false" @@ -49,6 +50,7 @@ Options: --use-claude-code-subagents [BOOL] Use Claude Code subagents (default: from config.yml) --agent-os-commands [BOOL] Install agent-os commands (default: from config.yml) --standards-as-claude-code-skills [BOOL] Use Claude Code Skills for standards (default: from config.yml) + --factory-ai-droids [BOOL] Install Factory AI droids (default: from config.yml) --re-install Delete and reinstall Agent OS --overwrite-all Overwrite all existing files during update --overwrite-standards Overwrite existing standards during update @@ -100,6 +102,10 @@ parse_arguments() { read STANDARDS_AS_CLAUDE_CODE_SKILLS shift_count <<< "$(parse_bool_flag "$STANDARDS_AS_CLAUDE_CODE_SKILLS" "$2")" shift $shift_count ;; + --factory-ai-droids) + read FACTORY_AI_DROIDS shift_count <<< "$(parse_bool_flag "$FACTORY_AI_DROIDS" "$2")" + shift $shift_count + ;; --re-install) RE_INSTALL="true" shift @@ -153,6 +159,7 @@ load_configuration() { EFFECTIVE_USE_CLAUDE_CODE_SUBAGENTS="${USE_CLAUDE_CODE_SUBAGENTS:-$BASE_USE_CLAUDE_CODE_SUBAGENTS}" EFFECTIVE_AGENT_OS_COMMANDS="${AGENT_OS_COMMANDS:-$BASE_AGENT_OS_COMMANDS}" EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS="${STANDARDS_AS_CLAUDE_CODE_SKILLS:-$BASE_STANDARDS_AS_CLAUDE_CODE_SKILLS}" + EFFECTIVE_FACTORY_AI_DROIDS="${FACTORY_AI_DROIDS:-$BASE_FACTORY_AI_DROIDS}" EFFECTIVE_VERSION="$BASE_VERSION" # Validate configuration using common function (may override EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS if dependency not met) @@ -164,6 +171,7 @@ load_configuration() { print_verbose " Use Claude Code subagents: $EFFECTIVE_USE_CLAUDE_CODE_SUBAGENTS" print_verbose " Agent OS commands: $EFFECTIVE_AGENT_OS_COMMANDS" print_verbose " Standards as Claude Code Skills: $EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS" + print_verbose " Factory AI droids: $EFFECTIVE_FACTORY_AI_DROIDS" } # ----------------------------------------------------------------------------- @@ -375,7 +383,8 @@ create_agent_os_folder() { # Create the configuration file local config_file=$(write_project_config "$EFFECTIVE_VERSION" "$EFFECTIVE_PROFILE" \ "$EFFECTIVE_CLAUDE_CODE_COMMANDS" "$EFFECTIVE_USE_CLAUDE_CODE_SUBAGENTS" \ - "$EFFECTIVE_AGENT_OS_COMMANDS" "$EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS") + "$EFFECTIVE_AGENT_OS_COMMANDS" "$EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS" \ + "$EFFECTIVE_FACTORY_AI_DROIDS") if [[ "$DRY_RUN" == "true" && -n "$config_file" ]]; then INSTALLED_FILES+=("$config_file") fi @@ -422,6 +431,11 @@ perform_installation() { install_improve_skills_command fi + # Install Factory AI droids if enabled + if [[ "$EFFECTIVE_FACTORY_AI_DROIDS" == "true" ]]; then + install_factory_droids + fi + # Install agent-os commands if enabled if [[ "$EFFECTIVE_AGENT_OS_COMMANDS" == "true" ]]; then install_agent_os_commands @@ -458,6 +472,12 @@ perform_installation() { echo "" fi + # Install Factory AI droids if enabled + if [[ "$EFFECTIVE_FACTORY_AI_DROIDS" == "true" ]]; then + install_factory_droids + echo "" + fi + # Install agent-os commands if enabled if [[ "$EFFECTIVE_AGENT_OS_COMMANDS" == "true" ]]; then install_agent_os_commands diff --git a/scripts/project-update.sh b/scripts/project-update.sh index 8da09962..9b8c86d2 100755 --- a/scripts/project-update.sh +++ b/scripts/project-update.sh @@ -26,6 +26,7 @@ CLAUDE_CODE_COMMANDS="" USE_CLAUDE_CODE_SUBAGENTS="" AGENT_OS_COMMANDS="" STANDARDS_AS_CLAUDE_CODE_SKILLS="" +FACTORY_AI_DROIDS="" RE_INSTALL="false" OVERWRITE_ALL="false" OVERWRITE_AGENTS="false" @@ -51,6 +52,7 @@ Options: --use-claude-code-subagents [BOOL] Use Claude Code subagents with delegation (true/false) --agent-os-commands [BOOL] Install agent-os commands for other tools (true/false) --standards-as-claude-code-skills [BOOL] Use Claude Code Skills for standards (true/false) + --factory-ai-droids [BOOL] Install Factory AI droids (true/false) --re-install Delete and reinstall Agent OS --overwrite-all Overwrite all existing files --overwrite-agents Overwrite existing agent files @@ -102,6 +104,10 @@ parse_arguments() { read STANDARDS_AS_CLAUDE_CODE_SKILLS shift_count <<< "$(parse_bool_flag "$STANDARDS_AS_CLAUDE_CODE_SKILLS" "$2")" shift $shift_count ;; + --factory-ai-droids) + read FACTORY_AI_DROIDS shift_count <<< "$(parse_bool_flag "$FACTORY_AI_DROIDS" "$2")" + shift $shift_count + ;; --re-install) RE_INSTALL="true" shift @@ -177,6 +183,7 @@ load_configurations() { EFFECTIVE_USE_CLAUDE_CODE_SUBAGENTS="${USE_CLAUDE_CODE_SUBAGENTS:-$BASE_USE_CLAUDE_CODE_SUBAGENTS}" EFFECTIVE_AGENT_OS_COMMANDS="${AGENT_OS_COMMANDS:-$BASE_AGENT_OS_COMMANDS}" EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS="${STANDARDS_AS_CLAUDE_CODE_SKILLS:-$BASE_STANDARDS_AS_CLAUDE_CODE_SKILLS}" + EFFECTIVE_FACTORY_AI_DROIDS="${FACTORY_AI_DROIDS:-$BASE_FACTORY_AI_DROIDS}" EFFECTIVE_VERSION="$BASE_VERSION" # Validate config but suppress warnings (will show after user confirms update) @@ -189,6 +196,7 @@ load_configurations() { print_verbose " Use Claude Code subagents: $BASE_USE_CLAUDE_CODE_SUBAGENTS" print_verbose " Agent OS commands: $BASE_AGENT_OS_COMMANDS" print_verbose " Standards as Claude Code Skills: $BASE_STANDARDS_AS_CLAUDE_CODE_SKILLS" + print_verbose " Factory AI droids: $BASE_FACTORY_AI_DROIDS" print_verbose "Project configuration:" print_verbose " Version: $PROJECT_VERSION" @@ -197,6 +205,7 @@ load_configurations() { print_verbose " Use Claude Code subagents: $PROJECT_USE_CLAUDE_CODE_SUBAGENTS" print_verbose " Agent OS commands: $PROJECT_AGENT_OS_COMMANDS" print_verbose " Standards as Claude Code Skills: $PROJECT_STANDARDS_AS_CLAUDE_CODE_SKILLS" + print_verbose " Factory AI droids: $PROJECT_FACTORY_AI_DROIDS" print_verbose "Effective configuration:" print_verbose " Profile: $EFFECTIVE_PROFILE" @@ -204,6 +213,7 @@ load_configurations() { print_verbose " Use Claude Code subagents: $EFFECTIVE_USE_CLAUDE_CODE_SUBAGENTS" print_verbose " Agent OS commands: $EFFECTIVE_AGENT_OS_COMMANDS" print_verbose " Standards as Claude Code Skills: $EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS" + print_verbose " Factory AI droids: $EFFECTIVE_FACTORY_AI_DROIDS" } # ----------------------------------------------------------------------------- @@ -561,7 +571,8 @@ update_agent_os_folder() { # Update the configuration file write_project_config "$EFFECTIVE_VERSION" "$PROJECT_PROFILE" \ "$PROJECT_CLAUDE_CODE_COMMANDS" "$PROJECT_USE_CLAUDE_CODE_SUBAGENTS" \ - "$PROJECT_AGENT_OS_COMMANDS" "$PROJECT_STANDARDS_AS_CLAUDE_CODE_SKILLS" + "$PROJECT_AGENT_OS_COMMANDS" "$PROJECT_STANDARDS_AS_CLAUDE_CODE_SKILLS" \ + "$PROJECT_FACTORY_AI_DROIDS" if [[ "$DRY_RUN" != "true" ]]; then echo "✓ Updated agent-os folder" @@ -606,6 +617,12 @@ perform_update() { echo "" fi + # Install/update Factory AI droids if enabled + if [[ "$PROJECT_FACTORY_AI_DROIDS" == "true" ]]; then + install_factory_droids + echo "" + fi + # Update agent-os commands if enabled if [[ "$PROJECT_AGENT_OS_COMMANDS" == "true" ]]; then update_single_agent_commands @@ -763,6 +780,9 @@ prompt_update_confirmation() { if [[ "$EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS" == "true" ]] || [[ -d "$PROJECT_DIR/.claude/skills" ]]; then echo " - .claude/skills/ (Agent OS skills)" fi + if [[ "$EFFECTIVE_FACTORY_AI_DROIDS" == "true" ]] || [[ -d "$PROJECT_DIR/.factory/droids" ]]; then + echo " - .factory/droids/" + fi echo "" read -p "Do you want to proceed? (y/n): " -n 1 -r @@ -840,6 +860,14 @@ perform_update_cleanup() { done < <(get_profile_files "$PROJECT_PROFILE" "$BASE_DIR" "standards") fi + # Delete Factory AI droids directory if exists + if [[ -d "$PROJECT_DIR/.factory/droids" ]]; then + print_status "Removing .factory/droids/" + if [[ "$DRY_RUN" != "true" ]]; then + rm -rf "$PROJECT_DIR/.factory/droids" + fi + fi + # Delete agent-os/roles/ if exists (legacy) if [[ -d "$PROJECT_DIR/agent-os/roles" ]]; then print_status "Removing legacy agent-os/roles/" @@ -888,7 +916,8 @@ main() { [[ "$PROJECT_CLAUDE_CODE_COMMANDS" != "$EFFECTIVE_CLAUDE_CODE_COMMANDS" ]] || \ [[ "$PROJECT_USE_CLAUDE_CODE_SUBAGENTS" != "$EFFECTIVE_USE_CLAUDE_CODE_SUBAGENTS" ]] || \ [[ "$PROJECT_AGENT_OS_COMMANDS" != "$EFFECTIVE_AGENT_OS_COMMANDS" ]] || \ - [[ "$PROJECT_STANDARDS_AS_CLAUDE_CODE_SKILLS" != "$EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS" ]]; then + [[ "$PROJECT_STANDARDS_AS_CLAUDE_CODE_SKILLS" != "$EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS" ]] || \ + [[ "$PROJECT_FACTORY_AI_DROIDS" != "$EFFECTIVE_FACTORY_AI_DROIDS" ]]; then has_config_diff="true" fi @@ -908,6 +937,7 @@ main() { PROJECT_USE_CLAUDE_CODE_SUBAGENTS="$EFFECTIVE_USE_CLAUDE_CODE_SUBAGENTS" PROJECT_AGENT_OS_COMMANDS="$EFFECTIVE_AGENT_OS_COMMANDS" PROJECT_STANDARDS_AS_CLAUDE_CODE_SKILLS="$EFFECTIVE_STANDARDS_AS_CLAUDE_CODE_SKILLS" + PROJECT_FACTORY_AI_DROIDS="$EFFECTIVE_FACTORY_AI_DROIDS" # Proceed with update perform_update