remo-cli 3.1.0__tar.gz → 4.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 (644) hide show
  1. {remo_cli-3.1.0 → remo_cli-4.0.0}/.devcontainer/devcontainer.json +10 -0
  2. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/release-please.yml +37 -0
  3. remo_cli-4.0.0/.release-please-manifest.json +3 -0
  4. {remo_cli-3.1.0 → remo_cli-4.0.0}/AGENTS.md +4 -5
  5. {remo_cli-3.1.0 → remo_cli-4.0.0}/CHANGELOG.md +29 -0
  6. {remo_cli-3.1.0 → remo_cli-4.0.0}/CLAUDE.md +6 -6
  7. {remo_cli-3.1.0 → remo_cli-4.0.0}/CONTRIBUTING.md +6 -3
  8. {remo_cli-3.1.0 → remo_cli-4.0.0}/PKG-INFO +2 -2
  9. {remo_cli-3.1.0 → remo_cli-4.0.0}/README.md +1 -1
  10. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/aws_configure.yml +6 -0
  11. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/aws_site.yml +6 -0
  12. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/hetzner_configure.yml +6 -0
  13. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/hetzner_site.yml +6 -0
  14. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/incus_configure.yml +13 -0
  15. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/incus_site.yml +13 -0
  16. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/proxmox_bootstrap.yml +1 -1
  17. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/proxmox_configure.yml +13 -0
  18. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/proxmox_site.yml +13 -0
  19. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/nodejs/tasks/main.yml +7 -0
  20. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_container/defaults/main.yml +6 -0
  21. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_container/tasks/main.yml +41 -5
  22. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_container/tasks/preflight.yml +1 -1
  23. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/user_setup/defaults/main.yml +9 -0
  24. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/user_setup/tasks/main.yml +85 -22
  25. remo_cli-4.0.0/ansible/roles/zellij/defaults/main.yml +27 -0
  26. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/zellij/tasks/main.yml +39 -8
  27. remo_cli-4.0.0/ansible/tasks/repair_apt_sources.yml +72 -0
  28. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/providers.md +2 -2
  29. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/proxmox.md +37 -30
  30. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/web-session-interface.md +67 -17
  31. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/package-lock.json +0 -7
  32. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/package.json +0 -2
  33. remo_cli-4.0.0/frontend/src/api/client.test.ts +182 -0
  34. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/api/client.ts +132 -72
  35. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/api/generated/openapi.json +6 -1
  36. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/api/generated/schema.d.ts +9 -0
  37. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/AppShell.tsx +38 -3
  38. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/OfflineOverlay.css +6 -6
  39. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/SessionRail.css +9 -9
  40. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/SessionRail.tsx +5 -1
  41. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/SettingsPage.css +52 -3
  42. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/SettingsPage.tsx +124 -35
  43. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/ShortcutsModal.css +2 -2
  44. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/TerminalCard.css +112 -11
  45. remo_cli-4.0.0/frontend/src/components/TerminalCard.test.tsx +198 -0
  46. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/TerminalCard.tsx +145 -10
  47. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/TopBar.tsx +32 -0
  48. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/WorkspacePane.tsx +3 -0
  49. remo_cli-4.0.0/frontend/src/components/railModel.test.ts +121 -0
  50. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/railModel.ts +18 -3
  51. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/main.tsx +5 -8
  52. remo_cli-4.0.0/frontend/src/state/discovery.test.ts +105 -0
  53. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/state/discovery.ts +50 -6
  54. remo_cli-4.0.0/frontend/src/state/health.test.ts +77 -0
  55. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/state/health.ts +14 -1
  56. remo_cli-4.0.0/frontend/src/state/settings.test.ts +281 -0
  57. remo_cli-4.0.0/frontend/src/state/settings.ts +379 -0
  58. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/terminal/RendererAdapter.ts +45 -12
  59. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/terminal/XtermRenderer.ts +19 -7
  60. remo_cli-4.0.0/frontend/src/terminal/defaultRenderer.ts +26 -0
  61. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/terminal/keymap.ts +2 -2
  62. remo_cli-4.0.0/frontend/src/theme/terminalThemes.test.ts +146 -0
  63. remo_cli-4.0.0/frontend/src/theme/terminalThemes.ts +362 -0
  64. remo_cli-4.0.0/frontend/src/theme/tokens.css +201 -0
  65. {remo_cli-3.1.0 → remo_cli-4.0.0}/playwright.config.ts +2 -2
  66. {remo_cli-3.1.0 → remo_cli-4.0.0}/pyproject.toml +1 -1
  67. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/cli/providers/factory.py +2 -2
  68. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/cli/shell.py +1 -1
  69. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/provider_registry.py +1 -1
  70. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/registry.py +8 -1
  71. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/web_adopt.py +167 -18
  72. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/hetzner.py +8 -1
  73. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/incus.py +11 -1
  74. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/proxmox.py +68 -65
  75. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/proxmox_descriptor.py +17 -14
  76. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/api/hosts.py +13 -1
  77. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/app.py +9 -8
  78. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/discovery.py +6 -1
  79. remo_cli-4.0.0/tests/ansible/test_apt_sources_repair.py +253 -0
  80. remo_cli-4.0.0/tests/ansible/test_authorized_keys_bootstrap.py +298 -0
  81. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/e2e/fixtures.ts +4 -26
  82. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/e2e/keyboard-routing.spec.ts +2 -2
  83. remo_cli-3.1.0/tests/e2e/ghostty-shell-io.spec.ts → remo_cli-4.0.0/tests/e2e/terminal-shell-io.spec.ts +15 -21
  84. remo_cli-3.1.0/tests/e2e/ghostty-tui-compatibility.spec.ts → remo_cli-4.0.0/tests/e2e/terminal-tui-compatibility.spec.ts +6 -10
  85. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/providers/test_proxmox_sync_all.py +1 -1
  86. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/surface_baseline.py +9 -9
  87. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_registry_migration.py +2 -2
  88. remo_cli-4.0.0/tests/unit/core/test_web_push_self_heal.py +419 -0
  89. remo_cli-4.0.0/tests/unit/providers/test_host_user_consistency.py +289 -0
  90. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_provider_registry_entries.py +1 -1
  91. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_proxmox_marker.py +6 -6
  92. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_proxmox_provider_protocol.py +1 -1
  93. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_proxmox_resize.py +4 -4
  94. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_proxmox_snapshot.py +17 -2
  95. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_proxmox_sync.py +41 -16
  96. remo_cli-4.0.0/tests/unit/test_lockfile_version.py +55 -0
  97. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_csp.py +8 -5
  98. remo_cli-4.0.0/tests/unit/web/test_discovery_refresh_force.py +92 -0
  99. {remo_cli-3.1.0 → remo_cli-4.0.0}/uv.lock +1 -1
  100. remo_cli-3.1.0/.release-please-manifest.json +0 -3
  101. remo_cli-3.1.0/ansible/roles/zellij/defaults/main.yml +0 -13
  102. remo_cli-3.1.0/frontend/public/README.md +0 -10
  103. remo_cli-3.1.0/frontend/public/dist__ghostty-vt.wasm +0 -0
  104. remo_cli-3.1.0/frontend/public/ghostty-vt.wasm +0 -0
  105. remo_cli-3.1.0/frontend/scripts/copy-ghostty-wasm.mjs +0 -86
  106. remo_cli-3.1.0/frontend/src/state/settings.ts +0 -236
  107. remo_cli-3.1.0/frontend/src/terminal/GhosttyRenderer.ts +0 -194
  108. remo_cli-3.1.0/frontend/src/terminal/defaultRenderer.ts +0 -65
  109. remo_cli-3.1.0/frontend/src/theme/tokens.css +0 -128
  110. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/release/SKILL.md +0 -0
  111. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-analyze/SKILL.md +0 -0
  112. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-checklist/SKILL.md +0 -0
  113. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-clarify/SKILL.md +0 -0
  114. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-constitution/SKILL.md +0 -0
  115. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-converge/SKILL.md +0 -0
  116. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-git-commit/SKILL.md +0 -0
  117. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-git-feature/SKILL.md +0 -0
  118. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-git-initialize/SKILL.md +0 -0
  119. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-git-remote/SKILL.md +0 -0
  120. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-git-validate/SKILL.md +0 -0
  121. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-implement/SKILL.md +0 -0
  122. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-plan/SKILL.md +0 -0
  123. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-specify/SKILL.md +0 -0
  124. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-tasks/SKILL.md +0 -0
  125. {remo_cli-3.1.0 → remo_cli-4.0.0}/.claude/skills/speckit-taskstoissues/SKILL.md +0 -0
  126. {remo_cli-3.1.0 → remo_cli-4.0.0}/.dockerignore +0 -0
  127. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/CODEOWNERS +0 -0
  128. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/dependabot.yml +0 -0
  129. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/ci.yml +0 -0
  130. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/codeql.yml +0 -0
  131. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/dependency-review.yml +0 -0
  132. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/dev-build.yml +0 -0
  133. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/provision.yml +0 -0
  134. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/release.yml +0 -0
  135. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/smoke-test-cleanup.yml +0 -0
  136. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/smoke-test.yml +0 -0
  137. {remo_cli-3.1.0 → remo_cli-4.0.0}/.github/workflows/teardown.yml +0 -0
  138. {remo_cli-3.1.0 → remo_cli-4.0.0}/.gitignore +0 -0
  139. {remo_cli-3.1.0 → remo_cli-4.0.0}/.maverick/checkpoints/feature/implementation_complete.json +0 -0
  140. {remo_cli-3.1.0 → remo_cli-4.0.0}/.maverick/checkpoints/feature/phase_${{ index }}_complete.json +0 -0
  141. {remo_cli-3.1.0 → remo_cli-4.0.0}/.maverick/checkpoints/feature/validation_complete.json +0 -0
  142. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/.registry +0 -0
  143. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/README.md +0 -0
  144. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/commands/speckit.git.commit.md +0 -0
  145. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/commands/speckit.git.feature.md +0 -0
  146. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/commands/speckit.git.initialize.md +0 -0
  147. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/commands/speckit.git.remote.md +0 -0
  148. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/commands/speckit.git.validate.md +0 -0
  149. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/config-template.yml +0 -0
  150. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/extension.yml +0 -0
  151. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/git-config.yml +0 -0
  152. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/scripts/bash/auto-commit.sh +0 -0
  153. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/scripts/bash/create-new-feature.sh +0 -0
  154. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/scripts/bash/git-common.sh +0 -0
  155. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/scripts/bash/initialize-repo.sh +0 -0
  156. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
  157. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/scripts/powershell/create-new-feature.ps1 +0 -0
  158. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/scripts/powershell/git-common.ps1 +0 -0
  159. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
  160. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/extensions.yml +0 -0
  161. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/feature.json +0 -0
  162. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/init-options.json +0 -0
  163. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/integration.json +0 -0
  164. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/integrations/claude.manifest.json +0 -0
  165. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/integrations/speckit.manifest.json +0 -0
  166. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/memory/constitution.md +0 -0
  167. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/scripts/bash/check-prerequisites.sh +0 -0
  168. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/scripts/bash/common.sh +0 -0
  169. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/scripts/bash/create-new-feature.sh +0 -0
  170. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/scripts/bash/setup-plan.sh +0 -0
  171. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/scripts/bash/setup-tasks.sh +0 -0
  172. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/scripts/bash/update-agent-context.sh +0 -0
  173. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/templates/agent-file-template.md +0 -0
  174. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/templates/checklist-template.md +0 -0
  175. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/templates/constitution-template.md +0 -0
  176. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/templates/plan-template.md +0 -0
  177. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/templates/spec-template.md +0 -0
  178. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/templates/tasks-template.md +0 -0
  179. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/workflows/speckit/workflow.yml +0 -0
  180. {remo_cli-3.1.0 → remo_cli-4.0.0}/.specify/workflows/workflow-registry.json +0 -0
  181. {remo_cli-3.1.0 → remo_cli-4.0.0}/Dockerfile +0 -0
  182. {remo_cli-3.1.0 → remo_cli-4.0.0}/LICENSE +0 -0
  183. {remo_cli-3.1.0 → remo_cli-4.0.0}/SECURITY.md +0 -0
  184. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/.ansible-lint +0 -0
  185. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/README.md +0 -0
  186. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/ansible.cfg +0 -0
  187. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/aws_resize.yml +0 -0
  188. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/aws_teardown.yml +0 -0
  189. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/group_vars/all.yml +0 -0
  190. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/group_vars/incus_containers.yml +0 -0
  191. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/group_vars/proxmox_containers.yml +0 -0
  192. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/hetzner_provision.yml +0 -0
  193. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/hetzner_resize.yml +0 -0
  194. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/hetzner_teardown.yml +0 -0
  195. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/incus_bootstrap.yml +0 -0
  196. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/incus_provision.yml +0 -0
  197. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/incus_resize.yml +0 -0
  198. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/incus_teardown.yml +0 -0
  199. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/inventory/hosts.yml +0 -0
  200. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/inventory/incus_containers.yml +0 -0
  201. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/proxmox_provision.yml +0 -0
  202. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/proxmox_resize.yml +0 -0
  203. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/proxmox_teardown.yml +0 -0
  204. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/requirements.yml +0 -0
  205. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/aws_server/defaults/main.yml +0 -0
  206. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/aws_server/tasks/ebs.yml +0 -0
  207. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/aws_server/tasks/ec2.yml +0 -0
  208. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/aws_server/tasks/main.yml +0 -0
  209. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/aws_server/tasks/patch_manager.yml +0 -0
  210. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/aws_server/tasks/preflight.yml +0 -0
  211. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/aws_server/tasks/security_group.yml +0 -0
  212. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/deacon/defaults/main.yml +0 -0
  213. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/deacon/tasks/main.yml +0 -0
  214. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/devcontainers/tasks/main.yml +0 -0
  215. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/docker/handlers/main.yml +0 -0
  216. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/docker/tasks/main.yml +0 -0
  217. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/fzf/tasks/main.yml +0 -0
  218. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/github_cli/tasks/main.yml +0 -0
  219. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/hetzner_server/defaults/main.yml +0 -0
  220. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/hetzner_server/tasks/main.yml +0 -0
  221. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_bootstrap/defaults/main.yml +0 -0
  222. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_bootstrap/handlers/main.yml +0 -0
  223. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_bootstrap/tasks/main.yml +0 -0
  224. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_container/defaults/main.yml +0 -0
  225. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_container/handlers/main.yml +0 -0
  226. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_container/meta/main.yml +0 -0
  227. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_container/tasks/main.yml +0 -0
  228. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_container/tasks/preflight.yml +0 -0
  229. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_container_teardown/defaults/main.yml +0 -0
  230. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_container_teardown/meta/main.yml +0 -0
  231. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/incus_container_teardown/tasks/main.yml +0 -0
  232. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/nodejs/defaults/main.yml +0 -0
  233. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/nodejs/files/nodesource-repo.gpg.key +0 -0
  234. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_bootstrap/defaults/main.yml +0 -0
  235. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_bootstrap/meta/main.yml +0 -0
  236. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_bootstrap/tasks/main.yml +0 -0
  237. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_container/handlers/main.yml +0 -0
  238. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_container/meta/main.yml +0 -0
  239. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_container_teardown/defaults/main.yml +0 -0
  240. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_container_teardown/meta/main.yml +0 -0
  241. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/proxmox_container_teardown/tasks/main.yml +0 -0
  242. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/user_setup/templates/devshell.sh.j2 +0 -0
  243. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/user_setup/templates/project-launch.sh.j2 +0 -0
  244. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/user_setup/templates/project-menu.sh.j2 +0 -0
  245. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/user_setup/templates/remo-host.sh.j2 +0 -0
  246. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/zellij/templates/config.kdl.j2 +0 -0
  247. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/roles/zellij/templates/layouts/minimal.kdl.j2 +0 -0
  248. {remo_cli-3.1.0 → remo_cli-4.0.0}/ansible/tasks/configure_dev_tools.yml +0 -0
  249. {remo_cli-3.1.0 → remo_cli-4.0.0}/docker/Dockerfile +0 -0
  250. {remo_cli-3.1.0 → remo_cli-4.0.0}/docker/compose.example.yml +0 -0
  251. {remo_cli-3.1.0 → remo_cli-4.0.0}/docker/entrypoint.sh +0 -0
  252. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/aws.md +0 -0
  253. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/feature-history.md +0 -0
  254. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/hetzner.md +0 -0
  255. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/incus.md +0 -0
  256. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/install.sh +0 -0
  257. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/maintaining-claude-md.md +0 -0
  258. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/maintaining-generated-types.md +0 -0
  259. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/remo-web-speckit-input.md +0 -0
  260. {remo_cli-3.1.0 → remo_cli-4.0.0}/docs/remo-web.html +0 -0
  261. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/index.html +0 -0
  262. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/scripts/check-types-fresh.mjs +0 -0
  263. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/scripts/generate-frame-types.mjs +0 -0
  264. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/scripts/generate-schema-types.mjs +0 -0
  265. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/api/generated/README.md +0 -0
  266. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/api/generated/terminal-frames.d.ts +0 -0
  267. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/api/generated/terminal-frames.json +0 -0
  268. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/api/generated.test.ts +0 -0
  269. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/AppRoot.tsx +0 -0
  270. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/AppShell.css +0 -0
  271. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/AwaitingAdoption.css +0 -0
  272. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/AwaitingAdoption.tsx +0 -0
  273. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/OfflineOverlay.tsx +0 -0
  274. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/PairToSync.css +0 -0
  275. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/PairToSync.tsx +0 -0
  276. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/ShortcutsModal.tsx +0 -0
  277. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/TopBar.css +0 -0
  278. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/WorkspacePane.css +0 -0
  279. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/providerMeta.test.ts +0 -0
  280. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/components/providerMeta.ts +0 -0
  281. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/lib/clipboard.ts +0 -0
  282. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/lib/fullscreen.ts +0 -0
  283. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/state/fonts.ts +0 -0
  284. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/state/latency.test.ts +0 -0
  285. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/state/latency.ts +0 -0
  286. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/state/useConsoleKeyboard.ts +0 -0
  287. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/state/workspace.test.ts +0 -0
  288. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/state/workspace.ts +0 -0
  289. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/terminal/.gitkeep +0 -0
  290. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/terminal/TerminalConnection.test.ts +0 -0
  291. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/terminal/TerminalConnection.ts +0 -0
  292. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/terminal/keymap.test.ts +0 -0
  293. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/test/setup.ts +0 -0
  294. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/src/theme/fonts.ts +0 -0
  295. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/tsconfig.json +0 -0
  296. {remo_cli-3.1.0 → remo_cli-4.0.0}/frontend/vite.config.ts +0 -0
  297. {remo_cli-3.1.0 → remo_cli-4.0.0}/install.sh +0 -0
  298. {remo_cli-3.1.0 → remo_cli-4.0.0}/maverick.yaml +0 -0
  299. {remo_cli-3.1.0 → remo_cli-4.0.0}/project-menu.sh +0 -0
  300. {remo_cli-3.1.0 → remo_cli-4.0.0}/release-please-config.json +0 -0
  301. {remo_cli-3.1.0 → remo_cli-4.0.0}/remo +0 -0
  302. {remo_cli-3.1.0 → remo_cli-4.0.0}/remo.svg +0 -0
  303. {remo_cli-3.1.0 → remo_cli-4.0.0}/run.sh +0 -0
  304. {remo_cli-3.1.0 → remo_cli-4.0.0}/scripts/export_openapi.py +0 -0
  305. {remo_cli-3.1.0 → remo_cli-4.0.0}/scripts/setup-aws-oidc.sh +0 -0
  306. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/checklists/requirements.md +0 -0
  307. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/checklists/validation.md +0 -0
  308. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/contracts/playbook-interface.yaml +0 -0
  309. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/contracts/role-interface.yaml +0 -0
  310. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/data-model.md +0 -0
  311. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/plan.md +0 -0
  312. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/quickstart.md +0 -0
  313. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/research.md +0 -0
  314. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/spec.md +0 -0
  315. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/001-bootstrap-incus-host/tasks.md +0 -0
  316. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/checklists/requirements.md +0 -0
  317. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/contracts/playbook-interface.yaml +0 -0
  318. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/contracts/role-interface.yaml +0 -0
  319. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/data-model.md +0 -0
  320. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/plan.md +0 -0
  321. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/quickstart.md +0 -0
  322. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/research.md +0 -0
  323. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/spec.md +0 -0
  324. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/002-incus-container-support/tasks.md +0 -0
  325. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/003-python-cli-rewrite/checklists/requirements.md +0 -0
  326. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/003-python-cli-rewrite/data-model.md +0 -0
  327. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/003-python-cli-rewrite/plan.md +0 -0
  328. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/003-python-cli-rewrite/quickstart.md +0 -0
  329. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/003-python-cli-rewrite/research.md +0 -0
  330. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/003-python-cli-rewrite/spec.md +0 -0
  331. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/003-python-cli-rewrite/tasks.md +0 -0
  332. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/004-proxmox-container-support/spec.md +0 -0
  333. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/005-provider-snapshots/checklists/requirements.md +0 -0
  334. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/005-provider-snapshots/contracts/cli-surface.md +0 -0
  335. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/005-provider-snapshots/data-model.md +0 -0
  336. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/005-provider-snapshots/plan.md +0 -0
  337. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/005-provider-snapshots/quickstart.md +0 -0
  338. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/005-provider-snapshots/research.md +0 -0
  339. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/005-provider-snapshots/spec.md +0 -0
  340. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/005-provider-snapshots/tasks.md +0 -0
  341. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/checklists/requirements.md +0 -0
  342. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/contracts/remo-host-protocol.md +0 -0
  343. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/contracts/rest-api.md +0 -0
  344. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/contracts/terminal-websocket.md +0 -0
  345. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/data-model.md +0 -0
  346. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/plan.md +0 -0
  347. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/quickstart.md +0 -0
  348. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/research.md +0 -0
  349. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/spec.md +0 -0
  350. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/010-web-session-interface/tasks.md +0 -0
  351. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/checklists/requirements.md +0 -0
  352. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/contracts/cli-web-adopt.md +0 -0
  353. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/contracts/setup-api.md +0 -0
  354. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/data-model.md +0 -0
  355. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/plan.md +0 -0
  356. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/quickstart-results.md +0 -0
  357. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/quickstart.md +0 -0
  358. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/research.md +0 -0
  359. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/spec.md +0 -0
  360. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/011-web-adopt/tasks.md +0 -0
  361. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/contracts/cli-web-adopt.md +0 -0
  362. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/contracts/pairing-api.md +0 -0
  363. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/contracts/setup-api.md +0 -0
  364. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/data-model.md +0 -0
  365. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/plan.md +0 -0
  366. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/quickstart.md +0 -0
  367. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/research.md +0 -0
  368. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/spec.md +0 -0
  369. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/012-web-adopt-pairing/tasks.md +0 -0
  370. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/013-managed-instance-tags/contracts/cli-sync.md +0 -0
  371. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/013-managed-instance-tags/contracts/marker-commands.md +0 -0
  372. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/013-managed-instance-tags/data-model.md +0 -0
  373. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/013-managed-instance-tags/plan.md +0 -0
  374. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/013-managed-instance-tags/quickstart.md +0 -0
  375. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/013-managed-instance-tags/research.md +0 -0
  376. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/013-managed-instance-tags/spec.md +0 -0
  377. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/013-managed-instance-tags/tasks.md +0 -0
  378. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/014-register-ssh-host/contracts/add-command.md +0 -0
  379. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/014-register-ssh-host/contracts/remove-command.md +0 -0
  380. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/014-register-ssh-host/data-model.md +0 -0
  381. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/014-register-ssh-host/plan.md +0 -0
  382. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/014-register-ssh-host/quickstart.md +0 -0
  383. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/014-register-ssh-host/research.md +0 -0
  384. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/014-register-ssh-host/spec.md +0 -0
  385. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/014-register-ssh-host/tasks.md +0 -0
  386. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/checklists/requirements.md +0 -0
  387. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/contracts/mirror-payload-v2.md +0 -0
  388. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/contracts/registry-accessor-api.md +0 -0
  389. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/contracts/registry-file-v2.md +0 -0
  390. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/data-model.md +0 -0
  391. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/plan.md +0 -0
  392. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/quickstart.md +0 -0
  393. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/research.md +0 -0
  394. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/spec.md +0 -0
  395. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/015-registry-v2/tasks.md +0 -0
  396. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/checklists/requirements.md +0 -0
  397. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/contracts/cli-sync.md +0 -0
  398. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/contracts/provider-probe.md +0 -0
  399. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/data-model.md +0 -0
  400. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/plan.md +0 -0
  401. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/quickstart.md +0 -0
  402. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/research.md +0 -0
  403. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/spec.md +0 -0
  404. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/016-sync-reconcile/tasks.md +0 -0
  405. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/checklists/requirements.md +0 -0
  406. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/contracts/cli-web-push.md +0 -0
  407. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/contracts/cli-web-status.md +0 -0
  408. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/contracts/revocation.md +0 -0
  409. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/contracts/setup-status-marker.md +0 -0
  410. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/data-model.md +0 -0
  411. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/plan.md +0 -0
  412. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/quickstart.md +0 -0
  413. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/research.md +0 -0
  414. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/spec.md +0 -0
  415. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/017-web-adopt-simplify/tasks.md +0 -0
  416. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/baseline-notes.md +0 -0
  417. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/checklists/requirements.md +0 -0
  418. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/contracts/cli-surface.md +0 -0
  419. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/contracts/errors.md +0 -0
  420. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/contracts/lifecycle-templates.md +0 -0
  421. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/contracts/provider-protocol.md +0 -0
  422. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/contracts/sync-merge.md +0 -0
  423. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/data-model.md +0 -0
  424. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/plan.md +0 -0
  425. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/quickstart.md +0 -0
  426. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/research.md +0 -0
  427. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/spec.md +0 -0
  428. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/018-provider-abstraction/tasks.md +0 -0
  429. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/checklists/requirements.md +0 -0
  430. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/contracts/cli-surface-delta.md +0 -0
  431. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/contracts/docs-structure-check.md +0 -0
  432. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/data-model.md +0 -0
  433. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/plan.md +0 -0
  434. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/quickstart.md +0 -0
  435. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/research.md +0 -0
  436. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/spec.md +0 -0
  437. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/019-hygiene-deps-docs/tasks.md +0 -0
  438. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/checklists/requirements.md +0 -0
  439. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/contracts/drift-checks.md +0 -0
  440. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/contracts/terminal-frames-v1.md +0 -0
  441. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/data-model.md +0 -0
  442. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/plan.md +0 -0
  443. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/quickstart.md +0 -0
  444. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/research.md +0 -0
  445. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/spec.md +0 -0
  446. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/020-openapi-type-generation/tasks.md +0 -0
  447. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/021-cli-plane-separation/contracts/cli-surface.md +0 -0
  448. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/021-cli-plane-separation/contracts/descriptor-schema.md +0 -0
  449. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/021-cli-plane-separation/data-model.md +0 -0
  450. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/021-cli-plane-separation/plan.md +0 -0
  451. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/021-cli-plane-separation/quickstart.md +0 -0
  452. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/021-cli-plane-separation/research.md +0 -0
  453. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/021-cli-plane-separation/spec.md +0 -0
  454. {remo_cli-3.1.0 → remo_cli-4.0.0}/specs/021-cli-plane-separation/tasks.md +0 -0
  455. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/__init__.py +0 -0
  456. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/__main__.py +0 -0
  457. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/cli/__init__.py +0 -0
  458. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/cli/added.py +0 -0
  459. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/cli/cp.py +0 -0
  460. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/cli/main.py +0 -0
  461. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/cli/providers/__init__.py +0 -0
  462. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/cli/web.py +0 -0
  463. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/__init__.py +0 -0
  464. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/ansible_runner.py +0 -0
  465. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/completion.py +0 -0
  466. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/config.py +0 -0
  467. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/errors.py +0 -0
  468. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/known_hosts.py +0 -0
  469. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/lifecycle.py +0 -0
  470. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/output.py +0 -0
  471. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/picker.py +0 -0
  472. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/provider_protocol.py +0 -0
  473. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/reconcile.py +0 -0
  474. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/remo_host_client.py +0 -0
  475. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/rsync.py +0 -0
  476. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/snapshot.py +0 -0
  477. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/ssh.py +0 -0
  478. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/validation.py +0 -0
  479. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/version.py +0 -0
  480. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/core/web_drift.py +0 -0
  481. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/models/__init__.py +0 -0
  482. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/models/capability.py +0 -0
  483. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/models/discovery.py +0 -0
  484. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/models/host.py +0 -0
  485. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/models/session_target.py +0 -0
  486. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/models/snapshot.py +0 -0
  487. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/__init__.py +0 -0
  488. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/added.py +0 -0
  489. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/aws.py +0 -0
  490. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/aws_descriptor.py +0 -0
  491. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/builtin.py +0 -0
  492. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/hetzner_descriptor.py +0 -0
  493. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/providers/incus_descriptor.py +0 -0
  494. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/__init__.py +0 -0
  495. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/api/__init__.py +0 -0
  496. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/api/pairing.py +0 -0
  497. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/api/setup.py +0 -0
  498. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/api/terminals.py +0 -0
  499. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/check.py +0 -0
  500. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/config.py +0 -0
  501. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/frames.py +0 -0
  502. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/health.py +0 -0
  503. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/logging_config.py +0 -0
  504. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/models.py +0 -0
  505. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/operator_auth.py +0 -0
  506. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/pairing.py +0 -0
  507. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/ssh_master.py +0 -0
  508. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/state.py +0 -0
  509. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/terminal.py +0 -0
  510. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/terminal_registry.py +0 -0
  511. {remo_cli-3.1.0 → remo_cli-4.0.0}/src/remo_cli/web/tokens.py +0 -0
  512. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/__init__.py +0 -0
  513. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/ansible/__init__.py +0 -0
  514. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/ansible/test_remo_host_idempotency.py +0 -0
  515. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/conftest.py +0 -0
  516. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/e2e/mobile.spec.ts +0 -0
  517. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/e2e/reconnect.spec.ts +0 -0
  518. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/e2e/workspace-layout.spec.ts +0 -0
  519. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/image/__init__.py +0 -0
  520. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/image/test_docker_image.py +0 -0
  521. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/__init__.py +0 -0
  522. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/_nine_terminal_fixture.py +0 -0
  523. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/fish_completion.sh +0 -0
  524. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/orbstack-cloud-init.yml +0 -0
  525. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/orbstack.sh +0 -0
  526. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_nine_terminals.py +0 -0
  527. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_nine_terminals_soak.py +0 -0
  528. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_registry_concurrency.py +0 -0
  529. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_remo_host_e2e.py +0 -0
  530. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_security_rejections.py +0 -0
  531. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_setup_payload_versions.py +0 -0
  532. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_sync_reconcile.py +0 -0
  533. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_terminal_attach.py +0 -0
  534. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_web_adopt_e2e.py +0 -0
  535. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/integration/test_web_cli_parity.py +0 -0
  536. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/perf/__init__.py +0 -0
  537. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/perf/test_latency.py +0 -0
  538. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/perf/test_registry_perf.py +0 -0
  539. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/__init__.py +0 -0
  540. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/__init__.py +0 -0
  541. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/providers/test_aws_snapshot.py +0 -0
  542. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/providers/test_hetzner_snapshot.py +0 -0
  543. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/providers/test_incus_snapshot.py +0 -0
  544. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/providers/test_incus_sync_all.py +0 -0
  545. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/providers/test_proxmox_snapshot.py +0 -0
  546. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_add_cmd.py +0 -0
  547. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_cli_uniformity.py +0 -0
  548. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_cp.py +0 -0
  549. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_main.py +0 -0
  550. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_remove_cmd.py +0 -0
  551. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_shell.py +0 -0
  552. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_shell_added.py +0 -0
  553. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_startup_imports.py +0 -0
  554. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_surface_preservation.py +0 -0
  555. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/cli/test_web_adopt_cmd.py +0 -0
  556. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/__init__.py +0 -0
  557. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_ansible_runner.py +0 -0
  558. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_completion.py +0 -0
  559. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_config.py +0 -0
  560. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_errors.py +0 -0
  561. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_known_hosts.py +0 -0
  562. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_lifecycle.py +0 -0
  563. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_migration_tagging_notice.py +0 -0
  564. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_output.py +0 -0
  565. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_picker.py +0 -0
  566. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_provider_registry.py +0 -0
  567. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_reconcile.py +0 -0
  568. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_registry_format.py +0 -0
  569. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_registry_locking.py +0 -0
  570. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_remo_host_client.py +0 -0
  571. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_rsync.py +0 -0
  572. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_snapshot.py +0 -0
  573. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_ssh.py +0 -0
  574. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_ssh_added.py +0 -0
  575. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_ssh_controlpath.py +0 -0
  576. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_ssh_identity_opts.py +0 -0
  577. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_validation.py +0 -0
  578. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_version.py +0 -0
  579. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_web_adopt_authorize.py +0 -0
  580. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_web_adopt_code.py +0 -0
  581. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_web_adopt_payload.py +0 -0
  582. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_web_adopt_trust.py +0 -0
  583. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_web_drift.py +0 -0
  584. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/core/test_web_push.py +0 -0
  585. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/models/__init__.py +0 -0
  586. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/models/test_capability.py +0 -0
  587. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/models/test_discovery.py +0 -0
  588. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/models/test_session_target.py +0 -0
  589. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/__init__.py +0 -0
  590. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/fake_provider.py +0 -0
  591. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_added_add.py +0 -0
  592. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_added_provider_guard.py +0 -0
  593. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_added_update_remove.py +0 -0
  594. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_added_verify.py +0 -0
  595. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_aws_provider_protocol.py +0 -0
  596. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_aws_snapshot.py +0 -0
  597. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_aws_sync.py +0 -0
  598. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_aws_upgrade_resize.py +0 -0
  599. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_hetzner_entry_adapters.py +0 -0
  600. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_hetzner_http.py +0 -0
  601. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_hetzner_label.py +0 -0
  602. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_hetzner_resize.py +0 -0
  603. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_hetzner_snapshot.py +0 -0
  604. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_hetzner_sync.py +0 -0
  605. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_incus_entry_adapters.py +0 -0
  606. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_incus_marker.py +0 -0
  607. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_incus_resize.py +0 -0
  608. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_incus_snapshot.py +0 -0
  609. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_incus_sync.py +0 -0
  610. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_missing_sdk.py +0 -0
  611. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_provider_conformance.py +0 -0
  612. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/providers/test_proxmox_devcontainer_runtime.py +0 -0
  613. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/test_ansible_templates.py +0 -0
  614. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/test_architecture.py +0 -0
  615. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/test_docs_structure.py +0 -0
  616. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/test_host_model.py +0 -0
  617. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/test_host_ssh_type.py +0 -0
  618. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/test_schema_drift.py +0 -0
  619. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/__init__.py +0 -0
  620. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/_pairing_support.py +0 -0
  621. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/conftest.py +0 -0
  622. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/fixtures/hosts_response.json +0 -0
  623. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/fixtures/sessions_response.json +0 -0
  624. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_backpressure.py +0 -0
  625. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_check.py +0 -0
  626. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_discovery.py +0 -0
  627. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_frames.py +0 -0
  628. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_health_states.py +0 -0
  629. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_hosts_mapping.py +0 -0
  630. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_lazy_import.py +0 -0
  631. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_log_redaction.py +0 -0
  632. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_mint_gating.py +0 -0
  633. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_operator_auth.py +0 -0
  634. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_pairing.py +0 -0
  635. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_pairing_origin.py +0 -0
  636. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_payload_equivalence.py +0 -0
  637. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_registry_readonly.py +0 -0
  638. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_setup_api.py +0 -0
  639. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_setup_auth.py +0 -0
  640. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_setup_dormancy.py +0 -0
  641. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_state.py +0 -0
  642. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_terminal_resize.py +0 -0
  643. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_terminals_api.py +0 -0
  644. {remo_cli-3.1.0 → remo_cli-4.0.0}/tests/unit/web/test_tokens.py +0 -0
@@ -27,6 +27,16 @@
27
27
  "remoteEnv": {
28
28
  "GH_PAGER": ""
29
29
  },
30
+ "containerEnv": {
31
+ // Put Claude Code's config INSIDE the mounted ~/.claude directory.
32
+ // By default the config lives at ~/.claude.json, OUTSIDE that mount, so
33
+ // every container starts unauthenticated even though .credentials.json is
34
+ // shared. Bind-mounting the file directly does not work: a file bind pins
35
+ // to the inode, so the first atomic rewrite orphans the container's view
36
+ // and silently discards writes. Relocating into the directory mount avoids
37
+ // that entirely and shares auth across every devcontainer on the host.
38
+ "CLAUDE_CONFIG_DIR": "/home/vscode/.claude"
39
+ },
30
40
  "customizations": {
31
41
  "vscode": {
32
42
  "settings": {
@@ -43,6 +43,7 @@ jobs:
43
43
  private-key: ${{ secrets.RELEASE_PLEASE_APP_KEY }}
44
44
 
45
45
  - uses: googleapis/release-please-action@v4
46
+ id: release
46
47
  with:
47
48
  # Token precedence:
48
49
  # 1. GitHub App installation token (recommended — see above).
@@ -55,3 +56,39 @@ jobs:
55
56
  token: ${{ steps.app-token.outputs.token || secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
56
57
  config-file: release-please-config.json
57
58
  manifest-file: .release-please-manifest.json
59
+
60
+ # release-please bumps `pyproject.toml` but knows nothing about uv.lock,
61
+ # which records the project's own version in its `remo-cli` package entry.
62
+ # Left alone the two drift apart at every release (3.1.0 shipped with a
63
+ # lockfile still saying 3.0.0), and the drift then reappears as noise in
64
+ # the next unrelated PR, because any `uv run` regenerates it.
65
+ #
66
+ # Amend the sync onto the release PR itself. release-please force-pushes
67
+ # its branch whenever it refreshes the PR, which would drop this commit —
68
+ # but this job runs immediately after that refresh on every push to main,
69
+ # so the commit is simply re-made. `tests/unit/test_lockfile_version.py`
70
+ # is the backstop that keeps a drifted lockfile from merging at all.
71
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
72
+ if: ${{ steps.release.outputs.pr }}
73
+
74
+ - name: Sync uv.lock onto the release PR
75
+ if: ${{ steps.release.outputs.pr }}
76
+ env:
77
+ RELEASE_BRANCH: ${{ fromJSON(steps.release.outputs.pr).headBranchName }}
78
+ GH_TOKEN: ${{ steps.app-token.outputs.token || secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
79
+ run: |
80
+ set -euo pipefail
81
+ git clone --branch "$RELEASE_BRANCH" --depth 1 \
82
+ "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" release-pr
83
+ cd release-pr
84
+ # `uv lock` is not an upgrade: it re-resolves only what the manifest
85
+ # forces, so the sole change here is the bumped project version.
86
+ uv lock
87
+ if git diff --quiet -- uv.lock; then
88
+ echo "uv.lock already matches the bumped version; nothing to do."
89
+ exit 0
90
+ fi
91
+ git config user.name "github-actions[bot]"
92
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
93
+ git commit -m "chore: sync uv.lock with the released version" -- uv.lock
94
+ git push origin "HEAD:${RELEASE_BRANCH}"
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "4.0.0"
3
+ }
@@ -26,13 +26,13 @@ Principles I, IV, and VIII are machine-enforced — see [Quality Gates](#quality
26
26
  - Python 3.11+ + Click (CLI framework), InquirerPy (interactive picker), boto3 (unconditional runtime dependency, used by the CLI's own lazy `import boto3` in `providers/aws.py` and by the Ansible `amazon.aws`/`community.aws` collections), hcloud (unconditional runtime dependency, consumed by the Ansible layer, not the CLI's own Python code) (003-python-cli-rewrite)
27
27
  - Versioned JSON registry (`~/.config/remo/registry.json`, format v2 — named fields per type, no positional overloading; single accessor `core/registry.py` owns parse/serialize/validate/lock/migrate for CLI, providers, and the web service). Legacy `~/.config/remo/known_hosts` (colon-delimited) is read-only migration input, lazily migrated to v2 on first CLI read and renamed to `known_hosts.v1.bak`. (003-python-cli-rewrite; superseded by 015-registry-v2)
28
28
  - Cross-provider snapshot model (`models/snapshot.py`) + shared helpers in `core/snapshot.py` (name generator, validator, table formatter, destroy-time cleanup hook). No new runtime deps. (005-provider-snapshots)
29
- - FastAPI/Uvicorn + WebSockets (backend, optional `web` extra), TypeScript/Vite/React + ghostty-web (frontend), Bash (`remo-host` host command templated by Ansible) (010-web-session-interface)
29
+ - FastAPI/Uvicorn + WebSockets (backend, optional `web` extra), TypeScript/Vite/React + xterm.js (frontend), Bash (`remo-host` host command templated by Ansible) (010-web-session-interface)
30
30
  - Stdlib `urllib.request` CLI setup client + token-gated `/api/v1/setup/*` FastAPI surface; service state in flat files under the writable `REMO_HOME` volume (`web-identity/` keypair + service known_hosts, `~/.config/remo/web-service.json` saved credentials, `cache_version: 2`) (011-web-adopt; payload versioning updated by 015-registry-v2)
31
31
  - `core/registry.py`: stdlib `json` (format), `fcntl` (advisory locking via a `registry.lock` sidecar), `os.replace` (atomic writes). No new runtime deps. Setup API mirror payload moved to v2 (`contracts/mirror-payload-v2.md`) with a `payload_versions` capability handshake; an upgraded service still accepts v1 payloads. (015-registry-v2)
32
32
  - `core/reconcile.py`: provider-agnostic sync-reconcile engine (`SyncScope`, `DiscoveredHost`, `ProbeResult`, `build_plan` (pure), `render_plan`, the consent gate, `apply_plan` via the existing `mutate_registry()`, and the `run_sync` driver). No new runtime deps — stdlib only, built on `core/registry.py`/`core/output.py` as-is. (016-sync-reconcile)
33
33
  - `core/web_adopt.py` is now the single unified push engine (`run_push`; `run_adopt` is a thin deprecated alias) — first push adopts, later pushes re-sync, plus best-effort `remo-web@` revocation on removal, `--force` full re-authorization, and multi-workstation flap detection against the service's mirror-generation marker. `core/web_drift.py`: new stdlib-only offline registry-vs-push-cache diff (`diff_registry_against_cache`, `select_deployment`, `render_drift`) powering `remo web status` and the shared `out_of_date_notice()`/`emit_out_of_date_notice()` post-mutation nudge (importable without the `web` extra). Push cache bumped to `cache_version: 3` (`~/.config/remo/web-service.json`: per-deployment `{mirror_generation, instances}`, each instance retaining a non-secret connection tuple for revocation). Service side: `web/api/setup.py` writes/serves a `web-identity/mirror-meta.json` marker (generation + last-push descriptor) additively on `/setup/{status,registry}`; `web/state.py` mode detection fixed so a personal `~/.ssh/id_*` no longer forces `mount_configured` (non-writable `REMO_HOME` is the authoritative signal) with a new `REMO_WEB_MODE` override in `web/config.py`. No new runtime deps; no registry schema change. (017-web-adopt-simplify)
34
34
  - No new runtime deps or registry schema change. `pyproject.toml`'s existing `hcloud`/`boto3`/`httpx2` entries gained consumer-attribution comments; `tests/unit/test_docs_structure.py` is a new stdlib-only pytest module (parses the structure diagram below, no new dependency). (019-hygiene-deps-docs)
35
- - No new runtime deps; no registry schema change (the `host_user`/`node_user` JSON keys already matched the new flag spellings). `core/provider_registry.py` gains `ArgumentSpec` (positional-argument metadata) and `CommandSpec.target`; `ProviderDescriptor.update_options` is replaced by `upgrade_options`/`resize_dimensions`/`resize_options`/`tag_options`/`host_commands`. `cli/providers/factory.py` gains `_build_upgrade`/`_build_resize`/`_build_tag`/`_build_host_group` (dropping `_build_update` and flat-mounted `bootstrap`). (021-cli-plane-separation)
35
+ - No new runtime deps; no registry schema change (the `host_user`/`node_user` JSON keys already matched the new flag spellings). Superseded for Proxmox by the `--node-user` → `--host-user` rename: both host-scoped providers now spell the node/host login `--host-user`/`host_user` on the CLI, in the provider kwargs and in `registry.json`; `core/registry.py` still reads a legacy `proxmox.node_user` key so pre-rename registries load unchanged and migrate on the next write. `core/provider_registry.py` gains `ArgumentSpec` (positional-argument metadata) and `CommandSpec.target`; `ProviderDescriptor.update_options` is replaced by `upgrade_options`/`resize_dimensions`/`resize_options`/`tag_options`/`host_commands`. `cli/providers/factory.py` gains `_build_upgrade`/`_build_resize`/`_build_tag`/`_build_host_group` (dropping `_build_update` and flat-mounted `bootstrap`). (021-cli-plane-separation)
36
36
 
37
37
  - Ansible 2.14+ / YAML + `ansible.builtin`, `community.general` (for zypper module) (001-bootstrap-incus-host)
38
38
  - Formal provider abstraction: `core/provider_registry.py` (`ProviderDescriptor`/`OptionSpec`/`CommandSpec`/`ConnectionSpec` + registry), `core/provider_protocol.py` (`Provider` Protocol), `core/errors.py` (typed taxonomy: `ProviderError`/`MissingDependencyError`/`PreconditionError`/`OperationFailedError`/`UserAbortedError`), `core/lifecycle.py` (shared `run_destroy` template), `cli/providers/factory.py` (generates all four provider CLI groups from descriptors). No new runtime deps. (018-provider-abstraction)
@@ -76,7 +76,7 @@ src/remo_cli/ # Python CLI package (src layout, hatchling build)
76
76
  │ ├── ssh.py # build_ssh_base_cmd(), SSH options, terminal reset, timezone; SSM ProxyCommand construction lives behind descriptor.connection.proxy_hook (AWS: providers/aws.py:ssh_proxy_hook), not hardcoded here
77
77
  │ ├── reconcile.py # SyncScope/DiscoveredHost/build_plan/run_sync; DiscoveredHost.observed (frozenset[str] | None) + observed-aware merge_entry (closes #87 — a provider-filled default never clobbers a hand-edited registry value); SyncScope validation/scoping driven by descriptor name_format + is_provider_type, no literal type tuples
78
78
  │ ├── remo_host_client.py # Versioned remo-host protocol client (shared by CLI + web)
79
- │ ├── web_adopt.py # Unified workstation push engine: run_push (adopt-or-resync), run_adopt alias, keyscan trust verify, authorized_keys authorize + best-effort revoke, --force, flap detection, push cache v3, --via tunnel (stdlib HTTP)
79
+ │ ├── web_adopt.py # Unified workstation push engine: run_push (adopt-or-resync), run_adopt alias, keyscan trust verify, authorized_keys authorize + best-effort revoke, verification-driven self-heal of `unchanged` instances that verify auth_failed (#122), --force, flap detection, push cache v3, --via tunnel (stdlib HTTP)
80
80
  │ ├── web_drift.py # Offline registry-vs-push-cache diff + shared out-of-date nudge (stdlib + core/models only; no web extra)
81
81
  │ ├── ansible_runner.py # Ansible playbook subprocess; build_configure_extra_vars() (timezone+tools+version, replaces 8 inline copies) and run_resize_playbook() (raises OperationFailedError on nonzero rc)
82
82
  │ ├── snapshot.py # Name generation/validation/table formatting; list_all_snapshots(type_name, lister) aggregates across a provider's registry slice (replaces 4 CLI-layer loops)
@@ -118,8 +118,7 @@ frontend/ # remo-web browser SPA (Vite + React + TypeScript)
118
118
  │ ├── api/client.ts # REST + WS terminal client (remo-terminal.v1 subprotocol)
119
119
  │ ├── components/ # Dashboard, InstanceGroup, TargetCard, GridView, TabView, TerminalCard
120
120
  │ ├── state/ # discovery.ts, workspace.ts (layout persisted to localStorage)
121
- │ └── terminal/ # RendererAdapter, GhosttyRenderer (default), XtermRenderer (fallback)
122
- └── public/ # Same-origin-served ghostty-web WASM asset
121
+ │ └── terminal/ # RendererAdapter (seam), XtermRenderer (the one engine), TerminalConnection, keymap
123
122
 
124
123
  docker/ # remo-web container packaging (010-web-session-interface, US4)
125
124
  ├── Dockerfile # multi-stage: frontend build -> wheel build -> slim Python runtime
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.0.0](https://github.com/get2knowio/remo/compare/v3.1.0...v4.0.0) (2026-08-03)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * **web:** drop the ghostty-web renderer, leaving xterm.js as the engine ([#130](https://github.com/get2knowio/remo/issues/130))
9
+ * **providers:** `remo proxmox`'s `--node-user` flag is now `--host-user`, on every verb that took it (create, upgrade, resize, tag, destroy, sync, info, host bootstrap). Scripts passing `--node-user` will fail with a Click "no such option" error naming the new spelling. Separately, a container whose registry entry has no recorded host user is now reached via ssh_config rather than as root — matching how create reached it.
10
+
11
+ ### Features
12
+
13
+ * **web:** give the console a light/dark mode and selectable terminal themes ([#129](https://github.com/get2knowio/remo/issues/129)) ([7905c4b](https://github.com/get2knowio/remo/commit/7905c4b4f4d94403cc4a48c7a9858776774bf47c))
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * **ansible:** stop provisioning failing when GitHub rate-limits the zellij lookup ([#132](https://github.com/get2knowio/remo/issues/132)) ([cda5d0b](https://github.com/get2knowio/remo/commit/cda5d0b748bc90bb685b28510645d4fe29c35061))
19
+ * **ansible:** survive the SSM reconnect after the UID-1000 swap ([#133](https://github.com/get2knowio/remo/issues/133)) ([1a76f92](https://github.com/get2knowio/remo/commit/1a76f92107e3bd6fb7bfce60e51a0d284a0f4dcf))
20
+ * **devcontainer:** point CLAUDE_CONFIG_DIR at the mounted ~/.claude ([#125](https://github.com/get2knowio/remo/issues/125)) ([b9da45d](https://github.com/get2knowio/remo/commit/b9da45ddc4ed6f513a895e54de9e2e0dd16fe436))
21
+ * **providers:** spell the Proxmox node login `--host-user`, and record it honestly ([#124](https://github.com/get2knowio/remo/issues/124)) ([830d4d6](https://github.com/get2knowio/remo/commit/830d4d65ecab5c9e78b019323b3ad8b9d926f474)), closes [#106](https://github.com/get2knowio/remo/issues/106) [#107](https://github.com/get2knowio/remo/issues/107)
22
+ * **release:** keep uv.lock's version in step with the release bump ([#126](https://github.com/get2knowio/remo/issues/126)) ([137fa55](https://github.com/get2knowio/remo/commit/137fa55dead73c2da07037d22480e788332f9bb3))
23
+ * unwedge apt, stop authorized_keys being clobbered, and self-heal `remo web push` ([#123](https://github.com/get2knowio/remo/issues/123)) ([679fab9](https://github.com/get2knowio/remo/commit/679fab9f84b90fa33d3ef6eb2f58e568430c9fd9))
24
+ * **web:** make the console's background poll actually re-run discovery ([#128](https://github.com/get2knowio/remo/issues/128)) ([6d18d37](https://github.com/get2knowio/remo/commit/6d18d374023b2d6f1dccf4535016d00bfde92b12))
25
+ * **web:** recover from an expired access-proxy session without a manual reload ([#131](https://github.com/get2knowio/remo/issues/131)) ([3ce3e8e](https://github.com/get2knowio/remo/commit/3ce3e8ea9c1ab3c568b128356e5884631465df9f))
26
+
27
+
28
+ ### Code Refactoring
29
+
30
+ * **web:** drop the ghostty-web renderer, leaving xterm.js as the engine ([#130](https://github.com/get2knowio/remo/issues/130)) ([c3e9170](https://github.com/get2knowio/remo/commit/c3e917044c756e1138817b70380177d636824ab2))
31
+
3
32
  ## [3.1.0](https://github.com/get2knowio/remo/compare/v3.0.0...v3.1.0) (2026-07-29)
4
33
 
5
34
 
@@ -26,13 +26,13 @@ Principles I, IV, and VIII are machine-enforced — see [Quality Gates](#quality
26
26
  - Python 3.11+ + Click (CLI framework), InquirerPy (interactive picker), boto3 (unconditional runtime dependency, used by the CLI's own lazy `import boto3` in `providers/aws.py` and by the Ansible `amazon.aws`/`community.aws` collections), hcloud (unconditional runtime dependency, consumed by the Ansible layer, not the CLI's own Python code) (003-python-cli-rewrite)
27
27
  - Versioned JSON registry (`~/.config/remo/registry.json`, format v2 — named fields per type, no positional overloading; single accessor `core/registry.py` owns parse/serialize/validate/lock/migrate for CLI, providers, and the web service). Legacy `~/.config/remo/known_hosts` (colon-delimited) is read-only migration input, lazily migrated to v2 on first CLI read and renamed to `known_hosts.v1.bak`. (003-python-cli-rewrite; superseded by 015-registry-v2)
28
28
  - Cross-provider snapshot model (`models/snapshot.py`) + shared helpers in `core/snapshot.py` (name generator, validator, table formatter, destroy-time cleanup hook). No new runtime deps. (005-provider-snapshots)
29
- - FastAPI/Uvicorn + WebSockets (backend, optional `web` extra), TypeScript/Vite/React + ghostty-web (frontend), Bash (`remo-host` host command templated by Ansible) (010-web-session-interface)
29
+ - FastAPI/Uvicorn + WebSockets (backend, optional `web` extra), TypeScript/Vite/React + xterm.js (frontend), Bash (`remo-host` host command templated by Ansible) (010-web-session-interface)
30
30
  - Stdlib `urllib.request` CLI setup client + token-gated `/api/v1/setup/*` FastAPI surface; service state in flat files under the writable `REMO_HOME` volume (`web-identity/` keypair + service known_hosts, `~/.config/remo/web-service.json` saved credentials, `cache_version: 2`) (011-web-adopt; payload versioning updated by 015-registry-v2)
31
31
  - `core/registry.py`: stdlib `json` (format), `fcntl` (advisory locking via a `registry.lock` sidecar), `os.replace` (atomic writes). No new runtime deps. Setup API mirror payload moved to v2 (`contracts/mirror-payload-v2.md`) with a `payload_versions` capability handshake; an upgraded service still accepts v1 payloads. (015-registry-v2)
32
32
  - `core/reconcile.py`: provider-agnostic sync-reconcile engine (`SyncScope`, `DiscoveredHost`, `ProbeResult`, `build_plan` (pure), `render_plan`, the consent gate, `apply_plan` via the existing `mutate_registry()`, and the `run_sync` driver). No new runtime deps — stdlib only, built on `core/registry.py`/`core/output.py` as-is. (016-sync-reconcile)
33
33
  - `core/web_adopt.py` is now the single unified push engine (`run_push`; `run_adopt` is a thin deprecated alias) — first push adopts, later pushes re-sync, plus best-effort `remo-web@` revocation on removal, `--force` full re-authorization, and multi-workstation flap detection against the service's mirror-generation marker. `core/web_drift.py`: new stdlib-only offline registry-vs-push-cache diff (`diff_registry_against_cache`, `select_deployment`, `render_drift`) powering `remo web status` and the shared `out_of_date_notice()`/`emit_out_of_date_notice()` post-mutation nudge (importable without the `web` extra). Push cache bumped to `cache_version: 3` (`~/.config/remo/web-service.json`: per-deployment `{mirror_generation, instances}`, each instance retaining a non-secret connection tuple for revocation). Service side: `web/api/setup.py` writes/serves a `web-identity/mirror-meta.json` marker (generation + last-push descriptor) additively on `/setup/{status,registry}`; `web/state.py` mode detection fixed so a personal `~/.ssh/id_*` no longer forces `mount_configured` (non-writable `REMO_HOME` is the authoritative signal) with a new `REMO_WEB_MODE` override in `web/config.py`. No new runtime deps; no registry schema change. (017-web-adopt-simplify)
34
34
  - No new runtime deps or registry schema change. `pyproject.toml`'s existing `hcloud`/`boto3`/`httpx2` entries gained consumer-attribution comments; `tests/unit/test_docs_structure.py` is a new stdlib-only pytest module (parses the structure diagram below, no new dependency). (019-hygiene-deps-docs)
35
- - No new runtime deps; no registry schema change (the `host_user`/`node_user` JSON keys already matched the new flag spellings). `core/provider_registry.py` gains `ArgumentSpec` (positional-argument metadata) and `CommandSpec.target`; `ProviderDescriptor.update_options` is replaced by `upgrade_options`/`resize_dimensions`/`resize_options`/`tag_options`/`host_commands`. `cli/providers/factory.py` gains `_build_upgrade`/`_build_resize`/`_build_tag`/`_build_host_group` (dropping `_build_update` and flat-mounted `bootstrap`). (021-cli-plane-separation)
35
+ - No new runtime deps; no registry schema change (the `host_user`/`node_user` JSON keys already matched the new flag spellings). Superseded for Proxmox by the `--node-user` → `--host-user` rename: both host-scoped providers now spell the node/host login `--host-user`/`host_user` on the CLI, in the provider kwargs and in `registry.json`; `core/registry.py` still reads a legacy `proxmox.node_user` key so pre-rename registries load unchanged and migrate on the next write. `core/provider_registry.py` gains `ArgumentSpec` (positional-argument metadata) and `CommandSpec.target`; `ProviderDescriptor.update_options` is replaced by `upgrade_options`/`resize_dimensions`/`resize_options`/`tag_options`/`host_commands`. `cli/providers/factory.py` gains `_build_upgrade`/`_build_resize`/`_build_tag`/`_build_host_group` (dropping `_build_update` and flat-mounted `bootstrap`). (021-cli-plane-separation)
36
36
 
37
37
  - Ansible 2.14+ / YAML + `ansible.builtin`, `community.general` (for zypper module) (001-bootstrap-incus-host)
38
38
  - Formal provider abstraction: `core/provider_registry.py` (`ProviderDescriptor`/`OptionSpec`/`CommandSpec`/`ConnectionSpec` + registry), `core/provider_protocol.py` (`Provider` Protocol), `core/errors.py` (typed taxonomy: `ProviderError`/`MissingDependencyError`/`PreconditionError`/`OperationFailedError`/`UserAbortedError`), `core/lifecycle.py` (shared `run_destroy` template), `cli/providers/factory.py` (generates all four provider CLI groups from descriptors). No new runtime deps. (018-provider-abstraction)
@@ -76,7 +76,7 @@ src/remo_cli/ # Python CLI package (src layout, hatchling build)
76
76
  │ ├── ssh.py # build_ssh_base_cmd(), SSH options, terminal reset, timezone; SSM ProxyCommand construction lives behind descriptor.connection.proxy_hook (AWS: providers/aws.py:ssh_proxy_hook), not hardcoded here
77
77
  │ ├── reconcile.py # SyncScope/DiscoveredHost/build_plan/run_sync; DiscoveredHost.observed (frozenset[str] | None) + observed-aware merge_entry (closes #87 — a provider-filled default never clobbers a hand-edited registry value); SyncScope validation/scoping driven by descriptor name_format + is_provider_type, no literal type tuples
78
78
  │ ├── remo_host_client.py # Versioned remo-host protocol client (shared by CLI + web)
79
- │ ├── web_adopt.py # Unified workstation push engine: run_push (adopt-or-resync), run_adopt alias, keyscan trust verify, authorized_keys authorize + best-effort revoke, --force, flap detection, push cache v3, --via tunnel (stdlib HTTP)
79
+ │ ├── web_adopt.py # Unified workstation push engine: run_push (adopt-or-resync), run_adopt alias, keyscan trust verify, authorized_keys authorize + best-effort revoke, verification-driven self-heal of `unchanged` instances that verify auth_failed (#122), --force, flap detection, push cache v3, --via tunnel (stdlib HTTP)
80
80
  │ ├── web_drift.py # Offline registry-vs-push-cache diff + shared out-of-date nudge (stdlib + core/models only; no web extra)
81
81
  │ ├── ansible_runner.py # Ansible playbook subprocess; build_configure_extra_vars() (timezone+tools+version, replaces 8 inline copies) and run_resize_playbook() (raises OperationFailedError on nonzero rc)
82
82
  │ ├── snapshot.py # Name generation/validation/table formatting; list_all_snapshots(type_name, lister) aggregates across a provider's registry slice (replaces 4 CLI-layer loops)
@@ -117,9 +117,9 @@ frontend/ # remo-web browser SPA (Vite + React + TypeScript)
117
117
  ├── src/
118
118
  │ ├── api/client.ts # REST + WS terminal client (remo-terminal.v1 subprotocol)
119
119
  │ ├── components/ # Dashboard, InstanceGroup, TargetCard, GridView, TabView, TerminalCard
120
- │ ├── state/ # discovery.ts, workspace.ts (layout persisted to localStorage)
121
- │ └── terminal/ # RendererAdapter, GhosttyRenderer (default), XtermRenderer (fallback)
122
- └── public/ # Same-origin-served ghostty-web WASM asset
120
+ │ ├── state/ # discovery.ts, workspace.ts (layout persisted to localStorage), settings.ts (display prefs: site light/dark mode, accent, fonts, terminal theme + per-target overrides)
121
+ │ ├── terminal/ # RendererAdapter (seam), XtermRenderer (the one engine), TerminalConnection, keymap
122
+ │ └── theme/ # tokens.css (light-dark() palette, one pair per token), fonts.ts, terminalThemes.ts (8 terminal color schemes: a token-derived Remo Dark/Light pair the default 'auto' selection tracks, plus 6 curated third-party)
123
123
 
124
124
  docker/ # remo-web container packaging (010-web-session-interface, US4)
125
125
  ├── Dockerfile # multi-stage: frontend build -> wheel build -> slim Python runtime
@@ -148,9 +148,12 @@ curl -fsSL https://get2knowio.github.io/remo/install.sh | bash
148
148
  >
149
149
  > See `.github/workflows/release-please.yml`.
150
150
  >
151
- > **Note:** release-please does not run `uv lock`; if `uv.lock`'s recorded
152
- > project version matters to you, run `uv lock` and amend it onto the release PR
153
- > before merging.
151
+ > **`uv.lock` is synced for you.** release-please bumps `pyproject.toml` but
152
+ > knows nothing about `uv.lock`, which records the project's own version too.
153
+ > The workflow now runs `uv lock` against the release branch and commits the
154
+ > result onto the release PR, and `tests/unit/test_lockfile_version.py` fails
155
+ > the build if the two ever disagree — so a drifted lockfile can't merge. If
156
+ > that test does fire, the fix is `uv lock` plus a commit.
154
157
 
155
158
  ### Version Numbering
156
159
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remo-cli
3
- Version: 3.1.0
3
+ Version: 4.0.0
4
4
  Summary: Remote development environment CLI
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -375,7 +375,7 @@ remo proxmox sync --host <node> # Reconcile registry with remo-managed conta
375
375
  remo proxmox sync --host <node> --all # Also adopt non-remo containers on the node
376
376
  remo proxmox sync --host <node> --yes # Skip the removal confirmation
377
377
  remo proxmox sync --host <node> --dry-run # Preview the plan, change nothing
378
- remo proxmox upgrade <n> [--host H] [--node-user U] # Update dev tools
378
+ remo proxmox upgrade <n> [--host H] [--host-user U] # Update dev tools
379
379
  remo proxmox resize <n> --volume-size 40 --cores 4 --memory 4096
380
380
  remo proxmox tag <n> # Mark as remo-managed
381
381
  remo proxmox destroy --name <n> [--yes] [--purge] # Destroy container
@@ -349,7 +349,7 @@ remo proxmox sync --host <node> # Reconcile registry with remo-managed conta
349
349
  remo proxmox sync --host <node> --all # Also adopt non-remo containers on the node
350
350
  remo proxmox sync --host <node> --yes # Skip the removal confirmation
351
351
  remo proxmox sync --host <node> --dry-run # Preview the plan, change nothing
352
- remo proxmox upgrade <n> [--host H] [--node-user U] # Update dev tools
352
+ remo proxmox upgrade <n> [--host H] [--host-user U] # Update dev tools
353
353
  remo proxmox resize <n> --volume-size 40 --cores 4 --memory 4096
354
354
  remo proxmox tag <n> # Mark as remo-managed
355
355
  remo proxmox destroy --name <n> [--yes] [--purge] # Destroy container
@@ -72,6 +72,12 @@
72
72
  delay: 10
73
73
  until: apt_lock_result.rc | default(1) == 0
74
74
 
75
+ # Unwedge apt before the first apt call: a sources line naming a keyring
76
+ # that no longer exists makes apt refuse to read ANY source list, which
77
+ # would fail the cache update below and leave the host unrepairable (#120).
78
+ - name: Repair apt sources referencing a missing keyring
79
+ ansible.builtin.include_tasks: tasks/repair_apt_sources.yml
80
+
75
81
  - name: Update apt cache
76
82
  ansible.builtin.apt:
77
83
  update_cache: true
@@ -53,6 +53,12 @@
53
53
  delay: 10
54
54
  until: apt_lock_result.rc | default(1) == 0
55
55
 
56
+ # Unwedge apt before the first apt call: a sources line naming a keyring
57
+ # that no longer exists makes apt refuse to read ANY source list, which
58
+ # would fail the cache update below and leave the host unrepairable (#120).
59
+ - name: Repair apt sources referencing a missing keyring
60
+ ansible.builtin.include_tasks: tasks/repair_apt_sources.yml
61
+
56
62
  - name: Update apt cache
57
63
  ansible.builtin.apt:
58
64
  update_cache: true
@@ -33,6 +33,12 @@
33
33
  delay: 10
34
34
  until: apt_lock_result.rc | default(1) == 0
35
35
 
36
+ # Unwedge apt before the first apt call: a sources line naming a keyring
37
+ # that no longer exists makes apt refuse to read ANY source list, which
38
+ # would fail the cache update below and leave the host unrepairable (#120).
39
+ - name: Repair apt sources referencing a missing keyring
40
+ ansible.builtin.include_tasks: tasks/repair_apt_sources.yml
41
+
36
42
  - name: Update apt cache
37
43
  ansible.builtin.apt:
38
44
  update_cache: true
@@ -35,6 +35,12 @@
35
35
  delay: 10
36
36
  until: apt_lock_result.rc | default(1) == 0
37
37
 
38
+ # Unwedge apt before the first apt call: a sources line naming a keyring
39
+ # that no longer exists makes apt refuse to read ANY source list, which
40
+ # would fail the cache update below and leave the host unrepairable (#120).
41
+ - name: Repair apt sources referencing a missing keyring
42
+ ansible.builtin.include_tasks: tasks/repair_apt_sources.yml
43
+
38
44
  - name: Update apt cache
39
45
  ansible.builtin.apt:
40
46
  update_cache: true
@@ -43,6 +43,13 @@
43
43
  become: true
44
44
  gather_facts: true
45
45
 
46
+ # Proxmox/Incus place the operator's key straight into the remo user's
47
+ # authorized_keys at create time, so user_setup must not re-seed it from
48
+ # root's — doing so overwrote keys placed by other tooling, notably the
49
+ # `remo-web@…` line `remo web push` installs (#121).
50
+ vars:
51
+ user_setup_bootstrap_cloud_keys: false
52
+
46
53
  pre_tasks:
47
54
  - name: Wait for apt to be ready
48
55
  ansible.builtin.shell: |
@@ -57,6 +64,12 @@
57
64
  delay: 10
58
65
  until: apt_lock_result.rc | default(1) == 0
59
66
 
67
+ # Unwedge apt before the first apt call: a sources line naming a keyring
68
+ # that no longer exists makes apt refuse to read ANY source list, which
69
+ # would fail the cache update below and leave the host unrepairable (#120).
70
+ - name: Repair apt sources referencing a missing keyring
71
+ ansible.builtin.include_tasks: tasks/repair_apt_sources.yml
72
+
60
73
  - name: Update apt cache
61
74
  ansible.builtin.apt:
62
75
  update_cache: true
@@ -50,6 +50,13 @@
50
50
  become: true
51
51
  gather_facts: false
52
52
 
53
+ # Proxmox/Incus place the operator's key straight into the remo user's
54
+ # authorized_keys at create time, so user_setup must not re-seed it from
55
+ # root's — doing so overwrote keys placed by other tooling, notably the
56
+ # `remo-web@…` line `remo web push` installs (#121).
57
+ vars:
58
+ user_setup_bootstrap_cloud_keys: false
59
+
53
60
  pre_tasks:
54
61
  - name: Wait for SSH to stabilize after cloud-init
55
62
  ansible.builtin.wait_for_connection:
@@ -72,6 +79,12 @@
72
79
  delay: 10
73
80
  until: apt_lock_result.rc | default(1) == 0
74
81
 
82
+ # Unwedge apt before the first apt call: a sources line naming a keyring
83
+ # that no longer exists makes apt refuse to read ANY source list, which
84
+ # would fail the cache update below and leave the host unrepairable (#120).
85
+ - name: Repair apt sources referencing a missing keyring
86
+ ansible.builtin.include_tasks: tasks/repair_apt_sources.yml
87
+
75
88
  - name: Update apt cache
76
89
  ansible.builtin.apt:
77
90
  update_cache: true
@@ -32,4 +32,4 @@
32
32
  - Template: {{ proxmox_template }}
33
33
 
34
34
  Launch a container:
35
- remo proxmox create --name dev1 --host {{ inventory_hostname }} --node-user {{ ansible_user | default('root') }}
35
+ remo proxmox create --name dev1 --host {{ inventory_hostname }} --host-user {{ ansible_user | default('root') }}
@@ -30,6 +30,13 @@
30
30
  become: true
31
31
  gather_facts: true
32
32
 
33
+ # Proxmox/Incus place the operator's key straight into the remo user's
34
+ # authorized_keys at create time, so user_setup must not re-seed it from
35
+ # root's — doing so overwrote keys placed by other tooling, notably the
36
+ # `remo-web@…` line `remo web push` installs (#121).
37
+ vars:
38
+ user_setup_bootstrap_cloud_keys: false
39
+
33
40
  pre_tasks:
34
41
  - name: Wait for apt to be ready
35
42
  ansible.builtin.shell: |
@@ -44,6 +51,12 @@
44
51
  delay: 10
45
52
  until: apt_lock_result.rc | default(1) == 0
46
53
 
54
+ # Unwedge apt before the first apt call: a sources line naming a keyring
55
+ # that no longer exists makes apt refuse to read ANY source list, which
56
+ # would fail the cache update below and leave the host unrepairable (#120).
57
+ - name: Repair apt sources referencing a missing keyring
58
+ ansible.builtin.include_tasks: tasks/repair_apt_sources.yml
59
+
47
60
  - name: Update apt cache
48
61
  ansible.builtin.apt:
49
62
  update_cache: true
@@ -50,6 +50,13 @@
50
50
  become: true
51
51
  gather_facts: false
52
52
 
53
+ # Proxmox/Incus place the operator's key straight into the remo user's
54
+ # authorized_keys at create time, so user_setup must not re-seed it from
55
+ # root's — doing so overwrote keys placed by other tooling, notably the
56
+ # `remo-web@…` line `remo web push` installs (#121).
57
+ vars:
58
+ user_setup_bootstrap_cloud_keys: false
59
+
53
60
  pre_tasks:
54
61
  - name: Wait for SSH to stabilize
55
62
  ansible.builtin.wait_for_connection:
@@ -72,6 +79,12 @@
72
79
  delay: 10
73
80
  until: apt_lock_result.rc | default(1) == 0
74
81
 
82
+ # Unwedge apt before the first apt call: a sources line naming a keyring
83
+ # that no longer exists makes apt refuse to read ANY source list, which
84
+ # would fail the cache update below and leave the host unrepairable (#120).
85
+ - name: Repair apt sources referencing a missing keyring
86
+ ansible.builtin.include_tasks: tasks/repair_apt_sources.yml
87
+
75
88
  - name: Update apt cache
76
89
  ansible.builtin.apt:
77
90
  update_cache: true
@@ -49,6 +49,13 @@
49
49
 
50
50
  # Superseded by nodesource.asc above; removed so a rotated key cannot leave a
51
51
  # stale trusted key behind on an already-provisioned machine.
52
+ #
53
+ # Removing the keyring is not enough on its own: the `deb ... signed-by=...
54
+ # nodesource.gpg` line that names it survives in nodesource.list, and apt
55
+ # rejects the whole sources tree over the conflicting Signed-By (#120). That
56
+ # line is dropped by `ansible/tasks/repair_apt_sources.yml`, which every
57
+ # configure/site playbook runs as a pre_task — it has to happen before the
58
+ # first apt call, which is earlier than this role can run.
52
59
  - name: Remove superseded de-armored NodeSource keyring
53
60
  ansible.builtin.file:
54
61
  path: /etc/apt/keyrings/nodesource.gpg
@@ -66,6 +66,12 @@ proxmox_container_ssh_key_path: "~/.ssh/id_rsa.pub"
66
66
  # connect to the container in the configure play.
67
67
  proxmox_container_ssh_private_key: "~/.ssh/id_rsa"
68
68
 
69
+ # Scratch path inside the container where the pubkey lands before it is merged
70
+ # into authorized_keys. Staging exists so the install is additive rather than a
71
+ # `pct push` overwrite that would revoke keys remo did not place (#121); the
72
+ # file is removed by the merge step.
73
+ proxmox_container_pubkey_staging_path: "/run/remo-pubkey.pub"
74
+
69
75
  # ============================================================================
70
76
  # WAIT TIMEOUTS
71
77
  # ============================================================================
@@ -224,19 +224,55 @@
224
224
  changed_when: false
225
225
  failed_when: pct_sshdir_result.rc | default(1) != 0
226
226
 
227
- - name: Push SSH pubkey into container via pct push
227
+ # `pct push` straight onto authorized_keys REPLACES the file, so re-running
228
+ # create against an existing container destroyed every key remo did not put
229
+ # there — the same defect user_setup had on the configure path (#121). Stage
230
+ # the pubkey, then merge it line by line: additive, so a key installed by other
231
+ # tooling (notably `remo web push`'s `remo-web@…` line) survives, and a second
232
+ # run reports no change (Principle VII).
233
+ - name: Stage SSH pubkey inside container via pct push
228
234
  ansible.builtin.command:
229
235
  cmd: >-
230
236
  pct push {{ proxmox_container_vmid }}
231
237
  {{ proxmox_container_pubkey_host_path }}
232
- /home/{{ proxmox_container_ssh_user }}/.ssh/authorized_keys
233
- --user {{ proxmox_container_ssh_user }}
234
- --group {{ proxmox_container_ssh_user }}
238
+ {{ proxmox_container_pubkey_staging_path }}
235
239
  --perms 0600
236
240
  register: pct_push_result
237
- changed_when: pct_push_result.rc | default(1) == 0
241
+ changed_when: false
238
242
  failed_when: pct_push_result.rc | default(1) != 0
239
243
 
244
+ - name: Merge staged pubkey into authorized_keys
245
+ ansible.builtin.command:
246
+ argv:
247
+ - pct
248
+ - exec
249
+ - "{{ proxmox_container_vmid }}"
250
+ - --
251
+ - bash
252
+ - -c
253
+ - |
254
+ set -eu
255
+ user={{ proxmox_container_ssh_user | quote }}
256
+ staged={{ proxmox_container_pubkey_staging_path | quote }}
257
+ ak="/home/$user/.ssh/authorized_keys"
258
+ install -d -o "$user" -g "$user" -m 0700 "/home/$user/.ssh"
259
+ [ -f "$ak" ] || : > "$ak"
260
+ changed=0
261
+ while IFS= read -r line || [ -n "$line" ]; do
262
+ case "$line" in ''|'#'*) continue ;; esac
263
+ if ! grep -qxF "$line" "$ak"; then
264
+ printf '%s\n' "$line" >> "$ak"
265
+ changed=1
266
+ fi
267
+ done < "$staged"
268
+ chown "$user:$user" "$ak"
269
+ chmod 0600 "$ak"
270
+ rm -f "$staged"
271
+ echo "remo_authorized_keys_changed=$changed"
272
+ register: pct_merge_key_result
273
+ changed_when: "'remo_authorized_keys_changed=1' in (pct_merge_key_result.stdout | default(''))"
274
+ failed_when: pct_merge_key_result.rc | default(1) != 0
275
+
240
276
  - name: Harden sshd config (UseDNS no, PermitRootLogin no, GSSAPI off)
241
277
  ansible.builtin.command:
242
278
  cmd: >-
@@ -44,5 +44,5 @@
44
44
  pveam update
45
45
  pveam download {{ proxmox_container_template.split(':')[0] }} {{ proxmox_container_template.split('/')[-1] }}
46
46
 
47
- Or run: remo proxmox host bootstrap {{ inventory_hostname }} --node-user {{ ansible_user | default('root') }}
47
+ Or run: remo proxmox host bootstrap {{ inventory_hostname }} --host-user {{ ansible_user | default('root') }}
48
48
  when: proxmox_container_template not in (template_check.stdout | default(''))
@@ -1,6 +1,15 @@
1
1
  ---
2
2
  remo_user: "remo"
3
3
 
4
+ # Seed the remo user's authorized_keys from the key the cloud provider injected
5
+ # elsewhere on the box (Hetzner -> root, EC2 -> ubuntu). Only Hetzner and AWS
6
+ # need this; Proxmox and Incus write the key straight into the remo user's file
7
+ # at create time, and running the bootstrap there overwrote keys placed by other
8
+ # tooling — notably the `remo-web@…` line `remo web push` installs (#121). Those
9
+ # two providers' configure/site playbooks set this false. Even where it does
10
+ # run, the bootstrap merges and only fires on first contact.
11
+ user_setup_bootstrap_cloud_keys: true
12
+
4
13
  # Version displayed in project-menu banner
5
14
  remo_version: ""
6
15