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,485 @@
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
+ # Hetzner Helper Script
5
+ # Manages Hetzner Cloud VPS servers across multiple projects
6
+
7
+ # Colors for output
8
+ # String literal constants
9
+ readonly ERROR_CONFIG_NOT_FOUND="Configuration file not found"
10
+ readonly ERROR_SERVER_NAME_REQUIRED="Server name is required"
11
+ readonly ERROR_INVALID_JSON="Invalid JSON in configuration file"
12
+ readonly ERROR_UNKNOWN_COMMAND="Unknown command:"
13
+
14
+ GREEN='\033[0;32m'
15
+ BLUE='\033[0;34m'
16
+ YELLOW='\033[1;33m'
17
+ RED='\033[0;31m'
18
+ NC='\033[0m' # No Color
19
+
20
+ # Common message constants
21
+ readonly HELP_SHOW_MESSAGE="Show this help"
22
+ readonly USAGE_COMMAND_OPTIONS="Usage: $0 [command] [options]"
23
+ readonly HELP_USAGE_INFO="Use '$0 help' for usage information"
24
+
25
+ # Common constants
26
+ readonly AUTH_BEARER_PREFIX="Authorization: Bearer"
27
+ readonly CONTENT_TYPE_JSON="$CONTENT_TYPE_JSON"
28
+ readonly HETZNER_API_SERVERS="https://api.hetzner.cloud/v1/servers"
29
+
30
+ print_info() {
31
+ local msg="$1"
32
+ echo -e "${BLUE}[INFO]${NC} $msg"
33
+ return 0
34
+ }
35
+
36
+ print_success() {
37
+ local msg="$1"
38
+ echo -e "${GREEN}[SUCCESS]${NC} $msg"
39
+ return 0
40
+ }
41
+
42
+ print_warning() {
43
+ local msg="$1"
44
+ echo -e "${YELLOW}[WARNING]${NC} $msg"
45
+ return 0
46
+ }
47
+
48
+ print_error() {
49
+ local msg="$1"
50
+ echo -e "${RED}[ERROR]${NC} $msg" >&2
51
+ return 0
52
+ }
53
+
54
+ # Configuration file
55
+ CONFIG_FILE="../configs/hetzner-config.json"
56
+
57
+ # Check if config file exists
58
+ check_config() {
59
+ if [[ ! -f "$CONFIG_FILE" ]]; then
60
+ print_error "$ERROR_CONFIG_NOT_FOUND"
61
+ print_info "Copy and customize: cp ../configs/hetzner-config.json.txt $CONFIG_FILE"
62
+ exit 1
63
+ fi
64
+
65
+ if ! jq empty "$CONFIG_FILE" 2>/dev/null; then
66
+ print_error "$ERROR_INVALID_JSON"
67
+ exit 1
68
+ fi
69
+
70
+ return 0
71
+ }
72
+
73
+ # List all servers from all projects
74
+ list_servers() {
75
+ check_config
76
+ print_info "Fetching servers from all Hetzner projects..."
77
+
78
+ projects=$(jq -r '.projects | keys[]' "$CONFIG_FILE")
79
+
80
+ for project in $projects; do
81
+ api_token=$(jq -r ".projects.$project.api_token" "$CONFIG_FILE")
82
+ description=$(jq -r ".projects.$project.description" "$CONFIG_FILE")
83
+ account=$(jq -r ".projects.$project.account" "$CONFIG_FILE")
84
+
85
+ print_info "Project: $project ($description)"
86
+ print_info "Account: $account"
87
+
88
+ servers=$(curl -s -H "$AUTH_BEARER_PREFIX $api_token" \
89
+ "$HETZNER_API_SERVERS" | \
90
+ jq -r '.servers[]? | " - \(.name) (\(.public_net.ipv4.ip)) - \(.server_type.name) - \(.status)"')
91
+
92
+ if [[ -n "$servers" ]]; then
93
+ echo "$servers"
94
+ else
95
+ echo " - No servers found"
96
+ fi
97
+
98
+ echo ""
99
+ done
100
+
101
+ return 0
102
+ }
103
+
104
+ # Connect to a specific server
105
+ connect_server() {
106
+ local server_name="$1"
107
+ check_config
108
+
109
+ if [[ -z "$server_name" ]]; then
110
+ print_error "$ERROR_SERVER_NAME_REQUIRED"
111
+ list_servers
112
+ exit 1
113
+ fi
114
+
115
+ # Find server across all projects
116
+ local server_info
117
+ server_info=$(get_server_details "$server_name")
118
+ if [[ -z "$server_info" ]]; then
119
+ print_error "Server not found: $server_name"
120
+ exit 1
121
+ fi
122
+
123
+ read -r ip name project <<< "$server_info"
124
+ print_info "Connecting to $name ($ip) in project $project..."
125
+ ssh "root@$ip"
126
+ return 0
127
+ }
128
+
129
+ # Execute command on server
130
+ exec_on_server() {
131
+ local server_name="$1"
132
+ local command="$2"
133
+ check_config
134
+
135
+ if [[ -z "$server_name" || -z "$command" ]]; then
136
+ print_error "Usage: exec [server] [command]"
137
+ exit 1
138
+ fi
139
+
140
+ local server_info
141
+ server_info=$(get_server_details "$server_name")
142
+ if [[ -z "$server_info" ]]; then
143
+ print_error "Server not found: $server_name"
144
+ exit 1
145
+ fi
146
+
147
+ read -r ip name project <<< "$server_info"
148
+ print_info "Executing '$command' on $name..."
149
+ ssh "root@$ip" "$command"
150
+ return 0
151
+ }
152
+
153
+ # Get server details by name
154
+ get_server_details() {
155
+ local server_name="$1"
156
+ check_config
157
+
158
+ projects=$(jq -r '.projects | keys[]' "$CONFIG_FILE")
159
+
160
+ for project in $projects; do
161
+ api_token=$(jq -r ".projects.$project.api_token" "$CONFIG_FILE")
162
+
163
+ server_info=$(curl -s -H "$AUTH_BEARER_PREFIX $api_token" \
164
+ "$HETZNER_API_SERVERS" | \
165
+ jq -r ".servers[]? | select(.name == \"$server_name\") | \"\(.public_net.ipv4.ip) \(.name) $project\"")
166
+
167
+ if [[ -n "$server_info" ]]; then
168
+ echo "$server_info"
169
+ return 0
170
+ fi
171
+ done
172
+
173
+ return 1
174
+ }
175
+
176
+ # Generate SSH configurations
177
+ generate_ssh_configs() {
178
+ check_config
179
+ print_info "Generating SSH configurations for all servers..."
180
+
181
+ projects=$(jq -r '.projects | keys[]' "$CONFIG_FILE")
182
+
183
+ echo "# Hetzner servers SSH configuration" > ~/.ssh/hetzner_config
184
+ echo "# Generated on $(date)" >> ~/.ssh/hetzner_config
185
+
186
+ for project in $projects; do
187
+ api_token=$(jq -r ".projects.$project.api_token" "$CONFIG_FILE")
188
+ description=$(jq -r ".projects.$project.description" "$CONFIG_FILE")
189
+
190
+ print_info "Processing project: $project ($description)"
191
+
192
+ servers=$(curl -s -H "$AUTH_BEARER_PREFIX $api_token" \
193
+ "$HETZNER_API_SERVERS" | \
194
+ jq -r '.servers[]? | "\(.name) \(.public_net.ipv4.ip)"')
195
+
196
+ if [[ -n "$servers" ]]; then
197
+ echo "" >> ~/.ssh/hetzner_config
198
+ echo "# Project: $project ($description)" >> ~/.ssh/hetzner_config
199
+
200
+ while IFS=' ' read -r name ip; do
201
+ if [[ -n "$name" && -n "$ip" && "$name" != "null" && "$ip" != "null" ]]; then
202
+ echo "" >> ~/.ssh/hetzner_config
203
+ echo "Host $name" >> ~/.ssh/hetzner_config
204
+ echo " HostName $ip" >> ~/.ssh/hetzner_config
205
+ echo " User root" >> ~/.ssh/hetzner_config
206
+ echo " IdentityFile ~/.ssh/id_ed25519" >> ~/.ssh/hetzner_config
207
+ echo " AddKeysToAgent yes" >> ~/.ssh/hetzner_config
208
+ echo " UseKeychain yes" >> ~/.ssh/hetzner_config
209
+ echo " # Project: $project" >> ~/.ssh/hetzner_config
210
+ print_success "Added SSH config for $name ($ip)"
211
+ fi
212
+ done <<< "$servers"
213
+ fi
214
+ done
215
+
216
+ print_success "SSH configurations generated in ~/.ssh/hetzner_config"
217
+ print_info "Add 'Include ~/.ssh/hetzner_config' to your ~/.ssh/config"
218
+ return 0
219
+ }
220
+
221
+ # Create a new VPS
222
+ create_server() {
223
+ local project_name="$1"
224
+ local server_name="$2"
225
+ local server_type="${3:-cx22}"
226
+ local location="${4:-nbg1}"
227
+ local image="${5:-ubuntu-24.04}"
228
+
229
+ check_config
230
+
231
+ if [[ -z "$project_name" || -z "$server_name" ]]; then
232
+ print_error "Usage: create [project] [server_name] [server_type] [location] [image]"
233
+ print_info "Available projects:"
234
+ jq -r '.accounts | keys[]' "$CONFIG_FILE" | sed 's/^/ - /'
235
+ exit 1
236
+ fi
237
+
238
+ # Get API token for project
239
+ local api_token
240
+ api_token=$(jq -r ".accounts.\"$project_name\".api_token" "$CONFIG_FILE")
241
+ if [[ "$api_token" == "null" || -z "$api_token" ]]; then
242
+ print_error "Project '$project_name' not found in configuration"
243
+ exit 1
244
+ fi
245
+
246
+ print_info "Creating VPS with specifications:"
247
+ echo " Project: $project_name"
248
+ echo " Name: $server_name"
249
+ echo " Type: $server_type"
250
+ echo " Location: $location"
251
+ echo " Image: $image"
252
+ echo ""
253
+
254
+ # Create the server
255
+ local response
256
+ response=$(curl -s -X POST \
257
+ -H "$AUTH_BEARER_PREFIX $api_token" \
258
+ -H "$CONTENT_TYPE_JSON" \
259
+ -d "{
260
+ \"name\": \"$server_name\",
261
+ \"server_type\": \"$server_type\",
262
+ \"location\": \"$location\",
263
+ \"image\": \"$image\",
264
+ \"start_after_create\": true
265
+ }" \
266
+ "$HETZNER_API_SERVERS")
267
+
268
+ # Check if creation was successful
269
+ if echo "$response" | jq -e '.server' > /dev/null; then
270
+ local server_id
271
+ local server_ip
272
+ local root_password
273
+ server_id=$(echo "$response" | jq -r '.server.id')
274
+ server_ip=$(echo "$response" | jq -r '.server.public_net.ipv4.ip // "pending"')
275
+ root_password=$(echo "$response" | jq -r '.root_password // "not_provided"')
276
+
277
+ print_success "VPS created successfully!"
278
+ echo " Server ID: $server_id"
279
+ echo " Server Name: $server_name"
280
+ echo " IP Address: $server_ip"
281
+ echo " Root Password: $root_password"
282
+ echo ""
283
+ print_info "The server is being initialized. This may take a few minutes."
284
+ print_info "Check status with: $0 status $server_name"
285
+
286
+ else
287
+ print_error "Failed to create VPS"
288
+ echo "Response: $response"
289
+ exit 1
290
+ fi
291
+
292
+ return 0
293
+ }
294
+
295
+ # Check server status
296
+ check_server_status() {
297
+ local server_name="$1"
298
+ check_config
299
+
300
+ if [[ -z "$server_name" ]]; then
301
+ print_error "Server name is required"
302
+ exit 1
303
+ fi
304
+
305
+ # Find server across all projects
306
+ local found=false
307
+ local projects
308
+ projects=$(jq -r '.accounts | keys[]' "$CONFIG_FILE")
309
+
310
+ for project in $projects; do
311
+ local api_token
312
+ api_token=$(jq -r ".accounts.\"$project\".api_token" "$CONFIG_FILE")
313
+
314
+ local response
315
+ response=$(curl -s -H "$AUTH_BEARER_PREFIX $api_token" \
316
+ "$HETZNER_API_SERVERS")
317
+
318
+ local server_info
319
+ server_info=$(echo "$response" | jq -r ".servers[] | select(.name == \"$server_name\")")
320
+
321
+ if [[ -n "$server_info" ]]; then
322
+ local status
323
+ local ip
324
+ local server_type
325
+ status=$(echo "$server_info" | jq -r '.status')
326
+ ip=$(echo "$server_info" | jq -r '.public_net.ipv4.ip')
327
+ server_type=$(echo "$server_info" | jq -r '.server_type.name')
328
+
329
+ print_info "Server: $server_name (Project: $project)"
330
+ echo " Status: $status"
331
+ echo " IP: $ip"
332
+ echo " Type: $server_type"
333
+ found=true
334
+ break
335
+ fi
336
+ done
337
+
338
+ if [[ "$found" == false ]]; then
339
+ print_error "Server '$server_name' not found"
340
+ exit 1
341
+ fi
342
+
343
+ return 0
344
+ }
345
+
346
+ # List available server types
347
+ list_server_types() {
348
+ local project_name="${1:-main}"
349
+ check_config
350
+
351
+ local api_token
352
+ api_token=$(jq -r ".accounts.\"$project_name\".api_token" "$CONFIG_FILE")
353
+ if [[ "$api_token" == "null" || -z "$api_token" ]]; then
354
+ print_error "Project '$project_name' not found in configuration"
355
+ exit 1
356
+ fi
357
+
358
+ print_info "Available server types:"
359
+ curl -s -H "$AUTH_BEARER_PREFIX $api_token" \
360
+ "https://api.hetzner.cloud/v1/server_types" | \
361
+ jq -r '.server_types[] | " \(.name) - \(.cores) cores, \(.memory)GB RAM, \(.disk)GB disk - €\(.prices[0].price_monthly.gross)/month"'
362
+
363
+ return 0
364
+ }
365
+
366
+ # List available locations
367
+ list_locations() {
368
+ local project_name="${1:-main}"
369
+ check_config
370
+
371
+ local api_token
372
+ api_token=$(jq -r ".accounts.\"$project_name\".api_token" "$CONFIG_FILE")
373
+ if [[ "$api_token" == "null" || -z "$api_token" ]]; then
374
+ print_error "Project '$project_name' not found in configuration"
375
+ exit 1
376
+ fi
377
+
378
+ print_info "Available locations:"
379
+ curl -s -H "$AUTH_BEARER_PREFIX $api_token" \
380
+ "https://api.hetzner.cloud/v1/locations" | \
381
+ jq -r '.locations[] | " \(.name) - \(.description) (\(.country))"'
382
+
383
+ return 0
384
+ }
385
+
386
+ # List available images
387
+ list_images() {
388
+ local project_name="${1:-main}"
389
+ check_config
390
+
391
+ local api_token
392
+ api_token=$(jq -r ".accounts.\"$project_name\".api_token" "$CONFIG_FILE")
393
+ if [[ "$api_token" == "null" || -z "$api_token" ]]; then
394
+ print_error "Project '$project_name' not found in configuration"
395
+ exit 1
396
+ fi
397
+
398
+ print_info "Available images (OS):"
399
+ curl -s -H "$AUTH_BEARER_PREFIX $api_token" \
400
+ "https://api.hetzner.cloud/v1/images?type=system" | \
401
+ jq -r '.images[] | select(.status == "available") | " \(.name) - \(.description)"'
402
+
403
+ return 0
404
+ }
405
+
406
+ # Main function
407
+ main() {
408
+ # Assign positional parameters to local variables
409
+ local command="${1:-help}"
410
+ local param2="$2"
411
+ local param3="$3"
412
+ local param4="$4"
413
+ local param5="$5"
414
+ local param6="$6"
415
+
416
+ # Main command handler
417
+ case "$command" in
418
+ "list")
419
+ list_servers
420
+ ;;
421
+ "create")
422
+ create_server "$param2" "$param3" "$param4" "$param5" "$param6"
423
+ ;;
424
+ "status")
425
+ check_server_status "$param2"
426
+ ;;
427
+ "connect")
428
+ connect_server "$param2"
429
+ ;;
430
+ "exec")
431
+ exec_on_server "$param2" "$param3"
432
+ ;;
433
+ "list-types")
434
+ list_server_types "$param2"
435
+ ;;
436
+ "list-locations")
437
+ list_locations "$param2"
438
+ ;;
439
+ "list-images")
440
+ list_images "$param2"
441
+ ;;
442
+ "generate-ssh-configs")
443
+ generate_ssh_configs
444
+ ;;
445
+ "help"|"-h"|"--help"|"")
446
+ echo "Hetzner Helper Script"
447
+ echo "$USAGE_COMMAND_OPTIONS"
448
+ echo ""
449
+ echo "Commands:"
450
+ echo " list - List all servers across projects"
451
+ echo " create [project] [name] [type] [location] [image] - Create new VPS"
452
+ echo " status [server] - Check server status"
453
+ echo " connect [server] - Connect to server via SSH"
454
+ echo " exec [server] [command] - Execute command on server"
455
+ echo " list-types [project] - List available server types"
456
+ echo " list-locations [project] - List available locations"
457
+ echo " list-images [project] - List available OS images"
458
+ echo " generate-ssh-configs - Generate SSH configurations"
459
+ echo " help - $HELP_SHOW_MESSAGE"
460
+ echo ""
461
+ echo "Examples:"
462
+ echo " $0 list"
463
+ echo " $0 create main my-server cx22 nbg1 ubuntu-24.04"
464
+ echo " $0 status my-server"
465
+ echo " $0 connect web-server-01"
466
+ echo " $0 exec web-server-01 'uptime'"
467
+ echo " $0 list-types main"
468
+ echo " $0 generate-ssh-configs"
469
+ echo ""
470
+ echo "Defaults for create command:"
471
+ echo " Server Type: cx22 (2 cores, 4GB RAM, 40GB disk)"
472
+ echo " Location: nbg1 (Nuremberg, Germany)"
473
+ echo " Image: ubuntu-24.04 (Ubuntu 24.04 LTS)"
474
+ ;;
475
+ *)
476
+ print_error "$ERROR_UNKNOWN_COMMAND $command"
477
+ print_info "$HELP_USAGE_INFO"
478
+ exit 1
479
+ ;;
480
+ esac
481
+ return 0
482
+ }
483
+
484
+ # Run main function
485
+ main "$@"
@@ -0,0 +1,229 @@
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
+ # Hostinger Helper Script
5
+ # Manages Hostinger shared hosting sites and API operations
6
+
7
+ # Source shared constants if available
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || exit
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
+ # HTTP Constants
19
+ readonly AUTH_HEADER_PREFIX="Authorization: Bearer"
20
+ # Error message constants
21
+ readonly ERROR_UNKNOWN_COMMAND="Unknown command:"
22
+ readonly HELP_SHOW_MESSAGE="Show this help"
23
+ readonly HELP_USAGE_INFO="Use '$0 help' for usage information"
24
+
25
+ print_info() {
26
+ local msg="$1"
27
+ echo -e "${BLUE}[INFO]${NC} $msg"
28
+ return 0
29
+ }
30
+
31
+ print_success() {
32
+ local msg="$1"
33
+ echo -e "${GREEN}[SUCCESS]${NC} $msg"
34
+ return 0
35
+ }
36
+
37
+ print_warning() {
38
+ local msg="$1"
39
+ echo -e "${YELLOW}[WARNING]${NC} $msg"
40
+ return 0
41
+ }
42
+
43
+ print_error() {
44
+ local msg="$1"
45
+ echo -e "${RED}[ERROR]${NC} $msg" >&2
46
+ return 0
47
+ }
48
+
49
+ # Configuration file
50
+ CONFIG_FILE="../configs/hostinger-config.json"
51
+
52
+ # Check if config file exists
53
+ check_config() {
54
+ if [[ ! -f "$CONFIG_FILE" ]]; then
55
+ print_error "$ERROR_CONFIG_NOT_FOUND"
56
+ print_info "Copy and customize: cp ../configs/hostinger-config.json.txt $CONFIG_FILE"
57
+ exit 1
58
+ fi
59
+
60
+ if ! jq empty "$CONFIG_FILE" 2>/dev/null; then
61
+ print_error "$ERROR_INVALID_JSON"
62
+ exit 1
63
+ fi
64
+
65
+ return 0
66
+ }
67
+
68
+ # List all sites
69
+ list_sites() {
70
+ check_config
71
+ print_info "Available Hostinger sites:"
72
+
73
+ sites=$(jq -r '.sites | keys[]' "$CONFIG_FILE")
74
+ for site in $sites; do
75
+ description=$(jq -r ".sites.$site.description" "$CONFIG_FILE")
76
+ path=$(jq -r ".sites.$site.domain_path" "$CONFIG_FILE")
77
+ echo " - $site: $description ($path)"
78
+ done
79
+
80
+ return 0
81
+ }
82
+
83
+ # Connect to a specific site
84
+ connect_site() {
85
+ local site="$1"
86
+ check_config
87
+
88
+ if [[ -z "$site" ]]; then
89
+ print_error "Please specify a site name"
90
+ list_sites
91
+ exit 1
92
+ fi
93
+
94
+ # Get site configuration
95
+ local server
96
+ local port
97
+ local username
98
+ local password_file
99
+ local domain_path
100
+ server=$(jq -r ".sites.$site.server" "$CONFIG_FILE")
101
+ port=$(jq -r ".sites.$site.port" "$CONFIG_FILE")
102
+ username=$(jq -r ".sites.$site.username" "$CONFIG_FILE")
103
+ password_file=$(jq -r ".sites.$site.password_file" "$CONFIG_FILE")
104
+ domain_path=$(jq -r ".sites.$site.domain_path" "$CONFIG_FILE")
105
+
106
+ if [[ "$server" == "null" ]]; then
107
+ print_error "Site not found: $site"
108
+ list_sites
109
+ exit 1
110
+ fi
111
+
112
+ print_info "Connecting to $site..."
113
+
114
+ # Check if password file exists
115
+ password_file="${password_file/\~/$HOME}"
116
+ if [[ ! -f "$password_file" ]]; then
117
+ print_error "Password file not found: $password_file"
118
+ print_info "Create password file: echo 'your-password' > $password_file && chmod 600 $password_file"
119
+ exit 1
120
+ fi
121
+
122
+ # Connect with sshpass
123
+ sshpass -f "$password_file" ssh -p "$port" "$username@$server" -t "cd $domain_path && bash" || exit
124
+ return 0
125
+ }
126
+
127
+ # Execute command on site
128
+ exec_on_site() {
129
+ local site="$1"
130
+ local command="$2"
131
+ check_config
132
+
133
+ if [[ -z "$site" || -z "$command" ]]; then
134
+ print_error "Usage: exec [site] [command]"
135
+ exit 1
136
+ fi
137
+
138
+ # Get site configuration
139
+ local server
140
+ local port
141
+ local username
142
+ local password_file
143
+ local domain_path
144
+ server=$(jq -r ".sites.$site.server" "$CONFIG_FILE")
145
+ port=$(jq -r ".sites.$site.port" "$CONFIG_FILE")
146
+ username=$(jq -r ".sites.$site.username" "$CONFIG_FILE")
147
+ password_file=$(jq -r ".sites.$site.password_file" "$CONFIG_FILE")
148
+ domain_path=$(jq -r ".sites.$site.domain_path" "$CONFIG_FILE")
149
+
150
+ if [[ "$server" == "null" ]]; then
151
+ print_error "Site not found: $site"
152
+ exit 1
153
+ fi
154
+
155
+ password_file="${password_file/\~/$HOME}"
156
+ print_info "Executing '$command' on $site..."
157
+
158
+ sshpass -f "$password_file" ssh -p "$port" "$username@$server" "cd $domain_path && $command" || exit
159
+ return 0
160
+ }
161
+
162
+ # API operations
163
+ api_call() {
164
+ local endpoint="$1"
165
+ check_config
166
+
167
+ local api_token
168
+ local base_url
169
+ api_token=$(jq -r '.api.token' "$CONFIG_FILE")
170
+ base_url=$(jq -r '.api.base_url' "$CONFIG_FILE")
171
+
172
+ if [[ "$api_token" == "null" || "$api_token" == "YOUR_HOSTINGER_API_TOKEN_HERE" ]]; then
173
+ print_error "API token not configured"
174
+ exit 1
175
+ fi
176
+
177
+ curl -s -H "$AUTH_HEADER_PREFIX $api_token" "$base_url/$endpoint"
178
+ return 0
179
+ }
180
+
181
+ # Main function
182
+ main() {
183
+ # Assign positional parameters to local variables
184
+ local command="${1:-help}"
185
+ local param2="$2"
186
+ local param3="$3"
187
+
188
+ # Main command handler
189
+ case "$command" in
190
+ "list")
191
+ list_sites
192
+ ;;
193
+ "connect")
194
+ connect_site "$param2"
195
+ ;;
196
+ "exec")
197
+ exec_on_site "$param2" "$param3"
198
+ ;;
199
+ "api")
200
+ api_call "$param2"
201
+ ;;
202
+ "help"|"-h"|"--help"|"")
203
+ echo "Hostinger Helper Script"
204
+ echo "Usage: $0 [command] [options]"
205
+ echo ""
206
+ echo "Commands:"
207
+ echo " list - List all configured sites"
208
+ echo " connect [site] - Connect to site directory via SSH"
209
+ echo " exec [site] [cmd] - Execute command on site"
210
+ echo " api [endpoint] - Make API call to Hostinger"
211
+ echo " help - $HELP_SHOW_MESSAGE"
212
+ echo ""
213
+ echo "Examples:"
214
+ echo " $0 list"
215
+ echo " $0 connect example.com"
216
+ echo " $0 exec example.com 'ls -la'"
217
+ echo " $0 api domains"
218
+ ;;
219
+ *)
220
+ print_error "$ERROR_UNKNOWN_COMMAND $command"
221
+ print_info "$HELP_USAGE_INFO"
222
+ exit 1
223
+ ;;
224
+ esac
225
+ return 0
226
+ }
227
+
228
+ # Run main function
229
+ main "$@"