wasm-cli 0.15.8__tar.gz → 1.0.1__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 (266) hide show
  1. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/MANIFEST.in +1 -1
  2. {wasm_cli-0.15.8/src/wasm_cli.egg-info → wasm_cli-1.0.1}/PKG-INFO +69 -51
  3. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/README.md +52 -32
  4. wasm_cli-1.0.1/docs/superpowers/specs/2026-08-12-wasm-panel-design-direction.md +133 -0
  5. wasm_cli-1.0.1/docs/superpowers/specs/2026-08-12-wasm-v1-refactor-design.md +240 -0
  6. wasm_cli-1.0.1/man/wasm.1 +1290 -0
  7. wasm_cli-1.0.1/pyproject.toml +220 -0
  8. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/setup.py +13 -13
  9. wasm_cli-1.0.1/src/wasm/__init__.py +37 -0
  10. wasm_cli-1.0.1/src/wasm/cli/__init__.py +9 -0
  11. wasm_cli-1.0.1/src/wasm/cli/app.py +331 -0
  12. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/cli/commands/__init__.py +8 -8
  13. wasm_cli-1.0.1/src/wasm/cli/commands/backup.py +1160 -0
  14. wasm_cli-1.0.1/src/wasm/cli/commands/cert.py +713 -0
  15. wasm_cli-1.0.1/src/wasm/cli/commands/config.py +264 -0
  16. wasm_cli-1.0.1/src/wasm/cli/commands/db.py +1855 -0
  17. wasm_cli-1.0.1/src/wasm/cli/commands/env.py +366 -0
  18. wasm_cli-1.0.1/src/wasm/cli/commands/health.py +392 -0
  19. wasm_cli-1.0.1/src/wasm/cli/commands/monitor.py +666 -0
  20. wasm_cli-1.0.1/src/wasm/cli/commands/service.py +480 -0
  21. wasm_cli-1.0.1/src/wasm/cli/commands/setup.py +1620 -0
  22. wasm_cli-1.0.1/src/wasm/cli/commands/site.py +618 -0
  23. wasm_cli-1.0.1/src/wasm/cli/commands/store.py +610 -0
  24. wasm_cli-1.0.1/src/wasm/cli/commands/version.py +115 -0
  25. wasm_cli-1.0.1/src/wasm/cli/commands/web.py +1622 -0
  26. wasm_cli-1.0.1/src/wasm/cli/commands/webapp.py +1769 -0
  27. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/cli/interactive.py +88 -85
  28. wasm_cli-1.0.1/src/wasm/core/config.py +912 -0
  29. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/core/dependencies.py +282 -163
  30. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/core/exceptions.py +43 -10
  31. wasm_cli-1.0.1/src/wasm/core/fs.py +333 -0
  32. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/core/logger.py +228 -70
  33. wasm_cli-1.0.1/src/wasm/core/runner.py +932 -0
  34. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/core/store.py +521 -370
  35. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/core/update_checker.py +63 -86
  36. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/core/utils.py +207 -236
  37. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/__init__.py +5 -5
  38. wasm_cli-1.0.1/src/wasm/deployers/auto.py +219 -0
  39. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/base.py +675 -640
  40. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/docker_compose.py +261 -146
  41. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/helpers/env_manager.py +226 -48
  42. wasm_cli-1.0.1/src/wasm/deployers/helpers/health.py +75 -0
  43. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/helpers/nginx_config.py +15 -11
  44. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/helpers/package_manager.py +75 -27
  45. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/helpers/path_resolver.py +12 -13
  46. wasm_cli-1.0.1/src/wasm/deployers/helpers/preflight.py +150 -0
  47. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/helpers/prisma.py +4 -4
  48. wasm_cli-1.0.1/src/wasm/deployers/helpers/registration.py +196 -0
  49. wasm_cli-1.0.1/src/wasm/deployers/helpers/summary.py +91 -0
  50. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/helpers/turbo.py +18 -20
  51. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/helpers/workspace.py +29 -27
  52. wasm_cli-1.0.1/src/wasm/deployers/interface.py +212 -0
  53. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/monorepo.py +482 -264
  54. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/nextjs.py +66 -48
  55. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/nodejs.py +53 -34
  56. wasm_cli-1.0.1/src/wasm/deployers/pipeline.py +124 -0
  57. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/python.py +89 -62
  58. wasm_cli-1.0.1/src/wasm/deployers/registry.py +178 -0
  59. wasm_cli-1.0.1/src/wasm/deployers/static.py +200 -0
  60. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/vite.py +67 -45
  61. wasm_cli-1.0.1/src/wasm/main.py +23 -0
  62. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/managers/__init__.py +8 -8
  63. wasm_cli-1.0.1/src/wasm/managers/apache_manager.py +60 -0
  64. wasm_cli-1.0.1/src/wasm/managers/backup_manager.py +2497 -0
  65. wasm_cli-1.0.1/src/wasm/managers/backup_scheduler.py +471 -0
  66. wasm_cli-1.0.1/src/wasm/managers/base_manager.py +300 -0
  67. wasm_cli-1.0.1/src/wasm/managers/cert_manager.py +964 -0
  68. wasm_cli-1.0.1/src/wasm/managers/database/base.py +1333 -0
  69. wasm_cli-1.0.1/src/wasm/managers/database/mongodb.py +819 -0
  70. wasm_cli-1.0.1/src/wasm/managers/database/mysql.py +888 -0
  71. wasm_cli-1.0.1/src/wasm/managers/database/postgres.py +952 -0
  72. wasm_cli-1.0.1/src/wasm/managers/database/redis.py +916 -0
  73. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/managers/database/registry.py +39 -32
  74. wasm_cli-1.0.1/src/wasm/managers/nginx_manager.py +98 -0
  75. wasm_cli-1.0.1/src/wasm/managers/service_manager.py +1203 -0
  76. wasm_cli-1.0.1/src/wasm/managers/source_manager.py +1660 -0
  77. wasm_cli-1.0.1/src/wasm/managers/webserver.py +982 -0
  78. wasm_cli-1.0.1/src/wasm/monitor/__init__.py +96 -0
  79. wasm_cli-1.0.1/src/wasm/monitor/email_notifier.py +454 -0
  80. wasm_cli-1.0.1/src/wasm/monitor/metrics.py +347 -0
  81. wasm_cli-1.0.1/src/wasm/monitor/models.py +168 -0
  82. wasm_cli-1.0.1/src/wasm/monitor/observation_store.py +381 -0
  83. wasm_cli-1.0.1/src/wasm/monitor/process_monitor.py +625 -0
  84. wasm_cli-1.0.1/src/wasm/monitor/signals.py +227 -0
  85. wasm_cli-1.0.1/src/wasm/templates/systemd/_escape.j2 +15 -0
  86. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/systemd/app.service.j2 +9 -8
  87. wasm_cli-1.0.1/src/wasm/templates/systemd/backup-service.j2 +10 -0
  88. wasm_cli-1.0.1/src/wasm/templates/systemd/backup-timer.j2 +14 -0
  89. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/systemd/docker-compose.service.j2 +7 -6
  90. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/validators/__init__.py +16 -16
  91. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/validators/domain.py +27 -29
  92. wasm_cli-1.0.1/src/wasm/validators/environment.py +235 -0
  93. wasm_cli-1.0.1/src/wasm/validators/names.py +326 -0
  94. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/validators/port.py +42 -37
  95. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/validators/source.py +68 -76
  96. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/validators/ssh.py +78 -77
  97. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/web/__init__.py +2 -2
  98. wasm_cli-1.0.1/src/wasm/web/api/apps.py +411 -0
  99. wasm_cli-1.0.1/src/wasm/web/api/auth.py +322 -0
  100. wasm_cli-1.0.1/src/wasm/web/api/backups.py +390 -0
  101. wasm_cli-1.0.1/src/wasm/web/api/certs.py +353 -0
  102. wasm_cli-1.0.1/src/wasm/web/api/config.py +504 -0
  103. wasm_cli-1.0.1/src/wasm/web/api/databases.py +1263 -0
  104. wasm_cli-1.0.1/src/wasm/web/api/deps.py +228 -0
  105. wasm_cli-1.0.1/src/wasm/web/api/jobs.py +497 -0
  106. wasm_cli-1.0.1/src/wasm/web/api/monitor.py +725 -0
  107. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/web/api/router.py +21 -9
  108. wasm_cli-1.0.1/src/wasm/web/api/services.py +578 -0
  109. wasm_cli-1.0.1/src/wasm/web/api/sites.py +516 -0
  110. wasm_cli-1.0.1/src/wasm/web/api/system.py +512 -0
  111. wasm_cli-1.0.1/src/wasm/web/auth.py +1962 -0
  112. wasm_cli-1.0.1/src/wasm/web/jobs.py +1046 -0
  113. wasm_cli-1.0.1/src/wasm/web/server.py +895 -0
  114. wasm_cli-1.0.1/src/wasm/web/static/app.css +956 -0
  115. wasm_cli-1.0.1/src/wasm/web/static/panel.js +233 -0
  116. wasm_cli-1.0.1/src/wasm/web/static/vendor/alpine.min.js +5 -0
  117. wasm_cli-1.0.1/src/wasm/web/static/vendor/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
  118. wasm_cli-1.0.1/src/wasm/web/static/vendor/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
  119. wasm_cli-1.0.1/src/wasm/web/static/vendor/fonts/ibm-plex-sans-condensed-latin-500-normal.woff2 +0 -0
  120. wasm_cli-1.0.1/src/wasm/web/static/vendor/fonts/ibm-plex-sans-condensed-latin-600-normal.woff2 +0 -0
  121. wasm_cli-1.0.1/src/wasm/web/static/vendor/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
  122. wasm_cli-1.0.1/src/wasm/web/static/vendor/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
  123. wasm_cli-1.0.1/src/wasm/web/static/vendor/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
  124. wasm_cli-1.0.1/src/wasm/web/static/vendor/htmx.min.js +1 -0
  125. wasm_cli-1.0.1/src/wasm/web/static/vendor/uplot.min.css +1 -0
  126. wasm_cli-1.0.1/src/wasm/web/static/vendor/uplot.min.js +2 -0
  127. wasm_cli-1.0.1/src/wasm/web/static/vendor/xterm.css +285 -0
  128. wasm_cli-1.0.1/src/wasm/web/static/vendor/xterm.js +2 -0
  129. wasm_cli-1.0.1/src/wasm/web/templates/_macros.html +226 -0
  130. wasm_cli-1.0.1/src/wasm/web/templates/base.html +124 -0
  131. wasm_cli-1.0.1/src/wasm/web/templates/fragments/machine.html +44 -0
  132. wasm_cli-1.0.1/src/wasm/web/templates/login.html +69 -0
  133. wasm_cli-1.0.1/src/wasm/web/templates/pages/activity.html +75 -0
  134. wasm_cli-1.0.1/src/wasm/web/templates/pages/app.html +102 -0
  135. wasm_cli-1.0.1/src/wasm/web/templates/pages/backups.html +41 -0
  136. wasm_cli-1.0.1/src/wasm/web/templates/pages/certificates.html +74 -0
  137. wasm_cli-1.0.1/src/wasm/web/templates/pages/dashboard.html +104 -0
  138. wasm_cli-1.0.1/src/wasm/web/templates/pages/missing.html +20 -0
  139. wasm_cli-1.0.1/src/wasm/web/templates/pages/resources.html +42 -0
  140. wasm_cli-1.0.1/src/wasm/web/templates/pages/settings.html +55 -0
  141. wasm_cli-1.0.1/src/wasm/web/views/__init__.py +20 -0
  142. wasm_cli-1.0.1/src/wasm/web/views/context.py +136 -0
  143. wasm_cli-1.0.1/src/wasm/web/views/machine.py +157 -0
  144. wasm_cli-1.0.1/src/wasm/web/views/rendering.py +239 -0
  145. wasm_cli-1.0.1/src/wasm/web/views/resources.py +817 -0
  146. wasm_cli-1.0.1/src/wasm/web/views/router.py +372 -0
  147. wasm_cli-1.0.1/src/wasm/web/websockets/router.py +730 -0
  148. {wasm_cli-0.15.8 → wasm_cli-1.0.1/src/wasm_cli.egg-info}/PKG-INFO +69 -51
  149. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm_cli.egg-info/SOURCES.txt +54 -35
  150. wasm_cli-1.0.1/src/wasm_cli.egg-info/entry_points.txt +2 -0
  151. wasm_cli-1.0.1/src/wasm_cli.egg-info/requires.txt +33 -0
  152. wasm_cli-0.15.8/man/wasm.1 +0 -521
  153. wasm_cli-0.15.8/pyproject.toml +0 -167
  154. wasm_cli-0.15.8/src/wasm/__init__.py +0 -24
  155. wasm_cli-0.15.8/src/wasm/cli/__init__.py +0 -6
  156. wasm_cli-0.15.8/src/wasm/cli/commands/backup.py +0 -601
  157. wasm_cli-0.15.8/src/wasm/cli/commands/cert.py +0 -238
  158. wasm_cli-0.15.8/src/wasm/cli/commands/config.py +0 -96
  159. wasm_cli-0.15.8/src/wasm/cli/commands/db.py +0 -1010
  160. wasm_cli-0.15.8/src/wasm/cli/commands/env.py +0 -220
  161. wasm_cli-0.15.8/src/wasm/cli/commands/health.py +0 -231
  162. wasm_cli-0.15.8/src/wasm/cli/commands/monitor.py +0 -387
  163. wasm_cli-0.15.8/src/wasm/cli/commands/service.py +0 -203
  164. wasm_cli-0.15.8/src/wasm/cli/commands/setup.py +0 -1077
  165. wasm_cli-0.15.8/src/wasm/cli/commands/site.py +0 -298
  166. wasm_cli-0.15.8/src/wasm/cli/commands/store.py +0 -496
  167. wasm_cli-0.15.8/src/wasm/cli/commands/version.py +0 -111
  168. wasm_cli-0.15.8/src/wasm/cli/commands/web.py +0 -665
  169. wasm_cli-0.15.8/src/wasm/cli/commands/webapp.py +0 -1019
  170. wasm_cli-0.15.8/src/wasm/cli/parser.py +0 -1936
  171. wasm_cli-0.15.8/src/wasm/completions/__init__.py +0 -31
  172. wasm_cli-0.15.8/src/wasm/completions/_wasm +0 -829
  173. wasm_cli-0.15.8/src/wasm/completions/wasm.bash +0 -926
  174. wasm_cli-0.15.8/src/wasm/completions/wasm.fish +0 -509
  175. wasm_cli-0.15.8/src/wasm/core/config.py +0 -381
  176. wasm_cli-0.15.8/src/wasm/deployers/registry.py +0 -147
  177. wasm_cli-0.15.8/src/wasm/deployers/static.py +0 -214
  178. wasm_cli-0.15.8/src/wasm/main.py +0 -180
  179. wasm_cli-0.15.8/src/wasm/managers/apache_manager.py +0 -405
  180. wasm_cli-0.15.8/src/wasm/managers/backup_manager.py +0 -1256
  181. wasm_cli-0.15.8/src/wasm/managers/backup_scheduler.py +0 -266
  182. wasm_cli-0.15.8/src/wasm/managers/base_manager.py +0 -107
  183. wasm_cli-0.15.8/src/wasm/managers/cert_manager.py +0 -512
  184. wasm_cli-0.15.8/src/wasm/managers/database/base.py +0 -665
  185. wasm_cli-0.15.8/src/wasm/managers/database/mongodb.py +0 -595
  186. wasm_cli-0.15.8/src/wasm/managers/database/mysql.py +0 -686
  187. wasm_cli-0.15.8/src/wasm/managers/database/postgres.py +0 -769
  188. wasm_cli-0.15.8/src/wasm/managers/database/redis.py +0 -716
  189. wasm_cli-0.15.8/src/wasm/managers/nginx_manager.py +0 -401
  190. wasm_cli-0.15.8/src/wasm/managers/service_manager.py +0 -521
  191. wasm_cli-0.15.8/src/wasm/managers/source_manager.py +0 -579
  192. wasm_cli-0.15.8/src/wasm/monitor/__init__.py +0 -30
  193. wasm_cli-0.15.8/src/wasm/monitor/ai_analyzer.py +0 -628
  194. wasm_cli-0.15.8/src/wasm/monitor/email_notifier.py +0 -629
  195. wasm_cli-0.15.8/src/wasm/monitor/process_monitor.py +0 -1105
  196. wasm_cli-0.15.8/src/wasm/monitor/threat_store.py +0 -332
  197. wasm_cli-0.15.8/src/wasm/templates/systemd/backup-service.j2 +0 -9
  198. wasm_cli-0.15.8/src/wasm/templates/systemd/backup-timer.j2 +0 -13
  199. wasm_cli-0.15.8/src/wasm/web/api/apps.py +0 -452
  200. wasm_cli-0.15.8/src/wasm/web/api/auth.py +0 -157
  201. wasm_cli-0.15.8/src/wasm/web/api/backups.py +0 -353
  202. wasm_cli-0.15.8/src/wasm/web/api/certs.py +0 -368
  203. wasm_cli-0.15.8/src/wasm/web/api/config.py +0 -360
  204. wasm_cli-0.15.8/src/wasm/web/api/databases.py +0 -815
  205. wasm_cli-0.15.8/src/wasm/web/api/jobs.py +0 -320
  206. wasm_cli-0.15.8/src/wasm/web/api/monitor.py +0 -650
  207. wasm_cli-0.15.8/src/wasm/web/api/services.py +0 -498
  208. wasm_cli-0.15.8/src/wasm/web/api/sites.py +0 -522
  209. wasm_cli-0.15.8/src/wasm/web/api/system.py +0 -497
  210. wasm_cli-0.15.8/src/wasm/web/auth.py +0 -546
  211. wasm_cli-0.15.8/src/wasm/web/jobs.py +0 -697
  212. wasm_cli-0.15.8/src/wasm/web/server.py +0 -441
  213. wasm_cli-0.15.8/src/wasm/web/static/css/main.css +0 -931
  214. wasm_cli-0.15.8/src/wasm/web/static/index.html +0 -2159
  215. wasm_cli-0.15.8/src/wasm/web/static/js/components/cards.js +0 -396
  216. wasm_cli-0.15.8/src/wasm/web/static/js/components/jobs.js +0 -145
  217. wasm_cli-0.15.8/src/wasm/web/static/js/components/metrics.js +0 -262
  218. wasm_cli-0.15.8/src/wasm/web/static/js/components/skeleton.js +0 -172
  219. wasm_cli-0.15.8/src/wasm/web/static/js/core/api.js +0 -261
  220. wasm_cli-0.15.8/src/wasm/web/static/js/core/dialogs.js +0 -208
  221. wasm_cli-0.15.8/src/wasm/web/static/js/core/notifications.js +0 -249
  222. wasm_cli-0.15.8/src/wasm/web/static/js/core/router.js +0 -159
  223. wasm_cli-0.15.8/src/wasm/web/static/js/core/search.js +0 -365
  224. wasm_cli-0.15.8/src/wasm/web/static/js/core/shortcuts.js +0 -210
  225. wasm_cli-0.15.8/src/wasm/web/static/js/core/theme.js +0 -129
  226. wasm_cli-0.15.8/src/wasm/web/static/js/core/ui.js +0 -304
  227. wasm_cli-0.15.8/src/wasm/web/static/js/core/websocket.js +0 -172
  228. wasm_cli-0.15.8/src/wasm/web/static/js/main.js +0 -187
  229. wasm_cli-0.15.8/src/wasm/web/static/js/pages/apps.js +0 -218
  230. wasm_cli-0.15.8/src/wasm/web/static/js/pages/backups.js +0 -387
  231. wasm_cli-0.15.8/src/wasm/web/static/js/pages/certs.js +0 -152
  232. wasm_cli-0.15.8/src/wasm/web/static/js/pages/config.js +0 -494
  233. wasm_cli-0.15.8/src/wasm/web/static/js/pages/dashboard.js +0 -210
  234. wasm_cli-0.15.8/src/wasm/web/static/js/pages/databases.js +0 -1099
  235. wasm_cli-0.15.8/src/wasm/web/static/js/pages/jobs.js +0 -245
  236. wasm_cli-0.15.8/src/wasm/web/static/js/pages/logs.js +0 -121
  237. wasm_cli-0.15.8/src/wasm/web/static/js/pages/monitor.js +0 -545
  238. wasm_cli-0.15.8/src/wasm/web/static/js/pages/services.js +0 -338
  239. wasm_cli-0.15.8/src/wasm/web/static/js/pages/sites.js +0 -305
  240. wasm_cli-0.15.8/src/wasm/web/static/login.html +0 -293
  241. wasm_cli-0.15.8/src/wasm/web/websockets/router.py +0 -675
  242. wasm_cli-0.15.8/src/wasm_cli.egg-info/entry_points.txt +0 -2
  243. wasm_cli-0.15.8/src/wasm_cli.egg-info/requires.txt +0 -39
  244. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/LICENSE +0 -0
  245. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/docs/MONITOR.md +0 -0
  246. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/docs/OBS_SETUP.md +0 -0
  247. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/docs/assets/logo.png +0 -0
  248. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/docs/assets/logo_bg.png +0 -0
  249. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/setup.cfg +0 -0
  250. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/__main__.py +0 -0
  251. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/core/__init__.py +18 -18
  252. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/deployers/helpers/__init__.py +2 -2
  253. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/managers/database/__init__.py +5 -5
  254. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/__init__.py +0 -0
  255. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/apache/proxy.conf.j2 +0 -0
  256. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/apache/static.conf.j2 +0 -0
  257. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/nginx/advanced.conf.j2 +0 -0
  258. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/nginx/monorepo.conf.j2 +0 -0
  259. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/nginx/proxy.conf.j2 +0 -0
  260. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/templates/nginx/static.conf.j2 +0 -0
  261. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/web/api/__init__.py +0 -0
  262. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/web/static/logo.png +0 -0
  263. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/web/static/logo.webp +0 -0
  264. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm/web/websockets/__init__.py +0 -0
  265. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm_cli.egg-info/dependency_links.txt +0 -0
  266. {wasm_cli-0.15.8 → wasm_cli-1.0.1}/src/wasm_cli.egg-info/top_level.txt +0 -0
@@ -10,8 +10,8 @@ include pyproject.toml
10
10
  # Include source code (handled by setuptools, but explicit is better)
11
11
  recursive-include src *.py
12
12
  recursive-include src/wasm/templates *.j2
13
- recursive-include src/wasm/completions *
14
13
  recursive-include src/wasm/web/static *
14
+ recursive-include src/wasm/web/templates *.html
15
15
 
16
16
  # Include documentation
17
17
  recursive-include docs *.md *.png *.jpg *.svg
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wasm-cli
3
- Version: 0.15.8
3
+ Version: 1.0.1
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>
@@ -20,45 +20,43 @@ Classifier: Programming Language :: Python :: 3
20
20
  Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
23
25
  Classifier: Topic :: System :: Installation/Setup
24
26
  Classifier: Topic :: System :: Systems Administration
25
27
  Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
26
28
  Requires-Python: >=3.10
27
29
  Description-Content-Type: text/markdown
28
30
  License-File: LICENSE
31
+ Requires-Dist: click>=8.0
29
32
  Requires-Dist: Jinja2>=3.1.0
30
33
  Requires-Dist: PyYAML>=6.0
31
- Provides-Extra: interactive
32
- Requires-Dist: inquirer>=3.1.0; extra == "interactive"
34
+ Requires-Dist: questionary>=2.0
35
+ Requires-Dist: rich>=13.0
33
36
  Provides-Extra: dev
34
- Requires-Dist: pytest>=7.0; extra == "dev"
35
- Requires-Dist: pytest-cov>=4.0; extra == "dev"
36
- Requires-Dist: black>=23.0; extra == "dev"
37
- Requires-Dist: isort>=5.12; extra == "dev"
38
- Requires-Dist: mypy>=1.0; extra == "dev"
39
- Requires-Dist: ruff>=0.1.0; extra == "dev"
40
- Provides-Extra: rich
41
- Requires-Dist: rich>=13.0; extra == "rich"
37
+ Requires-Dist: pytest>=8.0; extra == "dev"
38
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
39
+ Requires-Dist: pytest-mock>=3.12; extra == "dev"
40
+ Requires-Dist: syrupy>=4.6; extra == "dev"
41
+ Requires-Dist: hypothesis>=6.100; extra == "dev"
42
+ Requires-Dist: mypy>=1.10; extra == "dev"
43
+ Requires-Dist: ruff>=0.6; extra == "dev"
42
44
  Provides-Extra: monitor
43
45
  Requires-Dist: psutil>=5.9.0; extra == "monitor"
44
46
  Requires-Dist: httpx>=0.25.0; extra == "monitor"
45
47
  Provides-Extra: web
46
48
  Requires-Dist: fastapi>=0.109.0; extra == "web"
49
+ Requires-Dist: starlette>=0.36.0; extra == "web"
50
+ Requires-Dist: pydantic>=2.0; extra == "web"
47
51
  Requires-Dist: uvicorn[standard]>=0.27.0; extra == "web"
48
- Requires-Dist: python-jose[cryptography]>=3.3.0; extra == "web"
49
- Requires-Dist: passlib[bcrypt]>=1.7.4; extra == "web"
50
52
  Requires-Dist: psutil>=5.9.0; extra == "web"
51
- Requires-Dist: aiofiles>=23.0.0; extra == "web"
52
53
  Provides-Extra: all
53
- Requires-Dist: inquirer>=3.1.0; extra == "all"
54
- Requires-Dist: rich>=13.0; extra == "all"
55
54
  Requires-Dist: psutil>=5.9.0; extra == "all"
56
55
  Requires-Dist: httpx>=0.25.0; extra == "all"
57
56
  Requires-Dist: fastapi>=0.109.0; extra == "all"
57
+ Requires-Dist: starlette>=0.36.0; extra == "all"
58
+ Requires-Dist: pydantic>=2.0; extra == "all"
58
59
  Requires-Dist: uvicorn[standard]>=0.27.0; extra == "all"
59
- Requires-Dist: python-jose[cryptography]>=3.3.0; extra == "all"
60
- Requires-Dist: passlib[bcrypt]>=1.7.4; extra == "all"
61
- Requires-Dist: aiofiles>=23.0.0; extra == "all"
62
60
  Dynamic: author
63
61
  Dynamic: license-file
64
62
  Dynamic: requires-python
@@ -104,8 +102,8 @@ WASM is a command-line tool for deploying and managing web applications on Linux
104
102
  - Create and control systemd services
105
103
  - Database management (MySQL, PostgreSQL, Redis, MongoDB)
106
104
  - Backup and rollback system
107
- - Web-based dashboard (optional)
108
- - Process monitoring and security scanning
105
+ - Control panel (optional)
106
+ - Resource and service observability
109
107
 
110
108
  ---
111
109
 
@@ -115,11 +113,11 @@ WASM is a command-line tool for deploying and managing web applications on Linux
115
113
 
116
114
  ```bash
117
115
  # Add GPG key
118
- curl -fsSL https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_24.04/Release.key | \
116
+ curl -fsSL https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_26.04/Release.key | \
119
117
  gpg --dearmor | sudo tee /usr/share/keyrings/wasm.gpg > /dev/null
120
118
 
121
119
  # Add repository
122
- echo 'deb [signed-by=/usr/share/keyrings/wasm.gpg] https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_24.04/ /' | \
120
+ echo 'deb [signed-by=/usr/share/keyrings/wasm.gpg] https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_26.04/ /' | \
123
121
  sudo tee /etc/apt/sources.list.d/wasm.list
124
122
 
125
123
  # Install
@@ -128,15 +126,16 @@ sudo apt install wasm
128
126
  ```
129
127
 
130
128
  **Supported versions:**
131
- - Ubuntu 22.04 LTS (Jammy Jellyfish)
129
+ - Ubuntu 26.04 LTS (Resolute Raccoon, Python 3.14)
132
130
  - Ubuntu 24.04 LTS (Noble Numbat)
133
- - Debian 12 (Bookworm)
131
+ - Ubuntu 22.04 LTS (Jammy Jellyfish)
132
+ - Debian 12 (Bookworm) and 13 (Trixie)
134
133
 
135
134
  ### Fedora
136
135
 
137
136
  ```bash
138
137
  sudo dnf config-manager --add-repo \
139
- https://download.opensuse.org/repositories/home:/Perkybeet/Fedora_40/home:Perkybeet.repo
138
+ https://download.opensuse.org/repositories/home:/Perkybeet/Fedora_42/home:Perkybeet.repo
140
139
  sudo dnf install wasm-cli
141
140
  ```
142
141
 
@@ -479,9 +478,11 @@ wasm rollback <domain> [id] Quick rollback
479
478
 
480
479
  ---
481
480
 
482
- ## Web Dashboard
481
+ ## Control Panel
483
482
 
484
- WASM includes an optional web-based dashboard for remote management.
483
+ An optional panel for the machine WASM runs on. It is server-rendered HTML updated by
484
+ htmx, with no build step, no Node and no third-party CDN, so it works on a server with no
485
+ route to the internet.
485
486
 
486
487
  ### Installation
487
488
 
@@ -489,31 +490,47 @@ WASM includes an optional web-based dashboard for remote management.
489
490
  pip install wasm-cli[web]
490
491
  ```
491
492
 
492
- ### Start Dashboard
493
+ ### Start it
493
494
 
494
495
  ```bash
495
- wasm web start --host 0.0.0.0 --port 8080
496
+ # Localhost only. This is the default and the safe one.
497
+ wasm web start
498
+
499
+ # Reachable from the network. TLS is required, because the panel's token is
500
+ # root on this machine.
501
+ wasm web start --host 0.0.0.0 --require-https --tls-cert cert.pem --tls-key key.pem
502
+
503
+ # Behind a TLS-terminating reverse proxy: declare it, so the panel trusts its
504
+ # forwarded headers and marks the session cookie Secure.
505
+ wasm web start --trusted-proxy 127.0.0.1
496
506
  ```
497
507
 
498
- ### Features
508
+ Print the access token with `wasm web token`.
509
+
510
+ ### What it does
499
511
 
500
- - Application deployment and management
501
- - Real-time logs and monitoring
502
- - SSL certificate management
503
- - Service control
504
- - Backup creation and restoration
505
- - Database management
506
- - REST API with token authentication
512
+ - Overview of the machine: load, memory, disk and the state of every managed service
513
+ - Applications, services, sites and databases, with their live state
514
+ - Live logs streamed from journald into a docked terminal
515
+ - A JSON API under `/api` for automation, authenticated with the same token
507
516
 
508
- Access the dashboard at `http://your-server:8080`
517
+ Sessions use an HttpOnly cookie with CSRF protection; the API also accepts
518
+ `Authorization: Bearer` for scripts. Every privileged action is written to an append-only
519
+ audit log.
520
+
521
+ ### Not yet in the panel
522
+
523
+ Certificate issuance, backup and restore, scheduled jobs and settings currently have API
524
+ endpoints but no screen. Use the CLI for those.
509
525
 
510
526
  ---
511
527
 
512
528
  ## System Requirements
513
529
 
514
- - **Operating System**: Ubuntu 20.04+, Debian 11+, Fedora 38+, openSUSE Leap 15.5+
515
- - **Python**: 3.10 or higher
516
- - **Privileges**: sudo access for service management
530
+ - **Operating System**: Ubuntu 22.04+, Debian 12+, Fedora 40+, openSUSE Leap 15.6+
531
+ - **Python**: 3.10 to 3.14
532
+ - **Privileges**: root. WASM writes to /etc, /var and systemd, so it checks for
533
+ root on the commands that touch the system rather than escalating per call.
517
534
 
518
535
  ### Optional Dependencies
519
536
 
@@ -532,18 +549,19 @@ WASM will check for missing dependencies and prompt installation when needed.
532
549
 
533
550
  ```
534
551
  /var/www/apps/
535
- ├── wasm-example-com/
536
- │ ├── current/ # Active deployment
537
- │ ├── releases/ # Previous releases (for rollback)
538
- │ │ ├── 20260114120000/
539
- │ │ └── 20260113150000/
540
- │ ├── shared/ # Persistent files (uploads, logs)
541
- │ └── .env # Environment variables
542
- │
543
- └── wasm-another-app/
552
+ ├── example-com/ # The application, deployed in place
553
+ │ └── .env # Environment variables, mode 0600
554
+ └── another-app/
544
555
  └── ...
556
+
557
+ /var/lib/wasm/wasm.db # What WASM knows about this machine, mode 0600
558
+ /etc/wasm/config.yaml # Configuration, mode 0600 in a 0700 directory
559
+ /var/backups/wasm/ # Backup archives, each self-contained
545
560
  ```
546
561
 
562
+ Rolling back restores from a backup rather than switching a symlink between releases; see
563
+ `wasm backup list` and `wasm rollback`.
564
+
547
565
  ---
548
566
 
549
567
  ## Development
@@ -39,8 +39,8 @@ WASM is a command-line tool for deploying and managing web applications on Linux
39
39
  - Create and control systemd services
40
40
  - Database management (MySQL, PostgreSQL, Redis, MongoDB)
41
41
  - Backup and rollback system
42
- - Web-based dashboard (optional)
43
- - Process monitoring and security scanning
42
+ - Control panel (optional)
43
+ - Resource and service observability
44
44
 
45
45
  ---
46
46
 
@@ -50,11 +50,11 @@ WASM is a command-line tool for deploying and managing web applications on Linux
50
50
 
51
51
  ```bash
52
52
  # Add GPG key
53
- curl -fsSL https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_24.04/Release.key | \
53
+ curl -fsSL https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_26.04/Release.key | \
54
54
  gpg --dearmor | sudo tee /usr/share/keyrings/wasm.gpg > /dev/null
55
55
 
56
56
  # Add repository
57
- echo 'deb [signed-by=/usr/share/keyrings/wasm.gpg] https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_24.04/ /' | \
57
+ echo 'deb [signed-by=/usr/share/keyrings/wasm.gpg] https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_26.04/ /' | \
58
58
  sudo tee /etc/apt/sources.list.d/wasm.list
59
59
 
60
60
  # Install
@@ -63,15 +63,16 @@ sudo apt install wasm
63
63
  ```
64
64
 
65
65
  **Supported versions:**
66
- - Ubuntu 22.04 LTS (Jammy Jellyfish)
66
+ - Ubuntu 26.04 LTS (Resolute Raccoon, Python 3.14)
67
67
  - Ubuntu 24.04 LTS (Noble Numbat)
68
- - Debian 12 (Bookworm)
68
+ - Ubuntu 22.04 LTS (Jammy Jellyfish)
69
+ - Debian 12 (Bookworm) and 13 (Trixie)
69
70
 
70
71
  ### Fedora
71
72
 
72
73
  ```bash
73
74
  sudo dnf config-manager --add-repo \
74
- https://download.opensuse.org/repositories/home:/Perkybeet/Fedora_40/home:Perkybeet.repo
75
+ https://download.opensuse.org/repositories/home:/Perkybeet/Fedora_42/home:Perkybeet.repo
75
76
  sudo dnf install wasm-cli
76
77
  ```
77
78
 
@@ -414,9 +415,11 @@ wasm rollback <domain> [id] Quick rollback
414
415
 
415
416
  ---
416
417
 
417
- ## Web Dashboard
418
+ ## Control Panel
418
419
 
419
- WASM includes an optional web-based dashboard for remote management.
420
+ An optional panel for the machine WASM runs on. It is server-rendered HTML updated by
421
+ htmx, with no build step, no Node and no third-party CDN, so it works on a server with no
422
+ route to the internet.
420
423
 
421
424
  ### Installation
422
425
 
@@ -424,31 +427,47 @@ WASM includes an optional web-based dashboard for remote management.
424
427
  pip install wasm-cli[web]
425
428
  ```
426
429
 
427
- ### Start Dashboard
430
+ ### Start it
428
431
 
429
432
  ```bash
430
- wasm web start --host 0.0.0.0 --port 8080
433
+ # Localhost only. This is the default and the safe one.
434
+ wasm web start
435
+
436
+ # Reachable from the network. TLS is required, because the panel's token is
437
+ # root on this machine.
438
+ wasm web start --host 0.0.0.0 --require-https --tls-cert cert.pem --tls-key key.pem
439
+
440
+ # Behind a TLS-terminating reverse proxy: declare it, so the panel trusts its
441
+ # forwarded headers and marks the session cookie Secure.
442
+ wasm web start --trusted-proxy 127.0.0.1
431
443
  ```
432
444
 
433
- ### Features
445
+ Print the access token with `wasm web token`.
446
+
447
+ ### What it does
434
448
 
435
- - Application deployment and management
436
- - Real-time logs and monitoring
437
- - SSL certificate management
438
- - Service control
439
- - Backup creation and restoration
440
- - Database management
441
- - REST API with token authentication
449
+ - Overview of the machine: load, memory, disk and the state of every managed service
450
+ - Applications, services, sites and databases, with their live state
451
+ - Live logs streamed from journald into a docked terminal
452
+ - A JSON API under `/api` for automation, authenticated with the same token
442
453
 
443
- Access the dashboard at `http://your-server:8080`
454
+ Sessions use an HttpOnly cookie with CSRF protection; the API also accepts
455
+ `Authorization: Bearer` for scripts. Every privileged action is written to an append-only
456
+ audit log.
457
+
458
+ ### Not yet in the panel
459
+
460
+ Certificate issuance, backup and restore, scheduled jobs and settings currently have API
461
+ endpoints but no screen. Use the CLI for those.
444
462
 
445
463
  ---
446
464
 
447
465
  ## System Requirements
448
466
 
449
- - **Operating System**: Ubuntu 20.04+, Debian 11+, Fedora 38+, openSUSE Leap 15.5+
450
- - **Python**: 3.10 or higher
451
- - **Privileges**: sudo access for service management
467
+ - **Operating System**: Ubuntu 22.04+, Debian 12+, Fedora 40+, openSUSE Leap 15.6+
468
+ - **Python**: 3.10 to 3.14
469
+ - **Privileges**: root. WASM writes to /etc, /var and systemd, so it checks for
470
+ root on the commands that touch the system rather than escalating per call.
452
471
 
453
472
  ### Optional Dependencies
454
473
 
@@ -467,18 +486,19 @@ WASM will check for missing dependencies and prompt installation when needed.
467
486
 
468
487
  ```
469
488
  /var/www/apps/
470
- ├── wasm-example-com/
471
- │ ├── current/ # Active deployment
472
- │ ├── releases/ # Previous releases (for rollback)
473
- │ │ ├── 20260114120000/
474
- │ │ └── 20260113150000/
475
- │ ├── shared/ # Persistent files (uploads, logs)
476
- │ └── .env # Environment variables
477
- │
478
- └── wasm-another-app/
489
+ ├── example-com/ # The application, deployed in place
490
+ │ └── .env # Environment variables, mode 0600
491
+ └── another-app/
479
492
  └── ...
493
+
494
+ /var/lib/wasm/wasm.db # What WASM knows about this machine, mode 0600
495
+ /etc/wasm/config.yaml # Configuration, mode 0600 in a 0700 directory
496
+ /var/backups/wasm/ # Backup archives, each self-contained
480
497
  ```
481
498
 
499
+ Rolling back restores from a backup rather than switching a symlink between releases; see
500
+ `wasm backup list` and `wasm rollback`.
501
+
482
502
  ---
483
503
 
484
504
  ## Development
@@ -0,0 +1,133 @@
1
+ # Panel WASM - Dirección de diseño
2
+
3
+ Fecha: 2026-08-12
4
+ Aplica a: `src/wasm/web/` (backend de vistas y assets)
5
+
6
+ ## El sujeto
7
+
8
+ Quien usa este panel administra su propio servidor Linux. Eligió no usar Vercel. Está
9
+ cómodo en una terminal y abre el panel porque quiere ver el estado de la máquina de un
10
+ vistazo, no porque quiera que le escondan la máquina.
11
+
12
+ El trabajo de la interfaz es uno solo: **enseñar el estado real de esta máquina y dejar
13
+ actuar sobre él sin tener que abrir una sesión SSH.**
14
+
15
+ De ahí sale todo lo demás. El material del sujeto son units de systemd, bloques de nginx,
16
+ logs de journald, fechas de caducidad de certificados, números de puerto, códigos de salida.
17
+ Su vernáculo es la salida de `systemctl status`. La interfaz se construye con ese material,
18
+ no a pesar de él.
19
+
20
+ ## Lo que este panel NO es
21
+
22
+ No es una consola de nube. Imitar la estética SaaS neutra de Vercel sería a la vez el camino
23
+ más trillado y una mentira sobre lo que es el producto: aquí solo hay una máquina, es tuya, y
24
+ si la rompes se rompe.
25
+
26
+ Tampoco es una terminal nostálgica. Verde sobre negro es un disfraz, no un diseño.
27
+
28
+ ## Tokens
29
+
30
+ ### Color: el color solo significa estado
31
+
32
+ La regla que sostiene la identidad: **ningún elemento lleva color si no codifica estado.**
33
+ La navegación, las cabeceras, las tarjetas, los bordes y el texto son acromáticos. Si ves
34
+ color en la pantalla, es información: algo está corriendo, algo ha fallado, algo caduca
35
+ pronto.
36
+
37
+ Eso hace la pantalla escaneable y es exactamente lo contrario de un dashboard con degradados
38
+ decorativos.
39
+
40
+ | Rol | Claro | Oscuro | Significa |
41
+ |---|---|---|---|
42
+ | Fondo | `#FBFAF8` | `#12161A` | |
43
+ | Superficie | `#FFFFFF` | `#191E24` | |
44
+ | Borde | `#E4E1DC` | `#262D35` | |
45
+ | Texto | `#1A1D21` | `#E8EAED` | |
46
+ | Texto tenue | `#6B7178` | `#8A929B` | |
47
+ | Activo | `#1F7A4D` | `#3FA96E` | unidad corriendo, certificado válido |
48
+ | Detenido | `#6B7178` | `#8A929B` | parado a propósito, no es un problema |
49
+ | Fallo | `#B3261E` | `#E5534B` | unidad caída, despliegue fallido |
50
+ | En curso | `#9A6700` | `#D4A017` | desplegando, renovando, caduca pronto |
51
+
52
+ El modo claro es el que fija la identidad: un técnico denso, tipo hoja de datos, poco
53
+ frecuente en esta categoría. El oscuro es igual de completo, porque a las tres de la mañana
54
+ es el que se usa.
55
+
56
+ ### Tipografía: IBM Plex, tres voces
57
+
58
+ Una sola familia, tres cortes, todos OFL y vendorizables en cinco ficheros woff2.
59
+
60
+ - **IBM Plex Sans** para interfaz y prosa.
61
+ - **IBM Plex Sans Condensed** para cabeceras de tabla, etiquetas y ejes. El corte condensado
62
+ es la decisión distintiva: da densidad real y un aire de hoja de datos técnica que una
63
+ grotesca neutra no consigue.
64
+ - **IBM Plex Mono** para todo valor que sea del sistema: rutas, nombres de unit, puertos,
65
+ códigos de salida, marcas de tiempo, logs.
66
+
67
+ Plex no es a lo que se recurre por defecto en herramientas de desarrollo, que es Inter o
68
+ Geist. Tiene forma propia: terminaciones planas, `a` y `g` reconocibles, y fue diseñada
69
+ precisamente como tipografía de sistema para trabajo técnico.
70
+
71
+ **Cifras tabulares en todo valor que cambie.** Las columnas no bailan cuando se actualiza un
72
+ número. Es un detalle de instrumento que casi ningún panel acierta.
73
+
74
+ ### Estructura: el raíl de estado
75
+
76
+ Los recursos no son tarjetas flotando. Son filas de una tabla densa, y cada fila lleva un
77
+ raíl vertical de 3px a la izquierda cuyo color es su estado.
78
+
79
+ Recorrer el borde izquierdo con la vista cuenta la salud de todo sin leer una palabra. El
80
+ mismo lenguaje sirve para aplicaciones, servicios, sitios, certificados y backups, así que se
81
+ aprende una vez.
82
+
83
+ Los marcadores numerados (01 / 02 / 03) no se usan: aquí nada es una secuencia. Lo único que
84
+ lleva numeración es el pipeline de despliegue, porque ahí el orden sí es información.
85
+
86
+ ### El elemento firma: la banda de máquina
87
+
88
+ Una franja persistente en la parte superior, visible en todas las páginas, con el estado real
89
+ de esta máquina: hostname, uptime, carga con un sparkline en línea, memoria y disco como
90
+ barras finas de capacidad, y el recuento de units por estado. Todo en mono, cifras tabulares,
91
+ actualizándose por SSE.
92
+
93
+ No son tarjetas de estadística. Es una línea de estado de instrumento, como la de un equipo
94
+ de laboratorio. Y es lo que hace que se sienta una sala de control de una máquina concreta en
95
+ vez de un CRUD genérico. También es honesto: siempre sabes qué máquina estás a punto de
96
+ tocar.
97
+
98
+ ### El riesgo: el cajón de logs anclado
99
+
100
+ Los logs viven en un cajón anclado abajo, persistente entre navegaciones, con streaming de
101
+ journald por WebSocket sobre xterm.js. Como el terminal integrado de un editor.
102
+
103
+ Cuesta espacio vertical, y esa es la apuesta. Se justifica porque el momento en que más
104
+ falta hacen los logs es en mitad de un despliegue, y porque esconderlos detrás de un clic por
105
+ recurso es justo lo que hace que un panel web se sienta peor que una sesión SSH.
106
+
107
+ ## Movimiento
108
+
109
+ Casi ninguno. Esto es un instrumento.
110
+
111
+ 1. Un pulso breve en el raíl cuando una unidad cambia de estado, porque un cambio de estado
112
+ es el evento más importante que puede ocurrir.
113
+ 2. El deslizamiento del cajón de logs.
114
+ 3. Esqueleto a contenido.
115
+
116
+ `prefers-reduced-motion` se respeta en los tres.
117
+
118
+ ## Texto
119
+
120
+ - Nombrar por lo que la persona controla: "Reiniciar", no "Enviar".
121
+ - La acción conserva su nombre en todo el flujo: el botón "Publicar" produce el aviso
122
+ "Publicado".
123
+ - **Un error del sistema no se parafrasea nunca.** Se muestra literal, en mono, y encima se
124
+ pone qué hacer. Este público quiere el mensaje real de nginx o de systemd, no una versión
125
+ amable.
126
+ - Los vacíos son una invitación: "Todavía no hay aplicaciones. Despliega una desde aquí o con
127
+ `wasm deploy`."
128
+
129
+ ## Suelo de calidad
130
+
131
+ Responsive hasta móvil, foco de teclado visible, contraste AA como mínimo en texto y en los
132
+ colores de estado sobre su fondo, movimiento reducido respetado, y funcionamiento completo
133
+ sin conexión a internet: todos los assets vendorizados, cero CDN.