aidevops 2.80.0 → 2.81.0

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/README.md CHANGED
@@ -92,8 +92,8 @@ The result: AI agents that work *with* your development process, not around it.
92
92
  ### Agent Structure
93
93
 
94
94
  - 18 primary agents (Plan+, Build+, SEO, WordPress, etc.)
95
- - 530+ subagent markdown files organized by domain
96
- - 139+ helper scripts in `.agent/scripts/`
95
+ - 536+ subagent markdown files organized by domain
96
+ - 141+ helper scripts in `.agent/scripts/`
97
97
  - 41 slash commands for common workflows
98
98
 
99
99
  <!-- AI-CONTEXT-END -->
@@ -487,7 +487,7 @@ aidevops implements proven agent design patterns identified by [Lance Martin (La
487
487
 
488
488
  | Pattern | Description | aidevops Implementation |
489
489
  |---------|-------------|------------------------|
490
- | **Give Agents a Computer** | Filesystem + shell for persistent context | `~/.aidevops/.agent-workspace/`, 139+ helper scripts |
490
+ | **Give Agents a Computer** | Filesystem + shell for persistent context | `~/.aidevops/.agent-workspace/`, 141+ helper scripts |
491
491
  | **Multi-Layer Action Space** | Few tools, push actions to computer | Per-agent MCP filtering (~12-20 tools each) |
492
492
  | **Progressive Disclosure** | Load context on-demand | Subagent routing with content summaries, YAML frontmatter, read-on-demand |
493
493
  | **Offload Context** | Write results to filesystem | `.agent-workspace/work/[project]/` for persistence |
@@ -717,7 +717,7 @@ These use direct API calls via curl, avoiding MCP server startup entirely:
717
717
  - [Context7](https://context7.com/) - Real-time documentation access for thousands of libraries
718
718
  - [Repomix](https://github.com/yamadashy/repomix) - Pack codebases into AI-friendly context
719
719
 
720
- **Browser Automation** (6 tools, [benchmarked](#browser-automation)):
720
+ **Browser Automation** (6 tools + anti-detect stack, [benchmarked](#browser-automation)):
721
721
 
722
722
  - [Playwright](https://playwright.dev/) - Fastest engine (0.9s form fill), parallel contexts, extensions, proxy (auto-installed)
723
723
  - [dev-browser](https://github.com/nicholasgriffintn/dev-browser) - Persistent profile, stays logged in, ARIA snapshots, pairs with DevTools
@@ -727,6 +727,11 @@ These use direct API calls via curl, avoiding MCP server startup entirely:
727
727
  - [Stagehand](https://github.com/browserbase/stagehand) - Natural language automation, self-healing selectors
728
728
  - [Chrome DevTools MCP](https://github.com/nicholasgriffintn/chrome-devtools-mcp) - Companion: Lighthouse, network throttling, CSS coverage (pairs with any tool)
729
729
  - [Cloudflare Browser Rendering](https://developers.cloudflare.com/browser-rendering/) - Server-side web scraping
730
+ - **Anti-Detect Stack** ([details](#anti-detect-browser)):
731
+ - [Camoufox](https://github.com/daijro/camoufox) (4.9k stars) - Firefox anti-detect, C++ fingerprint injection, WebRTC/Canvas/WebGL spoofing
732
+ - [rebrowser-patches](https://github.com/nicedayfor/rebrowser-patches) (1.2k stars) - Chromium CDP leak prevention, automation signal removal
733
+ - Multi-profile management - Persistent/clean/warm/disposable profiles (like AdsPower/GoLogin)
734
+ - Proxy integration - Residential, SOCKS5, VPN per profile with geo-targeting
730
735
 
731
736
  **SEO & Research:**
732
737
 
@@ -801,7 +806,7 @@ These catch formatting and syntax issues during editing, reducing preflight/post
801
806
 
802
807
  ## **Browser Automation**
803
808
 
804
- 6 browser tools benchmarked and integrated for AI-assisted web automation, dev testing, and data extraction. Agents automatically select the optimal tool based on task requirements.
809
+ 6 browser tools + anti-detect stack, benchmarked and integrated for AI-assisted web automation, dev testing, data extraction, and bot detection evasion. Agents automatically select the optimal tool based on task requirements.
805
810
 
806
811
  ### Performance Benchmarks
807
812
 
@@ -839,6 +844,8 @@ Tested on macOS ARM64, all headless, warm daemon:
839
844
  | **CLI/CI/CD** | agent-browser | No server needed, `--session` isolation |
840
845
  | **Unknown pages** | Stagehand | Natural language, self-healing |
841
846
  | **Performance debugging** | Chrome DevTools MCP | Companion tool, pairs with any browser |
847
+ | **Bot detection evasion** | Anti-detect stack | Camoufox (full) or rebrowser-patches (quick) |
848
+ | **Multi-account** | Browser profiles | Persistent fingerprint + proxy per account |
842
849
 
843
850
  ### AI Page Understanding
844
851
 
@@ -853,6 +860,57 @@ Agents use lightweight methods instead of expensive vision API calls:
853
860
 
854
861
  See [`.agent/tools/browser/browser-automation.md`](.agent/tools/browser/browser-automation.md) for the full decision tree and [`browser-benchmark.md`](.agent/tools/browser/browser-benchmark.md) for reproducible benchmark scripts.
855
862
 
863
+ ### Anti-Detect Browser
864
+
865
+ Open-source alternative to AdsPower, GoLogin, and OctoBrowser for multi-account automation and bot detection evasion.
866
+
867
+ **Architecture:**
868
+
869
+ ```text
870
+ Layer 4: CAPTCHA Solving → CapSolver (existing)
871
+ Layer 3: Network Identity → Proxies (residential/SOCKS5/VPN per profile)
872
+ Layer 2: Browser Identity → Camoufox (C++ fingerprint injection)
873
+ Layer 1: Automation Stealth → rebrowser-patches (CDP leak prevention)
874
+ Layer 0: Browser Engine → Playwright (existing)
875
+ ```
876
+
877
+ **Profile Types:**
878
+
879
+ | Type | Cookies | Fingerprint | Use Case |
880
+ |------|---------|-------------|----------|
881
+ | **Persistent** | Saved | Fixed per profile | Account management, stay logged in |
882
+ | **Clean** | None | Random each launch | Scraping, one-off tasks |
883
+ | **Warm** | Saved | Fixed | Pre-warmed accounts (browsing history) |
884
+ | **Disposable** | None | Random | Single-use, maximum anonymity |
885
+
886
+ **Quick Start:**
887
+
888
+ ```bash
889
+ # Setup
890
+ anti-detect-helper.sh setup
891
+
892
+ # Create profile with proxy
893
+ anti-detect-helper.sh profile create "my-account" --type persistent --os macos
894
+
895
+ # Launch (Camoufox with auto-generated fingerprint)
896
+ anti-detect-helper.sh launch --profile "my-account" --headless
897
+
898
+ # Test detection (BrowserScan, SannyBot)
899
+ anti-detect-helper.sh test --profile "my-account"
900
+
901
+ # Warm up profile with browsing history
902
+ anti-detect-helper.sh warmup "my-account" --duration 30m
903
+ ```
904
+
905
+ **Engine Selection:**
906
+
907
+ | Engine | Stealth Level | Speed | Best For |
908
+ |--------|---------------|-------|----------|
909
+ | **Camoufox** (Firefox) | High (C++ level) | Medium | Full anti-detect, fingerprint rotation |
910
+ | **rebrowser-patches** (Chromium) | Medium (CDP patches) | Fast | Quick stealth on existing Playwright code |
911
+
912
+ See [`.agent/tools/browser/anti-detect-browser.md`](.agent/tools/browser/anti-detect-browser.md) for the full decision tree and subagent index.
913
+
856
914
  ## **Repomix - AI Context Generation**
857
915
 
858
916
  [Repomix](https://repomix.com/) packages your codebase into AI-friendly formats for sharing with AI assistants. This framework includes optimized Repomix configuration for consistent context generation.
@@ -1078,7 +1136,7 @@ aidevops is registered as a **Claude Code plugin marketplace**. Install with two
1078
1136
  /plugin install aidevops@aidevops
1079
1137
  ```
1080
1138
 
1081
- This installs the complete framework: 18 primary agents, 530+ subagents, and 139+ helper scripts.
1139
+ This installs the complete framework: 18 primary agents, 536+ subagents, and 141+ helper scripts.
1082
1140
 
1083
1141
  ### Importing External Skills
1084
1142
 
@@ -1158,7 +1216,7 @@ Ordered as they appear in OpenCode Tab selector and other AI assistants (15 tota
1158
1216
 
1159
1217
  ### **Example Subagents with MCP Integration**
1160
1218
 
1161
- These are examples of subagents that have supporting MCPs enabled. See `.agent/` for the full list of 530+ subagents organized by domain.
1219
+ These are examples of subagents that have supporting MCPs enabled. See `.agent/` for the full list of 536+ subagents organized by domain.
1162
1220
 
1163
1221
  | Agent | Purpose | MCPs Enabled |
1164
1222
  |-------|---------|--------------|
@@ -1694,7 +1752,8 @@ bash .agent/scripts/continue-cli.sh review
1694
1752
  **Agent Guides** (in `.agent/`):
1695
1753
 
1696
1754
  - **[API Integrations](.agent/aidevops/api-integrations.md)** - Service APIs
1697
- - **[Browser Automation](.agent/tools/browser/browser-automation.md)** - 6 tools benchmarked: decision tree, parallel, extensions, AI understanding
1755
+ - **[Browser Automation](.agent/tools/browser/browser-automation.md)** - 6 tools + anti-detect stack: decision tree, parallel, extensions, fingerprinting
1756
+ - **[Anti-Detect Browser](.agent/tools/browser/anti-detect-browser.md)** - Multi-profile management, fingerprint rotation, proxy integration
1698
1757
  - **[PageSpeed](.agent/tools/browser/pagespeed.md)** - Performance auditing
1699
1758
  - **[Pandoc](.agent/tools/conversion/pandoc.md)** - Document format conversion
1700
1759
  - **[Security](.agent/aidevops/security.md)** - Enterprise security standards
@@ -1710,7 +1769,7 @@ aidevops/
1710
1769
  ├── .agent/ # Agents and documentation
1711
1770
  │ ├── AGENTS.md # User guide (deployed to ~/.aidevops/agents/)
1712
1771
  │ ├── *.md # 18 primary agents
1713
- │ ├── scripts/ # 139+ helper scripts
1772
+ │ ├── scripts/ # 141+ helper scripts
1714
1773
  │ ├── tools/ # Cross-domain utilities (video, browser, git, etc.)
1715
1774
  │ ├── services/ # External service integrations
1716
1775
  │ └── workflows/ # Development process guides
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.80.0
1
+ 2.81.0
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.80.0
6
+ # Version: 2.81.0
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.80.0",
3
+ "version": "2.81.0",
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.80.0
6
+ # Version: 2.81.0
7
7
  #
8
8
  # Quick Install (one-liner):
9
9
  # bash <(curl -fsSL https://aidevops.dev/install)
@@ -228,7 +228,7 @@ cleanup_deprecated_mcps() {
228
228
  jq 'del(.agent.SEO.tools["dataforseo_*"]) | del(.agent.SEO.tools["serper_*"]) | del(.agent.SEO.tools["ahrefs_*"])' "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
229
229
  fi
230
230
 
231
- # Migrate npx/pipx commands to bare binary names (faster startup)
231
+ # Migrate npx/pipx commands to full binary paths (faster startup, PATH-independent)
232
232
  # Maps: package-name -> binary-name
233
233
  local -A mcp_migrations=(
234
234
  ["chrome-devtools-mcp"]="chrome-devtools-mcp"
@@ -242,35 +242,38 @@ cleanup_deprecated_mcps() {
242
242
 
243
243
  for pkg in "${!mcp_migrations[@]}"; do
244
244
  local bin_name="${mcp_migrations[$pkg]}"
245
- # Check if any MCP entry uses npx/bunx with this package
246
- if jq -e ".mcp | to_entries[] | select(.value.command != null) | select(.value.command | join(\" \") | test(\"npx.*${pkg}|bunx.*${pkg}|pipx.*run.*${pkg}\"))" "$tmp_config" > /dev/null 2>&1; then
247
- if command -v "$bin_name" &> /dev/null; then
248
- # Find the MCP key and update its command to bare binary
249
- local mcp_key
250
- mcp_key=$(jq -r ".mcp | to_entries[] | select(.value.command != null) | select(.value.command | join(\" \") | test(\"npx.*${pkg}|bunx.*${pkg}|pipx.*run.*${pkg}\")) | .key" "$tmp_config" 2>/dev/null | head -1)
251
- if [[ -n "$mcp_key" ]]; then
252
- # Preserve --mcp flag for repomix
253
- if [[ "$bin_name" == "repomix" ]]; then
254
- jq ".mcp[\"$mcp_key\"].command = [\"$bin_name\", \"--mcp\"]" "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
255
- else
256
- jq ".mcp[\"$mcp_key\"].command = [\"$bin_name\"]" "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
257
- fi
258
- ((cleaned++))
245
+ # Find MCP key using npx/bunx/pipx for this package (single query)
246
+ local mcp_key
247
+ mcp_key=$(jq -r ".mcp | to_entries[] | select(.value.command != null) | select(.value.command | join(\" \") | test(\"npx.*${pkg}|bunx.*${pkg}|pipx.*run.*${pkg}\")) | .key" "$tmp_config" 2>/dev/null | head -1)
248
+
249
+ if [[ -n "$mcp_key" ]]; then
250
+ # Resolve full path for the binary
251
+ local full_path
252
+ full_path=$(resolve_mcp_binary_path "$bin_name")
253
+ if [[ -n "$full_path" ]]; then
254
+ # Preserve --mcp flag for repomix
255
+ if [[ "$bin_name" == "repomix" ]]; then
256
+ jq --arg k "$mcp_key" --arg p "$full_path" '.mcp[$k].command = [$p, "--mcp"]' "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
257
+ else
258
+ jq --arg k "$mcp_key" --arg p "$full_path" '.mcp[$k].command = [$p]' "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
259
259
  fi
260
+ ((cleaned++))
260
261
  fi
261
262
  fi
262
263
  done
263
264
 
264
- # Migrate outscraper from bash -c wrapper to bare binary
265
+ # Migrate outscraper from bash -c wrapper to full binary path
265
266
  if jq -e '.mcp.outscraper.command | join(" ") | test("bash.*outscraper")' "$tmp_config" > /dev/null 2>&1; then
266
- if command -v outscraper-mcp-server &> /dev/null; then
267
+ local outscraper_path
268
+ outscraper_path=$(resolve_mcp_binary_path "outscraper-mcp-server")
269
+ if [[ -n "$outscraper_path" ]]; then
267
270
  # Source the API key and set it in environment
268
271
  local outscraper_key=""
269
272
  if [[ -f "$HOME/.config/aidevops/mcp-env.sh" ]]; then
270
273
  # shellcheck source=/dev/null
271
274
  outscraper_key=$(source "$HOME/.config/aidevops/mcp-env.sh" && echo "${OUTSCRAPER_API_KEY:-}")
272
275
  fi
273
- jq --arg key "$outscraper_key" '.mcp.outscraper.command = ["outscraper-mcp-server"] | .mcp.outscraper.environment = {"OUTSCRAPER_API_KEY": $key}' "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
276
+ jq --arg p "$outscraper_path" --arg key "$outscraper_key" '.mcp.outscraper.command = [$p] | .mcp.outscraper.environment = {"OUTSCRAPER_API_KEY": $key}' "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
274
277
  ((cleaned++))
275
278
  fi
276
279
  fi
@@ -278,10 +281,13 @@ cleanup_deprecated_mcps() {
278
281
  if [[ $cleaned -gt 0 ]]; then
279
282
  create_backup_with_rotation "$opencode_config" "opencode"
280
283
  mv "$tmp_config" "$opencode_config"
281
- print_info "Updated $cleaned MCP entry/entries in opencode.json (removed npx overhead, using global binaries)"
284
+ print_info "Updated $cleaned MCP entry/entries in opencode.json (using full binary paths)"
282
285
  else
283
286
  rm -f "$tmp_config"
284
287
  fi
288
+
289
+ # Always resolve bare binary names to full paths (fixes PATH-dependent startup)
290
+ update_mcp_paths_in_opencode
285
291
 
286
292
  return 0
287
293
  }
@@ -2136,14 +2142,14 @@ setup_nodejs_env() {
2136
2142
  install_mcp_packages() {
2137
2143
  print_info "Installing MCP server packages globally (eliminates npx startup delay)..."
2138
2144
 
2139
- # Node.js MCP packages (prefer bun, fallback to npm)
2140
- local node_mcps=(
2141
- "chrome-devtools-mcp"
2142
- "mcp-server-gsc"
2143
- "repomix"
2144
- "playwriter"
2145
- "@steipete/macos-automator-mcp"
2146
- "@steipete/claude-code-mcp"
2145
+ # Node.js MCP packages: package-name -> binary-name
2146
+ local -A node_mcps=(
2147
+ ["chrome-devtools-mcp"]="chrome-devtools-mcp"
2148
+ ["mcp-server-gsc"]="mcp-server-gsc"
2149
+ ["repomix"]="repomix"
2150
+ ["playwriter"]="playwriter"
2151
+ ["@steipete/macos-automator-mcp"]="macos-automator-mcp"
2152
+ ["@steipete/claude-code-mcp"]="claude-code-mcp"
2147
2153
  )
2148
2154
 
2149
2155
  local installer=""
@@ -2166,7 +2172,7 @@ install_mcp_packages() {
2166
2172
  # Always install latest (bun install -g is fast and idempotent)
2167
2173
  local updated=0
2168
2174
  local failed=0
2169
- for pkg in "${node_mcps[@]}"; do
2175
+ for pkg in "${!node_mcps[@]}"; do
2170
2176
  if $install_cmd "${pkg}@latest" > /dev/null 2>&1; then
2171
2177
  ((updated++))
2172
2178
  else
@@ -2201,10 +2207,132 @@ install_mcp_packages() {
2201
2207
  fi
2202
2208
  fi
2203
2209
 
2210
+ # Update opencode.json with resolved full paths for all MCP binaries
2211
+ update_mcp_paths_in_opencode
2212
+
2204
2213
  print_info "MCP servers will start instantly (no registry lookups on each launch)"
2205
2214
  return 0
2206
2215
  }
2207
2216
 
2217
+ # Resolve full path for an MCP binary, checking common install locations
2218
+ # Usage: resolve_mcp_binary_path "binary-name"
2219
+ # Returns: full path on stdout, or empty string if not found
2220
+ resolve_mcp_binary_path() {
2221
+ local bin_name="$1"
2222
+ local resolved=""
2223
+
2224
+ # Check common locations in priority order
2225
+ local search_paths=(
2226
+ "$HOME/.bun/bin/$bin_name"
2227
+ "/opt/homebrew/bin/$bin_name"
2228
+ "/usr/local/bin/$bin_name"
2229
+ "$HOME/.local/bin/$bin_name"
2230
+ "$HOME/.npm-global/bin/$bin_name"
2231
+ )
2232
+
2233
+ for path in "${search_paths[@]}"; do
2234
+ if [[ -x "$path" ]]; then
2235
+ resolved="$path"
2236
+ break
2237
+ fi
2238
+ done
2239
+
2240
+ # Fallback: use command -v if in PATH (portable, POSIX-compliant)
2241
+ if [[ -z "$resolved" ]]; then
2242
+ resolved=$(command -v "$bin_name" 2>/dev/null || true)
2243
+ fi
2244
+
2245
+ echo "$resolved"
2246
+ return 0
2247
+ }
2248
+
2249
+ # Update opencode.json MCP commands to use full binary paths
2250
+ # This ensures MCPs start regardless of PATH configuration
2251
+ update_mcp_paths_in_opencode() {
2252
+ local opencode_config="$HOME/.config/opencode/opencode.json"
2253
+
2254
+ if [[ ! -f "$opencode_config" ]]; then
2255
+ return 0
2256
+ fi
2257
+
2258
+ if ! command -v jq &> /dev/null; then
2259
+ return 0
2260
+ fi
2261
+
2262
+ local tmp_config
2263
+ tmp_config=$(mktemp)
2264
+ cp "$opencode_config" "$tmp_config"
2265
+
2266
+ local updated=0
2267
+
2268
+ # Get all MCP entries with local commands
2269
+ local mcp_keys
2270
+ mcp_keys=$(jq -r '.mcp | to_entries[] | select(.value.type == "local") | select(.value.command != null) | .key' "$tmp_config" 2>/dev/null)
2271
+
2272
+ while IFS= read -r mcp_key; do
2273
+ [[ -z "$mcp_key" ]] && continue
2274
+
2275
+ # Get the first element of the command array (the binary)
2276
+ local current_cmd
2277
+ current_cmd=$(jq -r --arg k "$mcp_key" '.mcp[$k].command[0]' "$tmp_config" 2>/dev/null)
2278
+
2279
+ # Skip if already a full path
2280
+ if [[ "$current_cmd" == /* ]]; then
2281
+ # Verify the path still exists
2282
+ if [[ ! -x "$current_cmd" ]]; then
2283
+ # Path is stale, try to resolve
2284
+ local bin_name
2285
+ bin_name=$(basename "$current_cmd")
2286
+ local new_path
2287
+ new_path=$(resolve_mcp_binary_path "$bin_name")
2288
+ if [[ -n "$new_path" && "$new_path" != "$current_cmd" ]]; then
2289
+ jq --arg k "$mcp_key" --arg p "$new_path" '.mcp[$k].command[0] = $p' "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
2290
+ ((updated++))
2291
+ fi
2292
+ fi
2293
+ continue
2294
+ fi
2295
+
2296
+ # Skip docker (container runtime) and node (resolved separately below)
2297
+ case "$current_cmd" in
2298
+ docker|node) continue ;;
2299
+ esac
2300
+
2301
+ # Resolve the full path
2302
+ local full_path
2303
+ full_path=$(resolve_mcp_binary_path "$current_cmd")
2304
+
2305
+ if [[ -n "$full_path" && "$full_path" != "$current_cmd" ]]; then
2306
+ jq --arg k "$mcp_key" --arg p "$full_path" '.mcp[$k].command[0] = $p' "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
2307
+ ((updated++))
2308
+ fi
2309
+ done <<< "$mcp_keys"
2310
+
2311
+ # Also resolve 'node' commands (e.g., quickfile, amazon-order-history)
2312
+ # These use ["node", "/path/to/index.js"] - node itself should be resolved
2313
+ local node_path
2314
+ node_path=$(resolve_mcp_binary_path "node")
2315
+ if [[ -n "$node_path" ]]; then
2316
+ local node_mcp_keys
2317
+ node_mcp_keys=$(jq -r '.mcp | to_entries[] | select(.value.type == "local") | select(.value.command != null) | select(.value.command[0] == "node") | .key' "$tmp_config" 2>/dev/null)
2318
+ while IFS= read -r mcp_key; do
2319
+ [[ -z "$mcp_key" ]] && continue
2320
+ jq --arg k "$mcp_key" --arg p "$node_path" '.mcp[$k].command[0] = $p' "$tmp_config" > "${tmp_config}.new" && mv "${tmp_config}.new" "$tmp_config"
2321
+ ((updated++))
2322
+ done <<< "$node_mcp_keys"
2323
+ fi
2324
+
2325
+ if [[ $updated -gt 0 ]]; then
2326
+ create_backup_with_rotation "$opencode_config" "opencode"
2327
+ mv "$tmp_config" "$opencode_config"
2328
+ print_success "Updated $updated MCP commands to use full binary paths in opencode.json"
2329
+ else
2330
+ rm -f "$tmp_config"
2331
+ fi
2332
+
2333
+ return 0
2334
+ }
2335
+
2208
2336
  # Setup LocalWP MCP server for AI database access
2209
2337
  setup_localwp_mcp() {
2210
2338
  print_info "Setting up LocalWP MCP server..."