<!-- SPDX-License-Identifier: MIT -->
<!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->

# setup.sh Function Audit and Module Assignment

**Task**: t316.1  
**Date**: 2026-02-12  
**Total Functions**: 87  
**Lines of Code**: ~5700

## Executive Summary

This audit catalogues all 87 functions in setup.sh, analyzes their dependencies, and proposes a modular decomposition strategy. The current monolithic structure has grown to 5700 lines with complex interdependencies. This document provides the foundation for future refactoring into domain-specific modules.

## Domain Classification

### 1. Core Utilities (9 functions)

**Purpose**: Foundational utilities used across all domains

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `print_info` | 29 | ~70 functions | echo |
| `print_success` | 30 | ~60 functions | echo |
| `print_warning` | 31 | ~50 functions | echo |
| `print_error` | 32 | ~20 functions | echo |
| `run_with_spinner` | 36 | 15 functions | kill, wait |
| `verified_install` | 76 | 4 functions | curl, mktemp, file, chmod |
| `confirm_step` | 201 | main (50+ calls) | read, echo, tr |
| `create_backup_with_rotation` | 246 | 7 functions | mkdir, date, cp, find, wc, sort, head, rm |
| `validate_namespace` | 288 | deploy_aidevops_agents | bash regex |

**Module Recommendation**: `lib/core-utils.sh`  
**Rationale**: Pure utilities with no domain-specific logic, widely reused

---

### 2. Shell Environment (11 functions)

**Purpose**: Shell detection, configuration, and PATH management

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `detect_running_shell` | 1537 | none (future use) | basename |
| `detect_default_shell` | 1550 | 3 functions | basename |
| `get_shell_rc` | 1557 | get_all_shell_rcs | uname |
| `get_all_shell_rcs` | 1595 | 6 functions | uname, touch |
| `setup_oh_my_zsh` | 1626 | main | zsh, chsh |
| `setup_shell_compatibility` | 1698 | main | zsh, bash, grep, chmod |
| `add_local_bin_to_path` | 2754 | install_aidevops_cli | mkdir, touch, grep |
| `install_aidevops_cli` | 2803 | main | bash, chmod, ln |
| `setup_aliases` | 2847 | main | grep, mkdir, touch |
| `setup_terminal_title` | 2951 | main | grep, bash |
| `find_opencode_config` | 138 | 6 functions | none |

**Module Recommendation**: `lib/shell-env.sh`  
**Rationale**: Cohesive shell environment management, minimal cross-domain dependencies

---

### 3. System Bootstrap & Requirements (7 functions)

**Purpose**: Initial system setup, package manager detection, dependency installation

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `bootstrap_repo` | 1049 | main (first step) | uname, brew, curl, git, xcode-select, apt-get, dnf, yum, pacman, apk |
| `detect_package_manager` | 1233 | 8 functions | command (brew, apt-get, dnf, yum, pacman, apk) |
| `install_packages` | 1252 | 6 functions | brew, apt-get, dnf, yum, pacman, apk, sudo |
| `ensure_homebrew` | 1287 | setup_beads | brew, apt-get, dnf, yum, command, eval |
| `check_requirements` | 1366 | main | brew, eval, command (jq, curl, ssh) |
| `check_quality_tools` | 1469 | main | shellcheck, shfmt, command |
| `check_optional_deps` | 1918 | main | command (sshpass) |

**Module Recommendation**: `lib/bootstrap.sh`  
**Rationale**: System-level setup, runs early in setup flow, clear boundaries

> **⚠️ Style Guide Violation — `eval` usage**: `ensure_homebrew` and `check_requirements` both use `eval` (e.g., `eval "$(/opt/homebrew/bin/brew shellenv)"`). The repository style guide explicitly forbids `eval` for security reasons. These must be refactored before or during module extraction. Use `source <(command)` as a safer alternative:
>
> ```bash
> # Instead of:
> eval "$(/opt/homebrew/bin/brew shellenv)"
>
> # Use:
> source <(/opt/homebrew/bin/brew shellenv)
> ```
>
> **Refactoring action**: Update both functions in Phase 1/2 of the refactoring strategy to eliminate `eval`.

---

### 4. Migrations (7 functions)

