wasm-cli 0.14.2__tar.gz → 0.14.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 (146) hide show
  1. {wasm_cli-0.14.2/src/wasm_cli.egg-info → wasm_cli-0.14.3}/PKG-INFO +1 -1
  2. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/pyproject.toml +1 -1
  3. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/setup.py +1 -1
  4. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/__init__.py +1 -1
  5. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/webapp.py +76 -6
  6. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/core/update_checker.py +21 -16
  7. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/monorepo.py +33 -19
  8. {wasm_cli-0.14.2 → wasm_cli-0.14.3/src/wasm_cli.egg-info}/PKG-INFO +1 -1
  9. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/LICENSE +0 -0
  10. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/MANIFEST.in +0 -0
  11. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/README.md +0 -0
  12. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/docs/MONITOR.md +0 -0
  13. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/docs/OBS_SETUP.md +0 -0
  14. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/docs/assets/logo.png +0 -0
  15. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/docs/assets/logo_bg.png +0 -0
  16. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/man/wasm.1 +0 -0
  17. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/setup.cfg +0 -0
  18. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/__main__.py +0 -0
  19. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/__init__.py +0 -0
  20. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/__init__.py +0 -0
  21. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/backup.py +0 -0
  22. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/cert.py +0 -0
  23. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/config.py +0 -0
  24. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/db.py +0 -0
  25. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/health.py +0 -0
  26. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/monitor.py +0 -0
  27. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/service.py +0 -0
  28. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/setup.py +0 -0
  29. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/site.py +0 -0
  30. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/store.py +0 -0
  31. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/version.py +0 -0
  32. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/commands/web.py +0 -0
  33. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/interactive.py +0 -0
  34. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/cli/parser.py +0 -0
  35. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/completions/__init__.py +0 -0
  36. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/completions/_wasm +0 -0
  37. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/completions/wasm.bash +0 -0
  38. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/completions/wasm.fish +0 -0
  39. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/core/__init__.py +0 -0
  40. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/core/config.py +0 -0
  41. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/core/dependencies.py +0 -0
  42. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/core/exceptions.py +0 -0
  43. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/core/logger.py +0 -0
  44. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/core/store.py +0 -0
  45. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/core/utils.py +0 -0
  46. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/__init__.py +0 -0
  47. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/base.py +0 -0
  48. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/helpers/__init__.py +0 -0
  49. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/helpers/package_manager.py +0 -0
  50. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/helpers/path_resolver.py +0 -0
  51. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/helpers/prisma.py +0 -0
  52. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/helpers/turbo.py +0 -0
  53. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/helpers/workspace.py +0 -0
  54. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/nextjs.py +0 -0
  55. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/nodejs.py +0 -0
  56. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/python.py +0 -0
  57. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/registry.py +0 -0
  58. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/static.py +0 -0
  59. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/deployers/vite.py +0 -0
  60. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/main.py +0 -0
  61. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/__init__.py +0 -0
  62. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/apache_manager.py +0 -0
  63. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/backup_manager.py +0 -0
  64. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/base_manager.py +0 -0
  65. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/cert_manager.py +0 -0
  66. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/database/__init__.py +0 -0
  67. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/database/base.py +0 -0
  68. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/database/mongodb.py +0 -0
  69. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/database/mysql.py +0 -0
  70. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/database/postgres.py +0 -0
  71. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/database/redis.py +0 -0
  72. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/database/registry.py +0 -0
  73. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/nginx_manager.py +0 -0
  74. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/service_manager.py +0 -0
  75. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/managers/source_manager.py +0 -0
  76. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/monitor/__init__.py +0 -0
  77. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/monitor/ai_analyzer.py +0 -0
  78. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/monitor/email_notifier.py +0 -0
  79. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/monitor/process_monitor.py +0 -0
  80. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/monitor/threat_store.py +0 -0
  81. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/templates/__init__.py +0 -0
  82. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/templates/apache/proxy.conf.j2 +0 -0
  83. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/templates/apache/static.conf.j2 +0 -0
  84. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/templates/nginx/monorepo.conf.j2 +0 -0
  85. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/templates/nginx/proxy.conf.j2 +0 -0
  86. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/templates/nginx/static.conf.j2 +0 -0
  87. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/templates/systemd/app.service.j2 +0 -0
  88. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/validators/__init__.py +0 -0
  89. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/validators/domain.py +0 -0
  90. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/validators/port.py +0 -0
  91. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/validators/source.py +0 -0
  92. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/validators/ssh.py +0 -0
  93. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/__init__.py +0 -0
  94. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/__init__.py +0 -0
  95. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/apps.py +0 -0
  96. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/auth.py +0 -0
  97. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/backups.py +0 -0
  98. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/certs.py +0 -0
  99. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/config.py +0 -0
  100. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/databases.py +0 -0
  101. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/jobs.py +0 -0
  102. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/monitor.py +0 -0
  103. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/router.py +0 -0
  104. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/services.py +0 -0
  105. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/sites.py +0 -0
  106. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/api/system.py +0 -0
  107. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/auth.py +0 -0
  108. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/jobs.py +0 -0
  109. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/server.py +0 -0
  110. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/css/main.css +0 -0
  111. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/index.html +0 -0
  112. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/components/cards.js +0 -0
  113. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/components/jobs.js +0 -0
  114. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/components/metrics.js +0 -0
  115. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/components/skeleton.js +0 -0
  116. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/api.js +0 -0
  117. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/dialogs.js +0 -0
  118. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/notifications.js +0 -0
  119. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/router.js +0 -0
  120. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/search.js +0 -0
  121. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/shortcuts.js +0 -0
  122. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/theme.js +0 -0
  123. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/ui.js +0 -0
  124. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/core/websocket.js +0 -0
  125. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/main.js +0 -0
  126. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/apps.js +0 -0
  127. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/backups.js +0 -0
  128. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/certs.js +0 -0
  129. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/config.js +0 -0
  130. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/dashboard.js +0 -0
  131. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/databases.js +0 -0
  132. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/jobs.js +0 -0
  133. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/logs.js +0 -0
  134. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/monitor.js +0 -0
  135. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/services.js +0 -0
  136. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/js/pages/sites.js +0 -0
  137. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/login.html +0 -0
  138. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/logo.png +0 -0
  139. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/static/logo.webp +0 -0
  140. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/websockets/__init__.py +0 -0
  141. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm/web/websockets/router.py +0 -0
  142. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm_cli.egg-info/SOURCES.txt +0 -0
  143. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm_cli.egg-info/dependency_links.txt +0 -0
  144. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm_cli.egg-info/entry_points.txt +0 -0
  145. {wasm_cli-0.14.2 → wasm_cli-0.14.3}/src/wasm_cli.egg-info/requires.txt +0 -0
  146. {wasm_cli-0.14.2 → wasm_cli-0.14.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: 0.14.2
3
+ Version: 0.14.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 = "0.14.2"
7
+ version = "0.14.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="0.14.2",
12
+ version="0.14.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",
@@ -8,7 +8,7 @@ WASM - Web App System Management
8
8
  A robust CLI tool for deploying and managing web applications on Linux servers.
9
9
  """
10
10
 
11
- __version__ = "0.14.2"
11
+ __version__ = "0.14.3"
12
12
  __author__ = "Yago López Prado"
13
13
  __license__ = "WASM-NCSAL"
14
14
 
@@ -594,22 +594,28 @@ def _handle_update(args: Namespace) -> int:
594
594
  else:
595
595
  logger.substep(f"Detected: {app_type}")
596
596
 
597
+ # Handle monorepo updates with dedicated flow
598
+ if app_type == "monorepo":
599
+ return _handle_monorepo_update(
600
+ args, app_path, app_name, domain, logger, total_steps
601
+ )
602
+
597
603
  deployer = get_deployer(app_type, verbose=args.verbose)
598
604
  deployer.app_path = app_path
599
605
  deployer.app_name = app_name
600
606
  deployer.domain = domain
601
607
  deployer._package_manager = package_manager
602
-
608
+
603
609
  # Run pre_install to detect package manager and prisma
604
610
  deployer.pre_install()
605
611
  logger.substep(f"Package manager: {deployer.package_manager}")
606
612
  if deployer.has_prisma:
607
613
  logger.substep("Prisma detected")
608
-
614
+
609
615
  # Step 4: Install dependencies (without stopping the app)
610
616
  logger.step(4, total_steps, "Installing dependencies")
611
617
  deployer.install_dependencies()
612
-
618
+
613
619
  # Step 5: Generate Prisma and run migrations if needed
614
620
  if deployer.has_prisma:
615
621
  logger.step(5, total_steps, "Updating Prisma")
@@ -617,11 +623,11 @@ def _handle_update(args: Namespace) -> int:
617
623
  deployer.run_prisma_migrate(deploy=True)
618
624
  else:
619
625
  logger.step(5, total_steps, "Prisma not detected, skipping")
620
-
626
+
621
627
  # Step 6: Build application (without stopping the app)
622
628
  logger.step(6, total_steps, "Building application")
623
629
  deployer.build()
624
-
630
+
625
631
  # Step 7: Restart service (only if not static)
626
632
  logger.step(7, total_steps, "Restarting application")
627
633
  service_manager = ServiceManager(verbose=args.verbose)
@@ -660,7 +666,71 @@ def _handle_update(args: Namespace) -> int:
660
666
  else:
661
667
  logger.warning("Application restarted but may not be running correctly")
662
668
  logger.info(f"Check logs with: wasm logs {domain}")
663
-
669
+
670
+ return 0
671
+
672
+
673
+ def _handle_monorepo_update(args, app_path, app_name, domain, logger, total_steps):
674
+ """Handle update for monorepo applications."""
675
+ from wasm.deployers.monorepo import MonorepoDeployer
676
+
677
+ deployer = MonorepoDeployer(verbose=args.verbose)
678
+ deployer.app_path = app_path
679
+ deployer.app_name = app_name
680
+ deployer.domain = domain
681
+ deployer.package_manager = "pnpm"
682
+
683
+ # Step 4: Install dependencies
684
+ logger.step(4, total_steps, "Installing dependencies")
685
+ deployer._install_dependencies()
686
+
687
+ # Step 5: Run Prisma migrations
688
+ logger.step(5, total_steps, "Running database migrations")
689
+ deployer._run_prisma_migrations()
690
+
691
+ # Step 6: Build all workspaces
692
+ logger.step(6, total_steps, "Building applications")
693
+ deployer._set_permissions()
694
+ deployer._build_all()
695
+
696
+ # Step 7: Restart all workspace services
697
+ logger.step(7, total_steps, "Restarting applications")
698
+ service_manager = ServiceManager(verbose=args.verbose)
699
+
700
+ # Find all services for this monorepo
701
+ from wasm.core.store import get_store
702
+ store = get_store()
703
+ app = store.get_app(domain)
704
+
705
+ restarted = []
706
+ if app:
707
+ all_services = store.list_services()
708
+ services = [s for s in all_services if s.app_id == app.id]
709
+ for service in services:
710
+ logger.substep(f"Restarting {service.name}")
711
+ try:
712
+ service_manager.restart(service.name)
713
+ restarted.append(service.name)
714
+ except Exception as e:
715
+ logger.warning(f"Failed to restart {service.name}: {e}")
716
+ else:
717
+ # Fallback: restart by app_name pattern
718
+ status = service_manager.get_status(app_name)
719
+ if status.get("exists"):
720
+ service_manager.restart(app_name)
721
+ restarted.append(app_name)
722
+
723
+ if restarted:
724
+ import time
725
+ time.sleep(3)
726
+ logger.success(f"Monorepo updated successfully: {domain}")
727
+ logger.blank()
728
+ for name in restarted:
729
+ logger.key_value("Restarted", name)
730
+ else:
731
+ logger.warning("No services found to restart")
732
+ logger.info(f"Try redeploying: wasm create -d {domain}")
733
+
664
734
  return 0
665
735
 
666
736
 
@@ -45,7 +45,10 @@ class UpdateChecker:
45
45
  if cls._is_cache_valid():
46
46
  cached_data = cls._read_cache()
47
47
  if cached_data and cached_data.get("has_update"):
48
- cls._update_version = cached_data["latest_version"]
48
+ cached_version = cached_data["latest_version"]
49
+ # Re-verify against current version (user may have updated)
50
+ if cls._is_newer_version(cached_version, __version__):
51
+ cls._update_version = cached_version
49
52
  return
50
53
 
51
54
  # Start background thread for network request
@@ -270,28 +273,17 @@ class UpdateChecker:
270
273
  if pipx_path.exists():
271
274
  return "pipx"
272
275
 
273
- # Check if installed with pip in current Python environment
274
- result = subprocess.run(
275
- [sys.executable, "-m", "pip", "show", "wasm-cli"],
276
- capture_output=True,
277
- text=True,
278
- timeout=2
279
- )
280
- if result.returncode == 0:
281
- # Check if installed in editable mode (from source)
282
- if "Editable project location:" in result.stdout or "-e " in result.stdout:
283
- return "source"
284
- return "pip"
276
+ # Check system package managers BEFORE pip, since system packages
277
+ # install Python files that pip can also detect (false positive)
285
278
 
286
- # Check system package managers
287
279
  # APT (Ubuntu, Debian) - package is called "wasm" not "wasm-cli"
288
280
  if Path("/var/lib/dpkg/status").exists():
289
281
  result = subprocess.run(
290
- ["dpkg", "-l", "wasm"],
282
+ ["dpkg", "-s", "wasm"],
291
283
  capture_output=True,
292
284
  timeout=2
293
285
  )
294
- if result.returncode == 0 and b"wasm" in result.stdout:
286
+ if result.returncode == 0:
295
287
  return "apt"
296
288
 
297
289
  # DNF/YUM (Fedora, RHEL, CentOS)
@@ -319,6 +311,19 @@ class UpdateChecker:
319
311
  except FileNotFoundError:
320
312
  pass
321
313
 
314
+ # Check pip (after system package managers)
315
+ result = subprocess.run(
316
+ [sys.executable, "-m", "pip", "show", "wasm-cli"],
317
+ capture_output=True,
318
+ text=True,
319
+ timeout=2
320
+ )
321
+ if result.returncode == 0:
322
+ # Check if installed in editable mode (from source)
323
+ if "Editable project location:" in result.stdout or "-e " in result.stdout:
324
+ return "source"
325
+ return "pip"
326
+
322
327
  except Exception as e:
323
328
  logger.debug(f"Failed to detect installation method: {e}")
324
329
 
@@ -187,32 +187,46 @@ class MonorepoDeployer:
187
187
  """
188
188
  Detect if path contains a Turborepo/pnpm monorepo.
189
189
 
190
+ Requires turbo.json AND workspace configuration AND at least 2
191
+ deployable applications in apps/ to distinguish from single apps
192
+ that use Turborepo for build caching.
193
+
190
194
  Args:
191
195
  path: Path to check.
192
196
 
193
197
  Returns:
194
198
  True if this deployer can handle the project.
195
199
  """
196
- # Check for turbo.json
197
- if (path / "turbo.json").exists():
198
- return True
199
-
200
- # Check for pnpm-workspace.yaml
201
- if (path / "pnpm-workspace.yaml").exists():
202
- return True
203
-
204
- # Check package.json for workspaces field
205
- package_json = path / "package.json"
206
- if package_json.exists():
207
- try:
208
- with open(package_json) as f:
209
- pkg = json.load(f)
210
- if "workspaces" in pkg:
211
- return True
212
- except (json.JSONDecodeError, OSError):
213
- pass
200
+ # Must have turbo.json (primary monorepo build tool)
201
+ if not (path / "turbo.json").exists():
202
+ return False
203
+
204
+ # Must have workspace configuration
205
+ has_workspace_config = (path / "pnpm-workspace.yaml").exists()
206
+ if not has_workspace_config:
207
+ package_json = path / "package.json"
208
+ if package_json.exists():
209
+ try:
210
+ with open(package_json) as f:
211
+ pkg = json.load(f)
212
+ has_workspace_config = "workspaces" in pkg
213
+ except (json.JSONDecodeError, OSError):
214
+ pass
215
+
216
+ if not has_workspace_config:
217
+ return False
218
+
219
+ # Must have multiple deployable apps in apps/ directory
220
+ apps_dir = path / "apps"
221
+ if not apps_dir.is_dir():
222
+ return False
223
+
224
+ app_count = sum(
225
+ 1 for d in apps_dir.iterdir()
226
+ if d.is_dir() and (d / "package.json").exists()
227
+ )
214
228
 
215
- return False
229
+ return app_count >= 2
216
230
 
217
231
  def _run(
218
232
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wasm-cli
3
- Version: 0.14.2
3
+ Version: 0.14.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>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes