kastell 1.4.0 → 1.5.2

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 (260) hide show
  1. package/README.md +56 -16
  2. package/README.tr.md +49 -16
  3. package/SECURITY.md +93 -6
  4. package/dist/adapters/coolify.d.ts +4 -3
  5. package/dist/adapters/coolify.d.ts.map +1 -1
  6. package/dist/adapters/coolify.js +106 -37
  7. package/dist/adapters/coolify.js.map +1 -1
  8. package/dist/adapters/dokploy.d.ts +5 -3
  9. package/dist/adapters/dokploy.d.ts.map +1 -1
  10. package/dist/adapters/dokploy.js +114 -37
  11. package/dist/adapters/dokploy.js.map +1 -1
  12. package/dist/adapters/factory.d.ts +1 -0
  13. package/dist/adapters/factory.d.ts.map +1 -1
  14. package/dist/adapters/factory.js +20 -0
  15. package/dist/adapters/factory.js.map +1 -1
  16. package/dist/adapters/interface.d.ts +12 -2
  17. package/dist/adapters/interface.d.ts.map +1 -1
  18. package/dist/adapters/shared.d.ts +13 -0
  19. package/dist/adapters/shared.d.ts.map +1 -0
  20. package/dist/adapters/shared.js +75 -0
  21. package/dist/adapters/shared.js.map +1 -0
  22. package/dist/commands/add.js +4 -4
  23. package/dist/commands/add.js.map +1 -1
  24. package/dist/commands/audit.d.ts +19 -0
  25. package/dist/commands/audit.d.ts.map +1 -0
  26. package/dist/commands/audit.js +134 -0
  27. package/dist/commands/audit.js.map +1 -0
  28. package/dist/commands/auth.d.ts +6 -0
  29. package/dist/commands/auth.d.ts.map +1 -0
  30. package/dist/commands/auth.js +78 -0
  31. package/dist/commands/auth.js.map +1 -0
  32. package/dist/commands/destroy.d.ts.map +1 -1
  33. package/dist/commands/destroy.js +1 -2
  34. package/dist/commands/destroy.js.map +1 -1
  35. package/dist/commands/domain.d.ts.map +1 -1
  36. package/dist/commands/domain.js +9 -0
  37. package/dist/commands/domain.js.map +1 -1
  38. package/dist/commands/firewall.d.ts +1 -1
  39. package/dist/commands/firewall.d.ts.map +1 -1
  40. package/dist/commands/firewall.js +5 -3
  41. package/dist/commands/firewall.js.map +1 -1
  42. package/dist/commands/health.d.ts.map +1 -1
  43. package/dist/commands/health.js +11 -4
  44. package/dist/commands/health.js.map +1 -1
  45. package/dist/commands/init.d.ts.map +1 -1
  46. package/dist/commands/init.js +6 -3
  47. package/dist/commands/init.js.map +1 -1
  48. package/dist/commands/interactive.d.ts.map +1 -1
  49. package/dist/commands/interactive.js +23 -0
  50. package/dist/commands/interactive.js.map +1 -1
  51. package/dist/commands/maintain.d.ts.map +1 -1
  52. package/dist/commands/maintain.js +98 -190
  53. package/dist/commands/maintain.js.map +1 -1
  54. package/dist/commands/restore.d.ts.map +1 -1
  55. package/dist/commands/restore.js +58 -140
  56. package/dist/commands/restore.js.map +1 -1
  57. package/dist/commands/snapshot.d.ts.map +1 -1
  58. package/dist/commands/snapshot.js +5 -0
  59. package/dist/commands/snapshot.js.map +1 -1
  60. package/dist/commands/status.d.ts.map +1 -1
  61. package/dist/commands/status.js +18 -11
  62. package/dist/commands/status.js.map +1 -1
  63. package/dist/commands/transfer.d.ts.map +1 -1
  64. package/dist/commands/transfer.js +14 -0
  65. package/dist/commands/transfer.js.map +1 -1
  66. package/dist/constants.d.ts +4 -2
  67. package/dist/constants.d.ts.map +1 -1
  68. package/dist/constants.js +8 -3
  69. package/dist/constants.js.map +1 -1
  70. package/dist/core/audit/checks/auth.d.ts +7 -0
  71. package/dist/core/audit/checks/auth.d.ts.map +1 -0
  72. package/dist/core/audit/checks/auth.js +123 -0
  73. package/dist/core/audit/checks/auth.js.map +1 -0
  74. package/dist/core/audit/checks/docker.d.ts +8 -0
  75. package/dist/core/audit/checks/docker.d.ts.map +1 -0
  76. package/dist/core/audit/checks/docker.js +155 -0
  77. package/dist/core/audit/checks/docker.js.map +1 -0
  78. package/dist/core/audit/checks/filesystem.d.ts +7 -0
  79. package/dist/core/audit/checks/filesystem.d.ts.map +1 -0
  80. package/dist/core/audit/checks/filesystem.js +117 -0
  81. package/dist/core/audit/checks/filesystem.js.map +1 -0
  82. package/dist/core/audit/checks/firewall.d.ts +7 -0
  83. package/dist/core/audit/checks/firewall.d.ts.map +1 -0
  84. package/dist/core/audit/checks/firewall.js +88 -0
  85. package/dist/core/audit/checks/firewall.js.map +1 -0
  86. package/dist/core/audit/checks/index.d.ts +22 -0
  87. package/dist/core/audit/checks/index.d.ts.map +1 -0
  88. package/dist/core/audit/checks/index.js +63 -0
  89. package/dist/core/audit/checks/index.js.map +1 -0
  90. package/dist/core/audit/checks/kernel.d.ts +7 -0
  91. package/dist/core/audit/checks/kernel.d.ts.map +1 -0
  92. package/dist/core/audit/checks/kernel.js +113 -0
  93. package/dist/core/audit/checks/kernel.js.map +1 -0
  94. package/dist/core/audit/checks/logging.d.ts +7 -0
  95. package/dist/core/audit/checks/logging.d.ts.map +1 -0
  96. package/dist/core/audit/checks/logging.js +110 -0
  97. package/dist/core/audit/checks/logging.js.map +1 -0
  98. package/dist/core/audit/checks/network.d.ts +7 -0
  99. package/dist/core/audit/checks/network.d.ts.map +1 -0
  100. package/dist/core/audit/checks/network.js +118 -0
  101. package/dist/core/audit/checks/network.js.map +1 -0
  102. package/dist/core/audit/checks/ssh.d.ts +7 -0
  103. package/dist/core/audit/checks/ssh.d.ts.map +1 -0
  104. package/dist/core/audit/checks/ssh.js +109 -0
  105. package/dist/core/audit/checks/ssh.js.map +1 -0
  106. package/dist/core/audit/checks/updates.d.ts +7 -0
  107. package/dist/core/audit/checks/updates.d.ts.map +1 -0
  108. package/dist/core/audit/checks/updates.js +97 -0
  109. package/dist/core/audit/checks/updates.js.map +1 -0
  110. package/dist/core/audit/commands.d.ts +28 -0
  111. package/dist/core/audit/commands.d.ts.map +1 -0
  112. package/dist/core/audit/commands.js +165 -0
  113. package/dist/core/audit/commands.js.map +1 -0
  114. package/dist/core/audit/fix.d.ts +46 -0
  115. package/dist/core/audit/fix.d.ts.map +1 -0
  116. package/dist/core/audit/fix.js +146 -0
  117. package/dist/core/audit/fix.js.map +1 -0
  118. package/dist/core/audit/formatters/badge.d.ts +11 -0
  119. package/dist/core/audit/formatters/badge.d.ts.map +1 -0
  120. package/dist/core/audit/formatters/badge.js +46 -0
  121. package/dist/core/audit/formatters/badge.js.map +1 -0
  122. package/dist/core/audit/formatters/index.d.ts +22 -0
  123. package/dist/core/audit/formatters/index.d.ts.map +1 -0
  124. package/dist/core/audit/formatters/index.js +38 -0
  125. package/dist/core/audit/formatters/index.js.map +1 -0
  126. package/dist/core/audit/formatters/json.d.ts +8 -0
  127. package/dist/core/audit/formatters/json.d.ts.map +1 -0
  128. package/dist/core/audit/formatters/json.js +9 -0
  129. package/dist/core/audit/formatters/json.js.map +1 -0
  130. package/dist/core/audit/formatters/report.d.ts +14 -0
  131. package/dist/core/audit/formatters/report.d.ts.map +1 -0
  132. package/dist/core/audit/formatters/report.js +156 -0
  133. package/dist/core/audit/formatters/report.js.map +1 -0
  134. package/dist/core/audit/formatters/summary.d.ts +10 -0
  135. package/dist/core/audit/formatters/summary.d.ts.map +1 -0
  136. package/dist/core/audit/formatters/summary.js +45 -0
  137. package/dist/core/audit/formatters/summary.js.map +1 -0
  138. package/dist/core/audit/formatters/terminal.d.ts +11 -0
  139. package/dist/core/audit/formatters/terminal.d.ts.map +1 -0
  140. package/dist/core/audit/formatters/terminal.js +92 -0
  141. package/dist/core/audit/formatters/terminal.js.map +1 -0
  142. package/dist/core/audit/history.d.ts +22 -0
  143. package/dist/core/audit/history.d.ts.map +1 -0
  144. package/dist/core/audit/history.js +108 -0
  145. package/dist/core/audit/history.js.map +1 -0
  146. package/dist/core/audit/index.d.ts +17 -0
  147. package/dist/core/audit/index.d.ts.map +1 -0
  148. package/dist/core/audit/index.js +59 -0
  149. package/dist/core/audit/index.js.map +1 -0
  150. package/dist/core/audit/quickwin.d.ts +16 -0
  151. package/dist/core/audit/quickwin.d.ts.map +1 -0
  152. package/dist/core/audit/quickwin.js +67 -0
  153. package/dist/core/audit/quickwin.js.map +1 -0
  154. package/dist/core/audit/scoring.d.ts +21 -0
  155. package/dist/core/audit/scoring.d.ts.map +1 -0
  156. package/dist/core/audit/scoring.js +44 -0
  157. package/dist/core/audit/scoring.js.map +1 -0
  158. package/dist/core/audit/types.d.ts +47 -0
  159. package/dist/core/audit/types.d.ts.map +1 -0
  160. package/dist/core/audit/types.js +6 -0
  161. package/dist/core/audit/types.js.map +1 -0
  162. package/dist/core/audit/watch.d.ts +19 -0
  163. package/dist/core/audit/watch.d.ts.map +1 -0
  164. package/dist/core/audit/watch.js +104 -0
  165. package/dist/core/audit/watch.js.map +1 -0
  166. package/dist/core/auth.d.ts +6 -0
  167. package/dist/core/auth.d.ts.map +1 -0
  168. package/dist/core/auth.js +80 -0
  169. package/dist/core/auth.js.map +1 -0
  170. package/dist/core/backup.d.ts.map +1 -1
  171. package/dist/core/backup.js +52 -85
  172. package/dist/core/backup.js.map +1 -1
  173. package/dist/core/deploy.d.ts +10 -1
  174. package/dist/core/deploy.d.ts.map +1 -1
  175. package/dist/core/deploy.js +296 -260
  176. package/dist/core/deploy.js.map +1 -1
  177. package/dist/core/firewall.d.ts +5 -2
  178. package/dist/core/firewall.d.ts.map +1 -1
  179. package/dist/core/firewall.js +14 -5
  180. package/dist/core/firewall.js.map +1 -1
  181. package/dist/core/logs.d.ts.map +1 -1
  182. package/dist/core/logs.js +5 -4
  183. package/dist/core/logs.js.map +1 -1
  184. package/dist/core/maintain.d.ts +1 -1
  185. package/dist/core/maintain.d.ts.map +1 -1
  186. package/dist/core/maintain.js +4 -4
  187. package/dist/core/maintain.js.map +1 -1
  188. package/dist/core/manage.d.ts +1 -1
  189. package/dist/core/manage.d.ts.map +1 -1
  190. package/dist/core/manage.js +20 -9
  191. package/dist/core/manage.js.map +1 -1
  192. package/dist/core/status.d.ts +1 -1
  193. package/dist/core/status.d.ts.map +1 -1
  194. package/dist/core/status.js +7 -4
  195. package/dist/core/status.js.map +1 -1
  196. package/dist/core/tokenBuffer.d.ts +5 -0
  197. package/dist/core/tokenBuffer.d.ts.map +1 -0
  198. package/dist/core/tokenBuffer.js +36 -0
  199. package/dist/core/tokenBuffer.js.map +1 -0
  200. package/dist/core/tokens.d.ts +4 -0
  201. package/dist/core/tokens.d.ts.map +1 -1
  202. package/dist/core/tokens.js +24 -1
  203. package/dist/core/tokens.js.map +1 -1
  204. package/dist/index.js +18 -0
  205. package/dist/index.js.map +1 -1
  206. package/dist/mcp/server.d.ts.map +1 -1
  207. package/dist/mcp/server.js +14 -0
  208. package/dist/mcp/server.js.map +1 -1
  209. package/dist/mcp/tools/serverAudit.d.ts +15 -0
  210. package/dist/mcp/tools/serverAudit.d.ts.map +1 -0
  211. package/dist/mcp/tools/serverAudit.js +68 -0
  212. package/dist/mcp/tools/serverAudit.js.map +1 -0
  213. package/dist/mcp/tools/serverInfo.d.ts.map +1 -1
  214. package/dist/mcp/tools/serverInfo.js +27 -15
  215. package/dist/mcp/tools/serverInfo.js.map +1 -1
  216. package/dist/mcp/tools/serverManage.js +2 -2
  217. package/dist/mcp/tools/serverManage.js.map +1 -1
  218. package/dist/mcp/tools/serverSecure.d.ts.map +1 -1
  219. package/dist/mcp/tools/serverSecure.js +10 -6
  220. package/dist/mcp/tools/serverSecure.js.map +1 -1
  221. package/dist/providers/base.d.ts +13 -0
  222. package/dist/providers/base.d.ts.map +1 -1
  223. package/dist/providers/base.js +27 -0
  224. package/dist/providers/base.js.map +1 -1
  225. package/dist/providers/digitalocean.d.ts.map +1 -1
  226. package/dist/providers/digitalocean.js +27 -27
  227. package/dist/providers/digitalocean.js.map +1 -1
  228. package/dist/providers/hetzner.d.ts.map +1 -1
  229. package/dist/providers/hetzner.js +28 -28
  230. package/dist/providers/hetzner.js.map +1 -1
  231. package/dist/providers/linode.d.ts.map +1 -1
  232. package/dist/providers/linode.js +28 -29
  233. package/dist/providers/linode.js.map +1 -1
  234. package/dist/providers/vultr.d.ts.map +1 -1
  235. package/dist/providers/vultr.js +27 -27
  236. package/dist/providers/vultr.js.map +1 -1
  237. package/dist/types/index.d.ts +2 -0
  238. package/dist/types/index.d.ts.map +1 -1
  239. package/dist/utils/cloudInit.d.ts +0 -1
  240. package/dist/utils/cloudInit.d.ts.map +1 -1
  241. package/dist/utils/cloudInit.js +1 -71
  242. package/dist/utils/cloudInit.js.map +1 -1
  243. package/dist/utils/config.d.ts +1 -0
  244. package/dist/utils/config.d.ts.map +1 -1
  245. package/dist/utils/config.js +23 -2
  246. package/dist/utils/config.js.map +1 -1
  247. package/dist/utils/ssh.d.ts +9 -1
  248. package/dist/utils/ssh.d.ts.map +1 -1
  249. package/dist/utils/ssh.js +24 -11
  250. package/dist/utils/ssh.js.map +1 -1
  251. package/dist/utils/updateCheck.js +1 -1
  252. package/dist/utils/updateCheck.js.map +1 -1
  253. package/dist/utils/yamlConfig.d.ts.map +1 -1
  254. package/dist/utils/yamlConfig.js +4 -1
  255. package/dist/utils/yamlConfig.js.map +1 -1
  256. package/package.json +7 -3
  257. package/dist/utils/logo.d.ts +0 -2
  258. package/dist/utils/logo.d.ts.map +0 -1
  259. package/dist/utils/logo.js +0 -10
  260. package/dist/utils/logo.js.map +0 -1
package/README.md CHANGED
@@ -14,8 +14,6 @@
14
14
  ![License](https://img.shields.io/badge/license-Apache%202.0-blue)
15
15
  ![GitHub stars](https://img.shields.io/github/stars/kastelldev/kastell?style=flat-square)
16
16
  [![Socket Badge](https://socket.dev/api/badge/npm/package/kastell)](https://socket.dev/npm/package/kastell)
17
- [![Website](https://img.shields.io/website?url=https%3A%2F%2Fkastell.dev&label=website)](https://kastell.dev)
18
-
19
17
  ## Why Kastell Exists
20
18
 
21
19
  Most self-hosted servers break because:
@@ -45,7 +43,7 @@ Running `kastell` without any arguments launches an **interactive search menu**
45
43
  ██║ ██╗ ██║ ██║ ███████║ ██║ ███████╗███████╗███████╗
46
44
  ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚══════╝╚══════╝╚══════╝
47
45
 
48
- KASTELL v1.4.0 · Your infrastructure, fortified.
46
+ KASTELL v1.5.2 · Your infrastructure, fortified.
49
47
 
50
48
  $ kastell init --template production → deploy a new server
51
49
  $ kastell status --all → check all servers
@@ -150,6 +148,22 @@ kastell secure setup my-server # SSH hardening + fail2ban
150
148
  kastell domain add my-server --domain example.com # Set domain + SSL
151
149
  ```
152
150
 
151
+ ### Security Audit
152
+ ```bash
153
+ kastell audit my-server # Full security audit (9 categories, 46+ checks)
154
+ kastell audit my-server --json # JSON output for automation
155
+ kastell audit my-server --threshold 70 # Exit code 1 if score below threshold
156
+ kastell audit my-server --fix # Interactive fix mode (prompts per severity)
157
+ kastell audit my-server --fix --dry-run # Preview fixes without executing
158
+ kastell audit my-server --watch # Re-audit every 5 min, show only changes
159
+ kastell audit my-server --watch 60 # Custom interval (60 seconds)
160
+ kastell audit --host root@1.2.3.4 # Audit unregistered server
161
+ kastell audit my-server --badge # SVG badge output
162
+ kastell audit my-server --report html # Full HTML report
163
+ kastell audit my-server --score-only # Just the score (CI-friendly)
164
+ kastell audit my-server --summary # Compact dashboard view
165
+ ```
166
+
153
167
  ### Monitor & Debug
154
168
  ```bash
155
169
  kastell monitor my-server # CPU, RAM, disk usage
@@ -163,20 +177,20 @@ kastell doctor # Check local environment
163
177
 
164
178
  | Provider | Status | Regions | Starting Price |
165
179
  |----------|--------|---------|---------------|
166
- | [Hetzner Cloud](https://hetzner.cloud) | Stable | EU, US | ~EUR4/mo |
180
+ | [Hetzner Cloud](https://hetzner.cloud) | Stable | EU, US | ~€4/mo |
167
181
  | [DigitalOcean](https://digitalocean.com) | Stable | Global | ~$18/mo |
168
- | [Vultr](https://vultr.com) | Stable | Global | ~$10/mo |
169
- | [Linode (Akamai)](https://linode.com) | Beta | Global | ~$24/mo |
182
+ | [Vultr](https://vultr.com) | Stable | Global | ~$12/mo |
183
+ | [Linode (Akamai)](https://linode.com) | Beta | Global | ~$12/mo |
170
184
 
171
- > Prices reflect the default starter template per provider. You can choose a different size during setup. Linode support is in beta -- community testing welcome.
185
+ > Prices reflect the cheapest plan with at least 2 GB RAM (required by Coolify and Dokploy). Bare mode has no minimum requirements -- plans start from ~$2.50/mo depending on provider. You can choose a different size during setup. Linode support is in beta -- community testing welcome.
172
186
 
173
187
  ## Supported Platforms
174
188
 
175
- | Platform | Mode Flag | Description |
176
- |----------|-----------|-------------|
177
- | Coolify | `--mode coolify` (default) | Docker-based PaaS |
178
- | Dokploy | `--mode dokploy` | Docker Swarm-based PaaS |
179
- | Bare | `--mode bare` | Generic VPS (no platform) |
189
+ | Platform | Mode Flag | Min RAM | Min CPU | Description |
190
+ |----------|-----------|---------|---------|-------------|
191
+ | Coolify | `--mode coolify` (default) | 2 GB | 2 vCPU | Docker-based PaaS (port 8000) |
192
+ | Dokploy | `--mode dokploy` | 2 GB | 2 vCPU | Docker Swarm-based PaaS (port 3000) |
193
+ | Bare | `--mode bare` | — | — | Generic VPS, no platform overhead |
180
194
 
181
195
  Kastell uses a **PlatformAdapter** architecture -- the same commands (`update`, `maintain`, `logs`, `health`) work across all platforms. The platform is stored in your server record and auto-detected on each command.
182
196
 
@@ -294,15 +308,41 @@ Available tools:
294
308
  | `server_secure` | secure, firewall, domain | SSH hardening, firewall rules, domain/SSL management (10 subcommands) |
295
309
  | `server_backup` | backup, snapshot | Backup/restore databases and create/manage VPS snapshots |
296
310
  | `server_provision` | create | Provision new servers on cloud providers |
311
+ | `server_audit` | audit | Run security audit with summary/json/score output formats |
297
312
 
298
313
  > All destructive operations (destroy, restore, snapshot-delete, provision, restart, maintain, snapshot-create) require `SAFE_MODE=false` to execute.
299
314
 
315
+ ## CI/CD Integration
316
+
317
+ Use `kastell audit` in your CI pipeline to enforce security baselines:
318
+
319
+ ```yaml
320
+ # .github/workflows/security-audit.yml
321
+ name: Security Audit
322
+ on:
323
+ schedule:
324
+ - cron: '0 6 * * 1' # Weekly Monday 6 AM
325
+ workflow_dispatch:
326
+ jobs:
327
+ audit:
328
+ runs-on: ubuntu-latest
329
+ steps:
330
+ - uses: actions/checkout@v4
331
+ - run: npm install -g kastell
332
+ - run: kastell audit --host root@${{ secrets.SERVER_IP }} --threshold 70 --json > audit-result.json
333
+ - uses: actions/upload-artifact@v4
334
+ with:
335
+ name: audit-report
336
+ path: audit-result.json
337
+ ```
338
+
339
+ The `--threshold` flag causes a non-zero exit code when the score falls below the target, failing the CI job automatically.
340
+
300
341
  ## What's Next
301
342
 
302
- - `kastell audit` -- security scanning and compliance reports (v1.5)
303
- - kastell.dev website (v1.5)
304
- - Guard daemon and fleet management (v1.6)
305
- - Plugin ecosystem for AI IDEs (v2.0)
343
+ - kastell.dev website
344
+ - Guard daemon and fleet management
345
+ - Plugin ecosystem for AI IDEs
306
346
 
307
347
  ## Philosophy
308
348
 
package/README.tr.md CHANGED
@@ -14,8 +14,6 @@
14
14
  ![License](https://img.shields.io/badge/license-Apache%202.0-blue)
15
15
  ![GitHub stars](https://img.shields.io/github/stars/kastelldev/kastell?style=flat-square)
16
16
  [![Socket Badge](https://socket.dev/api/badge/npm/package/kastell)](https://socket.dev/npm/package/kastell)
17
- [![Website](https://img.shields.io/website?url=https%3A%2F%2Fkastell.dev&label=website)](https://kastell.dev)
18
-
19
17
  ## Kastell Neden Var?
20
18
 
21
19
  Self-hosted sunucuların çoğu şu nedenlerle çöker:
@@ -45,7 +43,7 @@ npx kastell
45
43
  ██║ ██╗ ██║ ██║ ███████║ ██║ ███████╗███████╗███████╗
46
44
  ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚══════╝╚══════╝╚══════╝
47
45
 
48
- KASTELL v1.4.0 · Your infrastructure, fortified.
46
+ KASTELL v1.5.1 · Your infrastructure, fortified.
49
47
 
50
48
  $ kastell init --template production → deploy a new server
51
49
  $ kastell status --all → check all servers
@@ -150,6 +148,22 @@ kastell secure setup sunucum # SSH sıkılaştırma + fail2ban
150
148
  kastell domain add sunucum --domain ornek.com # Domain + SSL ayarla
151
149
  ```
152
150
 
151
+ ### Güvenlik Denetimi
152
+ ```bash
153
+ kastell audit sunucum # Tam güvenlik denetimi (9 kategori, 46+ kontrol)
154
+ kastell audit sunucum --json # Otomasyon için JSON çıktısı
155
+ kastell audit sunucum --threshold 70 # Skor eşiğin altındaysa exit code 1
156
+ kastell audit sunucum --fix # İnteraktif düzeltme modu (önem derecesine göre)
157
+ kastell audit sunucum --fix --dry-run # Düzeltmeleri çalıştırmadan önizle
158
+ kastell audit sunucum --watch # 5 dk aralıkla tekrar denetle, sadece değişiklikleri göster
159
+ kastell audit sunucum --watch 60 # Özel aralık (60 saniye)
160
+ kastell audit --host root@1.2.3.4 # Kayıtlı olmayan sunucuyu denetle
161
+ kastell audit sunucum --badge # SVG rozet çıktısı
162
+ kastell audit sunucum --report html # Tam HTML raporu
163
+ kastell audit sunucum --score-only # Sadece skor (CI uyumlu)
164
+ kastell audit sunucum --summary # Kompakt özet görünümü
165
+ ```
166
+
153
167
  ### İzleme ve Hata Ayıklama
154
168
  ```bash
155
169
  kastell monitor sunucum # CPU, RAM, disk kullanımı
@@ -163,20 +177,20 @@ kastell doctor # Yerel ortam kontrolü
163
177
 
164
178
  | Sağlayıcı | Durum | Bölgeler | Başlangıç Fiyatı |
165
179
  |-----------|-------|----------|------------------|
166
- | [Hetzner Cloud](https://hetzner.cloud) | Kararlı | Avrupa, ABD | ~EUR4/ay |
180
+ | [Hetzner Cloud](https://hetzner.cloud) | Kararlı | Avrupa, ABD | ~€4/ay |
167
181
  | [DigitalOcean](https://digitalocean.com) | Kararlı | Küresel | ~$18/ay |
168
- | [Vultr](https://vultr.com) | Kararlı | Küresel | ~$10/ay |
169
- | [Linode (Akamai)](https://linode.com) | Beta | Küresel | ~$24/ay |
182
+ | [Vultr](https://vultr.com) | Kararlı | Küresel | ~$12/ay |
183
+ | [Linode (Akamai)](https://linode.com) | Beta | Küresel | ~$12/ay |
170
184
 
171
- > Fiyatlar provider başına varsayılan starter şablonunu yansıtır. Kurulum sırasında farklı boyut seçebilirsiniz. Linode desteği beta aşamasındadır -- topluluk testleri memnuniyetle karşılanır.
185
+ > Fiyatlar en az 2 GB RAM'e sahip en ucuz planı yansıtır (Coolify ve Dokploy gereksinimi). Bare modda minimum gereksinim yoktur -- sağlayıcıya göre ~$2.50/ay'dan başlayan planlar kullanılabilir. Kurulum sırasında farklı boyut seçebilirsiniz. Linode desteği beta aşamasındadır -- topluluk testleri memnuniyetle karşılanır.
172
186
 
173
187
  ## Desteklenen Platformlar
174
188
 
175
- | Platform | Mod Bayrağı | Açıklama |
176
- |----------|-------------|----------|
177
- | Coolify | `--mode coolify` (varsayılan) | Docker tabanlı PaaS |
178
- | Dokploy | `--mode dokploy` | Docker Swarm tabanlı PaaS |
179
- | Bare | `--mode bare` | Genel VPS (platform yok) |
189
+ | Platform | Mod Bayrağı | Min RAM | Min CPU | Açıklama |
190
+ |----------|-------------|---------|---------|----------|
191
+ | Coolify | `--mode coolify` (varsayılan) | 2 GB | 2 vCPU | Docker tabanlı PaaS (port 8000) |
192
+ | Dokploy | `--mode dokploy` | 2 GB | 2 vCPU | Docker Swarm tabanlı PaaS (port 3000) |
193
+ | Bare | `--mode bare` | — | — | Genel VPS, platform yükü yok |
180
194
 
181
195
  Kastell **PlatformAdapter** mimarisini kullanır -- aynı komutlar (`update`, `maintain`, `logs`, `health`) tüm platformlarda çalışır. Platform sunucu kaydınızda saklanır ve her komutta otomatik algılanır.
182
196
 
@@ -294,15 +308,34 @@ Mevcut araçlar:
294
308
  | `server_secure` | secure, firewall, domain | SSH sıkılaştırma, güvenlik duvarı kuralları, domain/SSL yönetimi (10 alt komut) |
295
309
  | `server_backup` | backup, snapshot | Veritabanı yedekle/geri yükle ve VPS snapshot oluştur/yönet |
296
310
  | `server_provision` | create | Bulut sağlayıcılarda yeni sunucu oluştur |
311
+ | `server_audit` | audit | Güvenlik denetimi çalıştır (summary/json/score çıktı formatları) |
297
312
 
298
313
  > Tüm yıkıcı işlemler (destroy, restore, snapshot-delete, provision, restart, maintain, snapshot-create) çalıştırılmak için `SAFE_MODE=false` gerektirir.
299
314
 
315
+ `kastell audit` komutunu CI pipeline'ınızda güvenlik eşiği zorunluluğu için kullanın:
316
+
317
+ ```yaml
318
+ # .github/workflows/security-audit.yml
319
+ name: Güvenlik Denetimi
320
+ on:
321
+ schedule:
322
+ - cron: '0 6 * * 1' # Her Pazartesi 06:00
323
+ jobs:
324
+ audit:
325
+ runs-on: ubuntu-latest
326
+ steps:
327
+ - run: npx -y kastell audit --host root@${{ secrets.SERVER_IP }} --threshold 70 --json > audit-result.json
328
+ - uses: actions/upload-artifact@v4
329
+ with:
330
+ name: audit-report
331
+ path: audit-result.json
332
+ ```
333
+
300
334
  ## Gelecek Planlar
301
335
 
302
- - `kastell audit` -- güvenlik taraması ve uyumluluk raporları (v1.5)
303
- - kastell.dev web sitesi (v1.5)
304
- - Guard daemon ve fleet yönetimi (v1.6)
305
- - AI IDE'ler için plugin ekosistemi (v2.0)
336
+ - kastell.dev web sitesi
337
+ - Guard daemon ve fleet yönetimi
338
+ - AI IDE'ler için plugin ekosistemi
306
339
 
307
340
  ## Felsefe
308
341
 
package/SECURITY.md CHANGED
@@ -24,9 +24,11 @@ Response time: Within 48 hours
24
24
  ## Security Architecture
25
25
 
26
26
  ### Token Handling (A2 — Sensitive Data Exposure)
27
- - API tokens are **never stored on disk** runtime prompt or environment variables only
27
+ - Token resolution chain: OS keychain (primary) -> environment variable (fallback) -> undefined
28
28
  - Supported env vars: `HETZNER_TOKEN`, `DIGITALOCEAN_TOKEN`, `VULTR_TOKEN`, `LINODE_TOKEN`
29
- - API tokens collected via interactive secure prompts (masked input) when env vars are not set
29
+ - `kastell auth set <provider>` stores tokens in OS keychain (Windows Credential Manager, macOS Keychain, Linux Secret Service)
30
+ - Tokens are never written to disk in plaintext
31
+ - API tokens collected via interactive secure prompts (masked input) when neither keychain nor env var is available
30
32
  - `sanitizedEnv()` strips all keys containing TOKEN, SECRET, PASSWORD, CREDENTIAL from child process environments before every `spawn`/`spawnSync`/`exec` call
31
33
  - Provider errors sanitized via `stripSensitiveData()` — removes Authorization headers, request data, response headers, and non-whitelisted response body fields from axios errors before they propagate via error cause chains
32
34
 
@@ -102,13 +104,98 @@ All production dependencies use audited, versioned packages:
102
104
  - Linode API v4 (via Axios, HTTPS)
103
105
  - Model Context Protocol SDK (`@modelcontextprotocol/sdk`) for MCP server
104
106
  - Zod for runtime input validation
105
- - Coolify installed via `curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash` (official method, HTTPS)
107
+ - Coolify installed via download-then-execute pattern: `curl -fsSL URL -o /tmp/install.sh && bash /tmp/install.sh` (prevents partial execution on network failure)
106
108
 
107
109
  ### Dev Dependencies
108
- One moderate-severity ReDoS vulnerability remains in `test-exclude` → `glob` → `minimatch@10.0.0-10.2.2` (jest code coverage toolchain). This is a dev-only dependency not present in production builds. Remediation is blocked by the dependency chain — `npm audit fix --force` would cause lock file breakage per project policy. Risk accepted as dev-only, not exploitable in production.
110
+ No known vulnerabilities (minimatch pinned to ^10.2.4 via npm overrides).
109
111
 
110
112
  Security scan: https://socket.dev/npm/package/kastell
111
113
 
112
- ## HTTP Usage
114
+ ## Token Security
113
115
 
114
- Kastell accesses Coolify at `http://IP:8000` during initial setup. This is expected because SSL/TLS is not configured on a fresh Coolify installation. Users are warned to set up a domain and enable SSL for production use.
116
+ ### OS Keychain Integration
117
+
118
+ Kastell stores provider API tokens in the OS keychain using `@napi-rs/keyring`:
119
+
120
+ - **Windows:** Windows Credential Manager
121
+ - **macOS:** Keychain
122
+ - **Linux:** Secret Service (GNOME Keyring, KWallet)
123
+
124
+ Use `kastell auth set <provider>` to store tokens securely. Use `kastell auth list` to see which providers have stored tokens (token values are never displayed). Use `kastell auth remove <provider>` to delete a stored token.
125
+
126
+ In CI/headless environments where no keychain is available, Kastell automatically falls back to environment variables.
127
+
128
+ ### Subprocess Security
129
+
130
+ All child processes spawned by Kastell use `sanitizedEnv()` which strips TOKEN, SECRET, PASSWORD, and CREDENTIAL environment variables. This prevents accidental token leakage to SSH sessions and other subprocesses.
131
+
132
+ ### Disabling Core Dumps (Recommended for MCP/Long-Running Mode)
133
+
134
+ Core dumps can expose in-memory tokens. Disable on production servers:
135
+
136
+ **Linux:**
137
+ - `ulimit -c 0` (current session)
138
+ - `echo "* hard core 0" >> /etc/security/limits.conf` (permanent)
139
+
140
+ **macOS:**
141
+ - `launchctl limit core 0 0`
142
+
143
+ ### Swap Encryption (Recommended)
144
+
145
+ Unencrypted swap can expose in-memory tokens when pages are swapped to disk.
146
+
147
+ - **Linux:** Use encrypted swap (`cryptsetup` or `dm-crypt`)
148
+ - **macOS:** Encrypted by default with FileVault
149
+ - **Windows:** BitLocker encrypts the entire volume including pagefile
150
+
151
+ ## Known Limitations & Accepted Risks
152
+
153
+ ### 1. SSH Trust-On-First-Use (TOFU)
154
+
155
+ All SSH connections use `StrictHostKeyChecking=accept-new`. This automatically trusts the host key on first connection. A MITM attack during the very first SSH connection to a newly provisioned server would succeed silently.
156
+
157
+ **Why accepted:** Newly provisioned servers have unknown host keys — there is no known-good key to verify against. This is inherent to any server provisioning tool. Subsequent connections verify the stored key, so only the first connection is vulnerable.
158
+
159
+ **Mitigation:**
160
+ - Servers are provisioned via authenticated cloud provider APIs (HTTPS + API token), reducing the likelihood of a MITM during the narrow window between provision and first SSH connection.
161
+ - Set `KASTELL_STRICT_HOST_KEY=true` to reject unknown host keys entirely. This requires manual host key management but eliminates TOFU risk.
162
+
163
+ ### 2. Health Checks Over HTTP
164
+
165
+ Coolify (`http://IP:8000`) and Dokploy (`http://IP:3000`) health checks use unencrypted HTTP. No sensitive data is sent — only an HTTP status code is checked.
166
+
167
+ **Why accepted:** Fresh Coolify/Dokploy installations only listen on HTTP. HTTPS requires a domain + SSL certificate, which is configured after initial setup via `kastell domain-set --ssl`.
168
+
169
+ **Mitigation:** When a domain is configured via `kastell domain add --domain example.com`, health checks automatically try HTTPS first, falling back to HTTP only if HTTPS fails. The domain is stored in the server record for persistent HTTPS health checks.
170
+
171
+ **Recommendation:** Always configure a domain with SSL for production access: `kastell domain add <server> --domain example.com`
172
+
173
+ ### 3. API Token In-Memory Exposure
174
+
175
+ Provider API tokens are held as class properties in memory for the lifetime of the process.
176
+
177
+ **CLI mode (low risk):** Process runs for seconds, then exits. Token is freed with the process.
178
+
179
+ **MCP mode (elevated risk):** MCP server runs for hours. Token stays in memory and could theoretically be exposed via heap dump, core dump, or debugger attachment.
180
+
181
+ **Why accepted:** Node.js strings are immutable and managed by V8's garbage collector — there is no reliable way to zero a string in memory. Alternative approaches (Buffer-based token storage) would require changing all axios header construction and provide marginal benefit since `process.env` also holds the token in memory.
182
+
183
+ **Mitigations in place:**
184
+ - `sanitizedEnv()` strips tokens from all child process environments
185
+ - `stripSensitiveData()` removes Authorization headers from error objects
186
+ - Provider instances are not cached across MCP tool calls — each call creates a fresh instance, allowing GC to collect the previous one
187
+ - Tokens are never written to disk
188
+
189
+ **Future consideration:** Getter pattern that reads from `process.env` on each API call instead of storing as class property — reduces in-memory copies but does not eliminate the underlying exposure since `process.env` itself holds the value.
190
+
191
+ ### 4. Remote Install Scripts
192
+
193
+ Coolify and Dokploy are installed via remote shell scripts downloaded over HTTPS. A compromised CDN or DNS hijack could serve a malicious install script.
194
+
195
+ **Why accepted:** This is the official installation method provided by both Coolify and Dokploy upstream projects. There are no published checksums to verify against.
196
+
197
+ **Mitigations in place:**
198
+ - HTTPS transport security (TLS certificate validation)
199
+ - Download-then-execute pattern (prevents partial execution on network interruption)
200
+ - **Script validation before execution:** Downloaded scripts are verified to start with a shebang (`#!`) and have a minimum size (>100 bytes) before being executed. A truncated, empty, or non-script response will be rejected.
201
+ - Install scripts are downloaded to `/tmp/` and cleaned up after execution
@@ -1,12 +1,13 @@
1
- import type { PlatformAdapter, HealthResult, PlatformStatusResult, PlatformBackupResult, UpdateResult } from "./interface.js";
1
+ import type { PlatformAdapter, HealthResult, PlatformStatusResult, PlatformBackupResult, PlatformRestoreResult, UpdateResult } from "./interface.js";
2
+ import type { BackupManifest } from "../types/index.js";
2
3
  export declare class CoolifyAdapter implements PlatformAdapter {
3
4
  readonly name = "coolify";
4
5
  getCloudInit(serverName: string): string;
5
- healthCheck(ip: string): Promise<HealthResult>;
6
+ healthCheck(ip: string, domain?: string): Promise<HealthResult>;
6
7
  createBackup(ip: string, serverName: string, provider: string): Promise<PlatformBackupResult>;
8
+ restoreBackup(ip: string, backupPath: string, _manifest: BackupManifest): Promise<PlatformRestoreResult>;
7
9
  getStatus(ip: string): Promise<PlatformStatusResult>;
8
10
  update(ip: string): Promise<UpdateResult>;
9
- getLogCommand(lines: number, follow: boolean): string;
10
11
  private buildPgDumpCommand;
11
12
  private buildConfigTarCommand;
12
13
  private buildCleanupCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"coolify.d.ts","sourceRoot":"","sources":["../../src/adapters/coolify.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACb,MAAM,gBAAgB,CAAC;AAWxB,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAE1B,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAuElC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAa9C,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;IAuF1B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAWpD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAsB/C,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM;IAMrD,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;CAG5B"}
1
+ {"version":3,"file":"coolify.d.ts","sourceRoot":"","sources":["../../src/adapters/coolify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAmBxD,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAE1B,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAuElC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/D,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;IAuF1B,aAAa,CACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,qBAAqB,CAAC;IAkI3B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIpD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAM/C,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;CAG5B"}
@@ -1,10 +1,10 @@
1
- import axios from "axios";
2
1
  import { mkdirSync, writeFileSync } from "fs";
3
2
  import { join } from "path";
4
3
  import { COOLIFY_UPDATE_CMD } from "../constants.js";
5
4
  import { assertValidIp, sshExec } from "../utils/ssh.js";
6
- import { formatTimestamp, getBackupDir, scpDownload, } from "../core/backup.js";
5
+ import { formatTimestamp, getBackupDir, scpDownload, scpUpload, buildStopCoolifyCommand, buildStartCoolifyCommand, buildStartDbCommand, buildRestoreDbCommand, buildRestoreConfigCommand, buildCleanupCommand, tryRestartCoolify, } from "../core/backup.js";
7
6
  import { getErrorMessage, mapSshError, sanitizeStderr } from "../utils/errorMapper.js";
7
+ import { sharedHealthCheck, sharedUpdate, sharedGetStatus } from "./shared.js";
8
8
  export class CoolifyAdapter {
9
9
  name = "coolify";
10
10
  getCloudInit(serverName) {
@@ -40,7 +40,7 @@ apt-get update -y
40
40
 
41
41
  # Install Coolify
42
42
  echo "Installing Coolify..."
43
- curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
43
+ curl -fsSL https://cdn.coollabs.io/coolify/install.sh -o /tmp/coolify-install.sh && head -c2 /tmp/coolify-install.sh | grep -q "#!" && [ "$(wc -c < /tmp/coolify-install.sh)" -gt 100 ] && bash /tmp/coolify-install.sh && rm -f /tmp/coolify-install.sh
44
44
 
45
45
  # Wait for services
46
46
  echo "Waiting for Coolify services to start..."
@@ -77,18 +77,8 @@ echo "Please wait 3-5 more minutes for Coolify to fully initialize."
77
77
  echo "Then access your instance at: http://YOUR_SERVER_IP:8000"
78
78
  `;
79
79
  }
80
- async healthCheck(ip) {
81
- assertValidIp(ip);
82
- try {
83
- await axios.get(`http://${ip}:8000`, {
84
- timeout: 5000,
85
- validateStatus: () => true,
86
- });
87
- return { status: "running" };
88
- }
89
- catch {
90
- return { status: "not reachable" };
91
- }
80
+ async healthCheck(ip, domain) {
81
+ return sharedHealthCheck(ip, 8000, domain);
92
82
  }
93
83
  async createBackup(ip, serverName, provider) {
94
84
  assertValidIp(ip);
@@ -156,44 +146,123 @@ echo "Then access your instance at: http://YOUR_SERVER_IP:8000"
156
146
  };
157
147
  }
158
148
  }
159
- async getStatus(ip) {
160
- assertValidIp(ip);
161
- const versionResult = await sshExec(ip, this.buildVersionCommand());
162
- const platformVersion = versionResult.code === 0 ? versionResult.stdout.trim() : "unknown";
163
- const health = await this.healthCheck(ip);
164
- return {
165
- platformVersion,
166
- status: health.status,
167
- };
168
- }
169
- async update(ip) {
149
+ async restoreBackup(ip, backupPath, _manifest) {
170
150
  assertValidIp(ip);
151
+ const steps = [];
171
152
  try {
172
- const result = await sshExec(ip, COOLIFY_UPDATE_CMD);
173
- if (result.code === 0) {
174
- return { success: true, output: result.stdout || undefined };
153
+ // Upload backup files (before stopping Coolify -- safe to fail here)
154
+ const dbUpload = await scpUpload(ip, join(backupPath, "coolify-backup.sql.gz"), "/tmp/coolify-backup.sql.gz");
155
+ if (dbUpload.code !== 0) {
156
+ return {
157
+ success: false,
158
+ steps: [
159
+ {
160
+ name: "Upload database backup",
161
+ status: "failure",
162
+ error: sanitizeStderr(dbUpload.stderr),
163
+ },
164
+ ],
165
+ error: "Failed to upload database backup",
166
+ };
175
167
  }
176
- return {
177
- success: false,
178
- error: `Update failed (exit code ${result.code})`,
179
- output: result.stderr || result.stdout || undefined,
180
- };
168
+ steps.push({ name: "Upload database backup", status: "success" });
169
+ const configUpload = await scpUpload(ip, join(backupPath, "coolify-config.tar.gz"), "/tmp/coolify-config.tar.gz");
170
+ if (configUpload.code !== 0) {
171
+ return {
172
+ success: false,
173
+ steps: [
174
+ ...steps,
175
+ {
176
+ name: "Upload config backup",
177
+ status: "failure",
178
+ error: sanitizeStderr(configUpload.stderr),
179
+ },
180
+ ],
181
+ error: "Failed to upload config backup",
182
+ };
183
+ }
184
+ steps.push({ name: "Upload config backup", status: "success" });
185
+ // Step 1: Stop Coolify
186
+ const stopResult = await sshExec(ip, buildStopCoolifyCommand());
187
+ if (stopResult.code !== 0) {
188
+ steps.push({
189
+ name: "Stop Coolify",
190
+ status: "failure",
191
+ error: sanitizeStderr(stopResult.stderr),
192
+ });
193
+ return { success: false, steps, error: "Failed to stop Coolify" };
194
+ }
195
+ steps.push({ name: "Stop Coolify", status: "success" });
196
+ // Step 2: Start DB only
197
+ const dbStartResult = await sshExec(ip, buildStartDbCommand());
198
+ if (dbStartResult.code !== 0) {
199
+ steps.push({
200
+ name: "Start database",
201
+ status: "failure",
202
+ error: sanitizeStderr(dbStartResult.stderr),
203
+ });
204
+ await tryRestartCoolify(ip);
205
+ return { success: false, steps, error: "Failed to start database" };
206
+ }
207
+ steps.push({ name: "Start database", status: "success" });
208
+ // Step 3: Restore database
209
+ const restoreDbResult = await sshExec(ip, buildRestoreDbCommand());
210
+ if (restoreDbResult.code !== 0) {
211
+ steps.push({
212
+ name: "Restore database",
213
+ status: "failure",
214
+ error: sanitizeStderr(restoreDbResult.stderr),
215
+ });
216
+ await tryRestartCoolify(ip);
217
+ return { success: false, steps, error: "Database restore failed" };
218
+ }
219
+ steps.push({ name: "Restore database", status: "success" });
220
+ // Step 4: Restore config
221
+ const restoreConfigResult = await sshExec(ip, buildRestoreConfigCommand());
222
+ if (restoreConfigResult.code !== 0) {
223
+ steps.push({
224
+ name: "Restore config",
225
+ status: "failure",
226
+ error: sanitizeStderr(restoreConfigResult.stderr),
227
+ });
228
+ await tryRestartCoolify(ip);
229
+ return { success: false, steps, error: "Config restore failed" };
230
+ }
231
+ steps.push({ name: "Restore config", status: "success" });
232
+ // Step 5: Start Coolify
233
+ const startResult = await sshExec(ip, buildStartCoolifyCommand());
234
+ if (startResult.code !== 0) {
235
+ steps.push({
236
+ name: "Start Coolify",
237
+ status: "failure",
238
+ error: sanitizeStderr(startResult.stderr),
239
+ });
240
+ return { success: false, steps, error: "Failed to start Coolify" };
241
+ }
242
+ steps.push({ name: "Start Coolify", status: "success" });
243
+ // Cleanup remote (best-effort)
244
+ await sshExec(ip, buildCleanupCommand()).catch(() => { });
245
+ return { success: true, steps };
181
246
  }
182
247
  catch (error) {
183
248
  const hint = mapSshError(error, ip);
184
249
  return {
185
250
  success: false,
251
+ steps,
186
252
  error: getErrorMessage(error),
187
253
  ...(hint ? { hint } : {}),
188
254
  };
189
255
  }
190
256
  }
191
- getLogCommand(lines, follow) {
192
- return `docker logs coolify --tail ${lines}${follow ? " --follow" : ""}`;
257
+ async getStatus(ip) {
258
+ return sharedGetStatus(ip, this.buildVersionCommand(), 8000);
259
+ }
260
+ async update(ip) {
261
+ return sharedUpdate(ip, COOLIFY_UPDATE_CMD);
193
262
  }
194
263
  // ─── Private Helpers ────────────────────────────────────────────────────────
195
264
  buildPgDumpCommand() {
196
- return "docker exec coolify-db pg_dump -U coolify -d coolify | gzip > /tmp/coolify-backup.sql.gz";
265
+ return "set -o pipefail && docker exec coolify-db pg_dump -U coolify -d coolify | gzip > /tmp/coolify-backup.sql.gz";
197
266
  }
198
267
  buildConfigTarCommand() {
199
268
  return "tar czf /tmp/coolify-config.tar.gz -C /data/coolify/source .env docker-compose.yml docker-compose.prod.yml 2>/dev/null || tar czf /tmp/coolify-config.tar.gz -C /data/coolify/source .env docker-compose.yml";
@@ -1 +1 @@
1
- {"version":3,"file":"coolify.js","sourceRoot":"","sources":["../../src/adapters/coolify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"coolify.js","sourceRoot":"","sources":["../../src/adapters/coolify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EACL,eAAe,EACf,YAAY,EACZ,WAAW,EACX,SAAS,EACT,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE/E,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,SAAS,CAAC;IAE1B,YAAY,CAAC,UAAkB;QAC7B,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACvD,OAAO;;;;;;;;gBAQK,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DvB,CAAC;IACA,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU,EAAE,MAAe;QAC3C,OAAO,iBAAiB,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,EAAU,EACV,UAAkB,EAClB,QAAgB;QAEhB,aAAa,CAAC,EAAE,CAAC,CAAC;QAElB,IAAI,CAAC;YACH,4CAA4C;YAC5C,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;YACpE,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YAE1F,0BAA0B;YAC1B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAC9D,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,wBAAwB;oBAC/B,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,SAAS;iBACnD,CAAC;YACJ,CAAC;YAED,wBAAwB;YACxB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;YACrE,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,sBAAsB;oBAC7B,IAAI,EAAE,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS;iBACvD,CAAC;YACJ,CAAC;YAED,8CAA8C;YAC9C,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;YAC7D,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAExD,MAAM,IAAI,GAAG,MAAM,WAAW,CAC5B,EAAE,EACF,4BAA4B,EAC5B,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAC1C,CAAC;YACF,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACpB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,oCAAoC;oBAC3C,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,SAAS;iBAC/C,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,EAAE,EACF,4BAA4B,EAC5B,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAC1C,CAAC;YACF,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,kCAAkC;oBACzC,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,SAAS;iBACnD,CAAC;YACJ,CAAC;YAED,yBAAyB;YACzB,MAAM,QAAQ,GAAmB;gBAC/B,UAAU;gBACV,QAAQ;gBACR,SAAS;gBACT,cAAc;gBACd,KAAK,EAAE,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;aAC1D,CAAC;YACF,aAAa,CACX,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,EACjC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EACjC,EAAE,IAAI,EAAE,KAAK,EAAE,CAChB,CAAC;YAEF,uCAAuC;YACvC,MAAM,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAE9D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;QACjD,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACpC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC;gBAC7B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,EAAU,EACV,UAAkB,EAClB,SAAyB;QAEzB,aAAa,CAAC,EAAE,CAAC,CAAC;QAElB,MAAM,KAAK,GAIN,EAAE,CAAC;QAER,IAAI,CAAC;YACH,qEAAqE;YACrE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,EAAE,EACF,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,EACzC,4BAA4B,CAC7B,CAAC;YACF,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE;wBACL;4BACE,IAAI,EAAE,wBAAwB;4BAC9B,MAAM,EAAE,SAAS;4BACjB,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;yBACvC;qBACF;oBACD,KAAK,EAAE,kCAAkC;iBAC1C,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAElE,MAAM,YAAY,GAAG,MAAM,SAAS,CAClC,EAAE,EACF,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,EACzC,4BAA4B,CAC7B,CAAC;YACF,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE;wBACL,GAAG,KAAK;wBACR;4BACE,IAAI,EAAE,sBAAsB;4BAC5B,MAAM,EAAE,SAAS;4BACjB,KAAK,EAAE,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC;yBAC3C;qBACF;oBACD,KAAK,EAAE,gCAAgC;iBACxC,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAEhE,uBAAuB;YACvB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,uBAAuB,EAAE,CAAC,CAAC;YAChE,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,cAAc;oBACpB,MAAM,EAAE,SAAS;oBACjB,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC;iBACzC,CAAC,CAAC;gBACH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;YACpE,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAExD,wBAAwB;YACxB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,mBAAmB,EAAE,CAAC,CAAC;YAC/D,IAAI,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,gBAAgB;oBACtB,MAAM,EAAE,SAAS;oBACjB,KAAK,EAAE,cAAc,CAAC,aAAa,CAAC,MAAM,CAAC;iBAC5C,CAAC,CAAC;gBACH,MAAM,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBAC5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC;YACtE,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAE1D,2BAA2B;YAC3B,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,qBAAqB,EAAE,CAAC,CAAC;YACnE,IAAI,eAAe,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC/B,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,kBAAkB;oBACxB,MAAM,EAAE,SAAS;oBACjB,KAAK,EAAE,cAAc,CAAC,eAAe,CAAC,MAAM,CAAC;iBAC9C,CAAC,CAAC;gBACH,MAAM,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBAC5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;YACrE,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAE5D,yBAAyB;YACzB,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,yBAAyB,EAAE,CAAC,CAAC;YAC3E,IAAI,mBAAmB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACnC,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,gBAAgB;oBACtB,MAAM,EAAE,SAAS;oBACjB,KAAK,EAAE,cAAc,CAAC,mBAAmB,CAAC,MAAM,CAAC;iBAClD,CAAC,CAAC;gBACH,MAAM,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBAC5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;YACnE,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAE1D,wBAAwB;YACxB,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAClE,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,eAAe;oBACrB,MAAM,EAAE,SAAS;oBACjB,KAAK,EAAE,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC;iBAC1C,CAAC,CAAC;gBACH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;YACrE,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAEzD,+BAA+B;YAC/B,MAAM,OAAO,CAAC,EAAE,EAAE,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAEzD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAClC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACpC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK;gBACL,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC;gBAC7B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,EAAU;QACxB,OAAO,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,OAAO,YAAY,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;IAC9C,CAAC;IAED,+EAA+E;IAEvE,kBAAkB;QACxB,OAAO,6GAA6G,CAAC;IACvH,CAAC;IAEO,qBAAqB;QAC3B,OAAO,8MAA8M,CAAC;IACxN,CAAC;IAEO,mBAAmB;QACzB,OAAO,6DAA6D,CAAC;IACvE,CAAC;IAEO,mBAAmB;QACzB,OAAO,iGAAiG,CAAC;IAC3G,CAAC;CACF"}
@@ -1,12 +1,14 @@
1
- import type { PlatformAdapter, HealthResult, PlatformStatusResult, PlatformBackupResult, UpdateResult } from "./interface.js";
1
+ import type { PlatformAdapter, HealthResult, PlatformStatusResult, PlatformBackupResult, PlatformRestoreResult, UpdateResult } from "./interface.js";
2
+ import type { BackupManifest } from "../types/index.js";
2
3
  export declare class DokployAdapter implements PlatformAdapter {
3
4
  readonly name = "dokploy";
4
5
  getCloudInit(serverName: string): string;
5
- healthCheck(ip: string): Promise<HealthResult>;
6
+ healthCheck(ip: string, domain?: string): Promise<HealthResult>;
6
7
  createBackup(ip: string, serverName: string, provider: string): Promise<PlatformBackupResult>;
8
+ restoreBackup(ip: string, backupPath: string, _manifest: BackupManifest): Promise<PlatformRestoreResult>;
7
9
  getStatus(ip: string): Promise<PlatformStatusResult>;
8
10
  update(ip: string): Promise<UpdateResult>;
9
- getLogCommand(lines: number, follow: boolean): string;
11
+ private tryRestartDokploy;
10
12
  private buildPgDumpCommand;
11
13
  private buildConfigTarCommand;
12
14
  private buildCleanupCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"dokploy.d.ts","sourceRoot":"","sources":["../../src/adapters/dokploy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACb,MAAM,gBAAgB,CAAC;AAWxB,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAE1B,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IA4ElC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAa9C,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;IAwF1B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAWpD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAsB/C,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM;IAMrD,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;CAG5B"}
1
+ {"version":3,"file":"dokploy.d.ts","sourceRoot":"","sources":["../../src/adapters/dokploy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAYxD,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAE1B,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IA4ElC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/D,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;IAwF1B,aAAa,CACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,qBAAqB,CAAC;IA2I3B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIpD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;YAMjC,iBAAiB;IAQ/B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;CAG5B"}