**Purpose**: Version-to-version migration logic, cleanup of deprecated paths/configs

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `cleanup_deprecated_paths` | 305 | main | rm, jq |
| `migrate_agent_to_agents_folder` | 400 | main | jq, readlink, ln, mv, sed, grep, find |
| `cleanup_deprecated_mcps` | 524 | main | jq, mktemp, sed, grep |
| `disable_ondemand_mcps` | 661 | main | jq, mktemp |
| `migrate_mcp_env_to_credentials` | 838 | main | mv, chmod, ln, sed, grep |
| `migrate_old_backups` | 899 | main | find, wc, mkdir, mv, rm, basename |
| `migrate_loop_state_directories` | 956 | main | find, dirname, mv, cp, rmdir, grep |

**Module Recommendation**: `lib/migrations.sh`  
**Rationale**: Version-specific logic, can be pruned over time, isolated from core setup

**Note**: Migration functions should be versioned (e.g., `migrate_v1_to_v2()`) and removed after 2-3 major releases

---

### 5. Tool Installation (15 functions)

**Purpose**: Installing external tools, CLIs, and development utilities

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `find_python3` | 154 | setup_python_env | python3, command |
| `npm_global_install` | 179 | 6 functions | bun, npm, sudo, uname |
| `setup_git_clis` | 1955 | main | gh, glab, tea |
| `setup_file_discovery_tools` | 2042 | main | fd, fdfind, rg |
| `setup_shell_linting_tools` | 2170 | main | shellcheck, shfmt |
| `setup_rosetta_audit` | 2239 | main | uname, comm, wc, tr |
| `setup_worktrunk` | 2279 | main | wt, brew, cargo |
| `setup_recommended_tools` | 2396 | main | brew, open, xdg-open |
| `setup_minisim` | 2608 | main | xcrun, brew |
| `setup_nodejs` | 4650 | main | node, npm, brew, curl |
| `setup_opencode_cli` | 4771 | main | opencode, bun, npm |
| `setup_orbstack_vm` | 4826 | main | brew, orb |
| `install_beads_binary` | 4266 | setup_beads | curl, tar, install, sudo |
| `install_beads_go` | 4351 | setup_beads | go |
| `setup_beads` | 4364 | main | bd, brew, go |

**Module Recommendation**: `lib/tool-install.sh`  
**Rationale**: Clear domain boundary, can be extended with new tools without touching other modules

---

### 6. MCP Setup (11 functions)

**Purpose**: MCP server installation, configuration, and path resolution

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `setup_python_env` | 3814 | main | python3, pip |
| `setup_nodejs_env` | 3873 | main | node, npm |
| `install_mcp_packages` | 3909 | main | bun, npm, pipx, uv |
| `resolve_mcp_binary_path` | 3981 | 3 functions | command |
| `update_mcp_paths_in_opencode` | 4012 | 2 functions | jq, mktemp, basename |
| `setup_localwp_mcp` | 4100 | main | npm, uname |
| `setup_augment_context_engine` | 4150 | main | node, auggie |
| `setup_osgrep` | 4194 | main | node, osgrep |
| `setup_seo_mcps` | 5040 | main | bash |
| `setup_google_analytics_mcp` | 5078 | main | pipx, python3, jq |
| `setup_quickfile_mcp` | 5185 | main | node, npm, git, jq |

**Module Recommendation**: `lib/mcp-setup.sh`  
**Rationale**: MCP-specific logic, growing domain as more MCPs are added

---

### 7. Agent Deployment (10 functions)

**Purpose**: Deploying agents, templates, skills, and AI-related configurations

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `deploy_ai_templates` | 3023 | main | bash |
| `extract_opencode_prompts` | 3041 | main | bash |
| `check_opencode_prompt_drift` | 3054 | main | bash, cut |
| `deploy_aidevops_agents` | 3076 | main | cd, pwd, jq, rsync, tar, mkdir, find, wc, cp, grep, awk, mv |
| `sanitize_plugin_namespace` | 3274 | 2 functions | basename |
| `deploy_plugins` | 3293 | deploy_aidevops_agents | jq, git, rm, chmod |
| `generate_agent_skills` | 3394 | main | bash |
| `create_skill_symlinks` | 3413 | main | jq, mkdir, ln |
| `check_skill_updates` | 3499 | main | jq, curl, sed |
| `scan_imported_skills` | 3584 | main | uv, pipx, python3, pip3, mkdir, ln, rm |

