remo-cli 2.2.0rc13__tar.gz → 3.0.0__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 (651) hide show
  1. remo_cli-3.0.0/.claude/skills/release/SKILL.md +173 -0
  2. remo_cli-3.0.0/.github/CODEOWNERS +5 -0
  3. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/dependabot.yml +6 -0
  4. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/ci.yml +49 -13
  5. remo_cli-3.0.0/.github/workflows/codeql.yml +44 -0
  6. remo_cli-3.0.0/.github/workflows/dependency-review.yml +18 -0
  7. remo_cli-3.0.0/.github/workflows/dev-build.yml +78 -0
  8. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/provision.yml +2 -2
  9. remo_cli-3.0.0/.github/workflows/release-please.yml +57 -0
  10. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/release.yml +13 -13
  11. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/smoke-test-cleanup.yml +2 -2
  12. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/smoke-test.yml +27 -17
  13. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/teardown.yml +2 -2
  14. remo_cli-3.0.0/.release-please-manifest.json +3 -0
  15. remo_cli-3.0.0/.specify/feature.json +3 -0
  16. remo_cli-3.0.0/.specify/memory/constitution.md +461 -0
  17. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/plan-template.md +13 -1
  18. remo_cli-3.0.0/AGENTS.md +328 -0
  19. remo_cli-3.0.0/CHANGELOG.md +49 -0
  20. remo_cli-3.0.0/CLAUDE.md +324 -0
  21. remo_cli-3.0.0/CONTRIBUTING.md +208 -0
  22. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/PKG-INFO +146 -38
  23. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/README.md +145 -37
  24. remo_cli-3.0.0/SECURITY.md +31 -0
  25. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_bootstrap.yml +1 -1
  26. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/docker/tasks/main.yml +17 -0
  27. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/github_cli/tasks/main.yml +4 -0
  28. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/hetzner_server/tasks/main.yml +2 -0
  29. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_bootstrap/tasks/main.yml +4 -0
  30. remo_cli-3.0.0/ansible/roles/nodejs/defaults/main.yml +10 -0
  31. remo_cli-3.0.0/ansible/roles/nodejs/files/nodesource-repo.gpg.key +30 -0
  32. remo_cli-3.0.0/ansible/roles/nodejs/tasks/main.yml +95 -0
  33. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/defaults/main.yml +1 -1
  34. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/tasks/preflight.yml +1 -1
  35. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/aws.md +24 -10
  36. remo_cli-3.0.0/docs/feature-history.md +22 -0
  37. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/hetzner.md +77 -11
  38. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/incus.md +99 -22
  39. {remo_cli-2.2.0rc13 → remo_cli-3.0.0/docs}/install.sh +0 -1
  40. remo_cli-3.0.0/docs/maintaining-claude-md.md +109 -0
  41. remo_cli-3.0.0/docs/maintaining-generated-types.md +110 -0
  42. remo_cli-3.0.0/docs/providers.md +349 -0
  43. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/proxmox.md +93 -34
  44. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/web-session-interface.md +196 -93
  45. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/package-lock.json +309 -0
  46. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/package.json +5 -1
  47. remo_cli-3.0.0/frontend/scripts/check-types-fresh.mjs +277 -0
  48. remo_cli-3.0.0/frontend/scripts/generate-frame-types.mjs +145 -0
  49. remo_cli-3.0.0/frontend/scripts/generate-schema-types.mjs +65 -0
  50. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/api/client.ts +36 -92
  51. remo_cli-3.0.0/frontend/src/api/generated/README.md +15 -0
  52. remo_cli-3.0.0/frontend/src/api/generated/openapi.json +1170 -0
  53. remo_cli-3.0.0/frontend/src/api/generated/schema.d.ts +988 -0
  54. remo_cli-3.0.0/frontend/src/api/generated/terminal-frames.d.ts +129 -0
  55. remo_cli-3.0.0/frontend/src/api/generated/terminal-frames.json +199 -0
  56. remo_cli-3.0.0/frontend/src/api/generated.test.ts +70 -0
  57. remo_cli-3.0.0/frontend/src/components/providerMeta.test.ts +41 -0
  58. remo_cli-3.0.0/frontend/src/components/providerMeta.ts +69 -0
  59. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/TerminalConnection.ts +7 -7
  60. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/vite.config.ts +6 -1
  61. {remo_cli-2.2.0rc13/docs → remo_cli-3.0.0}/install.sh +52 -1
  62. remo_cli-3.0.0/pyproject.toml +78 -0
  63. remo_cli-3.0.0/release-please-config.json +21 -0
  64. remo_cli-3.0.0/remo.svg +8 -0
  65. remo_cli-3.0.0/scripts/export_openapi.py +149 -0
  66. remo_cli-3.0.0/specs/013-managed-instance-tags/contracts/cli-sync.md +59 -0
  67. remo_cli-3.0.0/specs/013-managed-instance-tags/contracts/marker-commands.md +58 -0
  68. remo_cli-3.0.0/specs/013-managed-instance-tags/data-model.md +80 -0
  69. remo_cli-3.0.0/specs/013-managed-instance-tags/plan.md +131 -0
  70. remo_cli-3.0.0/specs/013-managed-instance-tags/quickstart.md +93 -0
  71. remo_cli-3.0.0/specs/013-managed-instance-tags/research.md +132 -0
  72. remo_cli-3.0.0/specs/013-managed-instance-tags/spec.md +309 -0
  73. remo_cli-3.0.0/specs/013-managed-instance-tags/tasks.md +198 -0
  74. remo_cli-3.0.0/specs/014-register-ssh-host/contracts/add-command.md +47 -0
  75. remo_cli-3.0.0/specs/014-register-ssh-host/contracts/remove-command.md +33 -0
  76. remo_cli-3.0.0/specs/014-register-ssh-host/data-model.md +91 -0
  77. remo_cli-3.0.0/specs/014-register-ssh-host/plan.md +147 -0
  78. remo_cli-3.0.0/specs/014-register-ssh-host/quickstart.md +121 -0
  79. remo_cli-3.0.0/specs/014-register-ssh-host/research.md +192 -0
  80. remo_cli-3.0.0/specs/014-register-ssh-host/spec.md +333 -0
  81. remo_cli-3.0.0/specs/014-register-ssh-host/tasks.md +184 -0
  82. remo_cli-3.0.0/specs/015-registry-v2/checklists/requirements.md +36 -0
  83. remo_cli-3.0.0/specs/015-registry-v2/contracts/mirror-payload-v2.md +77 -0
  84. remo_cli-3.0.0/specs/015-registry-v2/contracts/registry-accessor-api.md +92 -0
  85. remo_cli-3.0.0/specs/015-registry-v2/contracts/registry-file-v2.md +130 -0
  86. remo_cli-3.0.0/specs/015-registry-v2/data-model.md +113 -0
  87. remo_cli-3.0.0/specs/015-registry-v2/plan.md +114 -0
  88. remo_cli-3.0.0/specs/015-registry-v2/quickstart.md +118 -0
  89. remo_cli-3.0.0/specs/015-registry-v2/research.md +115 -0
  90. remo_cli-3.0.0/specs/015-registry-v2/spec.md +195 -0
  91. remo_cli-3.0.0/specs/015-registry-v2/tasks.md +181 -0
  92. remo_cli-3.0.0/specs/016-sync-reconcile/checklists/requirements.md +44 -0
  93. remo_cli-3.0.0/specs/016-sync-reconcile/contracts/cli-sync.md +113 -0
  94. remo_cli-3.0.0/specs/016-sync-reconcile/contracts/provider-probe.md +96 -0
  95. remo_cli-3.0.0/specs/016-sync-reconcile/data-model.md +167 -0
  96. remo_cli-3.0.0/specs/016-sync-reconcile/plan.md +157 -0
  97. remo_cli-3.0.0/specs/016-sync-reconcile/quickstart.md +129 -0
  98. remo_cli-3.0.0/specs/016-sync-reconcile/research.md +164 -0
  99. remo_cli-3.0.0/specs/016-sync-reconcile/spec.md +290 -0
  100. remo_cli-3.0.0/specs/016-sync-reconcile/tasks.md +304 -0
  101. remo_cli-3.0.0/specs/017-web-adopt-simplify/checklists/requirements.md +36 -0
  102. remo_cli-3.0.0/specs/017-web-adopt-simplify/contracts/cli-web-push.md +43 -0
  103. remo_cli-3.0.0/specs/017-web-adopt-simplify/contracts/cli-web-status.md +50 -0
  104. remo_cli-3.0.0/specs/017-web-adopt-simplify/contracts/revocation.md +40 -0
  105. remo_cli-3.0.0/specs/017-web-adopt-simplify/contracts/setup-status-marker.md +59 -0
  106. remo_cli-3.0.0/specs/017-web-adopt-simplify/data-model.md +109 -0
  107. remo_cli-3.0.0/specs/017-web-adopt-simplify/plan.md +111 -0
  108. remo_cli-3.0.0/specs/017-web-adopt-simplify/quickstart.md +138 -0
  109. remo_cli-3.0.0/specs/017-web-adopt-simplify/research.md +91 -0
  110. remo_cli-3.0.0/specs/017-web-adopt-simplify/spec.md +225 -0
  111. remo_cli-3.0.0/specs/017-web-adopt-simplify/tasks.md +268 -0
  112. remo_cli-3.0.0/specs/018-provider-abstraction/baseline-notes.md +9 -0
  113. remo_cli-3.0.0/specs/018-provider-abstraction/checklists/requirements.md +38 -0
  114. remo_cli-3.0.0/specs/018-provider-abstraction/contracts/cli-surface.md +44 -0
  115. remo_cli-3.0.0/specs/018-provider-abstraction/contracts/errors.md +37 -0
  116. remo_cli-3.0.0/specs/018-provider-abstraction/contracts/lifecycle-templates.md +32 -0
  117. remo_cli-3.0.0/specs/018-provider-abstraction/contracts/provider-protocol.md +53 -0
  118. remo_cli-3.0.0/specs/018-provider-abstraction/contracts/sync-merge.md +37 -0
  119. remo_cli-3.0.0/specs/018-provider-abstraction/data-model.md +109 -0
  120. remo_cli-3.0.0/specs/018-provider-abstraction/plan.md +112 -0
  121. remo_cli-3.0.0/specs/018-provider-abstraction/quickstart.md +81 -0
  122. remo_cli-3.0.0/specs/018-provider-abstraction/research.md +105 -0
  123. remo_cli-3.0.0/specs/018-provider-abstraction/spec.md +210 -0
  124. remo_cli-3.0.0/specs/018-provider-abstraction/tasks.md +190 -0
  125. remo_cli-3.0.0/specs/019-hygiene-deps-docs/checklists/requirements.md +64 -0
  126. remo_cli-3.0.0/specs/019-hygiene-deps-docs/contracts/cli-surface-delta.md +100 -0
  127. remo_cli-3.0.0/specs/019-hygiene-deps-docs/contracts/docs-structure-check.md +154 -0
  128. remo_cli-3.0.0/specs/019-hygiene-deps-docs/data-model.md +154 -0
  129. remo_cli-3.0.0/specs/019-hygiene-deps-docs/plan.md +149 -0
  130. remo_cli-3.0.0/specs/019-hygiene-deps-docs/quickstart.md +297 -0
  131. remo_cli-3.0.0/specs/019-hygiene-deps-docs/research.md +288 -0
  132. remo_cli-3.0.0/specs/019-hygiene-deps-docs/spec.md +418 -0
  133. remo_cli-3.0.0/specs/019-hygiene-deps-docs/tasks.md +304 -0
  134. remo_cli-3.0.0/specs/020-openapi-type-generation/checklists/requirements.md +78 -0
  135. remo_cli-3.0.0/specs/020-openapi-type-generation/contracts/drift-checks.md +107 -0
  136. remo_cli-3.0.0/specs/020-openapi-type-generation/contracts/terminal-frames-v1.md +94 -0
  137. remo_cli-3.0.0/specs/020-openapi-type-generation/data-model.md +144 -0
  138. remo_cli-3.0.0/specs/020-openapi-type-generation/plan.md +234 -0
  139. remo_cli-3.0.0/specs/020-openapi-type-generation/quickstart.md +174 -0
  140. remo_cli-3.0.0/specs/020-openapi-type-generation/research.md +291 -0
  141. remo_cli-3.0.0/specs/020-openapi-type-generation/spec.md +216 -0
  142. remo_cli-3.0.0/specs/020-openapi-type-generation/tasks.md +327 -0
  143. remo_cli-3.0.0/specs/021-cli-plane-separation/contracts/cli-surface.md +90 -0
  144. remo_cli-3.0.0/specs/021-cli-plane-separation/contracts/descriptor-schema.md +64 -0
  145. remo_cli-3.0.0/specs/021-cli-plane-separation/data-model.md +101 -0
  146. remo_cli-3.0.0/specs/021-cli-plane-separation/plan.md +148 -0
  147. remo_cli-3.0.0/specs/021-cli-plane-separation/quickstart.md +100 -0
  148. remo_cli-3.0.0/specs/021-cli-plane-separation/research.md +223 -0
  149. remo_cli-3.0.0/specs/021-cli-plane-separation/spec.md +184 -0
  150. remo_cli-3.0.0/specs/021-cli-plane-separation/tasks.md +248 -0
  151. remo_cli-3.0.0/src/remo_cli/__main__.py +5 -0
  152. remo_cli-3.0.0/src/remo_cli/cli/added.py +106 -0
  153. remo_cli-3.0.0/src/remo_cli/cli/main.py +287 -0
  154. remo_cli-3.0.0/src/remo_cli/cli/providers/factory.py +550 -0
  155. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/shell.py +77 -42
  156. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/web.py +101 -31
  157. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/ansible_runner.py +33 -0
  158. remo_cli-3.0.0/src/remo_cli/core/completion.py +323 -0
  159. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/config.py +58 -0
  160. remo_cli-3.0.0/src/remo_cli/core/errors.py +45 -0
  161. remo_cli-3.0.0/src/remo_cli/core/known_hosts.py +255 -0
  162. remo_cli-3.0.0/src/remo_cli/core/lifecycle.py +82 -0
  163. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/output.py +41 -0
  164. remo_cli-3.0.0/src/remo_cli/core/provider_protocol.py +50 -0
  165. remo_cli-3.0.0/src/remo_cli/core/provider_registry.py +341 -0
  166. remo_cli-3.0.0/src/remo_cli/core/reconcile.py +522 -0
  167. remo_cli-3.0.0/src/remo_cli/core/registry.py +851 -0
  168. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/snapshot.py +29 -1
  169. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/ssh.py +53 -29
  170. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/web_adopt.py +526 -183
  171. remo_cli-3.0.0/src/remo_cli/core/web_drift.py +194 -0
  172. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/host.py +33 -0
  173. remo_cli-3.0.0/src/remo_cli/providers/added.py +354 -0
  174. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/providers/aws.py +435 -231
  175. remo_cli-3.0.0/src/remo_cli/providers/aws_descriptor.py +100 -0
  176. remo_cli-3.0.0/src/remo_cli/providers/builtin.py +19 -0
  177. remo_cli-3.0.0/src/remo_cli/providers/hetzner.py +894 -0
  178. remo_cli-3.0.0/src/remo_cli/providers/hetzner_descriptor.py +55 -0
  179. remo_cli-3.0.0/src/remo_cli/providers/incus.py +1174 -0
  180. remo_cli-3.0.0/src/remo_cli/providers/incus_descriptor.py +118 -0
  181. remo_cli-3.0.0/src/remo_cli/providers/proxmox.py +1353 -0
  182. remo_cli-3.0.0/src/remo_cli/providers/proxmox_descriptor.py +141 -0
  183. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/api/hosts.py +43 -10
  184. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/api/pairing.py +26 -3
  185. remo_cli-3.0.0/src/remo_cli/web/api/setup.py +605 -0
  186. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/api/terminals.py +63 -34
  187. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/check.py +54 -15
  188. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/config.py +35 -0
  189. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/discovery.py +39 -41
  190. remo_cli-3.0.0/src/remo_cli/web/frames.py +108 -0
  191. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/health.py +16 -2
  192. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/state.py +86 -46
  193. remo_cli-3.0.0/tests/conftest.py +120 -0
  194. remo_cli-3.0.0/tests/integration/fish_completion.sh +202 -0
  195. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/orbstack.sh +2 -2
  196. remo_cli-3.0.0/tests/integration/test_registry_concurrency.py +98 -0
  197. remo_cli-3.0.0/tests/integration/test_setup_payload_versions.py +279 -0
  198. remo_cli-3.0.0/tests/integration/test_sync_reconcile.py +245 -0
  199. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_web_adopt_e2e.py +91 -32
  200. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_web_cli_parity.py +179 -1
  201. remo_cli-3.0.0/tests/perf/test_registry_perf.py +86 -0
  202. remo_cli-3.0.0/tests/unit/cli/providers/test_aws_snapshot.py +223 -0
  203. remo_cli-3.0.0/tests/unit/cli/providers/test_hetzner_snapshot.py +191 -0
  204. remo_cli-3.0.0/tests/unit/cli/providers/test_incus_snapshot.py +376 -0
  205. remo_cli-3.0.0/tests/unit/cli/providers/test_incus_sync_all.py +59 -0
  206. remo_cli-3.0.0/tests/unit/cli/providers/test_proxmox_snapshot.py +211 -0
  207. remo_cli-3.0.0/tests/unit/cli/providers/test_proxmox_sync_all.py +68 -0
  208. remo_cli-3.0.0/tests/unit/cli/surface_baseline.py +267 -0
  209. remo_cli-3.0.0/tests/unit/cli/test_add_cmd.py +51 -0
  210. remo_cli-3.0.0/tests/unit/cli/test_cli_uniformity.py +139 -0
  211. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/test_main.py +68 -3
  212. remo_cli-3.0.0/tests/unit/cli/test_remove_cmd.py +32 -0
  213. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/test_shell.py +135 -33
  214. remo_cli-3.0.0/tests/unit/cli/test_shell_added.py +76 -0
  215. remo_cli-3.0.0/tests/unit/cli/test_startup_imports.py +27 -0
  216. remo_cli-3.0.0/tests/unit/cli/test_surface_preservation.py +59 -0
  217. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/test_web_adopt_cmd.py +146 -37
  218. remo_cli-3.0.0/tests/unit/core/test_completion.py +289 -0
  219. remo_cli-3.0.0/tests/unit/core/test_errors.py +44 -0
  220. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_known_hosts.py +27 -15
  221. remo_cli-3.0.0/tests/unit/core/test_lifecycle.py +108 -0
  222. remo_cli-3.0.0/tests/unit/core/test_migration_tagging_notice.py +89 -0
  223. remo_cli-3.0.0/tests/unit/core/test_provider_registry.py +241 -0
  224. remo_cli-3.0.0/tests/unit/core/test_reconcile.py +892 -0
  225. remo_cli-3.0.0/tests/unit/core/test_registry_format.py +450 -0
  226. remo_cli-3.0.0/tests/unit/core/test_registry_locking.py +141 -0
  227. remo_cli-3.0.0/tests/unit/core/test_registry_migration.py +364 -0
  228. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_ssh.py +13 -13
  229. remo_cli-3.0.0/tests/unit/core/test_ssh_added.py +96 -0
  230. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_ssh_controlpath.py +2 -2
  231. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_ssh_identity_opts.py +1 -1
  232. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_web_adopt_authorize.py +201 -0
  233. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_web_adopt_payload.py +25 -16
  234. remo_cli-3.0.0/tests/unit/core/test_web_drift.py +187 -0
  235. remo_cli-3.0.0/tests/unit/core/test_web_push.py +759 -0
  236. remo_cli-3.0.0/tests/unit/providers/fake_provider.py +160 -0
  237. remo_cli-3.0.0/tests/unit/providers/test_added_add.py +264 -0
  238. remo_cli-3.0.0/tests/unit/providers/test_added_provider_guard.py +214 -0
  239. remo_cli-3.0.0/tests/unit/providers/test_added_update_remove.py +125 -0
  240. remo_cli-3.0.0/tests/unit/providers/test_added_verify.py +124 -0
  241. remo_cli-3.0.0/tests/unit/providers/test_aws_provider_protocol.py +151 -0
  242. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_aws_snapshot.py +103 -91
  243. remo_cli-3.0.0/tests/unit/providers/test_aws_sync.py +599 -0
  244. remo_cli-3.0.0/tests/unit/providers/test_aws_upgrade_resize.py +117 -0
  245. remo_cli-3.0.0/tests/unit/providers/test_hetzner_entry_adapters.py +173 -0
  246. remo_cli-3.0.0/tests/unit/providers/test_hetzner_http.py +280 -0
  247. remo_cli-3.0.0/tests/unit/providers/test_hetzner_label.py +175 -0
  248. remo_cli-3.0.0/tests/unit/providers/test_hetzner_resize.py +70 -0
  249. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_hetzner_snapshot.py +63 -91
  250. remo_cli-3.0.0/tests/unit/providers/test_hetzner_sync.py +272 -0
  251. remo_cli-3.0.0/tests/unit/providers/test_incus_entry_adapters.py +189 -0
  252. remo_cli-3.0.0/tests/unit/providers/test_incus_marker.py +196 -0
  253. remo_cli-3.0.0/tests/unit/providers/test_incus_resize.py +95 -0
  254. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_incus_snapshot.py +13 -132
  255. remo_cli-3.0.0/tests/unit/providers/test_incus_sync.py +175 -0
  256. remo_cli-3.0.0/tests/unit/providers/test_missing_sdk.py +58 -0
  257. remo_cli-3.0.0/tests/unit/providers/test_provider_conformance.py +268 -0
  258. remo_cli-3.0.0/tests/unit/providers/test_provider_registry_entries.py +234 -0
  259. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_proxmox_devcontainer_runtime.py +9 -6
  260. remo_cli-3.0.0/tests/unit/providers/test_proxmox_marker.py +266 -0
  261. remo_cli-3.0.0/tests/unit/providers/test_proxmox_provider_protocol.py +160 -0
  262. remo_cli-3.0.0/tests/unit/providers/test_proxmox_resize.py +114 -0
  263. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_proxmox_snapshot.py +87 -96
  264. remo_cli-3.0.0/tests/unit/providers/test_proxmox_sync.py +252 -0
  265. remo_cli-3.0.0/tests/unit/test_architecture.py +303 -0
  266. remo_cli-3.0.0/tests/unit/test_docs_structure.py +493 -0
  267. remo_cli-3.0.0/tests/unit/test_host_ssh_type.py +145 -0
  268. remo_cli-3.0.0/tests/unit/test_schema_drift.py +861 -0
  269. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/conftest.py +28 -1
  270. remo_cli-3.0.0/tests/unit/web/fixtures/hosts_response.json +1 -0
  271. remo_cli-3.0.0/tests/unit/web/fixtures/sessions_response.json +1 -0
  272. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_check.py +7 -2
  273. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_csp.py +3 -2
  274. remo_cli-3.0.0/tests/unit/web/test_frames.py +235 -0
  275. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_health_states.py +2 -2
  276. remo_cli-3.0.0/tests/unit/web/test_payload_equivalence.py +122 -0
  277. remo_cli-3.0.0/tests/unit/web/test_registry_readonly.py +212 -0
  278. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_setup_api.py +258 -24
  279. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_setup_auth.py +2 -2
  280. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_state.py +87 -18
  281. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/uv.lock +1 -1
  282. remo_cli-2.2.0rc13/.specify/feature.json +0 -3
  283. remo_cli-2.2.0rc13/.specify/memory/constitution.md +0 -164
  284. remo_cli-2.2.0rc13/AGENTS.md +0 -152
  285. remo_cli-2.2.0rc13/CLAUDE.md +0 -197
  286. remo_cli-2.2.0rc13/CONTRIBUTING.md +0 -113
  287. remo_cli-2.2.0rc13/ansible/roles/nodejs/defaults/main.yml +0 -2
  288. remo_cli-2.2.0rc13/ansible/roles/nodejs/tasks/main.yml +0 -64
  289. remo_cli-2.2.0rc13/frontend/src/components/providerMeta.ts +0 -54
  290. remo_cli-2.2.0rc13/pyproject.toml +0 -60
  291. remo_cli-2.2.0rc13/src/remo_cli/__main__.py +0 -5
  292. remo_cli-2.2.0rc13/src/remo_cli/cli/main.py +0 -97
  293. remo_cli-2.2.0rc13/src/remo_cli/cli/providers/aws.py +0 -287
  294. remo_cli-2.2.0rc13/src/remo_cli/cli/providers/hetzner.py +0 -232
  295. remo_cli-2.2.0rc13/src/remo_cli/cli/providers/incus.py +0 -332
  296. remo_cli-2.2.0rc13/src/remo_cli/cli/providers/proxmox.py +0 -411
  297. remo_cli-2.2.0rc13/src/remo_cli/core/completion.py +0 -83
  298. remo_cli-2.2.0rc13/src/remo_cli/core/known_hosts.py +0 -253
  299. remo_cli-2.2.0rc13/src/remo_cli/providers/hetzner.py +0 -736
  300. remo_cli-2.2.0rc13/src/remo_cli/providers/incus.py +0 -932
  301. remo_cli-2.2.0rc13/src/remo_cli/providers/proxmox.py +0 -1016
  302. remo_cli-2.2.0rc13/src/remo_cli/web/api/setup.py +0 -412
  303. remo_cli-2.2.0rc13/tests/conftest.py +0 -26
  304. remo_cli-2.2.0rc13/tests/unit/cli/providers/test_aws_snapshot.py +0 -126
  305. remo_cli-2.2.0rc13/tests/unit/cli/providers/test_hetzner_snapshot.py +0 -129
  306. remo_cli-2.2.0rc13/tests/unit/cli/providers/test_incus_snapshot.py +0 -212
  307. remo_cli-2.2.0rc13/tests/unit/cli/providers/test_proxmox_snapshot.py +0 -158
  308. remo_cli-2.2.0rc13/tests/unit/core/test_web_push.py +0 -386
  309. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-analyze/SKILL.md +0 -0
  310. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-checklist/SKILL.md +0 -0
  311. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-clarify/SKILL.md +0 -0
  312. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-constitution/SKILL.md +0 -0
  313. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-converge/SKILL.md +0 -0
  314. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-commit/SKILL.md +0 -0
  315. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-feature/SKILL.md +0 -0
  316. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-initialize/SKILL.md +0 -0
  317. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-remote/SKILL.md +0 -0
  318. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-validate/SKILL.md +0 -0
  319. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-implement/SKILL.md +0 -0
  320. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-plan/SKILL.md +0 -0
  321. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-specify/SKILL.md +0 -0
  322. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-tasks/SKILL.md +0 -0
  323. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-taskstoissues/SKILL.md +0 -0
  324. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.devcontainer/devcontainer.json +0 -0
  325. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.dockerignore +0 -0
  326. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.gitignore +0 -0
  327. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.maverick/checkpoints/feature/implementation_complete.json +0 -0
  328. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.maverick/checkpoints/feature/phase_${{ index }}_complete.json +0 -0
  329. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.maverick/checkpoints/feature/validation_complete.json +0 -0
  330. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/.registry +0 -0
  331. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/README.md +0 -0
  332. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.commit.md +0 -0
  333. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.feature.md +0 -0
  334. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.initialize.md +0 -0
  335. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.remote.md +0 -0
  336. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.validate.md +0 -0
  337. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/config-template.yml +0 -0
  338. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/extension.yml +0 -0
  339. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/git-config.yml +0 -0
  340. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/bash/auto-commit.sh +0 -0
  341. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/bash/create-new-feature.sh +0 -0
  342. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/bash/git-common.sh +0 -0
  343. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/bash/initialize-repo.sh +0 -0
  344. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
  345. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/powershell/create-new-feature.ps1 +0 -0
  346. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/powershell/git-common.ps1 +0 -0
  347. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
  348. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions.yml +0 -0
  349. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/init-options.json +0 -0
  350. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/integration.json +0 -0
  351. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/integrations/claude.manifest.json +0 -0
  352. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/integrations/speckit.manifest.json +0 -0
  353. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/check-prerequisites.sh +0 -0
  354. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/common.sh +0 -0
  355. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/create-new-feature.sh +0 -0
  356. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/setup-plan.sh +0 -0
  357. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/setup-tasks.sh +0 -0
  358. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/update-agent-context.sh +0 -0
  359. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/agent-file-template.md +0 -0
  360. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/checklist-template.md +0 -0
  361. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/constitution-template.md +0 -0
  362. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/spec-template.md +0 -0
  363. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/tasks-template.md +0 -0
  364. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/workflows/speckit/workflow.yml +0 -0
  365. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/workflows/workflow-registry.json +0 -0
  366. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/Dockerfile +0 -0
  367. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/LICENSE +0 -0
  368. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/.ansible-lint +0 -0
  369. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/README.md +0 -0
  370. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/ansible.cfg +0 -0
  371. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/aws_configure.yml +0 -0
  372. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/aws_resize.yml +0 -0
  373. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/aws_site.yml +0 -0
  374. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/aws_teardown.yml +0 -0
  375. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/group_vars/all.yml +0 -0
  376. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/group_vars/incus_containers.yml +0 -0
  377. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/group_vars/proxmox_containers.yml +0 -0
  378. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_configure.yml +0 -0
  379. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_provision.yml +0 -0
  380. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_resize.yml +0 -0
  381. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_site.yml +0 -0
  382. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_teardown.yml +0 -0
  383. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_bootstrap.yml +0 -0
  384. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_configure.yml +0 -0
  385. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_provision.yml +0 -0
  386. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_resize.yml +0 -0
  387. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_site.yml +0 -0
  388. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_teardown.yml +0 -0
  389. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/inventory/hosts.yml +0 -0
  390. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/inventory/incus_containers.yml +0 -0
  391. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_configure.yml +0 -0
  392. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_provision.yml +0 -0
  393. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_resize.yml +0 -0
  394. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_site.yml +0 -0
  395. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_teardown.yml +0 -0
  396. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/requirements.yml +0 -0
  397. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/defaults/main.yml +0 -0
  398. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/ebs.yml +0 -0
  399. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/ec2.yml +0 -0
  400. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/main.yml +0 -0
  401. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/patch_manager.yml +0 -0
  402. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/preflight.yml +0 -0
  403. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/security_group.yml +0 -0
  404. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/deacon/defaults/main.yml +0 -0
  405. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/deacon/tasks/main.yml +0 -0
  406. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/devcontainers/tasks/main.yml +0 -0
  407. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/docker/handlers/main.yml +0 -0
  408. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/fzf/tasks/main.yml +0 -0
  409. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/hetzner_server/defaults/main.yml +0 -0
  410. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_bootstrap/defaults/main.yml +0 -0
  411. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_bootstrap/handlers/main.yml +0 -0
  412. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/defaults/main.yml +0 -0
  413. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/handlers/main.yml +0 -0
  414. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/meta/main.yml +0 -0
  415. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/tasks/main.yml +0 -0
  416. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/tasks/preflight.yml +0 -0
  417. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container_teardown/defaults/main.yml +0 -0
  418. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container_teardown/meta/main.yml +0 -0
  419. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container_teardown/tasks/main.yml +0 -0
  420. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_bootstrap/defaults/main.yml +0 -0
  421. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_bootstrap/meta/main.yml +0 -0
  422. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_bootstrap/tasks/main.yml +0 -0
  423. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/handlers/main.yml +0 -0
  424. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/meta/main.yml +0 -0
  425. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/tasks/main.yml +0 -0
  426. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container_teardown/defaults/main.yml +0 -0
  427. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container_teardown/meta/main.yml +0 -0
  428. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container_teardown/tasks/main.yml +0 -0
  429. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/defaults/main.yml +0 -0
  430. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/tasks/main.yml +0 -0
  431. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/templates/devshell.sh.j2 +0 -0
  432. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/templates/project-launch.sh.j2 +0 -0
  433. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/templates/project-menu.sh.j2 +0 -0
  434. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/templates/remo-host.sh.j2 +0 -0
  435. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/zellij/defaults/main.yml +0 -0
  436. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/zellij/tasks/main.yml +0 -0
  437. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/zellij/templates/config.kdl.j2 +0 -0
  438. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/zellij/templates/layouts/minimal.kdl.j2 +0 -0
  439. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/tasks/configure_dev_tools.yml +0 -0
  440. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docker/Dockerfile +0 -0
  441. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docker/compose.example.yml +0 -0
  442. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docker/entrypoint.sh +0 -0
  443. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/remo-web-speckit-input.md +0 -0
  444. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/remo-web.html +0 -0
  445. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/index.html +0 -0
  446. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/public/README.md +0 -0
  447. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/public/dist__ghostty-vt.wasm +0 -0
  448. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/public/ghostty-vt.wasm +0 -0
  449. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/scripts/copy-ghostty-wasm.mjs +0 -0
  450. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AppRoot.tsx +0 -0
  451. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AppShell.css +0 -0
  452. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AppShell.tsx +0 -0
  453. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AwaitingAdoption.css +0 -0
  454. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AwaitingAdoption.tsx +0 -0
  455. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/OfflineOverlay.css +0 -0
  456. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/OfflineOverlay.tsx +0 -0
  457. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/PairToSync.css +0 -0
  458. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/PairToSync.tsx +0 -0
  459. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/SessionRail.css +0 -0
  460. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/SessionRail.tsx +0 -0
  461. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/SettingsPage.css +0 -0
  462. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/SettingsPage.tsx +0 -0
  463. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/ShortcutsModal.css +0 -0
  464. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/ShortcutsModal.tsx +0 -0
  465. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/TerminalCard.css +0 -0
  466. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/TerminalCard.tsx +0 -0
  467. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/TopBar.css +0 -0
  468. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/TopBar.tsx +0 -0
  469. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/WorkspacePane.css +0 -0
  470. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/WorkspacePane.tsx +0 -0
  471. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/railModel.ts +0 -0
  472. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/lib/clipboard.ts +0 -0
  473. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/lib/fullscreen.ts +0 -0
  474. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/main.tsx +0 -0
  475. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/discovery.ts +0 -0
  476. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/fonts.ts +0 -0
  477. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/health.ts +0 -0
  478. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/latency.test.ts +0 -0
  479. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/latency.ts +0 -0
  480. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/settings.ts +0 -0
  481. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/useConsoleKeyboard.ts +0 -0
  482. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/workspace.test.ts +0 -0
  483. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/workspace.ts +0 -0
  484. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/.gitkeep +0 -0
  485. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/GhosttyRenderer.ts +0 -0
  486. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/RendererAdapter.ts +0 -0
  487. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/TerminalConnection.test.ts +0 -0
  488. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/XtermRenderer.ts +0 -0
  489. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/defaultRenderer.ts +0 -0
  490. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/keymap.test.ts +0 -0
  491. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/keymap.ts +0 -0
  492. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/test/setup.ts +0 -0
  493. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/theme/fonts.ts +0 -0
  494. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/theme/tokens.css +0 -0
  495. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/tsconfig.json +0 -0
  496. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/maverick.yaml +0 -0
  497. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/playwright.config.ts +0 -0
  498. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/project-menu.sh +0 -0
  499. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/remo +0 -0
  500. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/run.sh +0 -0
  501. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/scripts/setup-aws-oidc.sh +0 -0
  502. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/checklists/requirements.md +0 -0
  503. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/checklists/validation.md +0 -0
  504. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/contracts/playbook-interface.yaml +0 -0
  505. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/contracts/role-interface.yaml +0 -0
  506. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/data-model.md +0 -0
  507. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/plan.md +0 -0
  508. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/quickstart.md +0 -0
  509. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/research.md +0 -0
  510. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/spec.md +0 -0
  511. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/tasks.md +0 -0
  512. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/checklists/requirements.md +0 -0
  513. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/contracts/playbook-interface.yaml +0 -0
  514. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/contracts/role-interface.yaml +0 -0
  515. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/data-model.md +0 -0
  516. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/plan.md +0 -0
  517. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/quickstart.md +0 -0
  518. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/research.md +0 -0
  519. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/spec.md +0 -0
  520. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/tasks.md +0 -0
  521. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/checklists/requirements.md +0 -0
  522. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/data-model.md +0 -0
  523. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/plan.md +0 -0
  524. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/quickstart.md +0 -0
  525. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/research.md +0 -0
  526. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/spec.md +0 -0
  527. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/tasks.md +0 -0
  528. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/004-proxmox-container-support/spec.md +0 -0
  529. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/checklists/requirements.md +0 -0
  530. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/contracts/cli-surface.md +0 -0
  531. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/data-model.md +0 -0
  532. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/plan.md +0 -0
  533. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/quickstart.md +0 -0
  534. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/research.md +0 -0
  535. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/spec.md +0 -0
  536. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/tasks.md +0 -0
  537. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/checklists/requirements.md +0 -0
  538. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/contracts/remo-host-protocol.md +0 -0
  539. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/contracts/rest-api.md +0 -0
  540. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/contracts/terminal-websocket.md +0 -0
  541. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/data-model.md +0 -0
  542. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/plan.md +0 -0
  543. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/quickstart.md +0 -0
  544. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/research.md +0 -0
  545. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/spec.md +0 -0
  546. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/tasks.md +0 -0
  547. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/checklists/requirements.md +0 -0
  548. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/contracts/cli-web-adopt.md +0 -0
  549. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/contracts/setup-api.md +0 -0
  550. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/data-model.md +0 -0
  551. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/plan.md +0 -0
  552. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/quickstart-results.md +0 -0
  553. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/quickstart.md +0 -0
  554. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/research.md +0 -0
  555. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/spec.md +0 -0
  556. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/tasks.md +0 -0
  557. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/contracts/cli-web-adopt.md +0 -0
  558. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/contracts/pairing-api.md +0 -0
  559. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/contracts/setup-api.md +0 -0
  560. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/data-model.md +0 -0
  561. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/plan.md +0 -0
  562. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/quickstart.md +0 -0
  563. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/research.md +0 -0
  564. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/spec.md +0 -0
  565. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/tasks.md +0 -0
  566. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/__init__.py +0 -0
  567. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/__init__.py +0 -0
  568. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/cp.py +0 -0
  569. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/providers/__init__.py +0 -0
  570. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/__init__.py +0 -0
  571. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/picker.py +0 -0
  572. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/remo_host_client.py +0 -0
  573. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/rsync.py +0 -0
  574. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/validation.py +0 -0
  575. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/version.py +0 -0
  576. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/__init__.py +0 -0
  577. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/capability.py +0 -0
  578. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/discovery.py +0 -0
  579. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/session_target.py +0 -0
  580. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/snapshot.py +0 -0
  581. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/providers/__init__.py +0 -0
  582. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/__init__.py +0 -0
  583. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/api/__init__.py +0 -0
  584. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/app.py +0 -0
  585. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/logging_config.py +0 -0
  586. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/models.py +0 -0
  587. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/operator_auth.py +0 -0
  588. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/pairing.py +0 -0
  589. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/ssh_master.py +0 -0
  590. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/terminal.py +0 -0
  591. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/terminal_registry.py +0 -0
  592. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/tokens.py +0 -0
  593. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/__init__.py +0 -0
  594. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/ansible/__init__.py +0 -0
  595. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/ansible/test_remo_host_idempotency.py +0 -0
  596. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/fixtures.ts +0 -0
  597. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/ghostty-shell-io.spec.ts +0 -0
  598. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/ghostty-tui-compatibility.spec.ts +0 -0
  599. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/keyboard-routing.spec.ts +0 -0
  600. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/mobile.spec.ts +0 -0
  601. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/reconnect.spec.ts +0 -0
  602. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/workspace-layout.spec.ts +0 -0
  603. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/image/__init__.py +0 -0
  604. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/image/test_docker_image.py +0 -0
  605. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/__init__.py +0 -0
  606. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/_nine_terminal_fixture.py +0 -0
  607. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/orbstack-cloud-init.yml +0 -0
  608. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_nine_terminals.py +0 -0
  609. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_nine_terminals_soak.py +0 -0
  610. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_remo_host_e2e.py +0 -0
  611. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_security_rejections.py +0 -0
  612. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_terminal_attach.py +0 -0
  613. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/perf/__init__.py +0 -0
  614. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/perf/test_latency.py +0 -0
  615. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/__init__.py +0 -0
  616. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/__init__.py +0 -0
  617. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/test_cp.py +0 -0
  618. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/__init__.py +0 -0
  619. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_ansible_runner.py +0 -0
  620. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_config.py +0 -0
  621. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_output.py +0 -0
  622. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_picker.py +0 -0
  623. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_remo_host_client.py +0 -0
  624. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_rsync.py +0 -0
  625. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_snapshot.py +0 -0
  626. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_validation.py +0 -0
  627. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_version.py +0 -0
  628. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_web_adopt_code.py +0 -0
  629. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_web_adopt_trust.py +0 -0
  630. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/models/__init__.py +0 -0
  631. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/models/test_capability.py +0 -0
  632. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/models/test_discovery.py +0 -0
  633. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/models/test_session_target.py +0 -0
  634. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/__init__.py +0 -0
  635. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/test_ansible_templates.py +0 -0
  636. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/test_host_model.py +0 -0
  637. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/__init__.py +0 -0
  638. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/_pairing_support.py +0 -0
  639. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_backpressure.py +0 -0
  640. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_discovery.py +0 -0
  641. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_hosts_mapping.py +0 -0
  642. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_lazy_import.py +0 -0
  643. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_log_redaction.py +0 -0
  644. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_mint_gating.py +0 -0
  645. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_operator_auth.py +0 -0
  646. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_pairing.py +0 -0
  647. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_pairing_origin.py +0 -0
  648. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_setup_dormancy.py +0 -0
  649. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_terminal_resize.py +0 -0
  650. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_terminals_api.py +0 -0
  651. {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_tokens.py +0 -0
@@ -0,0 +1,173 @@
1
+ ---
2
+ name: release
3
+ description: Cut a remo release — drive the release-please stable release PR, or build/validate/publish a pre-release (RC) — with a mandatory local "test before PyPI" gate and explicit approval before anything is tagged, merged, or published.
4
+ argument-hint: "[stable | rc [X.Y.ZrcN]] — omit to be asked"
5
+ metadata:
6
+ author: remo
7
+ ---
8
+
9
+ # Release
10
+
11
+ Operationalizes remo's two-lane release process (see
12
+ [CONTRIBUTING.md](../../../CONTRIBUTING.md) → Release Process). Pairs with the
13
+ release-please integration.
14
+
15
+ **Non-negotiable safety rules — apply in every mode:**
16
+
17
+ - **Publishing to PyPI is irreversible.** A version, once uploaded, can never be
18
+ replaced. Run the local build + smoke gate (Step V below) before any tag,
19
+ merge, or publish — no exceptions.
20
+ - **Never** `git push` a tag, `git push` a version-bump commit, or `gh pr merge`
21
+ a release PR **without explicit user approval in the current turn.** Approval
22
+ from an earlier task does not carry over.
23
+ - Work only from a **clean working tree** on an **up-to-date `main`**. If the
24
+ tree is dirty or `main` is behind `origin/main`, stop and surface it.
25
+ - Prefer testing **without** publishing. Only publish an RC to PyPI when the user
26
+ explicitly asks for a public prerelease.
27
+
28
+ ## Step 0 — Determine the mode
29
+
30
+ From the argument, or by asking the user:
31
+
32
+ - **`stable`** — drive the release-please release PR to a published stable release.
33
+ - **`rc`** — build/validate a pre-release, optionally publishing it.
34
+
35
+ Then run `git fetch origin` and verify `git status` is clean and `main` is
36
+ up to date (`git rev-parse HEAD` == `git rev-parse origin/main`).
37
+
38
+ ---
39
+
40
+ ## Stable lane (release-please owns the version + tag)
41
+
42
+ 1. `git checkout main && git pull --ff-only`.
43
+ 2. Find the open release PR (release-please titles it `chore(main): release X.Y.Z`
44
+ and pushes it to a `release-please--…` branch). Match on either signal —
45
+ do **not** pass the title to `--search`, whose parser silently drops
46
+ `chore(main):` and returns zero results even when the PR exists:
47
+ ```bash
48
+ gh pr list --state open --limit 100 --json number,title,headRefName,url --jq \
49
+ '.[] | select((.headRefName | startswith("release-please--"))
50
+ or (.title | startswith("chore(main): release")))
51
+ | "\(.number)\t\(.title)\t\(.url)"'
52
+ ```
53
+ If none exists, tell the user release-please has not opened one (no
54
+ releasable `feat:`/`fix:` commits since the last release) and **stop**.
55
+ Before concluding that, sanity-check with a bare `gh pr list --state open`:
56
+ a filter bug and a genuinely absent PR look identical from here, and
57
+ wrongly reporting "no release PR" strands a real one.
58
+ 3. Show the proposed bump + changelog for review. `gh pr diff` takes no
59
+ pathspec (`gh pr diff <n> -- <files>` fails with "accepts at most 1 arg"),
60
+ so select the files from the API instead:
61
+ ```bash
62
+ gh api repos/{owner}/{repo}/pulls/<number>/files --paginate --jq \
63
+ '.[] | select(.filename == "pyproject.toml" or .filename == "CHANGELOG.md")
64
+ | "=== \(.filename) ===\n\(.patch)"'
65
+ ```
66
+ Read the `⚠ BREAKING CHANGES` block carefully — it is what drives a major
67
+ bump, and a spurious entry there is the usual cause of an unintended one.
68
+ 4. **Run the validation gate (Step V) on the PR's head branch** so you build the
69
+ exact version that will publish.
70
+ 5. **Only on explicit approval**, merge it (release-please then tags `vX.Y.Z`,
71
+ which triggers `release.yml` to publish to PyPI + GHCR):
72
+ ```bash
73
+ gh pr merge <number> --squash
74
+ ```
75
+ Before merging, confirm the `RELEASE_PLEASE_TOKEN` secret is set — without it
76
+ the tag will not trigger the publish. If it's missing, warn the user and let
77
+ them decide.
78
+ 6. Return to `main`, `git pull --ff-only`, report the new tag, and offer to watch
79
+ the release CI. `gh run watch` needs an explicit run id outside a TTY:
80
+ ```bash
81
+ gh run watch "$(gh run list --workflow=release.yml --limit 1 \
82
+ --json databaseId --jq '.[0].databaseId')"
83
+ ```
84
+
85
+ ---
86
+
87
+ ## RC lane (manual — release-please stays out)
88
+
89
+ 1. `git checkout main && git pull --ff-only`.
90
+ 2. Determine the RC version `X.Y.ZrcN` (PEP 440 form, **no separator**):
91
+ - `X.Y.Z` is the next target version (feat → minor, fix → patch over the last
92
+ stable tag).
93
+ - `N` increments from the last `vX.Y.Z-rcM` tag for the same `X.Y.Z`
94
+ (`git tag --list "vX.Y.Z-rc*"`), else `1`.
95
+ - Confirm the chosen version with the user.
96
+ 3. Confirm these two files carry no pre-existing edits, then bump
97
+ `pyproject.toml` `[project].version` to `X.Y.ZrcN` (optionally run `uv lock`
98
+ to keep the lockfile's version in step):
99
+ ```bash
100
+ git diff --quiet -- pyproject.toml uv.lock \
101
+ || { echo "pyproject.toml/uv.lock already modified — STOP"; }
102
+ ```
103
+ Step 0 already required a clean tree, but re-assert it here: the revert in
104
+ Step 5 discards whatever is in these files, and the gap between Step 0 and
105
+ Step 5 spans a full test run.
106
+ 4. **Run the validation gate (Step V).**
107
+ 5. Ask the user which outcome they want:
108
+ - **Local test only (default, no PyPI):** revert the bump, then hand off the
109
+ built wheel (`dist/*.whl`) or the git-install one-liner
110
+ (`uv tool install --force "git+https://github.com/get2knowio/remo.git@<branch>"`).
111
+ Nothing is committed, tagged, or published.
112
+
113
+ Look before discarding — never `git checkout`/`git restore` these paths
114
+ blind. Print the diff, confirm it is **only** the version bump you made in
115
+ Step 3, and only then restore:
116
+ ```bash
117
+ git diff -- pyproject.toml uv.lock # MUST show only the X.Y.ZrcN bump
118
+ git restore --source=HEAD --worktree -- pyproject.toml uv.lock
119
+ ```
120
+ If that diff contains anything else, stop and surface it: something edited
121
+ these files during the run, and discarding it destroys unrecoverable work.
122
+ - **CI dev build for cross-machine testing (no PyPI):** trigger the
123
+ `dev-build.yml` workflow, which builds the wheel in clean CI and uploads it
124
+ as a run artifact. The stamped version carries a `+g<sha>` local segment, so
125
+ it is unique and can never reach PyPI. Nothing is committed or tagged.
126
+ ```bash
127
+ gh workflow run dev-build.yml -f version=X.Y.ZrcN # omit -f for an auto dev version
128
+ # `gh run watch` with no argument fails outside a TTY ("run ID required
129
+ # when not running interactively"), so resolve the run id first. Give the
130
+ # dispatch a couple of seconds to register before listing.
131
+ RUN_ID="$(gh run list --workflow=dev-build.yml --limit 1 \
132
+ --json databaseId --jq '.[0].databaseId')"
133
+ gh run watch "$RUN_ID"
134
+ # then, on ANY machine:
135
+ gh run download "$RUN_ID" -n remo-wheel -D ./dl
136
+ uv tool install --force ./dl/remo_cli-*.whl
137
+ ```
138
+ - **Publish a prerelease (only on explicit approval):**
139
+ ```bash
140
+ git commit -am "chore(release): X.Y.ZrcN"
141
+ git tag vX.Y.Z-rcN
142
+ git push origin main vX.Y.Z-rcN
143
+ ```
144
+ `release.yml` detects the `rc` suffix, publishes the prerelease to PyPI +
145
+ GHCR, and never moves `latest`. Offer to watch CI.
146
+
147
+ ---
148
+
149
+ ## Step V — Validation gate (test the exact wheel before PyPI)
150
+
151
+ Run this on whatever ref will be released (the release-please PR head for stable,
152
+ or the bumped working tree for an RC). The published version comes from
153
+ `pyproject.toml` via `uv build`, so this builds the identical artifact:
154
+
155
+ ```bash
156
+ uv run pytest -q # full suite must pass
157
+ uv build # -> dist/remo_cli-<version>-py3-none-any.whl
158
+ VENV="$(mktemp -d)/venv"
159
+ uv venv "$VENV"
160
+ uv pip install --python "$VENV/bin/python" ./dist/remo_cli-<version>-py3-none-any.whl
161
+ "$VENV/bin/remo" --version # MUST equal <version>
162
+ "$VENV/bin/remo" --help # sanity-check the CLI loads
163
+ ```
164
+
165
+ Report the results. If tests fail, the wheel version doesn't match, or the CLI
166
+ doesn't load, **stop** and surface it — do not proceed to tag/merge/publish.
167
+
168
+ ## Done when
169
+
170
+ - The requested lane completed through the point the user approved (validated
171
+ only; RC wheel handed off; RC published; or stable PR merged).
172
+ - No tag was pushed, commit was pushed, or PR merged without explicit approval.
173
+ - The outcome (and, if published, the immutable version) was reported clearly.
@@ -0,0 +1,5 @@
1
+ # Code owners for remo.
2
+ # These owners are the default reviewers for every pull request in this repo.
3
+ # See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
4
+
5
+ * @pofallon
@@ -7,6 +7,10 @@ updates:
7
7
  interval: "weekly"
8
8
  day: "monday"
9
9
  open-pull-requests-limit: 5
10
+ # Let a new release settle before we bump to it, so we don't chase
11
+ # immediately-yanked or regression releases.
12
+ cooldown:
13
+ default-days: 7
10
14
  groups:
11
15
  # One PR per week with all minor/patch production deps bumped together.
12
16
  production-minor-patch:
@@ -29,6 +33,8 @@ updates:
29
33
  interval: "weekly"
30
34
  day: "monday"
31
35
  open-pull-requests-limit: 5
36
+ cooldown:
37
+ default-days: 7
32
38
  groups:
33
39
  actions:
34
40
  update-types:
@@ -15,9 +15,9 @@ jobs:
15
15
  python-version: ["3.11", "3.12", "3.13"]
16
16
 
17
17
  steps:
18
- - uses: actions/checkout@v7
18
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
19
19
 
20
- - uses: astral-sh/setup-uv@v7
20
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
21
21
 
22
22
  - name: Set up Python ${{ matrix.python-version }}
23
23
  run: uv python install ${{ matrix.python-version }}
@@ -39,16 +39,16 @@ jobs:
39
39
  # runs npm ci and pip install under QEMU.
40
40
  timeout-minutes: 45
41
41
  steps:
42
- - uses: actions/checkout@v7
42
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
43
43
 
44
44
  # Registers binfmt handlers so the arm64 half of tests/image/ can build
45
45
  # under emulation on an amd64 runner. The arch-selection branch
46
46
  # (FR-027/FR-042) has no other way to be exercised here.
47
- - uses: docker/setup-qemu-action@v4
47
+ - uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
48
48
 
49
- - uses: docker/setup-buildx-action@v4
49
+ - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
50
50
 
51
- - uses: astral-sh/setup-uv@v7
51
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
52
52
 
53
53
  - name: Install dependencies
54
54
  run: uv sync --all-extras
@@ -68,9 +68,9 @@ jobs:
68
68
  name: Wheel install smoke test
69
69
  runs-on: ubuntu-latest
70
70
  steps:
71
- - uses: actions/checkout@v7
71
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
72
72
 
73
- - uses: astral-sh/setup-uv@v7
73
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
74
74
 
75
75
  - name: Build wheel
76
76
  run: uv build --wheel
@@ -92,13 +92,39 @@ jobs:
92
92
  print("OK: ansible playbooks found in installed wheel")
93
93
  EOF
94
94
 
95
+ fish-completion:
96
+ name: Fish completion (real shell)
97
+ runs-on: ubuntu-latest
98
+ steps:
99
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
100
+
101
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
102
+
103
+ - name: Install fish
104
+ run: |
105
+ sudo apt-get update -qq
106
+ sudo apt-get install -y -qq fish
107
+
108
+ # The activation script shells out to `remo` by name, so it has to be a
109
+ # real binary on PATH — `uv run remo` would never be found by fish.
110
+ - name: Install remo onto PATH
111
+ run: |
112
+ uv sync
113
+ echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
114
+
115
+ # Asserting on the text of the generated script is not enough: the bug
116
+ # this guards against (a2542e9) produced a script that read fine and
117
+ # emitted a screenful of errors the moment fish executed it.
118
+ - name: Run completions in a real fish shell
119
+ run: ./tests/integration/fish_completion.sh
120
+
95
121
  lint:
96
- name: Lint
122
+ name: Lint & Types
97
123
  runs-on: ubuntu-latest
98
124
  steps:
99
- - uses: actions/checkout@v7
125
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
100
126
 
101
- - uses: astral-sh/setup-uv@v7
127
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
102
128
 
103
129
  - name: Install dependencies
104
130
  run: uv sync --all-extras
@@ -106,6 +132,13 @@ jobs:
106
132
  - name: Ruff check
107
133
  run: uv run ruff check src/remo_cli
108
134
 
135
+ # mypy analyses against python_version = "3.11" from [tool.mypy], so the
136
+ # result is independent of whichever interpreter uv resolves here. The
137
+ # `web` extra must be installed (it is, via --all-extras) or every
138
+ # src/remo_cli/web/ module degrades to Any and the gate goes blind.
139
+ - name: Mypy check
140
+ run: uv run mypy src/remo_cli
141
+
109
142
  frontend:
110
143
  name: Frontend (typecheck + unit + build)
111
144
  runs-on: ubuntu-latest
@@ -117,9 +150,9 @@ jobs:
117
150
  run:
118
151
  working-directory: frontend
119
152
  steps:
120
- - uses: actions/checkout@v7
153
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
121
154
 
122
- - uses: actions/setup-node@v4
155
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
123
156
  with:
124
157
  node-version: "20"
125
158
  cache: npm
@@ -131,6 +164,9 @@ jobs:
131
164
  - name: Typecheck
132
165
  run: npm run lint
133
166
 
167
+ - name: Check generated types are fresh
168
+ run: npm run check:types-fresh
169
+
134
170
  - name: Unit tests
135
171
  run: npm run test
136
172
 
@@ -0,0 +1,44 @@
1
+ name: CodeQL
2
+
3
+ # Static analysis (code scanning) for the repo's compiled/interpreted sources.
4
+ # Results appear under the Security tab and annotate pull requests.
5
+ on:
6
+ push:
7
+ branches: [main]
8
+ pull_request:
9
+ branches: [main]
10
+ schedule:
11
+ # Weekly full scan so newly published CodeQL queries catch existing code.
12
+ - cron: "27 4 * * 1"
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ analyze:
19
+ name: Analyze (${{ matrix.language }})
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ security-events: write # upload CodeQL results
23
+ packages: read # fetch CodeQL packs
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ include:
28
+ - language: python
29
+ build-mode: none
30
+ - language: javascript-typescript
31
+ build-mode: none
32
+ steps:
33
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
34
+
35
+ - name: Initialize CodeQL
36
+ uses: github/codeql-action/init@4187e74d05793876e9989daffde9c3e66b4acd07 # v3
37
+ with:
38
+ languages: ${{ matrix.language }}
39
+ build-mode: ${{ matrix.build-mode }}
40
+
41
+ - name: Perform CodeQL Analysis
42
+ uses: github/codeql-action/analyze@4187e74d05793876e9989daffde9c3e66b4acd07 # v3
43
+ with:
44
+ category: "/language:${{ matrix.language }}"
@@ -0,0 +1,18 @@
1
+ name: Dependency Review
2
+
3
+ # Scans dependency manifest changes on pull requests for known-vulnerable
4
+ # packages and disallowed licenses, blocking the PR before they reach main.
5
+ on:
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ dependency-review:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
16
+ - uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4
17
+ with:
18
+ fail-on-severity: high
@@ -0,0 +1,78 @@
1
+ name: dev-build
2
+
3
+ # Build an installable wheel and upload it as a run artifact you can download and
4
+ # test on ANY machine — no git tag, no PyPI, no version reserved.
5
+ #
6
+ # The stamped version always carries a PEP 440 *local* segment (`+g<shortsha>`),
7
+ # which PyPI rejects outright — so a dev build can never leak to PyPI, and every
8
+ # build is uniquely identifiable.
9
+ #
10
+ # Trigger manually:
11
+ # gh workflow run dev-build.yml # -> 2.2.0.dev<run>+g<sha>
12
+ # gh workflow run dev-build.yml -f version=2.3.0rc1 # -> 2.3.0rc1+g<sha>
13
+ #
14
+ # Then, on any machine:
15
+ # gh run download <run-id> -n remo-wheel -D ./dl
16
+ # uv tool install --force ./dl/remo_cli-*.whl
17
+
18
+ on:
19
+ workflow_dispatch:
20
+ inputs:
21
+ version:
22
+ description: "Full base version to stamp (e.g. 2.3.0rc1, 2.3.0). Blank = auto dev version from pyproject. A +g<sha> local segment is always appended."
23
+ required: false
24
+ default: ""
25
+
26
+ permissions:
27
+ contents: read
28
+
29
+ jobs:
30
+ build:
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
34
+ with:
35
+ fetch-depth: 0
36
+
37
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
38
+
39
+ - name: Compute dev version
40
+ id: ver
41
+ env:
42
+ INPUT_VERSION: ${{ inputs.version }}
43
+ run: |
44
+ set -euo pipefail
45
+ SHA=$(git rev-parse --short HEAD)
46
+ if [ -n "$INPUT_VERSION" ]; then
47
+ BASE="$INPUT_VERSION"
48
+ else
49
+ # Core X.Y.Z from pyproject, plus a per-run .dev segment.
50
+ CORE=$(grep -m1 '^version = ' pyproject.toml \
51
+ | sed -E 's/version = "([0-9]+\.[0-9]+\.[0-9]+).*"/\1/')
52
+ BASE="${CORE}.dev${GITHUB_RUN_NUMBER}"
53
+ fi
54
+ # Always append the local segment: unique + un-uploadable to PyPI.
55
+ VERSION="${BASE}+g${SHA}"
56
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
57
+ echo "Building version: $VERSION"
58
+
59
+ - name: Stamp version into pyproject.toml
60
+ env:
61
+ VERSION: ${{ steps.ver.outputs.version }}
62
+ run: |
63
+ set -euo pipefail
64
+ sed -i -E "0,/^version = \".*\"/s//version = \"${VERSION}\"/" pyproject.toml
65
+ grep -m1 '^version = ' pyproject.toml
66
+
67
+ - name: Build wheel + sdist
68
+ run: uv build
69
+
70
+ - name: Upload artifact
71
+ # NOTE: SHA-pin to match the repo's action-pinning convention once the
72
+ # v4 commit SHA is available (e.g. `@<sha> # v4`).
73
+ uses: actions/upload-artifact@v4
74
+ with:
75
+ name: remo-wheel
76
+ path: dist/*
77
+ retention-days: 30
78
+ if-no-files-found: error
@@ -16,10 +16,10 @@ jobs:
16
16
 
17
17
  steps:
18
18
  - name: Checkout repository
19
- uses: actions/checkout@v7
19
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
20
20
 
21
21
  - name: Install uv
22
- uses: astral-sh/setup-uv@v7
22
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
23
23
 
24
24
  - name: Install Ansible and dependencies
25
25
  run: |
@@ -0,0 +1,57 @@
1
+ name: release-please
2
+
3
+ # Automates STABLE releases from Conventional Commits.
4
+ #
5
+ # On every push to main, release-please maintains a "release PR" that bumps the
6
+ # version in pyproject.toml and updates CHANGELOG.md. Merging that PR creates the
7
+ # `vX.Y.Z` tag and a GitHub release — which in turn triggers the existing
8
+ # tag-driven `release.yml` (PyPI + Docker image).
9
+ #
10
+ # RCs / pre-releases are NOT handled here: cut those with a manual `vX.Y.Z-rcN`
11
+ # tag (see CONTRIBUTING.md → Release Process), which `release.yml` publishes as a
12
+ # prerelease. release-please stays out of the RC lane.
13
+
14
+ on:
15
+ push:
16
+ branches:
17
+ - main
18
+
19
+ permissions:
20
+ contents: write
21
+ pull-requests: write
22
+
23
+ jobs:
24
+ release-please:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ # Mint a short-lived GitHub App installation token when the App is
28
+ # configured (org secrets RELEASE_PLEASE_APP_ID + RELEASE_PLEASE_APP_KEY).
29
+ # An App token — like a PAT, unlike GITHUB_TOKEN — triggers the tag-driven
30
+ # `release.yml`, but it's short-lived, auto-minted (nothing to rotate), and
31
+ # tied to no human account. The step is skipped if the App isn't set up.
32
+ #
33
+ # NOTE: SHA-pin `create-github-app-token` and `release-please-action` to
34
+ # match the repo's action-pinning convention (e.g. `@<sha> # v2`) once the
35
+ # SHAs are available — left as floating tags because they can't be
36
+ # resolved offline.
37
+ - name: Mint GitHub App token
38
+ id: app-token
39
+ if: ${{ vars.RELEASE_PLEASE_APP_ID != '' }}
40
+ uses: actions/create-github-app-token@v2
41
+ with:
42
+ app-id: ${{ vars.RELEASE_PLEASE_APP_ID }}
43
+ private-key: ${{ secrets.RELEASE_PLEASE_APP_KEY }}
44
+
45
+ - uses: googleapis/release-please-action@v4
46
+ with:
47
+ # Token precedence:
48
+ # 1. GitHub App installation token (recommended — see above).
49
+ # 2. RELEASE_PLEASE_TOKEN PAT (if someone set one instead).
50
+ # 3. GITHUB_TOKEN fallback — release-please still opens/maintains the
51
+ # release PR out of the box, but a tag it creates will NOT fire
52
+ # `on: push: tags`, so `release.yml` (PyPI + Docker) won't run
53
+ # until a maintainer re-pushes the tag. Configure the App (or the
54
+ # PAT) to make merge-to-publish automatic.
55
+ token: ${{ steps.app-token.outputs.token || secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
56
+ config-file: release-please-config.json
57
+ manifest-file: .release-please-manifest.json
@@ -13,9 +13,9 @@ jobs:
13
13
  python-version: ["3.11", "3.12", "3.13"]
14
14
 
15
15
  steps:
16
- - uses: actions/checkout@v7
16
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
17
17
 
18
- - uses: astral-sh/setup-uv@v7
18
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
19
19
 
20
20
  - name: Set up Python ${{ matrix.python-version }}
21
21
  run: uv python install ${{ matrix.python-version }}
@@ -38,7 +38,7 @@ jobs:
38
38
 
39
39
  steps:
40
40
  - name: Checkout
41
- uses: actions/checkout@v7
41
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
42
42
  with:
43
43
  fetch-depth: 0
44
44
 
@@ -137,7 +137,7 @@ jobs:
137
137
  fi
138
138
 
139
139
  - name: Create Release
140
- uses: softprops/action-gh-release@v3
140
+ uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3
141
141
  with:
142
142
  tag_name: ${{ steps.tag.outputs.tag }}
143
143
  name: ${{ steps.tag.outputs.tag }}
@@ -153,15 +153,15 @@ jobs:
153
153
  environment: pypi
154
154
 
155
155
  steps:
156
- - uses: actions/checkout@v7
156
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
157
157
 
158
- - uses: astral-sh/setup-uv@v7
158
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
159
159
 
160
160
  - name: Build package
161
161
  run: uv build
162
162
 
163
163
  - name: Publish to PyPI
164
- uses: pypa/gh-action-pypi-publish@release/v1
164
+ uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # release/v1
165
165
 
166
166
  publish-image:
167
167
  # Publishes the remo-web container image that docker/compose.example.yml
@@ -177,16 +177,16 @@ jobs:
177
177
  timeout-minutes: 60
178
178
 
179
179
  steps:
180
- - uses: actions/checkout@v7
180
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
181
181
 
182
182
  # Needed for the linux/arm64 half of the manifest: GitHub's runners are
183
183
  # amd64, so arm64 is cross-built under emulation.
184
- - uses: docker/setup-qemu-action@v4
184
+ - uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
185
185
 
186
- - uses: docker/setup-buildx-action@v4
186
+ - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
187
187
 
188
188
  - name: Log in to GHCR
189
- uses: docker/login-action@v4
189
+ uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
190
190
  with:
191
191
  registry: ghcr.io
192
192
  username: ${{ github.actor }}
@@ -194,7 +194,7 @@ jobs:
194
194
 
195
195
  - name: Derive image tags and labels
196
196
  id: meta
197
- uses: docker/metadata-action@v6
197
+ uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
198
198
  with:
199
199
  images: ghcr.io/${{ github.repository_owner }}/remo-web
200
200
  # latest=false disables this action's automatic `latest`; the raw
@@ -207,7 +207,7 @@ jobs:
207
207
  type=raw,value=latest,enable=${{ needs.release.outputs.is_prerelease == 'false' }}
208
208
 
209
209
  - name: Build and push (amd64 + arm64)
210
- uses: docker/build-push-action@v7
210
+ uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
211
211
  with:
212
212
  context: .
213
213
  file: docker/Dockerfile
@@ -20,7 +20,7 @@ jobs:
20
20
  timeout-minutes: 10
21
21
  steps:
22
22
  - name: Configure AWS credentials (OIDC)
23
- uses: aws-actions/configure-aws-credentials@v6
23
+ uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6
24
24
  with:
25
25
  role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }}
26
26
  role-session-name: remo-cleanup-${{ github.run_id }}
@@ -81,7 +81,7 @@ jobs:
81
81
  timeout-minutes: 10
82
82
  steps:
83
83
  - name: Setup hcloud CLI
84
- uses: hetznercloud/setup-hcloud@v2
84
+ uses: hetznercloud/setup-hcloud@ac9e7d74fb41a3ca44a6a3da123bd5aa70731e3a # v2
85
85
 
86
86
  - name: Delete stale CI servers
87
87
  env: