aidevops 2.80.0 → 2.80.1

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 +157 -29
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.80.0
1
+ 2.80.1
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.80.1
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.80.1",
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.80.1
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..."