aidevops 2.52.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 (329) hide show
  1. package/.agent/AGENTS.md +614 -0
  2. package/.agent/accounts.md +65 -0
  3. package/.agent/aidevops/add-new-mcp-to-aidevops.md +456 -0
  4. package/.agent/aidevops/api-integrations.md +335 -0
  5. package/.agent/aidevops/architecture.md +510 -0
  6. package/.agent/aidevops/configs.md +274 -0
  7. package/.agent/aidevops/docs.md +244 -0
  8. package/.agent/aidevops/extension.md +311 -0
  9. package/.agent/aidevops/mcp-integrations.md +340 -0
  10. package/.agent/aidevops/mcp-troubleshooting.md +162 -0
  11. package/.agent/aidevops/memory-patterns.md +172 -0
  12. package/.agent/aidevops/providers.md +217 -0
  13. package/.agent/aidevops/recommendations.md +321 -0
  14. package/.agent/aidevops/requirements.md +301 -0
  15. package/.agent/aidevops/resources.md +214 -0
  16. package/.agent/aidevops/security-requirements.md +174 -0
  17. package/.agent/aidevops/security.md +350 -0
  18. package/.agent/aidevops/service-links.md +400 -0
  19. package/.agent/aidevops/services.md +357 -0
  20. package/.agent/aidevops/setup.md +153 -0
  21. package/.agent/aidevops/troubleshooting.md +389 -0
  22. package/.agent/aidevops.md +124 -0
  23. package/.agent/build-plus.md +244 -0
  24. package/.agent/content/guidelines.md +109 -0
  25. package/.agent/content.md +87 -0
  26. package/.agent/health.md +59 -0
  27. package/.agent/legal.md +59 -0
  28. package/.agent/loop-state/full-loop.local.md +16 -0
  29. package/.agent/loop-state/ralph-loop.local.md +10 -0
  30. package/.agent/marketing.md +440 -0
  31. package/.agent/memory/README.md +260 -0
  32. package/.agent/onboarding.md +796 -0
  33. package/.agent/plan-plus.md +245 -0
  34. package/.agent/research.md +100 -0
  35. package/.agent/sales.md +333 -0
  36. package/.agent/scripts/101domains-helper.sh +701 -0
  37. package/.agent/scripts/add-missing-returns.sh +140 -0
  38. package/.agent/scripts/agent-browser-helper.sh +311 -0
  39. package/.agent/scripts/agno-setup.sh +712 -0
  40. package/.agent/scripts/ahrefs-mcp-wrapper.js +168 -0
  41. package/.agent/scripts/aidevops-update-check.sh +71 -0
  42. package/.agent/scripts/ampcode-cli.sh +522 -0
  43. package/.agent/scripts/auto-version-bump.sh +156 -0
  44. package/.agent/scripts/autogen-helper.sh +512 -0
  45. package/.agent/scripts/beads-sync-helper.sh +596 -0
  46. package/.agent/scripts/closte-helper.sh +5 -0
  47. package/.agent/scripts/cloudron-helper.sh +321 -0
  48. package/.agent/scripts/codacy-cli-chunked.sh +581 -0
  49. package/.agent/scripts/codacy-cli.sh +442 -0
  50. package/.agent/scripts/code-audit-helper.sh +5 -0
  51. package/.agent/scripts/coderabbit-cli.sh +417 -0
  52. package/.agent/scripts/coderabbit-pro-analysis.sh +238 -0
  53. package/.agent/scripts/commands/code-simplifier.md +86 -0
  54. package/.agent/scripts/commands/full-loop.md +246 -0
  55. package/.agent/scripts/commands/postflight-loop.md +103 -0
  56. package/.agent/scripts/commands/recall.md +182 -0
  57. package/.agent/scripts/commands/remember.md +132 -0
  58. package/.agent/scripts/commands/save-todo.md +175 -0
  59. package/.agent/scripts/commands/session-review.md +154 -0
  60. package/.agent/scripts/comprehensive-quality-fix.sh +106 -0
  61. package/.agent/scripts/context-builder-helper.sh +522 -0
  62. package/.agent/scripts/coolify-cli-helper.sh +674 -0
  63. package/.agent/scripts/coolify-helper.sh +380 -0
  64. package/.agent/scripts/crawl4ai-examples.sh +401 -0
  65. package/.agent/scripts/crawl4ai-helper.sh +1078 -0
  66. package/.agent/scripts/crewai-helper.sh +681 -0
  67. package/.agent/scripts/dev-browser-helper.sh +513 -0
  68. package/.agent/scripts/dns-helper.sh +396 -0
  69. package/.agent/scripts/domain-research-helper.sh +917 -0
  70. package/.agent/scripts/dspy-helper.sh +285 -0
  71. package/.agent/scripts/dspyground-helper.sh +291 -0
  72. package/.agent/scripts/eeat-score-helper.sh +1242 -0
  73. package/.agent/scripts/efficient-return-fix.sh +92 -0
  74. package/.agent/scripts/extract-opencode-prompts.sh +128 -0
  75. package/.agent/scripts/find-missing-returns.sh +113 -0
  76. package/.agent/scripts/fix-auth-headers.sh +104 -0
  77. package/.agent/scripts/fix-common-strings.sh +254 -0
  78. package/.agent/scripts/fix-content-type.sh +100 -0
  79. package/.agent/scripts/fix-error-messages.sh +130 -0
  80. package/.agent/scripts/fix-misplaced-returns.sh +74 -0
  81. package/.agent/scripts/fix-remaining-literals.sh +152 -0
  82. package/.agent/scripts/fix-return-statements.sh +41 -0
  83. package/.agent/scripts/fix-s131-default-cases.sh +249 -0
  84. package/.agent/scripts/fix-sc2155-simple.sh +102 -0
  85. package/.agent/scripts/fix-shellcheck-critical.sh +187 -0
  86. package/.agent/scripts/fix-string-literals.sh +273 -0
  87. package/.agent/scripts/full-loop-helper.sh +773 -0
  88. package/.agent/scripts/generate-opencode-agents.sh +497 -0
  89. package/.agent/scripts/generate-opencode-commands.sh +1629 -0
  90. package/.agent/scripts/generate-skills.sh +366 -0
  91. package/.agent/scripts/git-platforms-helper.sh +640 -0
  92. package/.agent/scripts/gitea-cli-helper.sh +743 -0
  93. package/.agent/scripts/github-cli-helper.sh +702 -0
  94. package/.agent/scripts/gitlab-cli-helper.sh +682 -0
  95. package/.agent/scripts/gsc-add-user-helper.sh +325 -0
  96. package/.agent/scripts/gsc-sitemap-helper.sh +678 -0
  97. package/.agent/scripts/hetzner-helper.sh +485 -0
  98. package/.agent/scripts/hostinger-helper.sh +229 -0
  99. package/.agent/scripts/keyword-research-helper.sh +1815 -0
  100. package/.agent/scripts/langflow-helper.sh +544 -0
  101. package/.agent/scripts/linkedin-automation.py +241 -0
  102. package/.agent/scripts/linter-manager.sh +599 -0
  103. package/.agent/scripts/linters-local.sh +434 -0
  104. package/.agent/scripts/list-keys-helper.sh +488 -0
  105. package/.agent/scripts/local-browser-automation.py +339 -0
  106. package/.agent/scripts/localhost-helper.sh +744 -0
  107. package/.agent/scripts/loop-common.sh +806 -0
  108. package/.agent/scripts/mainwp-helper.sh +728 -0
  109. package/.agent/scripts/markdown-formatter.sh +338 -0
  110. package/.agent/scripts/markdown-lint-fix.sh +311 -0
  111. package/.agent/scripts/mass-fix-returns.sh +58 -0
  112. package/.agent/scripts/mcp-diagnose.sh +167 -0
  113. package/.agent/scripts/mcp-inspector-helper.sh +449 -0
  114. package/.agent/scripts/memory-helper.sh +650 -0
  115. package/.agent/scripts/monitor-code-review.sh +255 -0
  116. package/.agent/scripts/onboarding-helper.sh +706 -0
  117. package/.agent/scripts/opencode-github-setup-helper.sh +797 -0
  118. package/.agent/scripts/opencode-test-helper.sh +213 -0
  119. package/.agent/scripts/pagespeed-helper.sh +464 -0
  120. package/.agent/scripts/pandoc-helper.sh +362 -0
  121. package/.agent/scripts/postflight-check.sh +555 -0
  122. package/.agent/scripts/pre-commit-hook.sh +259 -0
  123. package/.agent/scripts/pre-edit-check.sh +169 -0
  124. package/.agent/scripts/qlty-cli.sh +356 -0
  125. package/.agent/scripts/quality-cli-manager.sh +525 -0
  126. package/.agent/scripts/quality-feedback-helper.sh +462 -0
  127. package/.agent/scripts/quality-fix.sh +263 -0
  128. package/.agent/scripts/quality-loop-helper.sh +1108 -0
  129. package/.agent/scripts/ralph-loop-helper.sh +836 -0
  130. package/.agent/scripts/ralph-upstream-check.sh +341 -0
  131. package/.agent/scripts/secretlint-helper.sh +847 -0
  132. package/.agent/scripts/servers-helper.sh +241 -0
  133. package/.agent/scripts/ses-helper.sh +619 -0
  134. package/.agent/scripts/session-review-helper.sh +404 -0
  135. package/.agent/scripts/setup-linters-wizard.sh +379 -0
  136. package/.agent/scripts/setup-local-api-keys.sh +330 -0
  137. package/.agent/scripts/setup-mcp-integrations.sh +472 -0
  138. package/.agent/scripts/shared-constants.sh +246 -0
  139. package/.agent/scripts/site-crawler-helper.sh +1487 -0
  140. package/.agent/scripts/snyk-helper.sh +940 -0
  141. package/.agent/scripts/sonarcloud-autofix.sh +193 -0
  142. package/.agent/scripts/sonarcloud-cli.sh +191 -0
  143. package/.agent/scripts/sonarscanner-cli.sh +455 -0
  144. package/.agent/scripts/spaceship-helper.sh +747 -0
  145. package/.agent/scripts/stagehand-helper.sh +321 -0
  146. package/.agent/scripts/stagehand-python-helper.sh +321 -0
  147. package/.agent/scripts/stagehand-python-setup.sh +441 -0
  148. package/.agent/scripts/stagehand-setup.sh +439 -0
  149. package/.agent/scripts/system-cleanup.sh +340 -0
  150. package/.agent/scripts/terminal-title-helper.sh +388 -0
  151. package/.agent/scripts/terminal-title-setup.sh +549 -0
  152. package/.agent/scripts/test-stagehand-both-integration.sh +317 -0
  153. package/.agent/scripts/test-stagehand-integration.sh +309 -0
  154. package/.agent/scripts/test-stagehand-python-integration.sh +341 -0
  155. package/.agent/scripts/todo-ready.sh +263 -0
  156. package/.agent/scripts/tool-version-check.sh +362 -0
  157. package/.agent/scripts/toon-helper.sh +469 -0
  158. package/.agent/scripts/twilio-helper.sh +917 -0
  159. package/.agent/scripts/updown-helper.sh +279 -0
  160. package/.agent/scripts/validate-mcp-integrations.sh +250 -0
  161. package/.agent/scripts/validate-version-consistency.sh +131 -0
  162. package/.agent/scripts/vaultwarden-helper.sh +597 -0
  163. package/.agent/scripts/vercel-cli-helper.sh +816 -0
  164. package/.agent/scripts/verify-mirrors.sh +169 -0
  165. package/.agent/scripts/version-manager.sh +831 -0
  166. package/.agent/scripts/webhosting-helper.sh +471 -0
  167. package/.agent/scripts/webhosting-verify.sh +238 -0
  168. package/.agent/scripts/wordpress-mcp-helper.sh +508 -0
  169. package/.agent/scripts/worktree-helper.sh +595 -0
  170. package/.agent/scripts/worktree-sessions.sh +577 -0
  171. package/.agent/seo/dataforseo.md +215 -0
  172. package/.agent/seo/domain-research.md +532 -0
  173. package/.agent/seo/eeat-score.md +659 -0
  174. package/.agent/seo/google-search-console.md +366 -0
  175. package/.agent/seo/gsc-sitemaps.md +282 -0
  176. package/.agent/seo/keyword-research.md +521 -0
  177. package/.agent/seo/serper.md +278 -0
  178. package/.agent/seo/site-crawler.md +387 -0
  179. package/.agent/seo.md +236 -0
  180. package/.agent/services/accounting/quickfile.md +159 -0
  181. package/.agent/services/communications/telfon.md +470 -0
  182. package/.agent/services/communications/twilio.md +569 -0
  183. package/.agent/services/crm/fluentcrm.md +449 -0
  184. package/.agent/services/email/ses.md +399 -0
  185. package/.agent/services/hosting/101domains.md +378 -0
  186. package/.agent/services/hosting/closte.md +177 -0
  187. package/.agent/services/hosting/cloudflare.md +251 -0
  188. package/.agent/services/hosting/cloudron.md +478 -0
  189. package/.agent/services/hosting/dns-providers.md +335 -0
  190. package/.agent/services/hosting/domain-purchasing.md +344 -0
  191. package/.agent/services/hosting/hetzner.md +327 -0
  192. package/.agent/services/hosting/hostinger.md +287 -0
  193. package/.agent/services/hosting/localhost.md +419 -0
  194. package/.agent/services/hosting/spaceship.md +353 -0
  195. package/.agent/services/hosting/webhosting.md +330 -0
  196. package/.agent/social-media.md +69 -0
  197. package/.agent/templates/plans-template.md +114 -0
  198. package/.agent/templates/prd-template.md +129 -0
  199. package/.agent/templates/tasks-template.md +108 -0
  200. package/.agent/templates/todo-template.md +89 -0
  201. package/.agent/tools/ai-assistants/agno.md +471 -0
  202. package/.agent/tools/ai-assistants/capsolver.md +326 -0
  203. package/.agent/tools/ai-assistants/configuration.md +221 -0
  204. package/.agent/tools/ai-assistants/overview.md +209 -0
  205. package/.agent/tools/ai-assistants/status.md +171 -0
  206. package/.agent/tools/ai-assistants/windsurf.md +193 -0
  207. package/.agent/tools/ai-orchestration/autogen.md +406 -0
  208. package/.agent/tools/ai-orchestration/crewai.md +445 -0
  209. package/.agent/tools/ai-orchestration/langflow.md +405 -0
  210. package/.agent/tools/ai-orchestration/openprose.md +487 -0
  211. package/.agent/tools/ai-orchestration/overview.md +362 -0
  212. package/.agent/tools/ai-orchestration/packaging.md +647 -0
  213. package/.agent/tools/browser/agent-browser.md +464 -0
  214. package/.agent/tools/browser/browser-automation.md +400 -0
  215. package/.agent/tools/browser/chrome-devtools.md +282 -0
  216. package/.agent/tools/browser/crawl4ai-integration.md +422 -0
  217. package/.agent/tools/browser/crawl4ai-resources.md +277 -0
  218. package/.agent/tools/browser/crawl4ai-usage.md +416 -0
  219. package/.agent/tools/browser/crawl4ai.md +585 -0
  220. package/.agent/tools/browser/dev-browser.md +341 -0
  221. package/.agent/tools/browser/pagespeed.md +260 -0
  222. package/.agent/tools/browser/playwright.md +266 -0
  223. package/.agent/tools/browser/playwriter.md +310 -0
  224. package/.agent/tools/browser/stagehand-examples.md +456 -0
  225. package/.agent/tools/browser/stagehand-python.md +483 -0
  226. package/.agent/tools/browser/stagehand.md +421 -0
  227. package/.agent/tools/build-agent/agent-review.md +224 -0
  228. package/.agent/tools/build-agent/build-agent.md +784 -0
  229. package/.agent/tools/build-mcp/aidevops-plugin.md +476 -0
  230. package/.agent/tools/build-mcp/api-wrapper.md +445 -0
  231. package/.agent/tools/build-mcp/build-mcp.md +240 -0
  232. package/.agent/tools/build-mcp/deployment.md +401 -0
  233. package/.agent/tools/build-mcp/server-patterns.md +632 -0
  234. package/.agent/tools/build-mcp/transports.md +366 -0
  235. package/.agent/tools/code-review/auditing.md +383 -0
  236. package/.agent/tools/code-review/automation.md +219 -0
  237. package/.agent/tools/code-review/best-practices.md +203 -0
  238. package/.agent/tools/code-review/codacy.md +151 -0
  239. package/.agent/tools/code-review/code-simplifier.md +174 -0
  240. package/.agent/tools/code-review/code-standards.md +309 -0
  241. package/.agent/tools/code-review/coderabbit.md +101 -0
  242. package/.agent/tools/code-review/management.md +155 -0
  243. package/.agent/tools/code-review/qlty.md +248 -0
  244. package/.agent/tools/code-review/secretlint.md +565 -0
  245. package/.agent/tools/code-review/setup.md +250 -0
  246. package/.agent/tools/code-review/snyk.md +563 -0
  247. package/.agent/tools/code-review/tools.md +230 -0
  248. package/.agent/tools/content/summarize.md +353 -0
  249. package/.agent/tools/context/augment-context-engine.md +468 -0
  250. package/.agent/tools/context/context-builder-agent.md +76 -0
  251. package/.agent/tools/context/context-builder.md +375 -0
  252. package/.agent/tools/context/context7.md +371 -0
  253. package/.agent/tools/context/dspy.md +302 -0
  254. package/.agent/tools/context/dspyground.md +374 -0
  255. package/.agent/tools/context/llm-tldr.md +219 -0
  256. package/.agent/tools/context/osgrep.md +488 -0
  257. package/.agent/tools/context/prompt-optimization.md +338 -0
  258. package/.agent/tools/context/toon.md +292 -0
  259. package/.agent/tools/conversion/pandoc.md +304 -0
  260. package/.agent/tools/credentials/api-key-management.md +154 -0
  261. package/.agent/tools/credentials/api-key-setup.md +224 -0
  262. package/.agent/tools/credentials/environment-variables.md +180 -0
  263. package/.agent/tools/credentials/vaultwarden.md +382 -0
  264. package/.agent/tools/data-extraction/outscraper.md +974 -0
  265. package/.agent/tools/deployment/coolify-cli.md +388 -0
  266. package/.agent/tools/deployment/coolify-setup.md +353 -0
  267. package/.agent/tools/deployment/coolify.md +345 -0
  268. package/.agent/tools/deployment/vercel.md +390 -0
  269. package/.agent/tools/git/authentication.md +132 -0
  270. package/.agent/tools/git/gitea-cli.md +193 -0
  271. package/.agent/tools/git/github-actions.md +207 -0
  272. package/.agent/tools/git/github-cli.md +223 -0
  273. package/.agent/tools/git/gitlab-cli.md +190 -0
  274. package/.agent/tools/git/opencode-github-security.md +350 -0
  275. package/.agent/tools/git/opencode-github.md +328 -0
  276. package/.agent/tools/git/opencode-gitlab.md +252 -0
  277. package/.agent/tools/git/security.md +196 -0
  278. package/.agent/tools/git.md +207 -0
  279. package/.agent/tools/opencode/oh-my-opencode.md +375 -0
  280. package/.agent/tools/opencode/opencode-anthropic-auth.md +446 -0
  281. package/.agent/tools/opencode/opencode.md +651 -0
  282. package/.agent/tools/social-media/bird.md +437 -0
  283. package/.agent/tools/task-management/beads.md +336 -0
  284. package/.agent/tools/terminal/terminal-title.md +251 -0
  285. package/.agent/tools/ui/shadcn.md +196 -0
  286. package/.agent/tools/ui/ui-skills.md +115 -0
  287. package/.agent/tools/wordpress/localwp.md +311 -0
  288. package/.agent/tools/wordpress/mainwp.md +391 -0
  289. package/.agent/tools/wordpress/scf.md +527 -0
  290. package/.agent/tools/wordpress/wp-admin.md +729 -0
  291. package/.agent/tools/wordpress/wp-dev.md +940 -0
  292. package/.agent/tools/wordpress/wp-preferred.md +398 -0
  293. package/.agent/tools/wordpress.md +95 -0
  294. package/.agent/workflows/branch/bugfix.md +63 -0
  295. package/.agent/workflows/branch/chore.md +95 -0
  296. package/.agent/workflows/branch/experiment.md +115 -0
  297. package/.agent/workflows/branch/feature.md +59 -0
  298. package/.agent/workflows/branch/hotfix.md +98 -0
  299. package/.agent/workflows/branch/refactor.md +92 -0
  300. package/.agent/workflows/branch/release.md +96 -0
  301. package/.agent/workflows/branch.md +347 -0
  302. package/.agent/workflows/bug-fixing.md +267 -0
  303. package/.agent/workflows/changelog.md +129 -0
  304. package/.agent/workflows/code-audit-remote.md +279 -0
  305. package/.agent/workflows/conversation-starter.md +69 -0
  306. package/.agent/workflows/error-feedback.md +578 -0
  307. package/.agent/workflows/feature-development.md +355 -0
  308. package/.agent/workflows/git-workflow.md +702 -0
  309. package/.agent/workflows/multi-repo-workspace.md +268 -0
  310. package/.agent/workflows/plans.md +709 -0
  311. package/.agent/workflows/postflight.md +604 -0
  312. package/.agent/workflows/pr.md +571 -0
  313. package/.agent/workflows/preflight.md +278 -0
  314. package/.agent/workflows/ralph-loop.md +773 -0
  315. package/.agent/workflows/release.md +498 -0
  316. package/.agent/workflows/session-manager.md +254 -0
  317. package/.agent/workflows/session-review.md +311 -0
  318. package/.agent/workflows/sql-migrations.md +631 -0
  319. package/.agent/workflows/version-bump.md +283 -0
  320. package/.agent/workflows/wiki-update.md +333 -0
  321. package/.agent/workflows/worktree.md +477 -0
  322. package/LICENSE +21 -0
  323. package/README.md +1446 -0
  324. package/VERSION +1 -0
  325. package/aidevops.sh +1746 -0
  326. package/bin/aidevops +21 -0
  327. package/package.json +75 -0
  328. package/scripts/npm-postinstall.js +60 -0
  329. package/setup.sh +2366 -0