**Module Recommendation**: `lib/agent-deploy.sh`  
**Rationale**: Agent-specific deployment logic, distinct from general tool installation

---

### 8. Configuration Management (8 functions)

**Purpose**: Managing configs, credentials, and OpenCode integration

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `setup_ssh_key` | 2690 | main | ssh-keygen |
| `setup_configs` | 2711 | main | mkdir, cp |
| `set_permissions` | 2735 | main | chmod, find |
| `validate_opencode_config` | 744 | main | jq, mktemp, command |
| `inject_agents_reference` | 3661 | main | mkdir, head, cat, mv, diff, cp |
| `update_opencode_config` | 3746 | main | bash |
| `verify_location` | 3793 | main | pwd |
| `setup_multi_tenant_credentials` | 5283 | main | bash |

**Module Recommendation**: `lib/config.sh`  
**Rationale**: Configuration-specific logic, clear separation from installation/deployment

---

### 9. Plugins & Skills (2 functions)

**Purpose**: OpenCode plugin management

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `add_opencode_plugin` | 4959 | setup_opencode_plugins | jq, mktemp |
| `setup_opencode_plugins` | 5000 | main | jq |

**Module Recommendation**: `lib/plugins.sh`  
**Rationale**: Plugin-specific logic, small but distinct domain

---

### 10. Specialized Tools (5 functions)

**Purpose**: Domain-specific tool setups (browser, beads UI, AI orchestration)

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `setup_beads_ui` | 4422 | setup_beads | brew, npm, cargo, go |
| `setup_browser_tools` | 4527 | main | bun, node, bash, npx, grep |
| `setup_ai_orchestration` | 4866 | main | python3 |
| `setup_safety_hooks` | 4927 | main | bash |
| `check_tool_updates` | 5347 | main | bash |

**Module Recommendation**: `lib/specialized-tools.sh`  
**Rationale**: Specialized setups that don't fit other categories, can be split further if this grows

---

### 11. Control Flow (2 functions)

**Purpose**: Argument parsing and main orchestration

| Function | Line | Called By | Key Dependencies |
|----------|------|-----------|------------------|
| `parse_args` | 5403 | main | none |
| `main` | 5450 | script execution | 61 functions |

**Module Recommendation**: `setup.sh` (remains as orchestrator)  
**Rationale**: Main entry point should remain in setup.sh, sources modular libraries

---

## Dependency Analysis

### Most Called Functions (Utilities)
1. `print_info` - ~70 callers
2. `print_success` - ~60 callers
3. `print_warning` - ~50 callers
4. `print_error` - ~20 callers
5. `run_with_spinner` - 15 callers
6. `create_backup_with_rotation` - 7 callers
7. `detect_package_manager` - 8 callers
8. `get_all_shell_rcs` - 6 callers

### External Command Dependencies (Top 15)
1. `jq` - JSON processing (20+ functions)
2. `bash` - Script execution (15+ functions)
3. `command` - Availability checks (30+ functions)
4. `grep` - Text search (15+ functions)
5. `mkdir` - Directory creation (15+ functions)
6. `brew` - macOS package manager (10+ functions)
7. `npm` / `bun` - Node package managers (10+ functions)
8. `curl` - Downloads (8+ functions)
9. `git` - Version control (5+ functions)
10. `sed` - Text processing (8+ functions)
11. `find` - File search (8+ functions)
12. `python3` - Python runtime (5+ functions)
13. `node` - Node.js runtime (8+ functions)
14. `chmod` - Permissions (6+ functions)
15. `cp` / `mv` - File operations (10+ functions)

### Dependency Depth
- **Maximum depth**: 4 levels
  - `main` → `setup_beads` → `ensure_homebrew` → `verified_install` → `print_info`
- **Average depth**: 2-3 levels
- **Circular dependencies**: None detected

---

## Module Assignment Table

| Module | Functions | LOC Est. | Dependencies | Priority |
|--------|-----------|----------|--------------|----------|
| `lib/core-utils.sh` | 9 | ~400 | None (base layer) | P0 |
| `lib/shell-env.sh` | 11 | ~650 | core-utils | P1 |
| `lib/bootstrap.sh` | 7 | ~500 | core-utils, shell-env | P0 |
| `lib/migrations.sh` | 7 | ~750 | core-utils, shell-env | P2 |
| `lib/tool-install.sh` | 15 | ~1200 | core-utils, bootstrap | P1 |
| `lib/mcp-setup.sh` | 11 | ~950 | core-utils, tool-install | P1 |
| `lib/agent-deploy.sh` | 10 | ~900 | core-utils, shell-env | P1 |
| `lib/config.sh` | 8 | ~500 | core-utils, shell-env | P1 |
| `lib/plugins.sh` | 2 | ~100 | core-utils, config | P2 |
| `lib/specialized-tools.sh` | 5 | ~450 | core-utils, tool-install | P2 |
| `setup.sh` (orchestrator) | 2 | ~500 | All modules | P0 |

**Total**: 87 functions, ~5700 LOC

---

## Refactoring Strategy

### Phase 1: Extract Core Utilities (P0)
1. Create `lib/core-utils.sh` with 9 utility functions
2. Update setup.sh to source `lib/core-utils.sh`
3. Test: Run full setup.sh in dry-run mode
4. **Benefit**: Reduces main file by ~400 LOC, establishes pattern

### Phase 2: Extract Bootstrap & Shell (P0-P1)
1. Create `lib/bootstrap.sh` (7 functions, ~500 LOC)
2. **Fix `eval` violations**: Replace `eval "$(...)"` with `source <(...)` in `ensure_homebrew` and `check_requirements` (style guide compliance — see note in §3 above)
3. Create `lib/shell-env.sh` (11 functions, ~650 LOC)
4. Update setup.sh to source both
5. Test: Run bootstrap and shell setup steps
6. **Benefit**: Reduces main file by ~1150 LOC, isolates system-level logic, eliminates `eval` security risk

### Phase 3: Extract Domain Modules (P1)
1. Create `lib/tool-install.sh` (15 functions, ~1200 LOC)
2. Create `lib/mcp-setup.sh` (11 functions, ~950 LOC)
3. Create `lib/agent-deploy.sh` (10 functions, ~900 LOC)
4. Create `lib/config.sh` (8 functions, ~500 LOC)
5. Update setup.sh to source all
6. Test: Run full setup with all domains
7. **Benefit**: Reduces main file by ~3550 LOC, clear domain boundaries

### Phase 4: Extract Remaining Modules (P2)
1. Create `lib/migrations.sh` (7 functions, ~750 LOC)
2. Create `lib/plugins.sh` (2 functions, ~100 LOC)
3. Create `lib/specialized-tools.sh` (5 functions, ~450 LOC)
4. Update setup.sh to source all
5. Test: Full integration test
6. **Benefit**: setup.sh reduced to ~500 LOC orchestrator

### Phase 5: Optimization
1. Version migrations (add `migrate_v1_to_v2` naming)
2. Prune old migrations (>2 major versions old)
3. Add module-level documentation
4. Create module dependency graph
5. **Benefit**: Maintainable, documented, modular codebase

---

## Testing Strategy

### Per-Module Tests
- Each module should have a `test-<module>.sh` script
- Test in isolation with mocked dependencies
- Verify all functions are callable
- Check for undefined variable references

### Integration Tests
- Full setup.sh run in Docker container (clean Ubuntu/Debian)
- Full setup.sh run on macOS (via CI)
- Verify all modules are sourced correctly
- Check for function name collisions

### Regression Tests
- Compare output of monolithic vs modular setup.sh
- Verify identical file deployments
- Check identical config modifications
- Ensure same external commands are called

---

## Migration Risks & Mitigations

### Risk 1: Function Name Collisions
**Mitigation**: Prefix module-specific functions (e.g., `mcp_resolve_binary_path`)

### Risk 2: Variable Scope Issues
**Mitigation**: Use `local` for all function variables, document global vars

### Risk 3: Source Order Dependencies
**Mitigation**: Explicit dependency tree in setup.sh, fail fast on missing sources

### Risk 4: Breaking Existing Workflows
**Mitigation**: Keep setup.sh as single entry point, maintain backward compatibility

### Risk 5: Testing Coverage Gaps
**Mitigation**: Incremental rollout with extensive CI testing at each phase

---

## Metrics & Success Criteria

### Code Quality Metrics
- **Current**: 5700 LOC monolithic file
- **Target**: 11 modules averaging 400-500 LOC each
- **Cyclomatic Complexity**: Reduce from ~150 to <20 per module
- **Maintainability Index**: Increase from ~40 to >60

### Developer Experience Metrics
- **Time to understand**: Reduce from ~2 hours to ~30 min per module
- **Time to add new tool**: Reduce from ~1 hour to ~15 min
- **Merge conflict frequency**: Reduce by ~70% (fewer devs editing same file)

### Operational Metrics
- **Setup success rate**: Maintain 100%
- **Setup time**: No regression (±5%)
- **Error clarity**: Improve (module-specific error messages)

---

## Next Steps

1. **Immediate**: Review this audit with team, validate domain boundaries
2. **Week 1**: Implement Phase 1 (core-utils extraction)
3. **Week 2**: Implement Phase 2 (bootstrap + shell-env)
4. **Week 3-4**: Implement Phase 3 (domain modules)
5. **Week 5**: Implement Phase 4 (remaining modules)
6. **Week 6**: Optimization and documentation

---

## Appendix: Function Reference

### Complete Function List (Alphabetical)

```
add_local_bin_to_path (2754)
add_opencode_plugin (4959)
bootstrap_repo (1049)
check_opencode_prompt_drift (3054)
check_optional_deps (1918)
check_quality_tools (1469)
check_requirements (1366)
check_skill_updates (3499)
check_tool_updates (5347)
cleanup_deprecated_mcps (524)
cleanup_deprecated_paths (305)
confirm_step (201)
create_backup_with_rotation (246)
create_skill_symlinks (3413)
deploy_ai_templates (3023)
deploy_aidevops_agents (3076)
deploy_plugins (3293)
detect_default_shell (1550)
detect_package_manager (1233)
detect_running_shell (1537)
disable_ondemand_mcps (661)
ensure_homebrew (1287)
extract_opencode_prompts (3041)
find_opencode_config (138)
find_python3 (154)
generate_agent_skills (3394)
get_all_shell_rcs (1595)
get_shell_rc (1557)
inject_agents_reference (3661)
install_aidevops_cli (2803)
install_beads_binary (4266)
install_beads_go (4351)
install_mcp_packages (3909)
install_packages (1252)
main (5450)
migrate_agent_to_agents_folder (400)
migrate_loop_state_directories (956)
migrate_mcp_env_to_credentials (838)
migrate_old_backups (899)
npm_global_install (179)
parse_args (5403)
print_error (32)
print_info (29)
print_success (30)
print_warning (31)
resolve_mcp_binary_path (3981)
run_with_spinner (36)
sanitize_plugin_namespace (3274)
scan_imported_skills (3584)
set_permissions (2735)
setup_ai_orchestration (4866)
setup_aliases (2847)
setup_augment_context_engine (4150)
setup_beads (4364)
setup_beads_ui (4422)
setup_browser_tools (4527)
setup_configs (2711)
setup_file_discovery_tools (2042)
setup_git_clis (1955)
setup_google_analytics_mcp (5078)
setup_localwp_mcp (4100)
setup_minisim (2608)
setup_multi_tenant_credentials (5283)
setup_nodejs (4650)
setup_nodejs_env (3873)
setup_oh_my_zsh (1626)
setup_opencode_cli (4771)
setup_opencode_plugins (5000)
setup_orbstack_vm (4826)
setup_osgrep (4194)
setup_python_env (3814)
setup_quickfile_mcp (5185)
setup_recommended_tools (2396)
setup_rosetta_audit (2239)
setup_safety_hooks (4927)
setup_seo_mcps (5040)
setup_shell_compatibility (1698)
setup_shell_linting_tools (2170)
setup_ssh_key (2690)
setup_terminal_title (2951)
setup_worktrunk (2279)
update_mcp_paths_in_opencode (4012)
update_opencode_config (3746)
validate_namespace (288)
validate_opencode_config (744)
verified_install (76)
verify_location (3793)
```

---

**Document Version**: 1.0  
**Last Updated**: 2026-02-12  
**Maintainer**: AI DevOps Team
