remo-cli 2.1.0__tar.gz → 2.2.0rc2__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 (428) hide show
  1. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-analyze/SKILL.md +2 -0
  2. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-checklist/SKILL.md +10 -6
  3. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-clarify/SKILL.md +60 -26
  4. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-constitution/SKILL.md +3 -1
  5. remo_cli-2.2.0rc2/.claude/skills/speckit-converge/SKILL.md +279 -0
  6. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-implement/SKILL.md +48 -32
  7. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-plan/SKILL.md +53 -36
  8. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-specify/SKILL.md +72 -54
  9. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-tasks/SKILL.md +54 -39
  10. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-taskstoissues/SKILL.md +7 -1
  11. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.devcontainer/devcontainer.json +2 -2
  12. remo_cli-2.2.0rc2/.dockerignore +38 -0
  13. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.github/workflows/ci.yml +36 -0
  14. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.github/workflows/release.yml +59 -0
  15. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.github/workflows/smoke-test.yml +24 -4
  16. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.gitignore +9 -0
  17. remo_cli-2.2.0rc2/.specify/feature.json +3 -0
  18. remo_cli-2.2.0rc2/.specify/init-options.json +9 -0
  19. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/integration.json +1 -1
  20. remo_cli-2.2.0rc2/.specify/integrations/claude.manifest.json +17 -0
  21. remo_cli-2.2.0rc2/.specify/integrations/speckit.manifest.json +17 -0
  22. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/scripts/bash/check-prerequisites.sh +49 -20
  23. remo_cli-2.2.0rc2/.specify/scripts/bash/common.sh +704 -0
  24. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/scripts/bash/create-new-feature.sh +130 -126
  25. remo_cli-2.2.0rc2/.specify/scripts/bash/setup-plan.sh +83 -0
  26. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/scripts/bash/setup-tasks.sh +3 -8
  27. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/templates/checklist-template.md +5 -5
  28. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/templates/plan-template.md +23 -14
  29. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/templates/spec-template.md +21 -5
  30. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/templates/tasks-template.md +6 -5
  31. remo_cli-2.1.0/CLAUDE.md → remo_cli-2.2.0rc2/AGENTS.md +14 -3
  32. remo_cli-2.2.0rc2/CLAUDE.md +195 -0
  33. remo_cli-2.1.0/README.md → remo_cli-2.2.0rc2/PKG-INFO +66 -0
  34. remo_cli-2.1.0/PKG-INFO → remo_cli-2.2.0rc2/README.md +40 -19
  35. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/user_setup/tasks/main.yml +8 -0
  36. remo_cli-2.2.0rc2/ansible/roles/user_setup/templates/remo-host.sh.j2 +299 -0
  37. remo_cli-2.2.0rc2/docker/Dockerfile +123 -0
  38. remo_cli-2.2.0rc2/docker/compose.example.yml +216 -0
  39. remo_cli-2.2.0rc2/docker/entrypoint.sh +37 -0
  40. remo_cli-2.2.0rc2/docs/remo-web-speckit-input.md +777 -0
  41. remo_cli-2.2.0rc2/docs/remo-web.html +223 -0
  42. remo_cli-2.2.0rc2/docs/web-session-interface.md +703 -0
  43. remo_cli-2.2.0rc2/frontend/index.html +12 -0
  44. remo_cli-2.2.0rc2/frontend/package-lock.json +1968 -0
  45. remo_cli-2.2.0rc2/frontend/package.json +35 -0
  46. remo_cli-2.2.0rc2/frontend/public/README.md +10 -0
  47. remo_cli-2.2.0rc2/frontend/public/dist__ghostty-vt.wasm +0 -0
  48. remo_cli-2.2.0rc2/frontend/public/ghostty-vt.wasm +0 -0
  49. remo_cli-2.2.0rc2/frontend/scripts/copy-ghostty-wasm.mjs +86 -0
  50. remo_cli-2.2.0rc2/frontend/src/api/client.ts +288 -0
  51. remo_cli-2.2.0rc2/frontend/src/components/AppRoot.tsx +25 -0
  52. remo_cli-2.2.0rc2/frontend/src/components/AppShell.css +89 -0
  53. remo_cli-2.2.0rc2/frontend/src/components/AppShell.tsx +233 -0
  54. remo_cli-2.2.0rc2/frontend/src/components/AwaitingAdoption.css +115 -0
  55. remo_cli-2.2.0rc2/frontend/src/components/AwaitingAdoption.tsx +109 -0
  56. remo_cli-2.2.0rc2/frontend/src/components/OfflineOverlay.css +52 -0
  57. remo_cli-2.2.0rc2/frontend/src/components/OfflineOverlay.tsx +26 -0
  58. remo_cli-2.2.0rc2/frontend/src/components/SessionRail.css +400 -0
  59. remo_cli-2.2.0rc2/frontend/src/components/SessionRail.tsx +358 -0
  60. remo_cli-2.2.0rc2/frontend/src/components/SettingsPage.css +298 -0
  61. remo_cli-2.2.0rc2/frontend/src/components/SettingsPage.tsx +251 -0
  62. remo_cli-2.2.0rc2/frontend/src/components/ShortcutsModal.css +49 -0
  63. remo_cli-2.2.0rc2/frontend/src/components/ShortcutsModal.tsx +30 -0
  64. remo_cli-2.2.0rc2/frontend/src/components/TerminalCard.css +201 -0
  65. remo_cli-2.2.0rc2/frontend/src/components/TerminalCard.tsx +376 -0
  66. remo_cli-2.2.0rc2/frontend/src/components/TopBar.css +129 -0
  67. remo_cli-2.2.0rc2/frontend/src/components/TopBar.tsx +113 -0
  68. remo_cli-2.2.0rc2/frontend/src/components/WorkspacePane.css +70 -0
  69. remo_cli-2.2.0rc2/frontend/src/components/WorkspacePane.tsx +117 -0
  70. remo_cli-2.2.0rc2/frontend/src/components/providerMeta.ts +54 -0
  71. remo_cli-2.2.0rc2/frontend/src/components/railModel.ts +137 -0
  72. remo_cli-2.2.0rc2/frontend/src/main.tsx +33 -0
  73. remo_cli-2.2.0rc2/frontend/src/state/discovery.ts +196 -0
  74. remo_cli-2.2.0rc2/frontend/src/state/fonts.ts +103 -0
  75. remo_cli-2.2.0rc2/frontend/src/state/health.ts +126 -0
  76. remo_cli-2.2.0rc2/frontend/src/state/settings.ts +221 -0
  77. remo_cli-2.2.0rc2/frontend/src/state/useConsoleKeyboard.ts +72 -0
  78. remo_cli-2.2.0rc2/frontend/src/state/workspace.ts +243 -0
  79. remo_cli-2.2.0rc2/frontend/src/terminal/GhosttyRenderer.ts +142 -0
  80. remo_cli-2.2.0rc2/frontend/src/terminal/RendererAdapter.ts +98 -0
  81. remo_cli-2.2.0rc2/frontend/src/terminal/TerminalConnection.ts +282 -0
  82. remo_cli-2.2.0rc2/frontend/src/terminal/XtermRenderer.ts +164 -0
  83. remo_cli-2.2.0rc2/frontend/src/terminal/defaultRenderer.ts +65 -0
  84. remo_cli-2.2.0rc2/frontend/src/theme/fonts.ts +15 -0
  85. remo_cli-2.2.0rc2/frontend/src/theme/tokens.css +128 -0
  86. remo_cli-2.2.0rc2/frontend/tsconfig.json +20 -0
  87. remo_cli-2.2.0rc2/frontend/vite.config.ts +18 -0
  88. remo_cli-2.2.0rc2/playwright.config.ts +75 -0
  89. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/pyproject.toml +18 -1
  90. remo_cli-2.2.0rc2/specs/010-web-session-interface/checklists/requirements.md +44 -0
  91. remo_cli-2.2.0rc2/specs/010-web-session-interface/contracts/remo-host-protocol.md +100 -0
  92. remo_cli-2.2.0rc2/specs/010-web-session-interface/contracts/rest-api.md +94 -0
  93. remo_cli-2.2.0rc2/specs/010-web-session-interface/contracts/terminal-websocket.md +74 -0
  94. remo_cli-2.2.0rc2/specs/010-web-session-interface/data-model.md +128 -0
  95. remo_cli-2.2.0rc2/specs/010-web-session-interface/plan.md +141 -0
  96. remo_cli-2.2.0rc2/specs/010-web-session-interface/quickstart.md +126 -0
  97. remo_cli-2.2.0rc2/specs/010-web-session-interface/research.md +164 -0
  98. remo_cli-2.2.0rc2/specs/010-web-session-interface/spec.md +344 -0
  99. remo_cli-2.2.0rc2/specs/010-web-session-interface/tasks.md +305 -0
  100. remo_cli-2.2.0rc2/specs/011-web-adopt/checklists/requirements.md +44 -0
  101. remo_cli-2.2.0rc2/specs/011-web-adopt/contracts/cli-web-adopt.md +78 -0
  102. remo_cli-2.2.0rc2/specs/011-web-adopt/contracts/setup-api.md +98 -0
  103. remo_cli-2.2.0rc2/specs/011-web-adopt/data-model.md +123 -0
  104. remo_cli-2.2.0rc2/specs/011-web-adopt/plan.md +163 -0
  105. remo_cli-2.2.0rc2/specs/011-web-adopt/quickstart-results.md +29 -0
  106. remo_cli-2.2.0rc2/specs/011-web-adopt/quickstart.md +135 -0
  107. remo_cli-2.2.0rc2/specs/011-web-adopt/research.md +311 -0
  108. remo_cli-2.2.0rc2/specs/011-web-adopt/spec.md +507 -0
  109. remo_cli-2.2.0rc2/specs/011-web-adopt/tasks.md +213 -0
  110. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/cli/main.py +2 -0
  111. remo_cli-2.2.0rc2/src/remo_cli/cli/web.py +320 -0
  112. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/config.py +47 -10
  113. remo_cli-2.2.0rc2/src/remo_cli/core/remo_host_client.py +460 -0
  114. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/ssh.py +183 -16
  115. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/validation.py +38 -0
  116. remo_cli-2.2.0rc2/src/remo_cli/core/web_adopt.py +1338 -0
  117. remo_cli-2.2.0rc2/src/remo_cli/models/capability.py +62 -0
  118. remo_cli-2.2.0rc2/src/remo_cli/models/discovery.py +57 -0
  119. remo_cli-2.2.0rc2/src/remo_cli/models/session_target.py +72 -0
  120. remo_cli-2.2.0rc2/src/remo_cli/web/__init__.py +3 -0
  121. remo_cli-2.2.0rc2/src/remo_cli/web/api/__init__.py +3 -0
  122. remo_cli-2.2.0rc2/src/remo_cli/web/api/hosts.py +180 -0
  123. remo_cli-2.2.0rc2/src/remo_cli/web/api/setup.py +394 -0
  124. remo_cli-2.2.0rc2/src/remo_cli/web/api/terminals.py +477 -0
  125. remo_cli-2.2.0rc2/src/remo_cli/web/app.py +216 -0
  126. remo_cli-2.2.0rc2/src/remo_cli/web/check.py +312 -0
  127. remo_cli-2.2.0rc2/src/remo_cli/web/config.py +185 -0
  128. remo_cli-2.2.0rc2/src/remo_cli/web/discovery.py +452 -0
  129. remo_cli-2.2.0rc2/src/remo_cli/web/health.py +227 -0
  130. remo_cli-2.2.0rc2/src/remo_cli/web/logging_config.py +116 -0
  131. remo_cli-2.2.0rc2/src/remo_cli/web/models.py +85 -0
  132. remo_cli-2.2.0rc2/src/remo_cli/web/ssh_master.py +107 -0
  133. remo_cli-2.2.0rc2/src/remo_cli/web/state.py +287 -0
  134. remo_cli-2.2.0rc2/src/remo_cli/web/terminal.py +548 -0
  135. remo_cli-2.2.0rc2/src/remo_cli/web/terminal_registry.py +221 -0
  136. remo_cli-2.2.0rc2/src/remo_cli/web/tokens.py +104 -0
  137. remo_cli-2.2.0rc2/tests/ansible/test_remo_host_idempotency.py +153 -0
  138. remo_cli-2.2.0rc2/tests/e2e/fixtures.ts +233 -0
  139. remo_cli-2.2.0rc2/tests/e2e/ghostty-shell-io.spec.ts +231 -0
  140. remo_cli-2.2.0rc2/tests/e2e/ghostty-tui-compatibility.spec.ts +235 -0
  141. remo_cli-2.2.0rc2/tests/e2e/keyboard-routing.spec.ts +101 -0
  142. remo_cli-2.2.0rc2/tests/e2e/mobile.spec.ts +81 -0
  143. remo_cli-2.2.0rc2/tests/e2e/reconnect.spec.ts +108 -0
  144. remo_cli-2.2.0rc2/tests/e2e/workspace-layout.spec.ts +106 -0
  145. remo_cli-2.2.0rc2/tests/image/test_docker_image.py +951 -0
  146. remo_cli-2.2.0rc2/tests/integration/_nine_terminal_fixture.py +486 -0
  147. remo_cli-2.2.0rc2/tests/integration/test_nine_terminals.py +255 -0
  148. remo_cli-2.2.0rc2/tests/integration/test_nine_terminals_soak.py +547 -0
  149. remo_cli-2.2.0rc2/tests/integration/test_remo_host_e2e.py +571 -0
  150. remo_cli-2.2.0rc2/tests/integration/test_security_rejections.py +354 -0
  151. remo_cli-2.2.0rc2/tests/integration/test_terminal_attach.py +379 -0
  152. remo_cli-2.2.0rc2/tests/integration/test_web_adopt_e2e.py +736 -0
  153. remo_cli-2.2.0rc2/tests/integration/test_web_cli_parity.py +522 -0
  154. remo_cli-2.2.0rc2/tests/perf/test_latency.py +622 -0
  155. remo_cli-2.2.0rc2/tests/unit/__init__.py +0 -0
  156. remo_cli-2.2.0rc2/tests/unit/cli/__init__.py +0 -0
  157. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/cli/test_main.py +10 -1
  158. remo_cli-2.2.0rc2/tests/unit/cli/test_web_adopt_cmd.py +354 -0
  159. remo_cli-2.2.0rc2/tests/unit/core/__init__.py +0 -0
  160. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_config.py +94 -0
  161. remo_cli-2.2.0rc2/tests/unit/core/test_remo_host_client.py +687 -0
  162. remo_cli-2.2.0rc2/tests/unit/core/test_ssh_controlpath.py +283 -0
  163. remo_cli-2.2.0rc2/tests/unit/core/test_ssh_identity_opts.py +363 -0
  164. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_validation.py +89 -0
  165. remo_cli-2.2.0rc2/tests/unit/core/test_web_adopt_authorize.py +346 -0
  166. remo_cli-2.2.0rc2/tests/unit/core/test_web_adopt_payload.py +253 -0
  167. remo_cli-2.2.0rc2/tests/unit/core/test_web_adopt_trust.py +554 -0
  168. remo_cli-2.2.0rc2/tests/unit/core/test_web_push.py +630 -0
  169. remo_cli-2.2.0rc2/tests/unit/models/__init__.py +0 -0
  170. remo_cli-2.2.0rc2/tests/unit/models/test_capability.py +90 -0
  171. remo_cli-2.2.0rc2/tests/unit/models/test_discovery.py +119 -0
  172. remo_cli-2.2.0rc2/tests/unit/models/test_session_target.py +106 -0
  173. remo_cli-2.2.0rc2/tests/unit/providers/__init__.py +0 -0
  174. remo_cli-2.2.0rc2/tests/unit/test_ansible_templates.py +312 -0
  175. remo_cli-2.2.0rc2/tests/unit/web/__init__.py +0 -0
  176. remo_cli-2.2.0rc2/tests/unit/web/conftest.py +188 -0
  177. remo_cli-2.2.0rc2/tests/unit/web/test_backpressure.py +165 -0
  178. remo_cli-2.2.0rc2/tests/unit/web/test_check.py +284 -0
  179. remo_cli-2.2.0rc2/tests/unit/web/test_csp.py +178 -0
  180. remo_cli-2.2.0rc2/tests/unit/web/test_discovery.py +254 -0
  181. remo_cli-2.2.0rc2/tests/unit/web/test_health_states.py +304 -0
  182. remo_cli-2.2.0rc2/tests/unit/web/test_hosts_mapping.py +72 -0
  183. remo_cli-2.2.0rc2/tests/unit/web/test_lazy_import.py +129 -0
  184. remo_cli-2.2.0rc2/tests/unit/web/test_log_redaction.py +250 -0
  185. remo_cli-2.2.0rc2/tests/unit/web/test_setup_api.py +484 -0
  186. remo_cli-2.2.0rc2/tests/unit/web/test_setup_auth.py +378 -0
  187. remo_cli-2.2.0rc2/tests/unit/web/test_state.py +292 -0
  188. remo_cli-2.2.0rc2/tests/unit/web/test_terminal_resize.py +133 -0
  189. remo_cli-2.2.0rc2/tests/unit/web/test_terminals_api.py +336 -0
  190. remo_cli-2.2.0rc2/tests/unit/web/test_tokens.py +140 -0
  191. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/uv.lock +584 -5
  192. remo_cli-2.1.0/.claude/commands/speckit.analyze.md +0 -184
  193. remo_cli-2.1.0/.claude/commands/speckit.checklist.md +0 -294
  194. remo_cli-2.1.0/.claude/commands/speckit.clarify.md +0 -181
  195. remo_cli-2.1.0/.claude/commands/speckit.constitution.md +0 -82
  196. remo_cli-2.1.0/.claude/commands/speckit.implement.md +0 -135
  197. remo_cli-2.1.0/.claude/commands/speckit.plan.md +0 -89
  198. remo_cli-2.1.0/.claude/commands/speckit.specify.md +0 -258
  199. remo_cli-2.1.0/.claude/commands/speckit.tasks.md +0 -137
  200. remo_cli-2.1.0/.claude/commands/speckit.taskstoissues.md +0 -30
  201. remo_cli-2.1.0/.dockerignore +0 -31
  202. remo_cli-2.1.0/.specify/init-options.json +0 -10
  203. remo_cli-2.1.0/.specify/integrations/claude.manifest.json +0 -16
  204. remo_cli-2.1.0/.specify/integrations/speckit.manifest.json +0 -9
  205. remo_cli-2.1.0/.specify/scripts/bash/common.sh +0 -156
  206. remo_cli-2.1.0/.specify/scripts/bash/setup-plan.sh +0 -61
  207. remo_cli-2.1.0/tests/unit/test_ansible_templates.py +0 -36
  208. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-git-commit/SKILL.md +0 -0
  209. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-git-feature/SKILL.md +0 -0
  210. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-git-initialize/SKILL.md +0 -0
  211. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-git-remote/SKILL.md +0 -0
  212. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.claude/skills/speckit-git-validate/SKILL.md +0 -0
  213. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.github/dependabot.yml +0 -0
  214. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.github/workflows/provision.yml +0 -0
  215. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.github/workflows/smoke-test-cleanup.yml +0 -0
  216. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.github/workflows/teardown.yml +0 -0
  217. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.maverick/checkpoints/feature/implementation_complete.json +0 -0
  218. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.maverick/checkpoints/feature/phase_${{ index }}_complete.json +0 -0
  219. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.maverick/checkpoints/feature/validation_complete.json +0 -0
  220. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/.registry +0 -0
  221. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/README.md +0 -0
  222. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/commands/speckit.git.commit.md +0 -0
  223. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/commands/speckit.git.feature.md +0 -0
  224. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/commands/speckit.git.initialize.md +0 -0
  225. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/commands/speckit.git.remote.md +0 -0
  226. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/commands/speckit.git.validate.md +0 -0
  227. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/config-template.yml +0 -0
  228. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/extension.yml +0 -0
  229. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/git-config.yml +0 -0
  230. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/scripts/bash/auto-commit.sh +0 -0
  231. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/scripts/bash/create-new-feature.sh +0 -0
  232. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/scripts/bash/git-common.sh +0 -0
  233. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/scripts/bash/initialize-repo.sh +0 -0
  234. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
  235. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/scripts/powershell/create-new-feature.ps1 +0 -0
  236. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/scripts/powershell/git-common.ps1 +0 -0
  237. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
  238. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/extensions.yml +0 -0
  239. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/memory/constitution.md +0 -0
  240. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/scripts/bash/update-agent-context.sh +0 -0
  241. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/templates/agent-file-template.md +0 -0
  242. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/templates/constitution-template.md +0 -0
  243. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/workflows/speckit/workflow.yml +0 -0
  244. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/.specify/workflows/workflow-registry.json +0 -0
  245. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/CONTRIBUTING.md +0 -0
  246. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/Dockerfile +0 -0
  247. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/LICENSE +0 -0
  248. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/.ansible-lint +0 -0
  249. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/README.md +0 -0
  250. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/ansible.cfg +0 -0
  251. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/aws_configure.yml +0 -0
  252. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/aws_resize.yml +0 -0
  253. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/aws_site.yml +0 -0
  254. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/aws_teardown.yml +0 -0
  255. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/group_vars/all.yml +0 -0
  256. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/group_vars/incus_containers.yml +0 -0
  257. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/group_vars/proxmox_containers.yml +0 -0
  258. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/hetzner_configure.yml +0 -0
  259. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/hetzner_provision.yml +0 -0
  260. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/hetzner_resize.yml +0 -0
  261. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/hetzner_site.yml +0 -0
  262. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/hetzner_teardown.yml +0 -0
  263. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/incus_bootstrap.yml +0 -0
  264. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/incus_configure.yml +0 -0
  265. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/incus_provision.yml +0 -0
  266. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/incus_resize.yml +0 -0
  267. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/incus_site.yml +0 -0
  268. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/incus_teardown.yml +0 -0
  269. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/inventory/hosts.yml +0 -0
  270. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/inventory/incus_containers.yml +0 -0
  271. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/proxmox_bootstrap.yml +0 -0
  272. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/proxmox_configure.yml +0 -0
  273. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/proxmox_provision.yml +0 -0
  274. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/proxmox_resize.yml +0 -0
  275. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/proxmox_site.yml +0 -0
  276. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/proxmox_teardown.yml +0 -0
  277. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/requirements.yml +0 -0
  278. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/aws_server/defaults/main.yml +0 -0
  279. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/aws_server/tasks/ebs.yml +0 -0
  280. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/aws_server/tasks/ec2.yml +0 -0
  281. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/aws_server/tasks/main.yml +0 -0
  282. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/aws_server/tasks/patch_manager.yml +0 -0
  283. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/aws_server/tasks/preflight.yml +0 -0
  284. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/aws_server/tasks/security_group.yml +0 -0
  285. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/deacon/defaults/main.yml +0 -0
  286. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/deacon/tasks/main.yml +0 -0
  287. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/devcontainers/tasks/main.yml +0 -0
  288. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/docker/handlers/main.yml +0 -0
  289. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/docker/tasks/main.yml +0 -0
  290. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/fzf/tasks/main.yml +0 -0
  291. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/github_cli/tasks/main.yml +0 -0
  292. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/hetzner_server/defaults/main.yml +0 -0
  293. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/hetzner_server/tasks/main.yml +0 -0
  294. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_bootstrap/defaults/main.yml +0 -0
  295. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_bootstrap/handlers/main.yml +0 -0
  296. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_bootstrap/tasks/main.yml +0 -0
  297. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_container/defaults/main.yml +0 -0
  298. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_container/handlers/main.yml +0 -0
  299. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_container/meta/main.yml +0 -0
  300. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_container/tasks/main.yml +0 -0
  301. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_container/tasks/preflight.yml +0 -0
  302. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_container_teardown/defaults/main.yml +0 -0
  303. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_container_teardown/meta/main.yml +0 -0
  304. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/incus_container_teardown/tasks/main.yml +0 -0
  305. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/nodejs/defaults/main.yml +0 -0
  306. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/nodejs/tasks/main.yml +0 -0
  307. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_bootstrap/defaults/main.yml +0 -0
  308. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_bootstrap/meta/main.yml +0 -0
  309. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_bootstrap/tasks/main.yml +0 -0
  310. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_container/defaults/main.yml +0 -0
  311. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_container/handlers/main.yml +0 -0
  312. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_container/meta/main.yml +0 -0
  313. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_container/tasks/main.yml +0 -0
  314. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_container/tasks/preflight.yml +0 -0
  315. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_container_teardown/defaults/main.yml +0 -0
  316. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_container_teardown/meta/main.yml +0 -0
  317. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/proxmox_container_teardown/tasks/main.yml +0 -0
  318. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/user_setup/defaults/main.yml +0 -0
  319. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/user_setup/templates/devshell.sh.j2 +0 -0
  320. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/user_setup/templates/project-launch.sh.j2 +0 -0
  321. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/user_setup/templates/project-menu.sh.j2 +0 -0
  322. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/zellij/defaults/main.yml +0 -0
  323. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/zellij/tasks/main.yml +0 -0
  324. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/zellij/templates/config.kdl.j2 +0 -0
  325. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/roles/zellij/templates/layouts/minimal.kdl.j2 +0 -0
  326. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/ansible/tasks/configure_dev_tools.yml +0 -0
  327. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/docs/aws.md +0 -0
  328. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/docs/hetzner.md +0 -0
  329. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/docs/incus.md +0 -0
  330. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/docs/install.sh +0 -0
  331. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/docs/proxmox.md +0 -0
  332. /remo_cli-2.1.0/src/remo_cli/cli/__init__.py → /remo_cli-2.2.0rc2/frontend/src/terminal/.gitkeep +0 -0
  333. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/install.sh +0 -0
  334. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/maverick.yaml +0 -0
  335. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/project-menu.sh +0 -0
  336. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/remo +0 -0
  337. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/run.sh +0 -0
  338. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/scripts/setup-aws-oidc.sh +0 -0
  339. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/checklists/requirements.md +0 -0
  340. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/checklists/validation.md +0 -0
  341. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/contracts/playbook-interface.yaml +0 -0
  342. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/contracts/role-interface.yaml +0 -0
  343. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/data-model.md +0 -0
  344. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/plan.md +0 -0
  345. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/quickstart.md +0 -0
  346. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/research.md +0 -0
  347. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/spec.md +0 -0
  348. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/001-bootstrap-incus-host/tasks.md +0 -0
  349. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/checklists/requirements.md +0 -0
  350. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/contracts/playbook-interface.yaml +0 -0
  351. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/contracts/role-interface.yaml +0 -0
  352. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/data-model.md +0 -0
  353. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/plan.md +0 -0
  354. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/quickstart.md +0 -0
  355. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/research.md +0 -0
  356. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/spec.md +0 -0
  357. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/002-incus-container-support/tasks.md +0 -0
  358. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/003-python-cli-rewrite/checklists/requirements.md +0 -0
  359. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/003-python-cli-rewrite/data-model.md +0 -0
  360. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/003-python-cli-rewrite/plan.md +0 -0
  361. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/003-python-cli-rewrite/quickstart.md +0 -0
  362. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/003-python-cli-rewrite/research.md +0 -0
  363. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/003-python-cli-rewrite/spec.md +0 -0
  364. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/003-python-cli-rewrite/tasks.md +0 -0
  365. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/004-proxmox-container-support/spec.md +0 -0
  366. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/005-provider-snapshots/checklists/requirements.md +0 -0
  367. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/005-provider-snapshots/contracts/cli-surface.md +0 -0
  368. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/005-provider-snapshots/data-model.md +0 -0
  369. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/005-provider-snapshots/plan.md +0 -0
  370. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/005-provider-snapshots/quickstart.md +0 -0
  371. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/005-provider-snapshots/research.md +0 -0
  372. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/005-provider-snapshots/spec.md +0 -0
  373. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/specs/005-provider-snapshots/tasks.md +0 -0
  374. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/__init__.py +0 -0
  375. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/__main__.py +0 -0
  376. {remo_cli-2.1.0/src/remo_cli/cli/providers → remo_cli-2.2.0rc2/src/remo_cli/cli}/__init__.py +0 -0
  377. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/cli/cp.py +0 -0
  378. {remo_cli-2.1.0/src/remo_cli/core → remo_cli-2.2.0rc2/src/remo_cli/cli/providers}/__init__.py +0 -0
  379. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/cli/providers/aws.py +0 -0
  380. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/cli/providers/hetzner.py +0 -0
  381. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/cli/providers/incus.py +0 -0
  382. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/cli/providers/proxmox.py +0 -0
  383. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/cli/shell.py +0 -0
  384. {remo_cli-2.1.0/src/remo_cli/models → remo_cli-2.2.0rc2/src/remo_cli/core}/__init__.py +0 -0
  385. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/ansible_runner.py +0 -0
  386. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/completion.py +0 -0
  387. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/known_hosts.py +0 -0
  388. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/output.py +0 -0
  389. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/picker.py +0 -0
  390. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/rsync.py +0 -0
  391. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/snapshot.py +0 -0
  392. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/core/version.py +0 -0
  393. {remo_cli-2.1.0/src/remo_cli/providers → remo_cli-2.2.0rc2/src/remo_cli/models}/__init__.py +0 -0
  394. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/models/host.py +0 -0
  395. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/models/snapshot.py +0 -0
  396. {remo_cli-2.1.0/tests → remo_cli-2.2.0rc2/src/remo_cli/providers}/__init__.py +0 -0
  397. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/providers/aws.py +0 -0
  398. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/providers/hetzner.py +0 -0
  399. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/providers/incus.py +0 -0
  400. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/src/remo_cli/providers/proxmox.py +0 -0
  401. {remo_cli-2.1.0/tests/integration → remo_cli-2.2.0rc2/tests}/__init__.py +0 -0
  402. {remo_cli-2.1.0/tests/unit → remo_cli-2.2.0rc2/tests/ansible}/__init__.py +0 -0
  403. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/conftest.py +0 -0
  404. {remo_cli-2.1.0/tests/unit/cli → remo_cli-2.2.0rc2/tests/image}/__init__.py +0 -0
  405. {remo_cli-2.1.0/tests/unit/core → remo_cli-2.2.0rc2/tests/integration}/__init__.py +0 -0
  406. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/integration/orbstack-cloud-init.yml +0 -0
  407. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/integration/orbstack.sh +0 -0
  408. {remo_cli-2.1.0/tests/unit/providers → remo_cli-2.2.0rc2/tests/perf}/__init__.py +0 -0
  409. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/cli/providers/test_aws_snapshot.py +0 -0
  410. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/cli/providers/test_hetzner_snapshot.py +0 -0
  411. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/cli/providers/test_incus_snapshot.py +0 -0
  412. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/cli/providers/test_proxmox_snapshot.py +0 -0
  413. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/cli/test_cp.py +0 -0
  414. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/cli/test_shell.py +0 -0
  415. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_ansible_runner.py +0 -0
  416. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_known_hosts.py +0 -0
  417. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_output.py +0 -0
  418. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_picker.py +0 -0
  419. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_rsync.py +0 -0
  420. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_snapshot.py +0 -0
  421. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_ssh.py +0 -0
  422. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/core/test_version.py +0 -0
  423. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/providers/test_aws_snapshot.py +0 -0
  424. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/providers/test_hetzner_snapshot.py +0 -0
  425. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/providers/test_incus_snapshot.py +0 -0
  426. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/providers/test_proxmox_devcontainer_runtime.py +0 -0
  427. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/providers/test_proxmox_snapshot.py +0 -0
  428. {remo_cli-2.1.0 → remo_cli-2.2.0rc2}/tests/unit/test_host_model.py +0 -0