@@ -0,0 +1,744 @@
1
+ #!/bin/bash
2
+ # shellcheck disable=SC2034,SC2155,SC2317,SC2329,SC2016,SC2181,SC1091,SC2154,SC2015,SC2086,SC2129,SC2030,SC2031,SC2119,SC2120,SC2001,SC2162,SC2088,SC2089,SC2090,SC2029,SC2006,SC2153
3
+
4
+ # Localhost Development Helper Script
5
+ # Sets up local Docker apps with .local domains and SSL certificates
6
+
7
+ # Source shared constants if available
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ source "$SCRIPT_DIR/shared-constants.sh" 2>/dev/null || true
10
+
11
+ # Colors for output
12
+ GREEN='\033[0;32m'
13
+ BLUE='\033[0;34m'
14
+ YELLOW='\033[1;33m'
15
+ RED='\033[0;31m'
16
+ NC='\033[0m' # No Color
17
+
18
+ # Error message constants (use shared-constants.sh if available, otherwise define locally)
19
+ if [[ -z "${ERROR_UNKNOWN_COMMAND:-}" ]]; then
20
+ readonly ERROR_UNKNOWN_COMMAND="Unknown command:"
21
+ fi
22
+ if [[ -z "${HELP_USAGE_INFO:-}" ]]; then
23
+ readonly HELP_USAGE_INFO="Use '$0 help' for usage information"
24
+ fi
25
+
26
+ print_info() {
27
+ local msg="$1"
28
+ echo -e "${BLUE}[INFO]${NC} $msg"
29
+ return 0
30
+ }
31
+
32
+ print_success() {
33
+ local msg="$1"
34
+ echo -e "${GREEN}[SUCCESS]${NC} $msg"
35
+ return 0
36
+ }
37
+
38
+ print_warning() {
39
+ local msg="$1"
40
+ echo -e "${YELLOW}[WARNING]${NC} $msg"
41
+ return 0
42
+ }
43
+
44
+ print_error() {
45
+ local msg="$1"
46
+ echo -e "${RED}[ERROR]${NC} $msg" >&2
47
+ return 0
48
+ }
49
+
50
+ # Configuration file
51
+ CONFIG_FILE="../configs/localhost-config.json"
52
+
53
+ # =============================================================================
54
+ # Port Management Functions
55
+ # =============================================================================
56
+ # These functions ensure port conflicts are avoided and services use available ports.
57
+ # This is critical for:
58
+ # 1. Avoiding "port already in use" errors
59
+ # 2. Enabling SSL via reverse proxy (password managers require HTTPS)
60
+ # 3. Consistent .local domain access across all local services
61
+
62
+ # Default port range for auto-assignment
63
+ readonly PORT_RANGE_START=3000
64
+ readonly PORT_RANGE_END=9999
65
+
66
+ # Check if a port is in use
67
+ # Returns 0 if port is FREE, 1 if port is IN USE
68
+ is_port_free() {
69
+ local port="$1"
70
+ if [[ -z "$port" ]]; then
71
+ print_error "Port number required"
72
+ return 1
73
+ fi
74
+
75
+ # Check using lsof (works on macOS and Linux)
76
+ if lsof -i :"$port" >/dev/null 2>&1; then
77
+ return 1 # Port is in use
78
+ fi
79
+
80
+ # Double-check with nc if available
81
+ if command -v nc >/dev/null 2>&1; then
82
+ if nc -z 127.0.0.1 "$port" 2>/dev/null; then
83
+ return 1 # Port is in use
84
+ fi
85
+ fi
86
+
87
+ return 0 # Port is free
88
+ }
89
+
90
+ # Find the next available port starting from a given port
91
+ # Usage: find_available_port [start_port]
92
+ # Returns: Prints the first available port
93
+ find_available_port() {
94
+ local start_port="${1:-$PORT_RANGE_START}"
95
+ local port="$start_port"
96
+
97
+ while [[ $port -le $PORT_RANGE_END ]]; do
98
+ if is_port_free "$port"; then
99
+ echo "$port"
100
+ return 0
101
+ fi
102
+ ((port++))
103
+ done
104
+
105
+ print_error "No available ports found in range $start_port-$PORT_RANGE_END"
106
+ return 1
107
+ }
108
+
109
+ # Check port and suggest alternative if in use
110
+ # Usage: check_port_or_suggest [port]
111
+ # Returns: 0 if port is free, 1 if in use (prints suggestion)
112
+ check_port_or_suggest() {
113
+ local port="$1"
114
+
115
+ if [[ -z "$port" ]]; then
116
+ print_error "Port number required"
117
+ return 1
118
+ fi
119
+
120
+ if is_port_free "$port"; then
121
+ print_success "Port $port is available"
122
+ return 0
123
+ else
124
+ local process_info
125
+ process_info=$(lsof -i :"$port" 2>/dev/null | tail -1 | awk '{print $1, $2}')
126
+ print_warning "Port $port is in use by: $process_info"
127
+
128
+ local suggested_port
129
+ suggested_port=$(find_available_port "$((port + 1))")
130
+ if [[ -n "$suggested_port" ]]; then
131
+ print_info "Suggested alternative: $suggested_port"
132
+ echo "SUGGESTED_PORT=$suggested_port"
133
+ fi
134
+ return 1
135
+ fi
136
+ }
137
+
138
+ # List all ports currently in use by local development services
139
+ list_dev_ports() {
140
+ print_info "Ports in use by local development services:"
141
+ echo ""
142
+
143
+ # Common development port ranges
144
+ local dev_ports=(3000 3001 3002 3003 4000 5000 5173 5174 8000 8080 8085 8888 9000 9222 11235)
145
+
146
+ for port in "${dev_ports[@]}"; do
147
+ if ! is_port_free "$port"; then
148
+ local process_info
149
+ process_info=$(lsof -i :"$port" 2>/dev/null | tail -1 | awk '{print $1}')
150
+ echo " :$port - $process_info"
151
+ fi
152
+ done
153
+
154
+ echo ""
155
+ print_info "Use 'lsof -i :<port>' for detailed process info"
156
+ return 0
157
+ }
158
+
159
+ # Kill process on a specific port
160
+ kill_port() {
161
+ local port="$1"
162
+
163
+ if [[ -z "$port" ]]; then
164
+ print_error "Port number required"
165
+ return 1
166
+ fi
167
+
168
+ local pids
169
+ pids=$(lsof -ti :"$port" 2>/dev/null)
170
+
171
+ if [[ -z "$pids" ]]; then
172
+ print_info "No process found on port $port"
173
+ return 0
174
+ fi
175
+
176
+ print_warning "Killing process(es) on port $port: $pids"
177
+ echo "$pids" | xargs kill -9 2>/dev/null
178
+
179
+ # Wait up to 3 seconds for the port to become free
180
+ for _ in {1..6}; do
181
+ if is_port_free "$port"; then
182
+ print_success "Port $port is now free"
183
+ return 0
184
+ fi
185
+ sleep 0.5
186
+ done
187
+
188
+ print_error "Failed to free port $port"
189
+ return 1
190
+ }
191
+
192
+ # Check if config file exists
193
+ check_config() {
194
+ if [[ ! -f "$CONFIG_FILE" ]]; then
195
+ print_error "$ERROR_CONFIG_NOT_FOUND"
196
+ print_info "Copy and customize: cp ../configs/localhost-config.json.txt $CONFIG_FILE"
197
+ exit 1
198
+ fi
199
+ return 0
200
+ }
201
+
202
+ # Check required tools
203
+ check_requirements() {
204
+ local missing_tools=()
205
+ local optional_tools=()
206
+
207
+ command -v docker >/dev/null 2>&1 || missing_tools+=("docker")
208
+ command -v mkcert >/dev/null 2>&1 || missing_tools+=("mkcert")
209
+ command -v dnsmasq >/dev/null 2>&1 || missing_tools+=("dnsmasq")
210
+
211
+ # Check for LocalWP (optional)
212
+ if [[ -d "/Applications/Local.app" ]] || [[ -d "$HOME/Applications/Local.app" ]]; then
213
+ print_success "LocalWP found - WordPress development integration available"
214
+
215
+ # Check for LocalWP MCP server
216
+ if command -v mcp-local-wp >/dev/null 2>&1; then
217
+ print_success "LocalWP MCP server found - AI database access available"
218
+ else
219
+ print_info "Install LocalWP MCP server: npm install -g @verygoodplugins/mcp-local-wp"
220
+
221
+ # Check for Context7 MCP server
222
+ if command -v npx >/dev/null 2>&1; then
223
+ print_success "Context7 MCP server available via npx"
224
+ else
225
+ print_info "Install Node.js and npm for Context7 MCP server access"
226
+ fi
227
+ fi
228
+ else
229
+ optional_tools+=("LocalWP")
230
+ fi
231
+
232
+ if [[ ${#missing_tools[@]} -gt 0 ]]; then
233
+ print_error "Missing required tools: ${missing_tools[*]}"
234
+ echo ""
235
+ echo "Install missing tools:"
236
+ echo " Docker: https://docs.docker.com/get-docker/"
237
+ echo " mkcert: brew install mkcert (macOS) or see https://github.com/FiloSottile/mkcert"
238
+ echo " dnsmasq: brew install dnsmasq (macOS) or sudo apt-get install dnsmasq (Linux)"
239
+ return 1
240
+ fi
241
+
242
+ if [[ ${#optional_tools[@]} -gt 0 ]]; then
243
+ print_info "Optional tools not found: ${optional_tools[*]}"
244
+ echo " LocalWP: https://localwp.com/ (for WordPress development)"
245
+ fi
246
+
247
+ return 0
248
+ }
249
+
250
+ # Setup local DNS resolution for .local domains
251
+ setup_local_dns() {
252
+ print_info "Setting up local DNS resolution for .local domains..."
253
+
254
+ # Check if dnsmasq is configured
255
+ local dnsmasq_conf="/usr/local/etc/dnsmasq.conf"
256
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
257
+ dnsmasq_conf="/etc/dnsmasq.conf"
258
+ fi
259
+
260
+ if [[ -f "$dnsmasq_conf" ]]; then
261
+ if ! grep -q "address=/.local/127.0.0.1" "$dnsmasq_conf"; then
262
+ print_info "Adding .local domain resolution to dnsmasq..."
263
+ echo "address=/.local/127.0.0.1" | sudo tee -a "$dnsmasq_conf"
264
+
265
+ # Restart dnsmasq
266
+ if [[ "$OSTYPE" == "darwin"* ]]; then
267
+ sudo brew services restart dnsmasq
268
+ else
269
+ sudo systemctl restart dnsmasq
270
+ fi
271
+
272
+ print_success "dnsmasq configured for .local domains"
273
+ else
274
+ print_info "dnsmasq already configured for .local domains"
275
+ fi
276
+ else
277
+ print_warning "dnsmasq configuration file not found"
278
+ print_info "Manual setup required - see documentation"
279
+ fi
280
+
281
+ # Setup resolver for macOS
282
+ if [[ "$OSTYPE" == "darwin"* ]]; then
283
+ sudo mkdir -p /etc/resolver
284
+ echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/local
285
+ print_success "macOS resolver configured for .local domains"
286
+ fi
287
+ return 0
288
+ }
289
+
290
+ # Generate SSL certificate for local domain
291
+ generate_ssl_cert() {
292
+ local domain="$1"
293
+
294
+ if [[ -z "$domain" ]]; then
295
+ print_error "Please specify a domain"
296
+ return 1
297
+ fi
298
+
299
+ print_info "Generating SSL certificate for $domain..."
300
+
301
+ # Create certs directory
302
+ mkdir -p ~/.local-ssl-certs
303
+
304
+ # Generate certificate with mkcert
305
+ cd ~/.local-ssl-certs || exit
306
+ mkcert "$domain" "*.$domain"
307
+
308
+ if docker --version >/dev/null 2>&1; then
309
+ print_success "SSL certificate generated for $domain"
310
+ print_info "Certificate files:"
311
+ print_info " - ~/.local-ssl-certs/$domain+1.pem (certificate)"
312
+ print_info " - ~/.local-ssl-certs/$domain+1-key.pem (private key)"
313
+ else
314
+ print_error "Failed to generate SSL certificate"
315
+ return 1
316
+ fi
317
+ return 0
318
+ }
319
+
320
+ # List configured local apps
321
+ list_apps() {
322
+ check_config
323
+ print_info "Configured local development apps:"
324
+
325
+ apps=$(jq -r '.apps | keys[]' "$CONFIG_FILE")
326
+ for app in $apps; do
327
+ domain=$(jq -r ".apps.$app.domain" "$CONFIG_FILE")
328
+ port=$(jq -r ".apps.$app.port" "$CONFIG_FILE")
329
+ ssl=$(jq -r ".apps.$app.ssl" "$CONFIG_FILE")
330
+ description=$(jq -r ".apps.$app.description" "$CONFIG_FILE")
331
+
332
+ ssl_status="HTTP"
333
+ if [[ "$ssl" == "true" ]]; then
334
+ ssl_status="HTTPS"
335
+ fi
336
+
337
+ echo " - $app: $description"
338
+ echo " URL: $ssl_status://$domain (port $port)"
339
+ echo ""
340
+ done
341
+ return 0
342
+ }
343
+
344
+ # Setup reverse proxy with Traefik
345
+ setup_traefik() {
346
+ print_info "Setting up Traefik reverse proxy for local development..."
347
+
348
+ # Create Traefik configuration
349
+ mkdir -p ~/.local-dev-proxy
350
+
351
+ cat > ~/.local-dev-proxy/traefik.yml << 'EOF'
352
+ api:
353
+ dashboard: true
354
+ insecure: true
355
+
356
+ entryPoints:
357
+ web:
358
+ address: ":80"
359
+ websecure:
360
+ address: ":443"
361
+
362
+ providers:
363
+ docker:
364
+ exposedByDefault: false
365
+ file:
366
+ filename: /etc/traefik/dynamic.yml
367
+ watch: true
368
+
369
+ certificatesResolvers:
370
+ local:
371
+ acme:
372
+ email: dev@localhost
373
+ storage: acme.json
374
+ keyType: EC256
375
+ EOF
376
+
377
+ cat > ~/.local-dev-proxy/dynamic.yml << 'EOF'
378
+ tls:
379
+ certificates:
380
+ - certFile: /certs/localhost.pem
381
+ keyFile: /certs/localhost-key.pem
382
+ EOF
383
+
384
+ # Create docker-compose for Traefik
385
+ cat > ~/.local-dev-proxy/docker-compose.yml << 'EOF'
386
+ version: '3.8'
387
+
388
+ services:
389
+ traefik:
390
+ image: traefik:v2.10
391
+ container_name: local-traefik
392
+ restart: unless-stopped
393
+ ports:
394
+ - "80:80"
395
+ - "443:443"
396
+ - "8080:8080" # Traefik dashboard
397
+ volumes:
398
+ - /var/run/docker.sock:/var/run/docker.sock:ro
399
+ - ./traefik.yml:/etc/traefik/traefik.yml:ro
400
+ - ./dynamic.yml:/etc/traefik/dynamic.yml:ro
401
+ - ~/.local-ssl-certs:/certs:ro
402
+ networks:
403
+ - local-dev
404
+
405
+ networks:
406
+ local-dev:
407
+ external: true
408
+ EOF
409
+
410
+ # Create network
411
+ docker network create local-dev 2>/dev/null || true
412
+
413
+ # Start Traefik
414
+ cd ~/.local-dev-proxy || exit
415
+ docker-compose up -d
416
+
417
+ print_success "Traefik reverse proxy started"
418
+ print_info "Dashboard available at: http://localhost:8080"
419
+ return 0
420
+ }
421
+
422
+ # List LocalWP sites
423
+ list_localwp_sites() {
424
+ print_info "Checking for LocalWP sites..."
425
+
426
+ local localwp_path="$HOME/Local Sites"
427
+ if [[ -d "$localwp_path" ]]; then
428
+ print_success "LocalWP sites found:"
429
+ for site_dir in "$localwp_path"/*; do
430
+ if [[ -d "$site_dir" ]]; then
431
+ local site_name
432
+ site_name=$(basename "$site_dir")
433
+ local conf_file="$site_dir/conf/nginx/site.conf"
434
+ if [[ -f "$conf_file" ]]; then
435
+ local port
436
+ port=$(grep -o 'listen [0-9]*' "$conf_file" | head -1 | awk '{print $param2}')
437
+ echo " - $site_name (http://localhost:$port)"
438
+ else
439
+ echo " - $site_name (configuration not found)"
440
+ fi
441
+ fi
442
+ done
443
+ else
444
+ print_warning "LocalWP sites directory not found at: $localwp_path"
445
+ print_info "Install LocalWP from: https://localwp.com/"
446
+ fi
447
+ return 0
448
+ }
449
+
450
+ # Create LocalWP-compatible .local domain
451
+ setup_localwp_domain() {
452
+ local site_name="$1"
453
+ local custom_domain="$param2"
454
+
455
+ if [[ -z "$site_name" ]]; then
456
+ print_error "Usage: setup-localwp-domain [site-name] [custom-domain.local]"
457
+ return 1
458
+ fi
459
+
460
+ local localwp_path="$HOME/Local Sites/$site_name"
461
+ if [[ ! -d "$localwp_path" ]]; then
462
+ print_error "LocalWP site not found: $site_name"
463
+ print_info "Available sites:"
464
+ list_localwp_sites
465
+ return 1
466
+ fi
467
+
468
+ local domain="${custom_domain:-$site_name.local}"
469
+ local conf_file="$localwp_path/conf/nginx/site.conf"
470
+
471
+ if [[ -f "$conf_file" ]]; then
472
+ local port
473
+ port=$(grep -o 'listen [0-9]*' "$conf_file" | head -1 | awk '{print $param2}')
474
+ print_info "Setting up $domain for LocalWP site $site_name (port $port)"
475
+
476
+ # Generate SSL certificate
477
+ generate_ssl_cert "$domain"
478
+
479
+ # Add to Traefik configuration
480
+ setup_localwp_traefik "$site_name" "$domain" "$port"
481
+
482
+ print_success "LocalWP site $site_name now available at: https://$domain"
483
+ else
484
+ print_error "LocalWP configuration not found for: $site_name"
485
+ fi
486
+ return 0
487
+ }
488
+
489
+ # Setup Traefik for LocalWP site
490
+ setup_localwp_traefik() {
491
+ local site_name="$1"
492
+ local domain="$param2"
493
+ local port="$param3"
494
+
495
+ # Create Traefik configuration for LocalWP site
496
+ mkdir -p ~/.local-dev-proxy/localwp
497
+
498
+ cat > ~/.local-dev-proxy/localwp/"$site_name".yml << EOF
499
+ http:
500
+ routers:
501
+ localwp-$site_name:
502
+ rule: "Host(\`$domain\`)"
503
+ tls: true
504
+ service: localwp-$site_name-service
505
+ entryPoints:
506
+ - websecure
507
+
508
+ services:
509
+ localwp-$site_name-service:
510
+ loadBalancer:
511
+ servers:
512
+ - url: "http://localhost:$port"
513
+ EOF
514
+
515
+ print_success "Traefik configuration created for $site_name"
516
+ return 0
517
+ }
518
+
519
+ # Create Docker app with .local domain
520
+ create_app() {
521
+ local app_name="$1"
522
+ local domain="$param2"
523
+ local port="$param3"
524
+ local ssl="${4:-true}"
525
+ local app_type="${5:-docker}"
526
+
527
+ if [[ -z "$app_name" || -z "$domain" || -z "$port" ]]; then
528
+ print_error "Usage: create-app [app-name] [domain.local] [port] [ssl:true/false] [type:docker/localwp]"
529
+ return 1
530
+ fi
531
+
532
+ print_info "Creating local app: $app_name at $domain:$port (type: $app_type)"
533
+
534
+ # Generate SSL certificate if needed
535
+ if [[ "$ssl" == "true" ]]; then
536
+ generate_ssl_cert "$domain"
537
+ fi
538
+
539
+ if [[ "$app_type" == "localwp" ]]; then
540
+ setup_localwp_domain "$app_name" "$domain"
541
+ return $?
542
+ fi
543
+
544
+ # Create app directory
545
+ mkdir -p ~/.local-apps/"$app_name"
546
+
547
+ # Create sample docker-compose with Traefik labels
548
+ cat > ~/.local-apps/"$app_name"/docker-compose.yml << EOF
549
+ version: '3.8'
550
+
551
+ services:
552
+ $app_name:
553
+ image: nginx:alpine
554
+ container_name: $app_name
555
+ restart: unless-stopped
556
+ labels:
557
+ - "traefik.enable=true"
558
+ - "traefik.http.routers.$app_name.rule=Host(\`$domain\`)"
559
+ - "traefik.http.services.$app_name.loadbalancer.server.port=$port"
560
+ EOF
561
+
562
+ if [[ "$ssl" == "true" ]]; then
563
+ cat >> ~/.local-apps/"$app_name"/docker-compose.yml << EOF
564
+ - "traefik.http.routers.$app_name.tls=true"
565
+ - "traefik.http.routers.$app_name.entrypoints=websecure"
566
+ EOF
567
+ else
568
+ cat >> ~/.local-apps/"$app_name"/docker-compose.yml << EOF
569
+ - "traefik.http.routers.$app_name.entrypoints=web"
570
+ EOF
571
+ fi
572
+
573
+ cat >> ~/.local-apps/"$app_name"/docker-compose.yml << EOF
574
+ networks:
575
+ - local-dev
576
+
577
+ networks:
578
+ local-dev:
579
+ external: true
580
+ EOF
581
+
582
+ print_success "App configuration created at ~/.local-apps/$app_name/"
583
+
584
+ if [[ "$ssl" == "true" ]]; then
585
+ print_info "Access your app at: https://$domain"
586
+ else
587
+ # SONAR: Local dev without SSL is intentional
588
+ print_info "Access your app at: http://$domain"
589
+ fi
590
+ return 0
591
+ }
592
+
593
+ # Start LocalWP MCP server
594
+ start_localwp_mcp() {
595
+ print_info "Starting LocalWP MCP server..."
596
+
597
+ if ! command -v mcp-local-wp >/dev/null 2>&1; then
598
+ print_error "LocalWP MCP server not installed"
599
+ print_info "Install with: npm install -g @verygoodplugins/mcp-local-wp"
600
+ return 1
601
+ fi
602
+
603
+ # Check if LocalWP is running
604
+ if ! pgrep -f "Local" >/dev/null 2>&1; then
605
+ print_warning "Local by Flywheel doesn't appear to be running"
606
+ print_info "Start Local by Flywheel and ensure a site is active"
607
+ fi
608
+
609
+ print_info "Starting MCP server on port 8085..."
610
+ mcp-local-wp --transport sse --port 8085 &
611
+ local mcp_pid=$!
612
+
613
+ sleep 2
614
+ if kill -0 "$mcp_pid" 2>/dev/null; then
615
+ print_success "LocalWP MCP server started (PID: $mcp_pid)"
616
+ print_info "AI assistants can now access your WordPress database"
617
+ print_info "Available tools: mysql_query, mysql_schema"
618
+ return 0
619
+ else
620
+ print_error "Failed to start LocalWP MCP server"
621
+ return 1
622
+ fi
623
+ return 0
624
+ }
625
+
626
+ # Stop LocalWP MCP server
627
+ stop_localwp_mcp() {
628
+ print_info "Stopping LocalWP MCP server..."
629
+
630
+ local pids
631
+ pids=$(pgrep -f "mcp-local-wp")
632
+ if [[ -n "$pids" ]]; then
633
+ echo "$pids" | xargs kill
634
+ print_success "LocalWP MCP server stopped"
635
+ else
636
+ print_info "LocalWP MCP server not running"
637
+ fi
638
+ return 0
639
+ }
640
+
641
+ # Main function
642
+ main() {
643
+ # Assign positional parameters to local variables
644
+ local command="${1:-help}"
645
+ local param2="$2"
646
+ local param3="$3"
647
+ local param4="$4"
648
+ local param5="$5"
649
+ local param6="$6"
650
+
651
+ # Main command handler
652
+ case "$command" in
653
+ "setup-dns")
654
+ check_requirements && setup_local_dns
655
+ ;;
656
+ "setup-proxy")
657
+ check_requirements && setup_traefik
658
+ ;;
659
+ "generate-cert")
660
+ generate_ssl_cert "$param2"
661
+ ;;
662
+ "list")
663
+ list_apps
664
+ ;;
665
+ "create-app")
666
+ create_app "$param2" "$param3" "$param4" "$param5" "$param6"
667
+ ;;
668
+ "list-localwp")
669
+ list_localwp_sites
670
+ ;;
671
+ "setup-localwp-domain")
672
+ setup_localwp_domain "$param2" "$param3"
673
+ ;;
674
+ "start-mcp")
675
+ start_localwp_mcp
676
+ ;;
677
+ "stop-mcp")
678
+ stop_localwp_mcp
679
+ ;;
680
+ "check-port")
681
+ check_port_or_suggest "$param2"
682
+ ;;
683
+ "find-port")
684
+ find_available_port "$param2"
685
+ ;;
686
+ "list-ports")
687
+ list_dev_ports
688
+ ;;
689
+ "kill-port")
690
+ kill_port "$param2"
691
+ ;;
692
+ "help"|"-h"|"--help"|"")
693
+ echo "Localhost Development Helper Script"
694
+ echo "Usage: $0 [command] [options]"
695
+ echo ""
696
+ echo "DNS & Proxy Commands:"
697
+ echo " setup-dns - Setup local DNS resolution for .local domains"
698
+ echo " setup-proxy - Setup Traefik reverse proxy"
699
+ echo " generate-cert [domain] - Generate SSL certificate for domain"
700
+ echo ""
701
+ echo "App Management Commands:"
702
+ echo " list - List configured local apps"
703
+ echo " create-app [name] [domain] [port] [ssl] [type] - Create new local app"
704
+ echo ""
705
+ echo "LocalWP Integration Commands:"
706
+ echo " list-localwp - List LocalWP sites"
707
+ echo " setup-localwp-domain [site] [domain] - Setup .local domain for LocalWP site"
708
+ echo " start-mcp - Start LocalWP MCP server for AI database access"
709
+ echo " stop-mcp - Stop LocalWP MCP server"
710
+ echo ""
711
+ echo "Port Management Commands:"
712
+ echo " check-port [port] - Check if port is available, suggest alternative"
713
+ echo " find-port [start] - Find next available port from start (default: 3000)"
714
+ echo " list-ports - List common dev ports in use"
715
+ echo " kill-port [port] - Kill process using specified port"
716
+ echo ""
717
+ echo "Examples:"
718
+ echo " $0 setup-dns"
719
+ echo " $0 setup-proxy"
720
+ echo " $0 generate-cert myapp.local"
721
+ echo " $0 create-app myapp myapp.local 3000 true docker"
722
+ echo " $0 list-localwp"
723
+ echo " $0 setup-localwp-domain plugin-testing plugin-testing.local"
724
+ echo " $0 start-mcp"
725
+ echo " $0 stop-mcp"
726
+ echo ""
727
+ echo "Requirements:"
728
+ echo " - Docker and Docker Compose"
729
+ echo " - mkcert for SSL certificates"
730
+ echo " - dnsmasq for local DNS resolution"
731
+ echo " - LocalWP (optional, for WordPress development)"
732
+ echo " - @verygoodplugins/mcp-local-wp (optional, for AI database access)"
733
+ ;;
734
+ *)
735
+ print_error "$ERROR_UNKNOWN_COMMAND $command"
736
+ print_info "$HELP_USAGE_INFO"
737
+ exit 1
738
+ ;;
739
+ esac
740
+ return 0
741
+ }
742
+
743
+ # Run main function
744
+ main "$@"