remo-cli 1.0.0__tar.gz → 1.0.2__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 (207) hide show
  1. {remo_cli-1.0.0 → remo_cli-1.0.2}/PKG-INFO +1 -1
  2. {remo_cli-1.0.0 → remo_cli-1.0.2}/pyproject.toml +1 -1
  3. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/shell.py +13 -0
  4. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/validation.py +32 -0
  5. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/providers/aws.py +3 -1
  6. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/providers/hetzner.py +3 -1
  7. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/providers/incus.py +3 -1
  8. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/providers/proxmox.py +3 -1
  9. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/cli/test_shell.py +18 -0
  10. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_validation.py +30 -0
  11. {remo_cli-1.0.0 → remo_cli-1.0.2}/uv.lock +1 -1
  12. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.analyze.md +0 -0
  13. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.checklist.md +0 -0
  14. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.clarify.md +0 -0
  15. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.constitution.md +0 -0
  16. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.implement.md +0 -0
  17. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.plan.md +0 -0
  18. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.specify.md +0 -0
  19. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.tasks.md +0 -0
  20. {remo_cli-1.0.0 → remo_cli-1.0.2}/.claude/commands/speckit.taskstoissues.md +0 -0
  21. {remo_cli-1.0.0 → remo_cli-1.0.2}/.devcontainer/devcontainer.json +0 -0
  22. {remo_cli-1.0.0 → remo_cli-1.0.2}/.dockerignore +0 -0
  23. {remo_cli-1.0.0 → remo_cli-1.0.2}/.github/dependabot.yml +0 -0
  24. {remo_cli-1.0.0 → remo_cli-1.0.2}/.github/workflows/ci.yml +0 -0
  25. {remo_cli-1.0.0 → remo_cli-1.0.2}/.github/workflows/provision.yml +0 -0
  26. {remo_cli-1.0.0 → remo_cli-1.0.2}/.github/workflows/release.yml +0 -0
  27. {remo_cli-1.0.0 → remo_cli-1.0.2}/.github/workflows/smoke-test-cleanup.yml +0 -0
  28. {remo_cli-1.0.0 → remo_cli-1.0.2}/.github/workflows/smoke-test.yml +0 -0
  29. {remo_cli-1.0.0 → remo_cli-1.0.2}/.github/workflows/teardown.yml +0 -0
  30. {remo_cli-1.0.0 → remo_cli-1.0.2}/.gitignore +0 -0
  31. {remo_cli-1.0.0 → remo_cli-1.0.2}/.maverick/checkpoints/feature/implementation_complete.json +0 -0
  32. {remo_cli-1.0.0 → remo_cli-1.0.2}/.maverick/checkpoints/feature/phase_${{ index }}_complete.json +0 -0
  33. {remo_cli-1.0.0 → remo_cli-1.0.2}/.maverick/checkpoints/feature/validation_complete.json +0 -0
  34. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/memory/constitution.md +0 -0
  35. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/scripts/bash/check-prerequisites.sh +0 -0
  36. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/scripts/bash/common.sh +0 -0
  37. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/scripts/bash/create-new-feature.sh +0 -0
  38. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/scripts/bash/setup-plan.sh +0 -0
  39. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/scripts/bash/update-agent-context.sh +0 -0
  40. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/templates/agent-file-template.md +0 -0
  41. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/templates/checklist-template.md +0 -0
  42. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/templates/plan-template.md +0 -0
  43. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/templates/spec-template.md +0 -0
  44. {remo_cli-1.0.0 → remo_cli-1.0.2}/.specify/templates/tasks-template.md +0 -0
  45. {remo_cli-1.0.0 → remo_cli-1.0.2}/CLAUDE.md +0 -0
  46. {remo_cli-1.0.0 → remo_cli-1.0.2}/CONTRIBUTING.md +0 -0
  47. {remo_cli-1.0.0 → remo_cli-1.0.2}/Dockerfile +0 -0
  48. {remo_cli-1.0.0 → remo_cli-1.0.2}/LICENSE +0 -0
  49. {remo_cli-1.0.0 → remo_cli-1.0.2}/README.md +0 -0
  50. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/.ansible-lint +0 -0
  51. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/README.md +0 -0
  52. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/ansible.cfg +0 -0
  53. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/aws_configure.yml +0 -0
  54. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/aws_resize.yml +0 -0
  55. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/aws_site.yml +0 -0
  56. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/aws_teardown.yml +0 -0
  57. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/group_vars/all.yml +0 -0
  58. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/group_vars/incus_containers.yml +0 -0
  59. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/group_vars/proxmox_containers.yml +0 -0
  60. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/hetzner_configure.yml +0 -0
  61. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/hetzner_provision.yml +0 -0
  62. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/hetzner_resize.yml +0 -0
  63. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/hetzner_site.yml +0 -0
  64. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/hetzner_teardown.yml +0 -0
  65. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/incus_bootstrap.yml +0 -0
  66. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/incus_configure.yml +0 -0
  67. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/incus_provision.yml +0 -0
  68. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/incus_resize.yml +0 -0
  69. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/incus_site.yml +0 -0
  70. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/incus_teardown.yml +0 -0
  71. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/inventory/hosts.yml +0 -0
  72. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/inventory/incus_containers.yml +0 -0
  73. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/proxmox_bootstrap.yml +0 -0
  74. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/proxmox_configure.yml +0 -0
  75. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/proxmox_provision.yml +0 -0
  76. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/proxmox_resize.yml +0 -0
  77. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/proxmox_site.yml +0 -0
  78. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/proxmox_teardown.yml +0 -0
  79. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/requirements.yml +0 -0
  80. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/aws_server/defaults/main.yml +0 -0
  81. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/aws_server/tasks/ebs.yml +0 -0
  82. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/aws_server/tasks/ec2.yml +0 -0
  83. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/aws_server/tasks/main.yml +0 -0
  84. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/aws_server/tasks/patch_manager.yml +0 -0
  85. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/aws_server/tasks/preflight.yml +0 -0
  86. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/aws_server/tasks/security_group.yml +0 -0
  87. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/devcontainers/tasks/main.yml +0 -0
  88. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/docker/handlers/main.yml +0 -0
  89. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/docker/tasks/main.yml +0 -0
  90. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/fzf/tasks/main.yml +0 -0
  91. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/github_cli/tasks/main.yml +0 -0
  92. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/hetzner_server/defaults/main.yml +0 -0
  93. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/hetzner_server/tasks/main.yml +0 -0
  94. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_bootstrap/defaults/main.yml +0 -0
  95. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_bootstrap/handlers/main.yml +0 -0
  96. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_bootstrap/tasks/main.yml +0 -0
  97. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_container/defaults/main.yml +0 -0
  98. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_container/handlers/main.yml +0 -0
  99. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_container/meta/main.yml +0 -0
  100. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_container/tasks/main.yml +0 -0
  101. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_container/tasks/preflight.yml +0 -0
  102. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_container_teardown/defaults/main.yml +0 -0
  103. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_container_teardown/meta/main.yml +0 -0
  104. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/incus_container_teardown/tasks/main.yml +0 -0
  105. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/nodejs/defaults/main.yml +0 -0
  106. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/nodejs/tasks/main.yml +0 -0
  107. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_bootstrap/defaults/main.yml +0 -0
  108. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_bootstrap/meta/main.yml +0 -0
  109. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_bootstrap/tasks/main.yml +0 -0
  110. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_container/defaults/main.yml +0 -0
  111. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_container/handlers/main.yml +0 -0
  112. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_container/meta/main.yml +0 -0
  113. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_container/tasks/main.yml +0 -0
  114. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_container/tasks/preflight.yml +0 -0
  115. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_container_teardown/defaults/main.yml +0 -0
  116. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_container_teardown/meta/main.yml +0 -0
  117. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/proxmox_container_teardown/tasks/main.yml +0 -0
  118. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/user_setup/defaults/main.yml +0 -0
  119. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/user_setup/tasks/main.yml +0 -0
  120. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/user_setup/templates/devshell.sh.j2 +0 -0
  121. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/user_setup/templates/project-menu.sh.j2 +0 -0
  122. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/zellij/defaults/main.yml +0 -0
  123. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/zellij/tasks/main.yml +0 -0
  124. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/zellij/templates/config.kdl.j2 +0 -0
  125. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/roles/zellij/templates/layouts/minimal.kdl.j2 +0 -0
  126. {remo_cli-1.0.0 → remo_cli-1.0.2}/ansible/tasks/configure_dev_tools.yml +0 -0
  127. {remo_cli-1.0.0 → remo_cli-1.0.2}/docs/aws.md +0 -0
  128. {remo_cli-1.0.0 → remo_cli-1.0.2}/docs/hetzner.md +0 -0
  129. {remo_cli-1.0.0 → remo_cli-1.0.2}/docs/incus.md +0 -0
  130. {remo_cli-1.0.0 → remo_cli-1.0.2}/docs/install.sh +0 -0
  131. {remo_cli-1.0.0 → remo_cli-1.0.2}/docs/proxmox.md +0 -0
  132. {remo_cli-1.0.0 → remo_cli-1.0.2}/install.sh +0 -0
  133. {remo_cli-1.0.0 → remo_cli-1.0.2}/maverick.yaml +0 -0
  134. {remo_cli-1.0.0 → remo_cli-1.0.2}/project-menu.sh +0 -0
  135. {remo_cli-1.0.0 → remo_cli-1.0.2}/remo +0 -0
  136. {remo_cli-1.0.0 → remo_cli-1.0.2}/run.sh +0 -0
  137. {remo_cli-1.0.0 → remo_cli-1.0.2}/scripts/setup-aws-oidc.sh +0 -0
  138. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/checklists/requirements.md +0 -0
  139. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/checklists/validation.md +0 -0
  140. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/contracts/playbook-interface.yaml +0 -0
  141. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/contracts/role-interface.yaml +0 -0
  142. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/data-model.md +0 -0
  143. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/plan.md +0 -0
  144. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/quickstart.md +0 -0
  145. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/research.md +0 -0
  146. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/spec.md +0 -0
  147. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/001-bootstrap-incus-host/tasks.md +0 -0
  148. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/checklists/requirements.md +0 -0
  149. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/contracts/playbook-interface.yaml +0 -0
  150. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/contracts/role-interface.yaml +0 -0
  151. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/data-model.md +0 -0
  152. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/plan.md +0 -0
  153. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/quickstart.md +0 -0
  154. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/research.md +0 -0
  155. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/spec.md +0 -0
  156. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/002-incus-container-support/tasks.md +0 -0
  157. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/003-python-cli-rewrite/checklists/requirements.md +0 -0
  158. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/003-python-cli-rewrite/data-model.md +0 -0
  159. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/003-python-cli-rewrite/plan.md +0 -0
  160. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/003-python-cli-rewrite/quickstart.md +0 -0
  161. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/003-python-cli-rewrite/research.md +0 -0
  162. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/003-python-cli-rewrite/spec.md +0 -0
  163. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/003-python-cli-rewrite/tasks.md +0 -0
  164. {remo_cli-1.0.0 → remo_cli-1.0.2}/specs/004-proxmox-container-support/spec.md +0 -0
  165. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/__init__.py +0 -0
  166. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/__main__.py +0 -0
  167. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/__init__.py +0 -0
  168. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/cp.py +0 -0
  169. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/main.py +0 -0
  170. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/providers/__init__.py +0 -0
  171. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/providers/aws.py +0 -0
  172. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/providers/hetzner.py +0 -0
  173. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/providers/incus.py +0 -0
  174. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/cli/providers/proxmox.py +0 -0
  175. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/__init__.py +0 -0
  176. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/ansible_runner.py +0 -0
  177. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/completion.py +0 -0
  178. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/config.py +0 -0
  179. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/known_hosts.py +0 -0
  180. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/output.py +0 -0
  181. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/picker.py +0 -0
  182. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/rsync.py +0 -0
  183. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/ssh.py +0 -0
  184. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/core/version.py +0 -0
  185. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/models/__init__.py +0 -0
  186. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/models/host.py +0 -0
  187. {remo_cli-1.0.0 → remo_cli-1.0.2}/src/remo_cli/providers/__init__.py +0 -0
  188. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/__init__.py +0 -0
  189. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/conftest.py +0 -0
  190. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/integration/__init__.py +0 -0
  191. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/integration/orbstack-cloud-init.yml +0 -0
  192. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/integration/orbstack.sh +0 -0
  193. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/__init__.py +0 -0
  194. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/cli/__init__.py +0 -0
  195. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/cli/test_cp.py +0 -0
  196. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/cli/test_main.py +0 -0
  197. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/__init__.py +0 -0
  198. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_ansible_runner.py +0 -0
  199. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_config.py +0 -0
  200. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_known_hosts.py +0 -0
  201. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_output.py +0 -0
  202. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_picker.py +0 -0
  203. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_rsync.py +0 -0
  204. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_ssh.py +0 -0
  205. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/core/test_version.py +0 -0
  206. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/providers/__init__.py +0 -0
  207. {remo_cli-1.0.0 → remo_cli-1.0.2}/tests/unit/test_host_model.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remo-cli
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: Remote development environment CLI
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "remo-cli"
7
- version = "1.0.0"
7
+ version = "1.0.2"
8
8
  description = "Remote development environment CLI"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -93,3 +93,16 @@ def _run_provider_update(host) -> None: # noqa: ANN001