@@ -52,6 +52,7 @@ You **MUST** consider the user input before proceeding (if not empty).
52
52
 
53
53
  Wait for the result of the hook command before proceeding to the Goal.
54
54
  ```
55
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
55
56
  - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
56
57
 
57
58
  ## Goal
@@ -236,6 +237,7 @@ After reporting, check if `.specify/extensions.yml` exists in the project root.
236
237
  Executing: `/{command}`
237
238
  EXECUTE_COMMAND: {command}
238
239
  ```
240
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
239
241
  - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
240
242
 
241
243
  ## Operating Principles
@@ -73,6 +73,7 @@ You **MUST** consider the user input before proceeding (if not empty).
73
73
 
74
74
  Wait for the result of the hook command before proceeding to the Execution Steps.
75
75
  ```
76
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
76
77
  - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
77
78
 
78
79
  ## Execution Steps
@@ -81,7 +82,9 @@ You **MUST** consider the user input before proceeding (if not empty).
81
82
  - All file paths must be absolute.
82
83
  - For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot").
83
84
 
84
- 2. **Clarify intent (dynamic)**: Derive up to THREE initial contextual clarifying questions (no pre-baked catalog). They MUST:
85
+ 2. **IF EXISTS**: Load `.specify/memory/constitution.md` for project principles and governance constraints.
86
+
87
+ 3. **Clarify intent (dynamic)**: Derive up to THREE initial contextual clarifying questions (no pre-baked catalog). They MUST:
85
88
  - Be generated from the user's phrasing + extracted signals from spec/plan/tasks
86
89
  - Only ask about information that materially changes checklist content
87
90
  - Be skipped individually if already unambiguous in `$ARGUMENTS`
@@ -113,13 +116,13 @@ You **MUST** consider the user input before proceeding (if not empty).
113
116
 
114
117
  Output the questions (label Q1/Q2/Q3). After answers: if ≥2 scenario classes (Alternate / Exception / Recovery / Non-Functional domain) remain unclear, you MAY ask up to TWO more targeted follow‑ups (Q4/Q5) with a one-line justification each (e.g., "Unresolved recovery path risk"). Do not exceed five total questions. Skip escalation if user explicitly declines more.
115
118
 
116
- 3. **Understand user request**: Combine `$ARGUMENTS` + clarifying answers:
119
+ 4. **Understand user request**: Combine `$ARGUMENTS` + clarifying answers:
117
120
  - Derive checklist theme (e.g., security, review, deploy, ux)
118
121
  - Consolidate explicit must-have items mentioned by user
119
122
  - Map focus selections to category scaffolding
120
123
  - Infer any missing context from spec/plan/tasks (do NOT hallucinate)
121
124
 
122
- 4. **Load feature context**: Read from FEATURE_DIR:
125
+ 5. **Load feature context**: Read from FEATURE_DIR:
123
126
  - spec.md: Feature requirements and scope
124
127
  - plan.md (if exists): Technical details, dependencies
125
128
  - tasks.md (if exists): Implementation tasks
@@ -130,7 +133,7 @@ You **MUST** consider the user input before proceeding (if not empty).
130
133
  - Use progressive disclosure: add follow-on retrieval only if gaps detected
131
134
  - If source docs are large, generate interim summary items instead of embedding raw text
132
135
 
133
- 5. **Generate checklist** - Create "Unit Tests for Requirements":
136
+ 6. **Generate checklist** - Create "Unit Tests for Requirements":
134
137
  - Create `FEATURE_DIR/checklists/` directory if it doesn't exist
135
138
  - Generate unique checklist filename:
136
139
  - Use short, descriptive name based on domain (e.g., `ux.md`, `api.md`, `security.md`)
@@ -248,9 +251,9 @@ You **MUST** consider the user input before proceeding (if not empty).
248
251
  - ✅ "Are [edge cases/scenarios] addressed in requirements?"
249
252
  - ✅ "Does the spec define [missing aspect]?"
250
253
 
251
- 6. **Structure Reference**: Generate the checklist following the canonical template in `.specify/templates/checklist-template.md` for title, meta section, category headings, and ID formatting. If template is unavailable, use: H1 title, purpose/created meta lines, `##` category sections containing `- [ ] CHK### <requirement item>` lines with globally incrementing IDs starting at CHK001.
254
+ 7. **Structure Reference**: Generate the checklist following the canonical template in `.specify/templates/checklist-template.md` for title, meta section, category headings, and ID formatting. If template is unavailable, use: H1 title, purpose/created meta lines, `##` category sections containing `- [ ] CHK### <requirement item>` lines with globally incrementing IDs starting at CHK001.
252
255
 
253
- 7. **Report**: Output full path to checklist file, item count, and summarize whether the run created a new file or appended to an existing one. Summarize:
256
+ 8. **Report**: Output full path to checklist file, item count, and summarize whether the run created a new file or appended to an existing one. Summarize:
254
257
  - Focus areas selected
255
258
  - Depth level
256
259
  - Actor/timing
@@ -369,4 +372,5 @@ Check if `.specify/extensions.yml` exists in the project root.
369
372
  Executing: `/{command}`
370
373
  EXECUTE_COMMAND: {command}
371
374
  ```
375
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
372
376
  - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
@@ -52,6 +52,7 @@ You **MUST** consider the user input before proceeding (if not empty).
52
52
 
53
53
  Wait for the result of the hook command before proceeding to the Outline.
54
54
  ```
55
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
55
56
  - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
56
57
 
57
58
  ## Outline
@@ -69,7 +70,9 @@ Execution steps:
69
70
  - If JSON parsing fails, abort and instruct user to re-run `/speckit-specify` or verify feature branch environment.
70
71
  - For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot").
71
72
 
72
- 2. Load the current spec file. Perform a structured ambiguity & coverage scan using this taxonomy. For each category, mark status: Clear / Partial / Missing. Produce an internal coverage map used for prioritization (do not output raw map unless no questions will be asked).
73
+ 2. **IF EXISTS**: Load `.specify/memory/constitution.md` for project principles and governance constraints.
74
+
75
+ 3. Load the current spec file. Perform a structured ambiguity & coverage scan using this taxonomy. For each category, mark status: Clear / Partial / Missing. Produce an internal coverage map used for prioritization (do not output raw map unless no questions will be asked).
73
76
 
74
77
  Functional Scope & Behavior:
75
78
  - Core user goals & success criteria
@@ -125,7 +128,7 @@ Execution steps:
125
128
  - Clarification would not materially change implementation or validation strategy
126
129
  - Information is better deferred to planning phase (note internally)
127
130
 
128
- 3. Generate (internally) a prioritized queue of candidate clarification questions (maximum 5). Do NOT output them all at once. Apply these constraints:
131
+ 4. Generate (internally) a prioritized queue of candidate clarification questions (maximum 5). Do NOT output them all at once. Apply these constraints:
129
132
  - Maximum of 5 total questions across the whole session.
130
133
  - Each question must be answerable with EITHER:
131
134
  - A short multiple‑choice selection (2–5 distinct, mutually exclusive options), OR
@@ -136,7 +139,7 @@ Execution steps:
136
139
  - Favor clarifications that reduce downstream rework risk or prevent misaligned acceptance tests.
137
140
  - If more than 5 categories remain unresolved, select the top 5 by (Impact * Uncertainty) heuristic.
138
141
 
139
- 4. Sequential questioning loop (interactive):
142
+ 5. Sequential questioning loop (interactive):
140
143
  - Present EXACTLY ONE question at a time.
141
144
  - For multiple‑choice questions:
142
145
  - **Analyze all options** and determine the **most suitable option** based on:
@@ -172,7 +175,7 @@ Execution steps:
172
175
  - Never reveal future queued questions in advance.
173
176
  - If no valid questions exist at start, immediately report no critical ambiguities.
174
177
 
175
- 5. Integration after EACH accepted answer (incremental update approach):
178
+ 6. Integration after EACH accepted answer (incremental update approach):
176
179
  - Maintain in-memory representation of the spec (loaded once at start) plus the raw file contents.
177
180
  - For the first integrated answer in this session:
178
181
  - Ensure a `## Clarifications` section exists (create it just after the highest-level contextual/overview section per the spec template if missing).
@@ -190,7 +193,7 @@ Execution steps:
190
193
  - Preserve formatting: do not reorder unrelated sections; keep heading hierarchy intact.
191
194
  - Keep each inserted clarification minimal and testable (avoid narrative drift).
192
195
 
193
- 6. Validation (performed after EACH write plus final pass):
196
+ 7. Validation (performed after EACH write plus final pass):
194
197
  - Clarifications session contains exactly one bullet per accepted answer (no duplicates).
195
198
  - Total asked (accepted) questions ≤ 5.
196
199
  - Updated sections contain no lingering vague placeholders the new answer was meant to resolve.
@@ -198,15 +201,26 @@ Execution steps:
198
201
  - Markdown structure valid; only allowed new headings: `## Clarifications`, `### Session YYYY-MM-DD`.
199
202
  - Terminology consistency: same canonical term used across all updated sections.
200
203
 
201
- 7. Write the updated spec back to `FEATURE_SPEC`.
202
-
203
- 8. Report completion (after questioning loop ends or early termination):
204
- - Number of questions asked & answered.
205
- - Path to updated spec.
206
- - Sections touched (list names).
207
- - Coverage summary table listing each taxonomy category with Status: Resolved (was Partial/Missing and addressed), Deferred (exceeds question quota or better suited for planning), Clear (already sufficient), Outstanding (still Partial/Missing but low impact).
208
- - If any Outstanding or Deferred remain, recommend whether to proceed to `/speckit-plan` or run `/speckit-clarify` again later post-plan.
209
- - Suggested next command.
204
+ 8. Write the updated spec back to `FEATURE_SPEC`.
205
+
206
+ 9. **Re-validate Spec Quality Checklist** (if it exists):
207
+ - Check if `FEATURE_DIR/checklists/requirements.md` exists.
208
+ - If it does NOT exist, skip this step silently.
209
+ - If it exists:
210
+ 1. Read the checklist file.
211
+ 2. Identify all GitHub task-list checkbox lines lines matching `- [ ]`, `- [x]`, or `- [X]` (case-insensitive, tolerant of leading whitespace for nested items) outside of code fences. Ignore all other content (headings, notes, non-checkbox bullets, metadata).
212
+ 3. For each checkbox line, record its current marker state (checked or unchecked) and item text into a before-snapshot list.
213
+ 4. Re-evaluate each checkbox item against the **updated** spec (the version just saved in step 7).
214
+ 5. For each checkbox item, update only if the checked/unchecked state actually changes:
215
+ - If the item now passes and was unchecked: change `[ ]` to `[x]`.
216
+ - If the item now fails and was checked: change `[x]`/`[X]` to `[ ]`.
217
+ - If the state is unchanged: leave the marker as-is (preserve existing case to avoid cosmetic diffs).
218
+ 6. Save the updated checklist file. **Only toggle the `[ ]`/`[x]` marker portion of checkbox lines whose state changed.** All other file content — headings, metadata, notes, line ordering, whitespace — must remain unchanged to avoid noisy diffs.
219
+ 7. Compare the before-snapshot with the current state to compute three lists for the Completion Report:
220
+ - **Newly passing**: items that changed from unchecked to checked.
221
+ - **Regressions**: items that changed from checked to unchecked.
222
+ - **Still unchecked**: items that remain unchecked.
223
+ 8. Record the before/after pass counts as checked/total checkbox items (e.g., "12/16 → 15/16 items passing").
210
224
 
211
225
  Behavior rules:
212
226
 
@@ -220,18 +234,29 @@ Behavior rules:
220
234
 
221
235
  Context for prioritization: $ARGUMENTS
222
236
 
223
- ## Post-Execution Checks
237
+ ## Mandatory Post-Execution Hooks
238
+
239
+ **You MUST complete this section before reporting completion to the user.**
224
240
 
225
- **Check for extension hooks (after clarification)**:
226
241
  Check if `.specify/extensions.yml` exists in the project root.
227
- - If it exists, read it and look for entries under the `hooks.after_clarify` key
228
- - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally
242
+ - If it does not exist, or no hooks are registered under `hooks.after_clarify`, skip to the Completion Report.
243
+ - If it exists, read it and look for entries under the `hooks.after_clarify` key.
244
+ - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue to the Completion Report.
229
245
  - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default.
230
246
  - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
231
247
  - If the hook has no `condition` field, or it is null/empty, treat the hook as executable
232
248
  - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
233
249
  - When constructing slash commands from hook command names, replace dots (`.`) with hyphens (`-`). For example, `speckit.git.commit` → `/speckit-git-commit`.
234
250
  - For each executable hook, output the following based on its `optional` flag:
251
+ - **Mandatory hook** (`optional: false`) — **You MUST emit `EXECUTE_COMMAND:` for each mandatory hook**:
252
+ ```
253
+ ## Extension Hooks
254
+
255
+ **Automatic Hook**: {extension}
256
+ Executing: `/{command}`
257
+ EXECUTE_COMMAND: {command}
258
+ ```
259
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
235
260
  - **Optional hook** (`optional: true`):
236
261
  ```
237
262
  ## Extension Hooks
@@ -243,12 +268,21 @@ Check if `.specify/extensions.yml` exists in the project root.
243
268
  Prompt: {prompt}
244
269
  To execute: `/{command}`
245
270
  ```
246
- - **Mandatory hook** (`optional: false`):
247
- ```
248
- ## Extension Hooks
249
271
 
250
- **Automatic Hook**: {extension}
251
- Executing: `/{command}`
252
- EXECUTE_COMMAND: {command}
253
- ```
254
- - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
272
+ ## Completion Report
273
+
274
+ Report completion (after questioning loop ends or early termination):
275
+ - Number of questions asked & answered.
276
+ - Path to updated spec.
277
+ - Sections touched (list names).
278
+ - Spec quality checklist status (if `FEATURE_DIR/checklists/requirements.md` was re-validated): show before/after pass counts (e.g., "Spec Quality Checklist: 12/16 → 15/16 items passing") and list any items that changed state — both newly checked (unchecked → checked) and any regressions (checked → unchecked). If any items remain unchecked, list them as areas needing attention.
279
+ - Coverage summary table listing each taxonomy category with Status: Resolved (was Partial/Missing and addressed), Deferred (exceeds question quota or better suited for planning), Clear (already sufficient), Outstanding (still Partial/Missing but low impact).
280
+ - If any Outstanding or Deferred remain, recommend whether to proceed to `/speckit-plan` or run `/speckit-clarify` again later post-plan.
281
+ - Suggested next command.
282
+
283
+ ## Done When
284
+
285
+ - [ ] Spec ambiguities identified and clarifications integrated into spec file
286
+ - [ ] Spec quality checklist re-validated against updated spec (if `FEATURE_DIR/checklists/requirements.md` exists)
287
+ - [ ] Extension hooks dispatched or skipped according to the rules in Mandatory Post-Execution Hooks above
288
+ - [ ] Completion reported to user with questions answered, sections touched, checklist status, and coverage summary
@@ -52,6 +52,7 @@ You **MUST** consider the user input before proceeding (if not empty).
52
52
 
53
53
  Wait for the result of the hook command before proceeding to the Outline.
54
54
  ```
55
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
55
56
  - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
56
57
 
57
58
  ## Outline
@@ -86,7 +87,7 @@ Follow this execution flow:
86
87
  - Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
87
88
  - Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
88
89
  - Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
89
- - Read each command file in `.specify/templates/commands/*.md` (including this one) to verify no outdated references (agent-specific names like CLAUDE only) remain when generic guidance is required.
90
+ - Read each installed Spec Kit command file for your agent (including this one) — named `speckit.*` or `speckit-*` (dot or hyphen depending on the agent), or laid out as `speckit-<name>/SKILL.md` for skills-based integrations, e.g. in `.github/agents/`, `.github/skills/`, `.claude/skills/`, or your agent's equivalent commands directory — to verify no outdated references (CLAUDE-only or other agent-specific names) remain when generic guidance is required.
90
91
  - Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
91
92
 
92
93
  5. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update):
@@ -154,4 +155,5 @@ Check if `.specify/extensions.yml` exists in the project root.
154
155
  Executing: `/{command}`
155
156
  EXECUTE_COMMAND: {command}
156
157
  ```
158
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
157
159
  - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
@@ -0,0 +1,279 @@
1
+ ---
2
+ name: "speckit-converge"
3
+ description: "Assess the current codebase against the feature's spec, plan, and tasks, then append any remaining unbuilt work as new tasks to tasks.md so implement can complete it."
4
+ compatibility: "Requires spec-kit project structure with .specify/ directory"
5
+ metadata:
6
+ author: "github-spec-kit"
7
+ source: "templates/commands/converge.md"
8
+ user-invocable: true
9
+ disable-model-invocation: false
10
+ ---
11
+
12
+
13
+ ## User Input
14
+
15
+ ```text
16
+ $ARGUMENTS
17
+ ```
18
+
19
+ You **MUST** consider the user input before proceeding (if not empty).
20
+
21
+ ## Pre-Execution Checks
22
+
23
+ **Check for extension hooks (before convergence)**:
24
+
25
+ - Check if `.specify/extensions.yml` exists in the project root.
26
+ - If it exists, read it and look for entries under the `hooks.before_converge` key
27
+ - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally
28
+ - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default.
29
+ - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
30
+ - If the hook has no `condition` field, or it is null/empty, treat the hook as executable
31
+ - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
32
+ - When constructing slash commands from hook command names, replace dots (`.`) with hyphens (`-`). For example, `speckit.git.commit` → `/speckit-git-commit`.
33
+ - For each executable hook, output the following based on its `optional` flag:
34
+ - **Optional hook** (`optional: true`):
35
+
36
+ ```text
37
+ ## Extension Hooks
38
+
39
+ **Optional Pre-Hook**: {extension}
40
+ Command: `/{command}`
41
+ Description: {description}
42
+
43
+ Prompt: {prompt}
44
+ To execute: `/{command}`
45
+ ```
46
+
47
+ - **Mandatory hook** (`optional: false`):
48
+
49
+ ```text
50
+ ## Extension Hooks
51
+
52
+ **Automatic Pre-Hook**: {extension}
53
+ Executing: `/{command}`
54
+ EXECUTE_COMMAND: {command}
55
+
56
+ Wait for the result of the hook command before proceeding to the Goal.
57
+ ```
58
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
59
+
60
+ - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
61
+
62
+ ## Goal
63
+
64
+ Close the gap between what a feature's specification, plan, and tasks call for and what the
65
+ codebase currently implements. Read `spec.md`, `plan.md`, and `tasks.md` as the **sole
66
+ source of intent** (with the constitution as governing constraints), assess the current
67
+ state of the code, determine which requirements, acceptance criteria, plan decisions, and
68
+ existing tasks are unmet, incomplete, or only partially satisfied, and **append each piece
69
+ of remaining work as a new, traceable task** at the bottom of `tasks.md` so that
70
+ `/speckit-implement` can complete it. This command MUST run only after
71
+ `/speckit-implement` has run on the current `tasks.md`, and after `/speckit-tasks` has produced a complete `tasks.md`.
72
+
73
+ This is **not** a diff tool and does **not** track changes. It assesses the present state
74
+ of the code relative to the feature's artifacts — no git, no branch comparison, no history.
75
+
76
+ ## Operating Constraints
77
+
78
+ **APPEND-ONLY, NEVER REWRITE**: The command's **only** write is appending a new
79
+ `## Phase N: Convergence` section to `tasks.md`. It MUST NOT:
80
+
81
+ - modify `spec.md` or `plan.md` in any way;
82
+ - rewrite, renumber, reorder, or delete any existing task (including tasks from a prior
83
+ Convergence phase);
84
+ - modify, create, or delete any application code — completing the appended tasks is the
85
+ job of `/speckit-implement`.
86
+
87
+ When the codebase already satisfies everything, the command MUST leave `tasks.md`
88
+ **byte-for-byte unchanged** (no empty Convergence header) and report a clean result.
89
+
90
+ **Constitution Authority**: The project constitution (`.specify/memory/constitution.md`) is
91
+ **non-negotiable**. Code that violates a MUST principle is the highest-severity finding and
92
+ produces a corresponding remediation task. If the constitution is an unfilled template,
93
+ skip constitution checks gracefully rather than failing.
94
+
95
+ ## Execution Steps
96
+
97
+ ### 1. Initialize Convergence Context
98
+
99
+ Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` once from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS. Derive absolute paths:
100
+
101
+ - SPEC = FEATURE_DIR/spec.md
102
+ - PLAN = FEATURE_DIR/plan.md
103
+ - TASKS = FEATURE_DIR/tasks.md
104
+ - CONSTITUTION = `.specify/memory/constitution.md` (if present)
105
+ If `spec.md`, `plan.md`, or `tasks.md` is missing, STOP with a clear, actionable message naming the
106
+ prerequisite command to run (`/speckit-specify` for a missing spec, `/speckit-plan` for a missing plan,
107
+ `/speckit-tasks` for missing tasks). Do not produce partial output.
108
+ For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot").
109
+
110
+ ### 2. Load Artifacts (Progressive Disclosure)
111
+
112
+ Load only the minimal necessary context from each artifact:
113
+
114
+ **From spec.md:**
115
+
116
+ - Functional Requirements (FR-###)
117
+ - Success Criteria (SC-###) — include only items requiring buildable work; exclude
118
+ post-launch outcome metrics and business KPIs
119
+ - User Stories and their Acceptance Scenarios
120
+ - Edge Cases (if present)
121
+
122
+ **From plan.md:**
123
+
124
+ - Architecture/stack choices and technical decisions
125
+ - Data Model references
126
+ - Phases and named touch-points (files/components the plan says will be created or edited)
127
+ - Technical constraints
128
+
129
+ **From tasks.md:**
130
+
131
+ - Task IDs (to compute the next ID and next phase number)
132
+ - Descriptions, phase grouping, and referenced file paths
133
+
134
+ **From constitution (if not an unfilled template):**
135
+
136
+ - Principle names and MUST/SHOULD normative statements
137
+
138
+ ### 3. Build the Intent Inventory
139
+
140
+ Create an internal model (do not echo raw artifacts):
141
+
142
+ - **Requirements inventory**: one stable key per FR-### / SC-### / user-story acceptance
143
+ scenario (e.g. `US1/AC2`), plus the plan decisions and constitution principles that
144
+ impose buildable obligations.
145
+ - **Code-scope map**: from the file paths named in `plan.md` and `tasks.md`, plus a keyword
146
+ search for the concepts each requirement describes, derive the set of source files and
147
+ components in scope for assessment. Bound the assessment to these — do **not** infer
148
+ scope beyond what the artifacts define.
149
+
150
+ ### 4. Assess the Codebase and Classify Findings
151
+
152
+ For each item in the intent inventory, inspect the current code in scope and produce a
153
+ `Finding` only where there is a gap. Classify every finding by **gap type**:
154
+
155
+ - **`missing`**: the required work is absent from the code entirely.
156
+ - **`partial`**: the work exists but does not yet fully satisfy the requirement /
157
+ acceptance criterion / plan decision.
158
+ - **`contradicts`**: the code does something that conflicts with stated intent or a
159
+ constitution MUST principle.
160
+ - **`unrequested`**: the code contains work not called for by the spec, plan, or tasks
161
+ (surfaced for awareness — converge does **not** delete code, it only appends a task to
162
+ review/justify or remove it).
163
+
164
+ Each `Finding` records: a stable id, the `source-ref` it traces to, the `gap-type`, a
165
+ severity, and a short human-readable description with the evidence (the file/area observed).
166
+
167
+ **Edge cases:**
168
+
169
+ - **Little or no code yet**: treat the entire specified scope as `missing` remaining work
170
+ rather than failing.
171
+ - **Nothing remains**: produce zero findings and follow the converged branch in Step 7.
172
+
173
+ ### 5. Assign Severity
174
+
175
+ - **CRITICAL**: violates a constitution MUST principle, or a `missing`/`contradicts` gap
176
+ that blocks baseline functionality of a P1 user story.
177
+ - **HIGH**: a `missing` or `partial` gap on a core functional requirement or acceptance
178
+ criterion.
179
+ - **MEDIUM**: a `partial` gap on a secondary requirement, or an `unrequested` addition with
180
+ unclear justification.
181
+ - **LOW**: minor partial gaps, polish, or low-risk `unrequested` additions.
182
+
183
+ ### 6. Present the In-Session Findings Summary
184
+
185
+ Before appending anything, output a compact, severity-graded summary (no file writes yet):
186
+
187
+ ## Convergence Findings
188
+
189
+ | ID | Gap Type | Severity | Source | Evidence | Remaining Work |
190
+ |----|----------|----------|--------|----------|----------------|
191
+ | F1 | missing | HIGH | FR-008 | Example: no append-only guard detected in path/to/module.py when writing tasks.md | Add append-only enforcement |
192
+
193
+ **Summary metrics:**
194
+
195
+ - Requirements / acceptance criteria checked
196
+ - Plan decisions checked
197
+ - Constitution principles checked (or "skipped — template")
198
+ - Findings by gap type (missing / partial / contradicts / unrequested)
199
+ - Findings by severity
200
+
201
+ ### 7. Append Convergence Tasks (or report converged)
202
+
203
+ **If there are one or more actionable findings** (`tasks_appended` outcome):
204
+
205
+ Append to the **end** of `tasks.md`, per the append contract:
206
+
207
+ 1. Scan all existing task IDs; let `M` be the maximum. Determine the next phase number `N`
208
+ (highest existing phase + 1).
209
+ 2. Write a single new section header `## Phase N: Convergence`.
210
+ 3. Emit one checklist item per actionable finding, ordered CRITICAL/HIGH first, assigning
211
+ zero-padded IDs `T{M+1:03d}, T{M+2:03d}, …`:
212
+
213
+ ```markdown
214
+ - [ ] T042 <imperative description> per <source-ref> (<gap-type>)
215
+ ```
216
+
217
+ `<source-ref>` traces the task to its origin: e.g. `FR-003`, `SC-002`,
218
+ `US1/AC2`, `plan: storage decision`, `Constitution II`.
219
+
220
+ `<gap-type>` is one of `missing`, `partial`, `contradicts`, `unrequested`.
221
+
222
+ Constitution-violation tasks MUST be emitted first and described as
223
+ `CRITICAL`.
224
+ 4. Never reuse or renumber existing IDs. If a prior Convergence phase exists, add a new,
225
+ separately-numbered one below it — do not touch the old one.
226
+
227
+ **If there are no actionable findings** (`converged` outcome):
228
+
229
+ - Do **not** modify `tasks.md` at all — no empty phase header.
230
+ - Report: **"✅ Converged — the implementation satisfies the spec, plan, and tasks."**
231
+ - Include the summary counts of what was checked.
232
+
233
+ ### 8. Provide Next Actions (Handoff)
234
+
235
+ - On `tasks_appended`: state how many tasks were appended under which phase, and recommend
236
+ running `/speckit-implement` to complete them; note that a follow-up converge
237
+ run will find fewer or no remaining items.
238
+ - On `converged`: recommend proceeding to review / opening a PR. No further implement pass
239
+ is needed for this feature's specified scope.
240
+
241
+ ### 9. Check for extension hooks
242
+
243
+ After producing the result, check if `.specify/extensions.yml` exists in the project root.
244
+
245
+ - If it exists, read it and look for entries under the `hooks.after_converge` key
246
+ - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally
247
+ - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default.
248
+ - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
249
+ - If the hook has no `condition` field, or it is null/empty, treat the hook as executable
250
+ - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
251
+ - Report the convergence outcome (`converged` or `tasks_appended`) in-session before listing
252
+ any hooks, so users can decide whether to run optional follow-up commands.
253
+ - When constructing slash commands from hook command names, replace dots (`.`) with hyphens (`-`). For example, `speckit.git.commit` → `/speckit-git-commit`.
254
+ - For each executable hook, output the following based on its `optional` flag:
255
+ - **Optional hook** (`optional: true`):
256
+
257
+ ```text
258
+ ## Extension Hooks
259
+
260
+ **Optional Hook**: {extension}
261
+ Command: `/{command}`
262
+ Description: {description}
263
+
264
+ Prompt: {prompt}
265
+ To execute: `/{command}`
266
+ ```
267
+
268
+ - **Mandatory hook** (`optional: false`):
269
+
270
+ ```text
271
+ ## Extension Hooks
272
+
273
+ **Automatic Hook**: {extension}
274
+ Executing: `/{command}`
275
+ EXECUTE_COMMAND: {command}
276
+ ```
277
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
278
+
279
+ - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
@@ -49,9 +49,10 @@ You **MUST** consider the user input before proceeding (if not empty).
49
49
  **Automatic Pre-Hook**: {extension}
50
50
  Executing: `/{command}`
51
51
  EXECUTE_COMMAND: {command}
52
-
52
+
53
53
  Wait for the result of the hook command before proceeding to the Outline.
54
54
  ```
55
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
55
56
  - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
56
57
 
57
58
  ## Outline
@@ -150,7 +151,7 @@ You **MUST** consider the user input before proceeding (if not empty).
150
151
 
151
152
  6. Execute implementation following the task plan:
152
153
  - **Phase-by-phase execution**: Complete each phase before moving to the next
153
- - **Respect dependencies**: Run sequential tasks in order, parallel tasks [P] can run together
154
+ - **Respect dependencies**: Run sequential tasks in order, parallel tasks [P] can run together
154
155
  - **Follow TDD approach**: Execute test tasks before their corresponding implementation tasks
155
156
  - **File-based coordination**: Tasks affecting the same files must run sequentially
156
157
  - **Validation checkpoints**: Verify each phase completion before proceeding
@@ -175,36 +176,51 @@ You **MUST** consider the user input before proceeding (if not empty).
175
176
  - Check that implemented features match the original specification
176
177
  - Validate that tests pass and coverage meets requirements
177
178
  - Confirm the implementation follows the technical plan
178
- - Report final status with summary of completed work
179
179
 
180
180
  Note: This command assumes a complete task breakdown exists in tasks.md. If tasks are incomplete or missing, suggest running `/speckit-tasks` first to regenerate the task list.
181
181
 
182
- 10. **Check for extension hooks**: After completion validation, check if `.specify/extensions.yml` exists in the project root.
183
- - If it exists, read it and look for entries under the `hooks.after_implement` key
184
- - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally
185
- - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default.
186
- - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
187
- - If the hook has no `condition` field, or it is null/empty, treat the hook as executable
188
- - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
189
- - When constructing slash commands from hook command names, replace dots (`.`) with hyphens (`-`). For example, `speckit.git.commit` → `/speckit-git-commit`.
190
- - For each executable hook, output the following based on its `optional` flag:
191
- - **Optional hook** (`optional: true`):
192
- ```
193
- ## Extension Hooks
194
-
195
- **Optional Hook**: {extension}
196
- Command: `/{command}`
197
- Description: {description}
198
-
199
- Prompt: {prompt}
200
- To execute: `/{command}`
201
- ```
202
- - **Mandatory hook** (`optional: false`):
203
- ```
204
- ## Extension Hooks
205
-
206
- **Automatic Hook**: {extension}
207
- Executing: `/{command}`
208
- EXECUTE_COMMAND: {command}
209
- ```
210
- - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
182
+ ## Mandatory Post-Execution Hooks
183
+
184
+ **You MUST complete this section before reporting completion to the user.**
185
+
186
+ Check if `.specify/extensions.yml` exists in the project root.
187
+ - If it does not exist, or no hooks are registered under `hooks.after_implement`, skip to the Completion Report.
188
+ - If it exists, read it and look for entries under the `hooks.after_implement` key.
189
+ - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue to the Completion Report.
190
+ - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default.
191
+ - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
192
+ - If the hook has no `condition` field, or it is null/empty, treat the hook as executable
193
+ - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
194
+ - When constructing slash commands from hook command names, replace dots (`.`) with hyphens (`-`). For example, `speckit.git.commit` → `/speckit-git-commit`.
195
+ - For each executable hook, output the following based on its `optional` flag:
196
+ - **Mandatory hook** (`optional: false`) — **You MUST emit `EXECUTE_COMMAND:` for each mandatory hook**:
197
+ ```
198
+ ## Extension Hooks
199
+
200
+ **Automatic Hook**: {extension}
201
+ Executing: `/{command}`
202
+ EXECUTE_COMMAND: {command}
203
+ ```
204
+ After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
205
+ - **Optional hook** (`optional: true`):
206
+ ```
207
+ ## Extension Hooks
208
+
209
+ **Optional Hook**: {extension}
210
+ Command: `/{command}`
211
+ Description: {description}
212
+
213
+ Prompt: {prompt}
214
+ To execute: `/{command}`
215
+ ```
216
+
217
+ ## Completion Report
218
+
219
+ Report final status with summary of completed work.
220
+
221
+ ## Done When
222
+
223
+ - [ ] All tasks in tasks.md completed and marked `[X]`
224
+ - [ ] Implementation validated against specification, plan, and test coverage
225
+ - [ ] Extension hooks dispatched or skipped according to the rules in Mandatory Post-Execution Hooks above
226
+ - [ ] Completion reported to user with summary of completed work