wasm-cli 1.6.2__tar.gz → 1.6.3__tar.gz

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 (247) hide show
  1. {wasm_cli-1.6.2/src/wasm_cli.egg-info → wasm_cli-1.6.3}/PKG-INFO +1 -1
  2. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/pyproject.toml +1 -1
  3. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/setup.py +1 -1
  4. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/__init__.py +1 -1
  5. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/webapp.py +32 -248
  6. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/docker_compose.py +3 -1
  7. wasm_cli-1.6.3/src/wasm/deployers/lifecycle.py +371 -0
  8. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/apps.py +9 -2
  9. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/hooks.py +5 -44
  10. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/services.py +6 -0
  11. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/jobs.py +40 -29
  12. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/websockets/router.py +8 -1
  13. {wasm_cli-1.6.2 → wasm_cli-1.6.3/src/wasm_cli.egg-info}/PKG-INFO +1 -1
  14. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/SOURCES.txt +1 -0
  15. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/LICENSE +0 -0
  16. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/MANIFEST.in +0 -0
  17. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/README.md +0 -0
  18. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/MONITOR.md +0 -0
  19. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/OBS_SETUP.md +0 -0
  20. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/assets/logo.png +0 -0
  21. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/assets/logo_bg.png +0 -0
  22. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/superpowers/plans/2026-08-13-wasm-competitive-parity-roadmap.md +0 -0
  23. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/superpowers/specs/2026-08-12-wasm-panel-design-direction.md +0 -0
  24. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/superpowers/specs/2026-08-12-wasm-v1-refactor-design.md +0 -0
  25. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/superpowers/specs/2026-08-13-wasm-competitive-parity-design.md +0 -0
  26. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/docs/superpowers/specs/2026-08-14-wasm-panel-design-v2.md +0 -0
  27. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/man/wasm.1 +0 -0
  28. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/setup.cfg +0 -0
  29. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/__main__.py +0 -0
  30. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/__init__.py +0 -0
  31. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/app.py +0 -0
  32. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/__init__.py +0 -0
  33. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/backup.py +0 -0
  34. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/cert.py +0 -0
  35. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/config.py +0 -0
  36. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/db.py +0 -0
  37. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/env.py +0 -0
  38. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/health.py +0 -0
  39. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/monitor.py +0 -0
  40. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/service.py +0 -0
  41. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/setup.py +0 -0
  42. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/site.py +0 -0
  43. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/store.py +0 -0
  44. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/version.py +0 -0
  45. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/commands/web.py +0 -0
  46. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/interactive.py +0 -0
  47. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/panel_links.py +0 -0
  48. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/cli/prompts.py +0 -0
  49. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/completions/README.md +0 -0
  50. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/completions/_wasm +0 -0
  51. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/completions/wasm.bash +0 -0
  52. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/completions/wasm.fish +0 -0
  53. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/__init__.py +0 -0
  54. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/app_state.py +0 -0
  55. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/config.py +0 -0
  56. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/dependencies.py +0 -0
  57. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/exceptions.py +0 -0
  58. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/fs.py +0 -0
  59. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/logger.py +0 -0
  60. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/net.py +0 -0
  61. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/notifier.py +0 -0
  62. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/runner.py +0 -0
  63. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/store.py +0 -0
  64. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/totp.py +0 -0
  65. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/update_checker.py +0 -0
  66. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/core/utils.py +0 -0
  67. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/__init__.py +0 -0
  68. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/auto.py +0 -0
  69. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/base.py +0 -0
  70. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/__init__.py +0 -0
  71. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/env_manager.py +0 -0
  72. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/health.py +0 -0
  73. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/nginx_config.py +0 -0
  74. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/package_manager.py +0 -0
  75. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/path_resolver.py +0 -0
  76. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/permissions.py +0 -0
  77. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/preflight.py +0 -0
  78. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/prisma.py +0 -0
  79. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/registration.py +0 -0
  80. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/summary.py +0 -0
  81. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/turbo.py +0 -0
  82. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/workspace.py +0 -0
  83. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/interface.py +0 -0
  84. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/monorepo.py +0 -0
  85. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/nextjs.py +0 -0
  86. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/nodejs.py +0 -0
  87. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/pipeline.py +0 -0
  88. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/python.py +0 -0
  89. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/recorder.py +0 -0
  90. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/registry.py +0 -0
  91. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/static.py +0 -0
  92. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/deployers/vite.py +0 -0
  93. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/main.py +0 -0
  94. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/__init__.py +0 -0
  95. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/apache_manager.py +0 -0
  96. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/backup_manager.py +0 -0
  97. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/backup_scheduler.py +0 -0
  98. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/base_manager.py +0 -0
  99. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/cert_manager.py +0 -0
  100. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/cron_manager.py +0 -0
  101. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/database/__init__.py +0 -0
  102. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/database/base.py +0 -0
  103. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/database/mongodb.py +0 -0
  104. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/database/mysql.py +0 -0
  105. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/database/postgres.py +0 -0
  106. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/database/redis.py +0 -0
  107. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/database/registry.py +0 -0
  108. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/nginx_manager.py +0 -0
  109. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/service_manager.py +0 -0
  110. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/source_manager.py +0 -0
  111. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/managers/webserver.py +0 -0
  112. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/monitor/__init__.py +0 -0
  113. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/monitor/email_notifier.py +0 -0
  114. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/monitor/metrics.py +0 -0
  115. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/monitor/models.py +0 -0
  116. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/monitor/observation_store.py +0 -0
  117. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/monitor/process_monitor.py +0 -0
  118. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/monitor/signals.py +0 -0
  119. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/monitor/timeseries.py +0 -0
  120. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/__init__.py +0 -0
  121. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/apache/proxy.conf.j2 +0 -0
  122. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/apache/static.conf.j2 +0 -0
  123. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/nginx/advanced.conf.j2 +0 -0
  124. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/nginx/monorepo.conf.j2 +0 -0
  125. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/nginx/proxy.conf.j2 +0 -0
  126. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/nginx/static.conf.j2 +0 -0
  127. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/systemd/_escape.j2 +0 -0
  128. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/systemd/app.service.j2 +0 -0
  129. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/systemd/backup-service.j2 +0 -0
  130. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/systemd/backup-timer.j2 +0 -0
  131. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/systemd/cron-service.j2 +0 -0
  132. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/systemd/cron-timer.j2 +0 -0
  133. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/templates/systemd/docker-compose.service.j2 +0 -0
  134. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/validators/__init__.py +0 -0
  135. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/validators/domain.py +0 -0
  136. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/validators/environment.py +0 -0
  137. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/validators/names.py +0 -0
  138. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/validators/port.py +0 -0
  139. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/validators/source.py +0 -0
  140. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/validators/ssh.py +0 -0
  141. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/__init__.py +0 -0
  142. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/__init__.py +0 -0
  143. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/auth.py +0 -0
  144. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/backup_schedules.py +0 -0
  145. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/backups.py +0 -0
  146. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/certs.py +0 -0
  147. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/config.py +0 -0
  148. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/cron.py +0 -0
  149. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/databases.py +0 -0
  150. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/deps.py +0 -0
  151. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/jobs.py +0 -0
  152. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/metrics.py +0 -0
  153. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/monitor.py +0 -0
  154. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/router.py +0 -0
  155. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/sites.py +0 -0
  156. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/api/system.py +0 -0
  157. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/auth.py +0 -0
  158. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/events.py +0 -0
  159. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/metrics_collector.py +0 -0
  160. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/pydantic_compat.py +0 -0
  161. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/server.py +0 -0
  162. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/app.css +0 -0
  163. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/logo.png +0 -0
  164. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/logo.webp +0 -0
  165. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/panel.js +0 -0
  166. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-mono-latin-400-normal.woff2 +0 -0
  167. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-mono-latin-500-normal.woff2 +0 -0
  168. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-sans-latin-400-normal.woff2 +0 -0
  169. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-sans-latin-500-normal.woff2 +0 -0
  170. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-sans-latin-600-normal.woff2 +0 -0
  171. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/htmx.min.js +0 -0
  172. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/qrcodegen.js +0 -0
  173. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/sse.js +0 -0
  174. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/uplot.min.css +0 -0
  175. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/uplot.min.js +0 -0
  176. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/xterm.css +0 -0
  177. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/xterm.js +0 -0
  178. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/_macros.html +0 -0
  179. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/base.html +0 -0
  180. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/api_tokens.html +0 -0
  181. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/app_charts.html +0 -0
  182. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/app_env.html +0 -0
  183. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/backup_schedule_section.html +0 -0
  184. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/cron_runs.html +0 -0
  185. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/cron_section.html +0 -0
  186. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/db_console.html +0 -0
  187. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/db_engine.html +0 -0
  188. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_form_check.html +0 -0
  189. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_form_options.html +0 -0
  190. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_recent.html +0 -0
  191. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_rollback.html +0 -0
  192. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_rows.html +0 -0
  193. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/infra_service_editor.html +0 -0
  194. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/infra_service_form.html +0 -0
  195. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/infra_site_editor.html +0 -0
  196. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/infra_site_form.html +0 -0
  197. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/machine.html +0 -0
  198. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/notif_channels.html +0 -0
  199. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/sessions.html +0 -0
  200. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_editor.html +0 -0
  201. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_backups.html +0 -0
  202. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_notifications.html +0 -0
  203. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_paths.html +0 -0
  204. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_ssl.html +0 -0
  205. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_web.html +0 -0
  206. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_webserver.html +0 -0
  207. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_section.html +0 -0
  208. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/totp.html +0 -0
  209. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/webhook_section.html +0 -0
  210. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/login.html +0 -0
  211. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/activity.html +0 -0
  212. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/app.html +0 -0
  213. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/backups.html +0 -0
  214. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/certificates.html +0 -0
  215. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/cron.html +0 -0
  216. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/dashboard.html +0 -0
  217. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/databases.html +0 -0
  218. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/deploy.html +0 -0
  219. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/deployment_detail.html +0 -0
  220. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/deployments.html +0 -0
  221. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/failure.html +0 -0
  222. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/missing.html +0 -0
  223. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/resources.html +0 -0
  224. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/service_editor.html +0 -0
  225. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/service_new.html +0 -0
  226. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/settings.html +0 -0
  227. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/site_editor.html +0 -0
  228. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/site_new.html +0 -0
  229. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/__init__.py +0 -0
  230. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/app_charts.py +0 -0
  231. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/backup_schedules.py +0 -0
  232. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/context.py +0 -0
  233. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/cron.py +0 -0
  234. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/databases.py +0 -0
  235. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/deploy_form.py +0 -0
  236. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/deployments.py +0 -0
  237. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/infrastructure.py +0 -0
  238. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/machine.py +0 -0
  239. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/rendering.py +0 -0
  240. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/resources.py +0 -0
  241. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/router.py +0 -0
  242. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/views/settings_editor.py +0 -0
  243. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm/web/websockets/__init__.py +0 -0
  244. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/dependency_links.txt +0 -0
  245. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/entry_points.txt +0 -0
  246. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/requires.txt +0 -0
  247. {wasm_cli-1.6.2 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wasm-cli
3
- Version: 1.6.2
3
+ Version: 1.6.3
4
4
  Summary: Web App System Management - Deploy and manage web applications on Linux servers
5
5
  Author: Yago López Prado
6
6
  Author-email: Yago López Prado <yago.lopez.adeje@gmail.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wasm-cli"
7
- version = "1.6.2"
7
+ version = "1.6.3"
8
8
  description = "Web App System Management - Deploy and manage web applications on Linux servers"
9
9
  readme = "README.md"
10
10
  license = { text = "WASM-NCSAL" }
@@ -9,7 +9,7 @@ from setuptools import setup, find_packages
9
9
 
10
10
  setup(
11
11
  name="wasm-cli",
12
- version="1.6.2",
12
+ version="1.6.3",
13
13
  description="Web App System Management - Deploy and manage web applications on Linux servers",
14
14
  author="Yago López Prado",
15
15
  author_email="yago.lopez.adeje@gmail.com",
@@ -15,7 +15,7 @@ from importlib.metadata import version as _installed_version
15
15
  #: as an OBS build directory. The single source of truth is the ``version``
16
16
  #: field of pyproject.toml; ``scripts/release.py`` keeps this literal and the
17
17
  #: distribution packaging files in step with it.
18
- _FALLBACK_VERSION = "1.6.2"
18
+ _FALLBACK_VERSION = "1.6.3"
19
19
 
20
20
  try:
21
21
  __version__ = _installed_version("wasm-cli")
@@ -24,7 +24,6 @@ from __future__ import annotations
24
24
 
25
25
  import re
26
26
  import sys
27
- import time
28
27
  from argparse import Namespace
29
28
  from collections.abc import Callable
30
29
  from pathlib import Path
@@ -43,18 +42,17 @@ from wasm.core.runner import (
43
42
  CommandResult,
44
43
  get_runner,
45
44
  )
46
- from wasm.core.store import get_store
45
+ from wasm.core.store import DeploymentTrigger, get_store
47
46
  from wasm.core.utils import domain_to_app_name, remove_directory
48
- from wasm.deployers import detect_app_type, get_deployer
47
+ from wasm.deployers import get_deployer
49
48
  from wasm.deployers.docker_compose import DockerComposeDeployer
49
+ from wasm.deployers.lifecycle import update_app
50
50
  from wasm.deployers.monorepo import MonorepoDeployer
51
51
  from wasm.deployers.registry import available_types
52
52
  from wasm.managers.apache_manager import ApacheManager
53
- from wasm.managers.backup_manager import RollbackManager
54
53
  from wasm.managers.cert_manager import CertManager
55
54
  from wasm.managers.nginx_manager import NginxManager
56
55
  from wasm.managers.service_manager import ServiceManager
57
- from wasm.managers.source_manager import SourceManager
58
56
  from wasm.validators.domain import should_include_www, validate_domain
59
57
  from wasm.validators.port import find_available_port, validate_port
60
58
 
@@ -648,8 +646,8 @@ def _update_app(
648
646
  """
649
647
  Rebuild a deployed application from its source, then restart it.
650
648
 
651
- The service is only restarted once the new build succeeded, so a broken
652
- build leaves the previous one serving traffic.
649
+ The sequence itself is :func:`wasm.deployers.lifecycle.update_app`, shared
650
+ with the panel and the git webhook; this only presents it.
653
651
 
654
652
  Args:
655
653
  domain: Application domain.
@@ -664,260 +662,46 @@ def _update_app(
664
662
  Raises:
665
663
  WASMError: When the application is unknown or a step fails.
666
664
  """
667
- config = Config()
668
- store = get_store()
669
-
670
- domain = validate_domain(domain)
671
-
672
- # The store holds the real path, which is what keeps legacy apps deployed
673
- # under a wasm- prefix updatable.
674
- app = store.get_app(domain)
675
-
676
- if app and app.app_path:
677
- app_path = Path(app.app_path)
678
- app_name = app_path.name
679
- else:
680
- app_name = domain_to_app_name(domain)
681
- app_path = config.apps_directory / app_name
682
-
683
- if not app_path.exists():
684
- raise WASMError(
685
- f"Application not found: {domain}",
686
- details=f"Nothing is deployed at {app_path}. Deploy it with: wasm create -d {domain}",
687
- )
688
-
689
665
  logger.header(f"Updating: {domain}")
690
666
  logger.blank()
691
667
 
692
- total_steps = 7
693
-
694
- logger.step(1, total_steps, "Creating pre-update backup")
695
- try:
696
- rollback_manager = RollbackManager(verbose=logger.verbose)
697
- backup = rollback_manager.create_pre_deploy_backup(
698
- domain=domain, description="Pre-update automatic backup"
699
- )
700
- if backup:
701
- logger.substep(f"Backup created: {backup.id}")
702
- else:
703
- logger.substep("No existing app to backup")
704
- except (WASMError, OSError) as e:
705
- logger.substep(f"Backup skipped: {e}")
706
-
707
- source_manager = SourceManager(verbose=logger.verbose)
708
-
709
- if source:
710
- logger.step(2, total_steps, "Fetching from new source")
711
- logger.substep(f"Source: {source}")
712
- # A forced fetch wipes the tree, and the environment file is the one
713
- # thing in it that is not in version control.
714
- env_backup = None
715
- env_file = app_path / ".env"
716
- if env_file.exists():
717
- env_backup = env_file.read_text()
718
-
719
- source_manager.fetch(source, app_path, branch=branch, force=True)
720
-
721
- if env_backup:
722
- env_file.write_text(env_backup)
723
- logger.substep("Restored .env file")
724
- else:
725
- logger.step(2, total_steps, "Pulling latest changes")
726
- source_manager.pull(app_path, branch=branch)
727
-
728
- logger.step(3, total_steps, "Detecting application type")
729
-
730
- # The initial deploy already settled the type; re-detecting can only change
731
- # its mind for the worse on a tree that now has build output in it.
732
- stored_type = app.app_type if app else None
733
- if stored_type and stored_type != "unknown":
734
- app_type = stored_type
735
- logger.substep(f"Detected: {app_type}")
736
- else:
737
- detected = detect_app_type(app_path, verbose=logger.verbose)
738
- if not detected:
739
- app_type = "nodejs"
740
- logger.substep(f"Using default: {app_type}")
741
- else:
742
- app_type = detected
743
- logger.substep(f"Detected: {app_type}")
744
-
745
- if app_type == "monorepo":
746
- return _update_monorepo(app_path, app_name, domain, logger, total_steps)
747
-
748
- if app_type == "docker-compose":
749
- return _update_docker_compose(app_path, app_name, domain, logger)
750
-
751
- deployer = get_deployer(app_type, verbose=logger.verbose)
752
- deployer.configure(
753
- domain=domain,
754
- source=str(app_path),
755
- app_path=app_path,
668
+ outcome = update_app(
669
+ domain,
670
+ source=source,
671
+ branch=branch,
756
672
  package_manager=package_manager,
673
+ trigger=DeploymentTrigger.CLI.value,
674
+ on_phase=logger.step,
675
+ on_step=logger.substep,
676
+ logger=logger,
677
+ verbose=logger.verbose,
757
678
  )
758
679
 
759
- # One call, not a second copy of the deploy pipeline. The deployer reports
760
- # each step as it starts so the numbering here stays the CLI's business.
761
- step = iter(range(4, total_steps + 1))
762
- result = deployer.update(on_step=lambda message: logger.step(next(step), total_steps, message))
763
-
764
- logger.substep(f"Package manager: {result.package_manager}")
765
- if result.prisma_updated:
766
- logger.substep("Prisma updated")
767
-
768
- logger.step(7, total_steps, "Restarting application")
769
- service_manager = ServiceManager(verbose=logger.verbose)
770
-
771
- if result.is_static:
772
- logger.substep("Static application - no service restart needed")
773
- logger.success(f"Application updated successfully: {domain}")
680
+ if outcome.is_static:
681
+ logger.success(f"Application updated successfully: {outcome.domain}")
774
682
  logger.blank()
775
- logger.key_value("Type", "Static")
776
- logger.key_value("Package Manager", result.package_manager)
683
+ logger.key_value("Type", outcome.app_type)
684
+ logger.key_value("Package Manager", outcome.package_manager)
777
685
  return 0
778
686
 
779
- status = service_manager.get_status(app_name)
780
- if not status.get("exists"):
781
- logger.warning("Service not found - application may need to be redeployed")
782
- logger.info(f"Try: wasm create -d {domain}")
687
+ if not outcome.restarted:
688
+ logger.warning("No service found to restart - the application may need to be redeployed")
689
+ logger.info(f"Try: wasm create -d {outcome.domain}")
783
690
  return 0
784
691
 
785
- logger.substep("Minimal downtime during restart...")
786
- service_manager.restart(app_name)
787
-
788
- # systemd reports the unit active the instant it forks, so give the process
789
- # a moment to fail before believing the health check.
790
- time.sleep(2)
791
-
792
- status = service_manager.get_status(app_name)
793
- if status.get("active"):
794
- logger.success(f"Application updated successfully: {domain}")
795
- logger.blank()
796
- logger.key_value("Status", "Running")
797
- logger.key_value("Package Manager", result.package_manager)
798
- if result.prisma_updated:
799
- logger.key_value("Prisma", "Updated")
800
- else:
692
+ if not outcome.active:
801
693
  logger.warning("Application restarted but may not be running correctly")
802
- logger.info(f"Check logs with: wasm logs {domain}")
803
-
804
- return 0
805
-
806
-
807
- def _update_monorepo(
808
- app_path: Path,
809
- app_name: str,
810
- domain: str,
811
- logger: Logger,
812
- total_steps: int,
813
- ) -> int:
814
- """
815
- Rebuild every workspace of a monorepo and restart their services.
816
-
817
- Args:
818
- app_path: Directory holding the application.
819
- app_name: Directory name of the application.
820
- domain: Validated domain.
821
- logger: Logger of the current command.
822
- total_steps: Number of steps reported to the user.
823
-
824
- Returns:
825
- Exit code.
826
-
827
- Raises:
828
- WASMError: When a build step fails.
829
- """
830
- deployer = MonorepoDeployer(verbose=logger.verbose)
831
- deployer.app_path = app_path
832
- deployer.app_name = app_name
833
- deployer.domain = domain
834
- deployer.package_manager = "pnpm"
835
-
836
- # The deployer's own update, not a copy of its steps: the copy handed the
837
- # tree over before building and left every build output owned by root.
838
- step = iter(range(4, total_steps + 1))
839
- deployer.update(on_step=lambda message: logger.step(next(step), total_steps, message))
840
-
841
- logger.step(7, total_steps, "Restarting applications")
842
- service_manager = ServiceManager(verbose=logger.verbose)
843
-
844
- store = get_store()
845
- app = store.get_app(domain)
846
-
847
- restarted = []
848
- if app:
849
- all_services = store.list_services()
850
- services = [s for s in all_services if s.app_id == app.id]
851
- for service in services:
852
- logger.substep(f"Restarting {service.name}")
853
- try:
854
- service_manager.restart(service.name)
855
- restarted.append(service.name)
856
- except ServiceError as e:
857
- logger.warning(f"Failed to restart {service.name}: {e}")
858
- else:
859
- status = service_manager.get_status(app_name)
860
- if status.get("exists"):
861
- service_manager.restart(app_name)
862
- restarted.append(app_name)
863
-
864
- if restarted:
865
- time.sleep(3)
866
- logger.success(f"Monorepo updated successfully: {domain}")
867
- logger.blank()
868
- for name in restarted:
869
- logger.key_value("Restarted", name)
870
- else:
871
- logger.warning("No services found to restart")
872
- logger.info(f"Try redeploying: wasm create -d {domain}")
873
-
874
- return 0
875
-
876
-
877
- def _update_docker_compose(
878
- app_path: Path,
879
- app_name: str,
880
- domain: str,
881
- logger: Logger,
882
- ) -> int:
883
- """
884
- Rebuild the images of a Docker Compose project and recreate its containers.
885
-
886
- Args:
887
- app_path: Directory holding the application.
888
- app_name: Directory name of the application.
889
- domain: Validated domain.
890
- logger: Logger of the current command.
891
-
892
- Returns:
893
- Exit code.
894
-
895
- Raises:
896
- WASMError: When the compose file cannot be found or a build fails.
897
- """
898
- deployer = DockerComposeDeployer(verbose=logger.verbose)
899
- deployer.app_path = app_path
900
- deployer.app_name = app_name
901
- deployer.domain = domain
902
-
903
- deployer._discover_compose_file()
904
-
905
- logger.step(4, 5, "Rebuilding Docker images")
906
- deployer._build_images()
907
-
908
- logger.step(5, 5, "Restarting containers")
909
- cmd = ["docker", "compose"]
910
- if deployer.compose_path:
911
- cmd.extend(["-f", str(deployer.compose_path)])
912
- cmd.extend(["up", "-d", "--remove-orphans"])
913
- result = get_runner().run(cmd, cwd=app_path, timeout=_COMPOSE_TIMEOUT)
914
-
915
- if result.success:
916
- logger.success(f"Docker Compose app updated: {domain}")
917
- else:
918
- logger.warning("Update may have issues. Check with: docker compose ps")
919
- logger.warning(result.stderr)
694
+ logger.info(f"Check logs with: wasm logs {outcome.domain}")
695
+ return 0
920
696
 
697
+ logger.success(f"Application updated successfully: {outcome.domain}")
698
+ logger.blank()
699
+ logger.key_value("Status", "Running")
700
+ for name in outcome.restarted:
701
+ logger.key_value("Restarted", name)
702
+ logger.key_value("Package Manager", outcome.package_manager)
703
+ if outcome.prisma_updated:
704
+ logger.key_value("Prisma", "Updated")
921
705
  return 0
922
706
 
923
707
 
@@ -928,7 +928,9 @@ class DockerComposeDeployer(AppDeployer):
928
928
  self._build_images()
929
929
 
930
930
  report("Recreating containers")
931
- result = self._run(self._compose("up", "-d", "--remove-orphans"))
931
+ # Services that name an image instead of building one pull it here,
932
+ # which is a download, not a local recreate.
933
+ result = self._run(self._compose("up", "-d", "--remove-orphans"), timeout=BUILD_TIMEOUT)
932
934
  if not result.success:
933
935
  raise DockerError("Failed to update containers", result.stderr)
934
936