93
93
  # Incus name in known_hosts is "host/container" — extract just the container name
94
94
  container_name = host.name.split("/", maxsplit=1)[-1] if "/" in host.name else host.name
95
95
  incus_update(name=container_name)
96
+ elif host.type == "proxmox":
97
+ from remo_cli.providers.proxmox import update as proxmox_update # noqa: PLC0415
98
+ # Proxmox name in known_hosts is "node/container".
99
+ # The proxmox SSH user is stored in the region slot (see providers.proxmox.create).
100
+ proxmox_host, _, container_name = host.name.partition("/")
101
+ if not container_name:
102
+ container_name = host.name
103
+ proxmox_host = ""
104
+ proxmox_update(
105
+ name=container_name,
106
+ host=proxmox_host,
107
+ user=host.region or "",
108
+ )
@@ -26,6 +26,38 @@ def validate_name(value: str, label: str = "name") -> None:
26
26
  )
27
27
 
28
28
 
29
+ def parse_volume_size(value: str) -> str:
30
+ """Normalize a user-provided volume size to a pure integer string.
31
+
32
+ Accepts a plain integer (``"100"``) or an integer with a common
33
+ size suffix (``"100G"``, ``"100GB"``, ``"100GiB"`` — case-insensitive)
34
+ and returns the integer portion as a string. Empty input passes
35
+ through unchanged so callers can treat ``""`` as "not provided".
36
+
37
+ Raises :class:`click.BadParameter` for anything else.
38
+ """
39
+ if not value:
40
+ return value
41
+ cleaned = value.strip()
42
+ lowered = cleaned.lower()
43
+ for suffix in ("gib", "gb", "g"):
44
+ if lowered.endswith(suffix):
45
+ cleaned = cleaned[: -len(suffix)].strip()
46
+ break
47
+ try:
48
+ as_int = int(cleaned)
49
+ except ValueError as exc:
50
+ raise click.BadParameter(
51
+ f"Invalid volume size: '{value}'. Expected an integer,"
52
+ " optionally with a G/GB/GiB suffix."
53
+ ) from exc
54
+ if as_int <= 0:
55
+ raise click.BadParameter(
56
+ f"Volume size must be a positive integer, got '{value}'."
57
+ )
58
+ return str(as_int)
59
+
60
+
29
61
  def validate_port(value: int) -> None:
30
62
  if not isinstance(value, int) or value < 1 or value > 65535:
31
63
  raise click.BadParameter(
@@ -27,7 +27,7 @@ from remo_cli.core.known_hosts import (
27
27
  )
28
28
  from remo_cli.core.output import confirm, print_error, print_info, print_success, print_warning
29
29
  from remo_cli.core.ssh import detect_timezone, require_session_manager_plugin
30
- from remo_cli.core.validation import build_tool_args, validate_name
30
+ from remo_cli.core.validation import build_tool_args, parse_volume_size, validate_name
31
31
  from remo_cli.core.version import get_current_version
32
32
  from remo_cli.models.host import KnownHost
33
33
 
@@ -388,6 +388,7 @@ def create(
388
388
  """
389
389
  if name:
390
390
  validate_name(name, "instance name")
391
+ volume_size = parse_volume_size(volume_size)
391
392
 
392
393
  print_info("Creating AWS EC2 instance...")
393
394
 
@@ -558,6 +559,7 @@ def update(
558
559
  """
559
560
  if name:
560
561
  validate_name(name, "instance name")
562
+ volume_size = parse_volume_size(volume_size)
561
563
 
562
564
  resource_name = name or os.environ.get("USER", "remo")
563
565
  region = get_aws_region(resource_name)
@@ -22,7 +22,7 @@ from remo_cli.core.known_hosts import (
22
22
  )
23
23
  from remo_cli.core.output import confirm, print_error, print_info, print_success, print_warning
24
24
  from remo_cli.core.ssh import detect_timezone
25
- from remo_cli.core.validation import build_tool_args, validate_name
25
+ from remo_cli.core.validation import build_tool_args, parse_volume_size, validate_name
26
26
  from remo_cli.core.version import get_current_version
27
27
  from remo_cli.models.host import KnownHost
28
28
 
@@ -94,6 +94,7 @@ def create(
94
94
  """
95
95
  if name:
96
96
  validate_name(name, "server name")
97
+ volume_size = parse_volume_size(volume_size)
97
98
 
98
99
  print_info("Creating Hetzner VM...")
99
100
 
@@ -215,6 +216,7 @@ def update(
215
216
  """
216
217
  if name:
217
218
  validate_name(name, "server name")
219
+ volume_size = parse_volume_size(volume_size)
218
220
 
219
221
  server_name = name or "remo"
220
222
 
@@ -20,7 +20,7 @@ from remo_cli.core.known_hosts import (
20
20
  )
21
21
  from remo_cli.core.output import confirm, print_error, print_info, print_warning
22
22
  from remo_cli.core.ssh import detect_timezone
23
- from remo_cli.core.validation import build_tool_args, validate_name
23
+ from remo_cli.core.validation import build_tool_args, parse_volume_size, validate_name
24
24
  from remo_cli.core.version import get_current_version
25
25
  from remo_cli.models.host import KnownHost
26
26
 
@@ -172,6 +172,7 @@ def create(
172
172
  Returns the ansible-playbook exit code (0 on success).
173
173
  """
174
174
  validate_name(name, "container name")
175
+ volume_size = parse_volume_size(volume_size)
175
176
 
176
177
  print_info(f"Creating Incus container '{name}'...")
177
178
 
@@ -304,6 +305,7 @@ def update(
304
305
  Returns the ansible-playbook exit code (0 on success).
305
306
  """
306
307
  validate_name(name, "container name")
308
+ volume_size = parse_volume_size(volume_size)
307
309
 
308
310
  # If --host not specified, look up container in known_hosts.
309
311
  if not host:
@@ -26,7 +26,7 @@ from remo_cli.core.known_hosts import (
26
26
  )
27
27
  from remo_cli.core.output import confirm, print_error, print_info, print_warning
28
28
  from remo_cli.core.ssh import detect_timezone
29
- from remo_cli.core.validation import build_tool_args, validate_name
29
+ from remo_cli.core.validation import build_tool_args, parse_volume_size, validate_name
30
30
  from remo_cli.core.version import get_current_version
31
31
  from remo_cli.models.host import KnownHost
32
32
 
@@ -187,6 +187,7 @@ def create(
187
187
  Returns the ansible-playbook exit code (0 on success).
188
188
  """
189
189
  validate_name(name, "container name")
190
+ volume_size = parse_volume_size(volume_size)
190
191
 
191
192
  if not host:
192
193
  print_error("Proxmox host is required (use --host).")
@@ -350,6 +351,7 @@ def update(
350
351
  Returns the ansible-playbook exit code (0 on success).
351
352
  """
352
353
  validate_name(name, "container name")
354
+ volume_size = parse_volume_size(volume_size)
353
355
 
354
356
  vmid = ""
355
357
  if not host:
@@ -158,3 +158,21 @@ class TestRunProviderUpdate:
158
158
  _run_provider_update(host)
159
159
 
160
160
  mock_update.assert_called_once_with(name="devcontainer")
161
+
162
+ def test_proxmox_update_extracts_node_and_container(self, mocker):
163
+ from remo_cli.cli.shell import _run_provider_update
164
+
165
+ host = KnownHost(
166
+ type="proxmox",
167
+ name="lab1/dev1",
168
+ host="192.168.1.46",
169
+ user="remo",
170
+ instance_id="100",
171
+ access_mode="direct",
172
+ region="root",
173
+ )
174
+ mock_update = mocker.patch("remo_cli.providers.proxmox.update", return_value=0)
175
+
176
+ _run_provider_update(host)
177
+
178
+ mock_update.assert_called_once_with(name="dev1", host="lab1", user="root")
@@ -8,6 +8,7 @@ import click
8
8
  from remo_cli.core.validation import (
9
9
  ALL_TOOLS,
10
10
  build_tool_args,
11
+ parse_volume_size,
11
12
  validate_name,
12
13
  validate_port,
13
14
  validate_region,
@@ -259,3 +260,32 @@ class TestBuildToolArgs:
259
260
  args = build_tool_args(only=ALL_TOOLS, skip=())
260
261
  for tool in ALL_TOOLS:
261
262
  assert f"configure_{tool}=true" in args
263
+
264
+
265
+ class TestParseVolumeSize:
266
+ """Tests for parse_volume_size()."""
267
+
268
+ def test_plain_integer(self):
269
+ assert parse_volume_size("100") == "100"
270
+
271
+ def test_empty_passes_through(self):
272
+ assert parse_volume_size("") == ""
273
+
274
+ @pytest.mark.parametrize("value", ["100G", "100GB", "100GiB", "100gb", "100gib"])
275
+ def test_strips_size_suffix(self, value):
276
+ assert parse_volume_size(value) == "100"
277
+
278
+ def test_strips_whitespace(self):
279
+ assert parse_volume_size(" 100G ") == "100"
280
+
281
+ def test_rejects_non_numeric(self):
282
+ with pytest.raises(click.BadParameter):
283
+ parse_volume_size("big")
284
+
285
+ def test_rejects_zero(self):
286
+ with pytest.raises(click.BadParameter):
287
+ parse_volume_size("0")
288
+
289
+ def test_rejects_negative(self):
290
+ with pytest.raises(click.BadParameter):
291
+ parse_volume_size("-5")
@@ -771,7 +771,7 @@ wheels = [
771
771
 
772
772
  [[package]]
773
773
  name = "remo-cli"
774
- version = "1.0.0"
774
+ version = "1.0.2"
775
775
  source = { editable = "." }
776
776
  dependencies = [
777
777
  { name = "ansible-core" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes