remo-cli 2.2.0rc13__tar.gz → 3.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- remo_cli-3.0.0/.claude/skills/release/SKILL.md +173 -0
- remo_cli-3.0.0/.github/CODEOWNERS +5 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/dependabot.yml +6 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/ci.yml +49 -13
- remo_cli-3.0.0/.github/workflows/codeql.yml +44 -0
- remo_cli-3.0.0/.github/workflows/dependency-review.yml +18 -0
- remo_cli-3.0.0/.github/workflows/dev-build.yml +78 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/provision.yml +2 -2
- remo_cli-3.0.0/.github/workflows/release-please.yml +57 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/release.yml +13 -13
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/smoke-test-cleanup.yml +2 -2
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/smoke-test.yml +27 -17
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.github/workflows/teardown.yml +2 -2
- remo_cli-3.0.0/.release-please-manifest.json +3 -0
- remo_cli-3.0.0/.specify/feature.json +3 -0
- remo_cli-3.0.0/.specify/memory/constitution.md +461 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/plan-template.md +13 -1
- remo_cli-3.0.0/AGENTS.md +328 -0
- remo_cli-3.0.0/CHANGELOG.md +49 -0
- remo_cli-3.0.0/CLAUDE.md +324 -0
- remo_cli-3.0.0/CONTRIBUTING.md +208 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/PKG-INFO +146 -38
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/README.md +145 -37
- remo_cli-3.0.0/SECURITY.md +31 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_bootstrap.yml +1 -1
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/docker/tasks/main.yml +17 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/github_cli/tasks/main.yml +4 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/hetzner_server/tasks/main.yml +2 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_bootstrap/tasks/main.yml +4 -0
- remo_cli-3.0.0/ansible/roles/nodejs/defaults/main.yml +10 -0
- remo_cli-3.0.0/ansible/roles/nodejs/files/nodesource-repo.gpg.key +30 -0
- remo_cli-3.0.0/ansible/roles/nodejs/tasks/main.yml +95 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/defaults/main.yml +1 -1
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/tasks/preflight.yml +1 -1
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/aws.md +24 -10
- remo_cli-3.0.0/docs/feature-history.md +22 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/hetzner.md +77 -11
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/incus.md +99 -22
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0/docs}/install.sh +0 -1
- remo_cli-3.0.0/docs/maintaining-claude-md.md +109 -0
- remo_cli-3.0.0/docs/maintaining-generated-types.md +110 -0
- remo_cli-3.0.0/docs/providers.md +349 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/proxmox.md +93 -34
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/web-session-interface.md +196 -93
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/package-lock.json +309 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/package.json +5 -1
- remo_cli-3.0.0/frontend/scripts/check-types-fresh.mjs +277 -0
- remo_cli-3.0.0/frontend/scripts/generate-frame-types.mjs +145 -0
- remo_cli-3.0.0/frontend/scripts/generate-schema-types.mjs +65 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/api/client.ts +36 -92
- remo_cli-3.0.0/frontend/src/api/generated/README.md +15 -0
- remo_cli-3.0.0/frontend/src/api/generated/openapi.json +1170 -0
- remo_cli-3.0.0/frontend/src/api/generated/schema.d.ts +988 -0
- remo_cli-3.0.0/frontend/src/api/generated/terminal-frames.d.ts +129 -0
- remo_cli-3.0.0/frontend/src/api/generated/terminal-frames.json +199 -0
- remo_cli-3.0.0/frontend/src/api/generated.test.ts +70 -0
- remo_cli-3.0.0/frontend/src/components/providerMeta.test.ts +41 -0
- remo_cli-3.0.0/frontend/src/components/providerMeta.ts +69 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/TerminalConnection.ts +7 -7
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/vite.config.ts +6 -1
- {remo_cli-2.2.0rc13/docs → remo_cli-3.0.0}/install.sh +52 -1
- remo_cli-3.0.0/pyproject.toml +78 -0
- remo_cli-3.0.0/release-please-config.json +21 -0
- remo_cli-3.0.0/remo.svg +8 -0
- remo_cli-3.0.0/scripts/export_openapi.py +149 -0
- remo_cli-3.0.0/specs/013-managed-instance-tags/contracts/cli-sync.md +59 -0
- remo_cli-3.0.0/specs/013-managed-instance-tags/contracts/marker-commands.md +58 -0
- remo_cli-3.0.0/specs/013-managed-instance-tags/data-model.md +80 -0
- remo_cli-3.0.0/specs/013-managed-instance-tags/plan.md +131 -0
- remo_cli-3.0.0/specs/013-managed-instance-tags/quickstart.md +93 -0
- remo_cli-3.0.0/specs/013-managed-instance-tags/research.md +132 -0
- remo_cli-3.0.0/specs/013-managed-instance-tags/spec.md +309 -0
- remo_cli-3.0.0/specs/013-managed-instance-tags/tasks.md +198 -0
- remo_cli-3.0.0/specs/014-register-ssh-host/contracts/add-command.md +47 -0
- remo_cli-3.0.0/specs/014-register-ssh-host/contracts/remove-command.md +33 -0
- remo_cli-3.0.0/specs/014-register-ssh-host/data-model.md +91 -0
- remo_cli-3.0.0/specs/014-register-ssh-host/plan.md +147 -0
- remo_cli-3.0.0/specs/014-register-ssh-host/quickstart.md +121 -0
- remo_cli-3.0.0/specs/014-register-ssh-host/research.md +192 -0
- remo_cli-3.0.0/specs/014-register-ssh-host/spec.md +333 -0
- remo_cli-3.0.0/specs/014-register-ssh-host/tasks.md +184 -0
- remo_cli-3.0.0/specs/015-registry-v2/checklists/requirements.md +36 -0
- remo_cli-3.0.0/specs/015-registry-v2/contracts/mirror-payload-v2.md +77 -0
- remo_cli-3.0.0/specs/015-registry-v2/contracts/registry-accessor-api.md +92 -0
- remo_cli-3.0.0/specs/015-registry-v2/contracts/registry-file-v2.md +130 -0
- remo_cli-3.0.0/specs/015-registry-v2/data-model.md +113 -0
- remo_cli-3.0.0/specs/015-registry-v2/plan.md +114 -0
- remo_cli-3.0.0/specs/015-registry-v2/quickstart.md +118 -0
- remo_cli-3.0.0/specs/015-registry-v2/research.md +115 -0
- remo_cli-3.0.0/specs/015-registry-v2/spec.md +195 -0
- remo_cli-3.0.0/specs/015-registry-v2/tasks.md +181 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/checklists/requirements.md +44 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/contracts/cli-sync.md +113 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/contracts/provider-probe.md +96 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/data-model.md +167 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/plan.md +157 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/quickstart.md +129 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/research.md +164 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/spec.md +290 -0
- remo_cli-3.0.0/specs/016-sync-reconcile/tasks.md +304 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/checklists/requirements.md +36 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/contracts/cli-web-push.md +43 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/contracts/cli-web-status.md +50 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/contracts/revocation.md +40 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/contracts/setup-status-marker.md +59 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/data-model.md +109 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/plan.md +111 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/quickstart.md +138 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/research.md +91 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/spec.md +225 -0
- remo_cli-3.0.0/specs/017-web-adopt-simplify/tasks.md +268 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/baseline-notes.md +9 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/checklists/requirements.md +38 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/contracts/cli-surface.md +44 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/contracts/errors.md +37 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/contracts/lifecycle-templates.md +32 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/contracts/provider-protocol.md +53 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/contracts/sync-merge.md +37 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/data-model.md +109 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/plan.md +112 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/quickstart.md +81 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/research.md +105 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/spec.md +210 -0
- remo_cli-3.0.0/specs/018-provider-abstraction/tasks.md +190 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/checklists/requirements.md +64 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/contracts/cli-surface-delta.md +100 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/contracts/docs-structure-check.md +154 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/data-model.md +154 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/plan.md +149 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/quickstart.md +297 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/research.md +288 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/spec.md +418 -0
- remo_cli-3.0.0/specs/019-hygiene-deps-docs/tasks.md +304 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/checklists/requirements.md +78 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/contracts/drift-checks.md +107 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/contracts/terminal-frames-v1.md +94 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/data-model.md +144 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/plan.md +234 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/quickstart.md +174 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/research.md +291 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/spec.md +216 -0
- remo_cli-3.0.0/specs/020-openapi-type-generation/tasks.md +327 -0
- remo_cli-3.0.0/specs/021-cli-plane-separation/contracts/cli-surface.md +90 -0
- remo_cli-3.0.0/specs/021-cli-plane-separation/contracts/descriptor-schema.md +64 -0
- remo_cli-3.0.0/specs/021-cli-plane-separation/data-model.md +101 -0
- remo_cli-3.0.0/specs/021-cli-plane-separation/plan.md +148 -0
- remo_cli-3.0.0/specs/021-cli-plane-separation/quickstart.md +100 -0
- remo_cli-3.0.0/specs/021-cli-plane-separation/research.md +223 -0
- remo_cli-3.0.0/specs/021-cli-plane-separation/spec.md +184 -0
- remo_cli-3.0.0/specs/021-cli-plane-separation/tasks.md +248 -0
- remo_cli-3.0.0/src/remo_cli/__main__.py +5 -0
- remo_cli-3.0.0/src/remo_cli/cli/added.py +106 -0
- remo_cli-3.0.0/src/remo_cli/cli/main.py +287 -0
- remo_cli-3.0.0/src/remo_cli/cli/providers/factory.py +550 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/shell.py +77 -42
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/web.py +101 -31
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/ansible_runner.py +33 -0
- remo_cli-3.0.0/src/remo_cli/core/completion.py +323 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/config.py +58 -0
- remo_cli-3.0.0/src/remo_cli/core/errors.py +45 -0
- remo_cli-3.0.0/src/remo_cli/core/known_hosts.py +255 -0
- remo_cli-3.0.0/src/remo_cli/core/lifecycle.py +82 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/output.py +41 -0
- remo_cli-3.0.0/src/remo_cli/core/provider_protocol.py +50 -0
- remo_cli-3.0.0/src/remo_cli/core/provider_registry.py +341 -0
- remo_cli-3.0.0/src/remo_cli/core/reconcile.py +522 -0
- remo_cli-3.0.0/src/remo_cli/core/registry.py +851 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/snapshot.py +29 -1
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/ssh.py +53 -29
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/web_adopt.py +526 -183
- remo_cli-3.0.0/src/remo_cli/core/web_drift.py +194 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/host.py +33 -0
- remo_cli-3.0.0/src/remo_cli/providers/added.py +354 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/providers/aws.py +435 -231
- remo_cli-3.0.0/src/remo_cli/providers/aws_descriptor.py +100 -0
- remo_cli-3.0.0/src/remo_cli/providers/builtin.py +19 -0
- remo_cli-3.0.0/src/remo_cli/providers/hetzner.py +894 -0
- remo_cli-3.0.0/src/remo_cli/providers/hetzner_descriptor.py +55 -0
- remo_cli-3.0.0/src/remo_cli/providers/incus.py +1174 -0
- remo_cli-3.0.0/src/remo_cli/providers/incus_descriptor.py +118 -0
- remo_cli-3.0.0/src/remo_cli/providers/proxmox.py +1353 -0
- remo_cli-3.0.0/src/remo_cli/providers/proxmox_descriptor.py +141 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/api/hosts.py +43 -10
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/api/pairing.py +26 -3
- remo_cli-3.0.0/src/remo_cli/web/api/setup.py +605 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/api/terminals.py +63 -34
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/check.py +54 -15
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/config.py +35 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/discovery.py +39 -41
- remo_cli-3.0.0/src/remo_cli/web/frames.py +108 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/health.py +16 -2
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/state.py +86 -46
- remo_cli-3.0.0/tests/conftest.py +120 -0
- remo_cli-3.0.0/tests/integration/fish_completion.sh +202 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/orbstack.sh +2 -2
- remo_cli-3.0.0/tests/integration/test_registry_concurrency.py +98 -0
- remo_cli-3.0.0/tests/integration/test_setup_payload_versions.py +279 -0
- remo_cli-3.0.0/tests/integration/test_sync_reconcile.py +245 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_web_adopt_e2e.py +91 -32
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_web_cli_parity.py +179 -1
- remo_cli-3.0.0/tests/perf/test_registry_perf.py +86 -0
- remo_cli-3.0.0/tests/unit/cli/providers/test_aws_snapshot.py +223 -0
- remo_cli-3.0.0/tests/unit/cli/providers/test_hetzner_snapshot.py +191 -0
- remo_cli-3.0.0/tests/unit/cli/providers/test_incus_snapshot.py +376 -0
- remo_cli-3.0.0/tests/unit/cli/providers/test_incus_sync_all.py +59 -0
- remo_cli-3.0.0/tests/unit/cli/providers/test_proxmox_snapshot.py +211 -0
- remo_cli-3.0.0/tests/unit/cli/providers/test_proxmox_sync_all.py +68 -0
- remo_cli-3.0.0/tests/unit/cli/surface_baseline.py +267 -0
- remo_cli-3.0.0/tests/unit/cli/test_add_cmd.py +51 -0
- remo_cli-3.0.0/tests/unit/cli/test_cli_uniformity.py +139 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/test_main.py +68 -3
- remo_cli-3.0.0/tests/unit/cli/test_remove_cmd.py +32 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/test_shell.py +135 -33
- remo_cli-3.0.0/tests/unit/cli/test_shell_added.py +76 -0
- remo_cli-3.0.0/tests/unit/cli/test_startup_imports.py +27 -0
- remo_cli-3.0.0/tests/unit/cli/test_surface_preservation.py +59 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/test_web_adopt_cmd.py +146 -37
- remo_cli-3.0.0/tests/unit/core/test_completion.py +289 -0
- remo_cli-3.0.0/tests/unit/core/test_errors.py +44 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_known_hosts.py +27 -15
- remo_cli-3.0.0/tests/unit/core/test_lifecycle.py +108 -0
- remo_cli-3.0.0/tests/unit/core/test_migration_tagging_notice.py +89 -0
- remo_cli-3.0.0/tests/unit/core/test_provider_registry.py +241 -0
- remo_cli-3.0.0/tests/unit/core/test_reconcile.py +892 -0
- remo_cli-3.0.0/tests/unit/core/test_registry_format.py +450 -0
- remo_cli-3.0.0/tests/unit/core/test_registry_locking.py +141 -0
- remo_cli-3.0.0/tests/unit/core/test_registry_migration.py +364 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_ssh.py +13 -13
- remo_cli-3.0.0/tests/unit/core/test_ssh_added.py +96 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_ssh_controlpath.py +2 -2
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_ssh_identity_opts.py +1 -1
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_web_adopt_authorize.py +201 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_web_adopt_payload.py +25 -16
- remo_cli-3.0.0/tests/unit/core/test_web_drift.py +187 -0
- remo_cli-3.0.0/tests/unit/core/test_web_push.py +759 -0
- remo_cli-3.0.0/tests/unit/providers/fake_provider.py +160 -0
- remo_cli-3.0.0/tests/unit/providers/test_added_add.py +264 -0
- remo_cli-3.0.0/tests/unit/providers/test_added_provider_guard.py +214 -0
- remo_cli-3.0.0/tests/unit/providers/test_added_update_remove.py +125 -0
- remo_cli-3.0.0/tests/unit/providers/test_added_verify.py +124 -0
- remo_cli-3.0.0/tests/unit/providers/test_aws_provider_protocol.py +151 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_aws_snapshot.py +103 -91
- remo_cli-3.0.0/tests/unit/providers/test_aws_sync.py +599 -0
- remo_cli-3.0.0/tests/unit/providers/test_aws_upgrade_resize.py +117 -0
- remo_cli-3.0.0/tests/unit/providers/test_hetzner_entry_adapters.py +173 -0
- remo_cli-3.0.0/tests/unit/providers/test_hetzner_http.py +280 -0
- remo_cli-3.0.0/tests/unit/providers/test_hetzner_label.py +175 -0
- remo_cli-3.0.0/tests/unit/providers/test_hetzner_resize.py +70 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_hetzner_snapshot.py +63 -91
- remo_cli-3.0.0/tests/unit/providers/test_hetzner_sync.py +272 -0
- remo_cli-3.0.0/tests/unit/providers/test_incus_entry_adapters.py +189 -0
- remo_cli-3.0.0/tests/unit/providers/test_incus_marker.py +196 -0
- remo_cli-3.0.0/tests/unit/providers/test_incus_resize.py +95 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_incus_snapshot.py +13 -132
- remo_cli-3.0.0/tests/unit/providers/test_incus_sync.py +175 -0
- remo_cli-3.0.0/tests/unit/providers/test_missing_sdk.py +58 -0
- remo_cli-3.0.0/tests/unit/providers/test_provider_conformance.py +268 -0
- remo_cli-3.0.0/tests/unit/providers/test_provider_registry_entries.py +234 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_proxmox_devcontainer_runtime.py +9 -6
- remo_cli-3.0.0/tests/unit/providers/test_proxmox_marker.py +266 -0
- remo_cli-3.0.0/tests/unit/providers/test_proxmox_provider_protocol.py +160 -0
- remo_cli-3.0.0/tests/unit/providers/test_proxmox_resize.py +114 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/test_proxmox_snapshot.py +87 -96
- remo_cli-3.0.0/tests/unit/providers/test_proxmox_sync.py +252 -0
- remo_cli-3.0.0/tests/unit/test_architecture.py +303 -0
- remo_cli-3.0.0/tests/unit/test_docs_structure.py +493 -0
- remo_cli-3.0.0/tests/unit/test_host_ssh_type.py +145 -0
- remo_cli-3.0.0/tests/unit/test_schema_drift.py +861 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/conftest.py +28 -1
- remo_cli-3.0.0/tests/unit/web/fixtures/hosts_response.json +1 -0
- remo_cli-3.0.0/tests/unit/web/fixtures/sessions_response.json +1 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_check.py +7 -2
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_csp.py +3 -2
- remo_cli-3.0.0/tests/unit/web/test_frames.py +235 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_health_states.py +2 -2
- remo_cli-3.0.0/tests/unit/web/test_payload_equivalence.py +122 -0
- remo_cli-3.0.0/tests/unit/web/test_registry_readonly.py +212 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_setup_api.py +258 -24
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_setup_auth.py +2 -2
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_state.py +87 -18
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/uv.lock +1 -1
- remo_cli-2.2.0rc13/.specify/feature.json +0 -3
- remo_cli-2.2.0rc13/.specify/memory/constitution.md +0 -164
- remo_cli-2.2.0rc13/AGENTS.md +0 -152
- remo_cli-2.2.0rc13/CLAUDE.md +0 -197
- remo_cli-2.2.0rc13/CONTRIBUTING.md +0 -113
- remo_cli-2.2.0rc13/ansible/roles/nodejs/defaults/main.yml +0 -2
- remo_cli-2.2.0rc13/ansible/roles/nodejs/tasks/main.yml +0 -64
- remo_cli-2.2.0rc13/frontend/src/components/providerMeta.ts +0 -54
- remo_cli-2.2.0rc13/pyproject.toml +0 -60
- remo_cli-2.2.0rc13/src/remo_cli/__main__.py +0 -5
- remo_cli-2.2.0rc13/src/remo_cli/cli/main.py +0 -97
- remo_cli-2.2.0rc13/src/remo_cli/cli/providers/aws.py +0 -287
- remo_cli-2.2.0rc13/src/remo_cli/cli/providers/hetzner.py +0 -232
- remo_cli-2.2.0rc13/src/remo_cli/cli/providers/incus.py +0 -332
- remo_cli-2.2.0rc13/src/remo_cli/cli/providers/proxmox.py +0 -411
- remo_cli-2.2.0rc13/src/remo_cli/core/completion.py +0 -83
- remo_cli-2.2.0rc13/src/remo_cli/core/known_hosts.py +0 -253
- remo_cli-2.2.0rc13/src/remo_cli/providers/hetzner.py +0 -736
- remo_cli-2.2.0rc13/src/remo_cli/providers/incus.py +0 -932
- remo_cli-2.2.0rc13/src/remo_cli/providers/proxmox.py +0 -1016
- remo_cli-2.2.0rc13/src/remo_cli/web/api/setup.py +0 -412
- remo_cli-2.2.0rc13/tests/conftest.py +0 -26
- remo_cli-2.2.0rc13/tests/unit/cli/providers/test_aws_snapshot.py +0 -126
- remo_cli-2.2.0rc13/tests/unit/cli/providers/test_hetzner_snapshot.py +0 -129
- remo_cli-2.2.0rc13/tests/unit/cli/providers/test_incus_snapshot.py +0 -212
- remo_cli-2.2.0rc13/tests/unit/cli/providers/test_proxmox_snapshot.py +0 -158
- remo_cli-2.2.0rc13/tests/unit/core/test_web_push.py +0 -386
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-analyze/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-checklist/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-clarify/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-constitution/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-converge/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-commit/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-feature/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-initialize/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-remote/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-git-validate/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-implement/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-plan/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-specify/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-tasks/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.claude/skills/speckit-taskstoissues/SKILL.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.devcontainer/devcontainer.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.dockerignore +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.gitignore +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.maverick/checkpoints/feature/implementation_complete.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.maverick/checkpoints/feature/phase_${{ index }}_complete.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.maverick/checkpoints/feature/validation_complete.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/.registry +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/README.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.commit.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.feature.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.initialize.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.remote.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/commands/speckit.git.validate.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/config-template.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/extension.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/git-config.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/bash/auto-commit.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/bash/create-new-feature.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/bash/git-common.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/bash/initialize-repo.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/powershell/create-new-feature.ps1 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/powershell/git-common.ps1 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/extensions.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/init-options.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/integration.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/integrations/claude.manifest.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/integrations/speckit.manifest.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/check-prerequisites.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/common.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/create-new-feature.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/setup-plan.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/setup-tasks.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/scripts/bash/update-agent-context.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/agent-file-template.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/checklist-template.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/constitution-template.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/spec-template.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/templates/tasks-template.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/workflows/speckit/workflow.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/.specify/workflows/workflow-registry.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/Dockerfile +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/LICENSE +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/.ansible-lint +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/README.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/ansible.cfg +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/aws_configure.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/aws_resize.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/aws_site.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/aws_teardown.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/group_vars/all.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/group_vars/incus_containers.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/group_vars/proxmox_containers.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_configure.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_provision.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_resize.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_site.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/hetzner_teardown.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_bootstrap.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_configure.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_provision.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_resize.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_site.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/incus_teardown.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/inventory/hosts.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/inventory/incus_containers.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_configure.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_provision.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_resize.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_site.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/proxmox_teardown.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/requirements.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/ebs.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/ec2.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/patch_manager.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/preflight.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/aws_server/tasks/security_group.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/deacon/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/deacon/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/devcontainers/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/docker/handlers/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/fzf/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/hetzner_server/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_bootstrap/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_bootstrap/handlers/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/handlers/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/meta/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container/tasks/preflight.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container_teardown/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container_teardown/meta/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/incus_container_teardown/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_bootstrap/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_bootstrap/meta/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_bootstrap/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/handlers/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/meta/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container_teardown/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container_teardown/meta/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/proxmox_container_teardown/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/templates/devshell.sh.j2 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/templates/project-launch.sh.j2 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/templates/project-menu.sh.j2 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/user_setup/templates/remo-host.sh.j2 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/zellij/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/zellij/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/zellij/templates/config.kdl.j2 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/roles/zellij/templates/layouts/minimal.kdl.j2 +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/ansible/tasks/configure_dev_tools.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docker/Dockerfile +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docker/compose.example.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docker/entrypoint.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/remo-web-speckit-input.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/docs/remo-web.html +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/index.html +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/public/README.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/public/dist__ghostty-vt.wasm +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/public/ghostty-vt.wasm +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/scripts/copy-ghostty-wasm.mjs +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AppRoot.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AppShell.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AppShell.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AwaitingAdoption.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/AwaitingAdoption.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/OfflineOverlay.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/OfflineOverlay.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/PairToSync.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/PairToSync.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/SessionRail.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/SessionRail.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/SettingsPage.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/SettingsPage.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/ShortcutsModal.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/ShortcutsModal.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/TerminalCard.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/TerminalCard.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/TopBar.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/TopBar.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/WorkspacePane.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/WorkspacePane.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/components/railModel.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/lib/clipboard.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/lib/fullscreen.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/main.tsx +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/discovery.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/fonts.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/health.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/latency.test.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/latency.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/settings.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/useConsoleKeyboard.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/workspace.test.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/state/workspace.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/.gitkeep +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/GhosttyRenderer.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/RendererAdapter.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/TerminalConnection.test.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/XtermRenderer.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/defaultRenderer.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/keymap.test.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/terminal/keymap.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/test/setup.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/theme/fonts.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/src/theme/tokens.css +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/frontend/tsconfig.json +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/maverick.yaml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/playwright.config.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/project-menu.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/remo +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/run.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/scripts/setup-aws-oidc.sh +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/checklists/validation.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/contracts/playbook-interface.yaml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/contracts/role-interface.yaml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/data-model.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/plan.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/quickstart.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/research.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/spec.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/001-bootstrap-incus-host/tasks.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/contracts/playbook-interface.yaml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/contracts/role-interface.yaml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/data-model.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/plan.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/quickstart.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/research.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/spec.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/002-incus-container-support/tasks.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/data-model.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/plan.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/quickstart.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/research.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/spec.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/003-python-cli-rewrite/tasks.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/004-proxmox-container-support/spec.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/contracts/cli-surface.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/data-model.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/plan.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/quickstart.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/research.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/spec.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/005-provider-snapshots/tasks.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/contracts/remo-host-protocol.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/contracts/rest-api.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/contracts/terminal-websocket.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/data-model.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/plan.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/quickstart.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/research.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/spec.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/010-web-session-interface/tasks.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/contracts/cli-web-adopt.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/contracts/setup-api.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/data-model.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/plan.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/quickstart-results.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/quickstart.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/research.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/spec.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/011-web-adopt/tasks.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/contracts/cli-web-adopt.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/contracts/pairing-api.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/contracts/setup-api.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/data-model.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/plan.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/quickstart.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/research.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/spec.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/specs/012-web-adopt-pairing/tasks.md +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/cp.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/cli/providers/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/picker.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/remo_host_client.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/rsync.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/validation.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/core/version.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/capability.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/discovery.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/session_target.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/models/snapshot.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/providers/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/api/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/app.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/logging_config.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/models.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/operator_auth.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/pairing.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/ssh_master.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/terminal.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/terminal_registry.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/src/remo_cli/web/tokens.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/ansible/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/ansible/test_remo_host_idempotency.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/fixtures.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/ghostty-shell-io.spec.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/ghostty-tui-compatibility.spec.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/keyboard-routing.spec.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/mobile.spec.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/reconnect.spec.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/e2e/workspace-layout.spec.ts +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/image/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/image/test_docker_image.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/_nine_terminal_fixture.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/orbstack-cloud-init.yml +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_nine_terminals.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_nine_terminals_soak.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_remo_host_e2e.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_security_rejections.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/integration/test_terminal_attach.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/perf/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/perf/test_latency.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/cli/test_cp.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_ansible_runner.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_config.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_output.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_picker.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_remo_host_client.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_rsync.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_snapshot.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_validation.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_version.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_web_adopt_code.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/core/test_web_adopt_trust.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/models/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/models/test_capability.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/models/test_discovery.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/models/test_session_target.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/providers/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/test_ansible_templates.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/test_host_model.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/__init__.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/_pairing_support.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_backpressure.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_discovery.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_hosts_mapping.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_lazy_import.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_log_redaction.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_mint_gating.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_operator_auth.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_pairing.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_pairing_origin.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_setup_dormancy.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_terminal_resize.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_terminals_api.py +0 -0
- {remo_cli-2.2.0rc13 → remo_cli-3.0.0}/tests/unit/web/test_tokens.py +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: Cut a remo release — drive the release-please stable release PR, or build/validate/publish a pre-release (RC) — with a mandatory local "test before PyPI" gate and explicit approval before anything is tagged, merged, or published.
|
|
4
|
+
argument-hint: "[stable | rc [X.Y.ZrcN]] — omit to be asked"
|
|
5
|
+
metadata:
|
|
6
|
+
author: remo
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Release
|
|
10
|
+
|
|
11
|
+
Operationalizes remo's two-lane release process (see
|
|
12
|
+
[CONTRIBUTING.md](../../../CONTRIBUTING.md) → Release Process). Pairs with the
|
|
13
|
+
release-please integration.
|
|
14
|
+
|
|
15
|
+
**Non-negotiable safety rules — apply in every mode:**
|
|
16
|
+
|
|
17
|
+
- **Publishing to PyPI is irreversible.** A version, once uploaded, can never be
|
|
18
|
+
replaced. Run the local build + smoke gate (Step V below) before any tag,
|
|
19
|
+
merge, or publish — no exceptions.
|
|
20
|
+
- **Never** `git push` a tag, `git push` a version-bump commit, or `gh pr merge`
|
|
21
|
+
a release PR **without explicit user approval in the current turn.** Approval
|
|
22
|
+
from an earlier task does not carry over.
|
|
23
|
+
- Work only from a **clean working tree** on an **up-to-date `main`**. If the
|
|
24
|
+
tree is dirty or `main` is behind `origin/main`, stop and surface it.
|
|
25
|
+
- Prefer testing **without** publishing. Only publish an RC to PyPI when the user
|
|
26
|
+
explicitly asks for a public prerelease.
|
|
27
|
+
|
|
28
|
+
## Step 0 — Determine the mode
|
|
29
|
+
|
|
30
|
+
From the argument, or by asking the user:
|
|
31
|
+
|
|
32
|
+
- **`stable`** — drive the release-please release PR to a published stable release.
|
|
33
|
+
- **`rc`** — build/validate a pre-release, optionally publishing it.
|
|
34
|
+
|
|
35
|
+
Then run `git fetch origin` and verify `git status` is clean and `main` is
|
|
36
|
+
up to date (`git rev-parse HEAD` == `git rev-parse origin/main`).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Stable lane (release-please owns the version + tag)
|
|
41
|
+
|
|
42
|
+
1. `git checkout main && git pull --ff-only`.
|
|
43
|
+
2. Find the open release PR (release-please titles it `chore(main): release X.Y.Z`
|
|
44
|
+
and pushes it to a `release-please--…` branch). Match on either signal —
|
|
45
|
+
do **not** pass the title to `--search`, whose parser silently drops
|
|
46
|
+
`chore(main):` and returns zero results even when the PR exists:
|
|
47
|
+
```bash
|
|
48
|
+
gh pr list --state open --limit 100 --json number,title,headRefName,url --jq \
|
|
49
|
+
'.[] | select((.headRefName | startswith("release-please--"))
|
|
50
|
+
or (.title | startswith("chore(main): release")))
|
|
51
|
+
| "\(.number)\t\(.title)\t\(.url)"'
|
|
52
|
+
```
|
|
53
|
+
If none exists, tell the user release-please has not opened one (no
|
|
54
|
+
releasable `feat:`/`fix:` commits since the last release) and **stop**.
|
|
55
|
+
Before concluding that, sanity-check with a bare `gh pr list --state open`:
|
|
56
|
+
a filter bug and a genuinely absent PR look identical from here, and
|
|
57
|
+
wrongly reporting "no release PR" strands a real one.
|
|
58
|
+
3. Show the proposed bump + changelog for review. `gh pr diff` takes no
|
|
59
|
+
pathspec (`gh pr diff <n> -- <files>` fails with "accepts at most 1 arg"),
|
|
60
|
+
so select the files from the API instead:
|
|
61
|
+
```bash
|
|
62
|
+
gh api repos/{owner}/{repo}/pulls/<number>/files --paginate --jq \
|
|
63
|
+
'.[] | select(.filename == "pyproject.toml" or .filename == "CHANGELOG.md")
|
|
64
|
+
| "=== \(.filename) ===\n\(.patch)"'
|
|
65
|
+
```
|
|
66
|
+
Read the `⚠ BREAKING CHANGES` block carefully — it is what drives a major
|
|
67
|
+
bump, and a spurious entry there is the usual cause of an unintended one.
|
|
68
|
+
4. **Run the validation gate (Step V) on the PR's head branch** so you build the
|
|
69
|
+
exact version that will publish.
|
|
70
|
+
5. **Only on explicit approval**, merge it (release-please then tags `vX.Y.Z`,
|
|
71
|
+
which triggers `release.yml` to publish to PyPI + GHCR):
|
|
72
|
+
```bash
|
|
73
|
+
gh pr merge <number> --squash
|
|
74
|
+
```
|
|
75
|
+
Before merging, confirm the `RELEASE_PLEASE_TOKEN` secret is set — without it
|
|
76
|
+
the tag will not trigger the publish. If it's missing, warn the user and let
|
|
77
|
+
them decide.
|
|
78
|
+
6. Return to `main`, `git pull --ff-only`, report the new tag, and offer to watch
|
|
79
|
+
the release CI. `gh run watch` needs an explicit run id outside a TTY:
|
|
80
|
+
```bash
|
|
81
|
+
gh run watch "$(gh run list --workflow=release.yml --limit 1 \
|
|
82
|
+
--json databaseId --jq '.[0].databaseId')"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## RC lane (manual — release-please stays out)
|
|
88
|
+
|
|
89
|
+
1. `git checkout main && git pull --ff-only`.
|
|
90
|
+
2. Determine the RC version `X.Y.ZrcN` (PEP 440 form, **no separator**):
|
|
91
|
+
- `X.Y.Z` is the next target version (feat → minor, fix → patch over the last
|
|
92
|
+
stable tag).
|
|
93
|
+
- `N` increments from the last `vX.Y.Z-rcM` tag for the same `X.Y.Z`
|
|
94
|
+
(`git tag --list "vX.Y.Z-rc*"`), else `1`.
|
|
95
|
+
- Confirm the chosen version with the user.
|
|
96
|
+
3. Confirm these two files carry no pre-existing edits, then bump
|
|
97
|
+
`pyproject.toml` `[project].version` to `X.Y.ZrcN` (optionally run `uv lock`
|
|
98
|
+
to keep the lockfile's version in step):
|
|
99
|
+
```bash
|
|
100
|
+
git diff --quiet -- pyproject.toml uv.lock \
|
|
101
|
+
|| { echo "pyproject.toml/uv.lock already modified — STOP"; }
|
|
102
|
+
```
|
|
103
|
+
Step 0 already required a clean tree, but re-assert it here: the revert in
|
|
104
|
+
Step 5 discards whatever is in these files, and the gap between Step 0 and
|
|
105
|
+
Step 5 spans a full test run.
|
|
106
|
+
4. **Run the validation gate (Step V).**
|
|
107
|
+
5. Ask the user which outcome they want:
|
|
108
|
+
- **Local test only (default, no PyPI):** revert the bump, then hand off the
|
|
109
|
+
built wheel (`dist/*.whl`) or the git-install one-liner
|
|
110
|
+
(`uv tool install --force "git+https://github.com/get2knowio/remo.git@<branch>"`).
|
|
111
|
+
Nothing is committed, tagged, or published.
|
|
112
|
+
|
|
113
|
+
Look before discarding — never `git checkout`/`git restore` these paths
|
|
114
|
+
blind. Print the diff, confirm it is **only** the version bump you made in
|
|
115
|
+
Step 3, and only then restore:
|
|
116
|
+
```bash
|
|
117
|
+
git diff -- pyproject.toml uv.lock # MUST show only the X.Y.ZrcN bump
|
|
118
|
+
git restore --source=HEAD --worktree -- pyproject.toml uv.lock
|
|
119
|
+
```
|
|
120
|
+
If that diff contains anything else, stop and surface it: something edited
|
|
121
|
+
these files during the run, and discarding it destroys unrecoverable work.
|
|
122
|
+
- **CI dev build for cross-machine testing (no PyPI):** trigger the
|
|
123
|
+
`dev-build.yml` workflow, which builds the wheel in clean CI and uploads it
|
|
124
|
+
as a run artifact. The stamped version carries a `+g<sha>` local segment, so
|
|
125
|
+
it is unique and can never reach PyPI. Nothing is committed or tagged.
|
|
126
|
+
```bash
|
|
127
|
+
gh workflow run dev-build.yml -f version=X.Y.ZrcN # omit -f for an auto dev version
|
|
128
|
+
# `gh run watch` with no argument fails outside a TTY ("run ID required
|
|
129
|
+
# when not running interactively"), so resolve the run id first. Give the
|
|
130
|
+
# dispatch a couple of seconds to register before listing.
|
|
131
|
+
RUN_ID="$(gh run list --workflow=dev-build.yml --limit 1 \
|
|
132
|
+
--json databaseId --jq '.[0].databaseId')"
|
|
133
|
+
gh run watch "$RUN_ID"
|
|
134
|
+
# then, on ANY machine:
|
|
135
|
+
gh run download "$RUN_ID" -n remo-wheel -D ./dl
|
|
136
|
+
uv tool install --force ./dl/remo_cli-*.whl
|
|
137
|
+
```
|
|
138
|
+
- **Publish a prerelease (only on explicit approval):**
|
|
139
|
+
```bash
|
|
140
|
+
git commit -am "chore(release): X.Y.ZrcN"
|
|
141
|
+
git tag vX.Y.Z-rcN
|
|
142
|
+
git push origin main vX.Y.Z-rcN
|
|
143
|
+
```
|
|
144
|
+
`release.yml` detects the `rc` suffix, publishes the prerelease to PyPI +
|
|
145
|
+
GHCR, and never moves `latest`. Offer to watch CI.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Step V — Validation gate (test the exact wheel before PyPI)
|
|
150
|
+
|
|
151
|
+
Run this on whatever ref will be released (the release-please PR head for stable,
|
|
152
|
+
or the bumped working tree for an RC). The published version comes from
|
|
153
|
+
`pyproject.toml` via `uv build`, so this builds the identical artifact:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
uv run pytest -q # full suite must pass
|
|
157
|
+
uv build # -> dist/remo_cli-<version>-py3-none-any.whl
|
|
158
|
+
VENV="$(mktemp -d)/venv"
|
|
159
|
+
uv venv "$VENV"
|
|
160
|
+
uv pip install --python "$VENV/bin/python" ./dist/remo_cli-<version>-py3-none-any.whl
|
|
161
|
+
"$VENV/bin/remo" --version # MUST equal <version>
|
|
162
|
+
"$VENV/bin/remo" --help # sanity-check the CLI loads
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Report the results. If tests fail, the wheel version doesn't match, or the CLI
|
|
166
|
+
doesn't load, **stop** and surface it — do not proceed to tag/merge/publish.
|
|
167
|
+
|
|
168
|
+
## Done when
|
|
169
|
+
|
|
170
|
+
- The requested lane completed through the point the user approved (validated
|
|
171
|
+
only; RC wheel handed off; RC published; or stable PR merged).
|
|
172
|
+
- No tag was pushed, commit was pushed, or PR merged without explicit approval.
|
|
173
|
+
- The outcome (and, if published, the immutable version) was reported clearly.
|
|
@@ -7,6 +7,10 @@ updates:
|
|
|
7
7
|
interval: "weekly"
|
|
8
8
|
day: "monday"
|
|
9
9
|
open-pull-requests-limit: 5
|
|
10
|
+
# Let a new release settle before we bump to it, so we don't chase
|
|
11
|
+
# immediately-yanked or regression releases.
|
|
12
|
+
cooldown:
|
|
13
|
+
default-days: 7
|
|
10
14
|
groups:
|
|
11
15
|
# One PR per week with all minor/patch production deps bumped together.
|
|
12
16
|
production-minor-patch:
|
|
@@ -29,6 +33,8 @@ updates:
|
|
|
29
33
|
interval: "weekly"
|
|
30
34
|
day: "monday"
|
|
31
35
|
open-pull-requests-limit: 5
|
|
36
|
+
cooldown:
|
|
37
|
+
default-days: 7
|
|
32
38
|
groups:
|
|
33
39
|
actions:
|
|
34
40
|
update-types:
|
|
@@ -15,9 +15,9 @@ jobs:
|
|
|
15
15
|
python-version: ["3.11", "3.12", "3.13"]
|
|
16
16
|
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@v7
|
|
18
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
19
19
|
|
|
20
|
-
- uses: astral-sh/setup-uv@v7
|
|
20
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
21
21
|
|
|
22
22
|
- name: Set up Python ${{ matrix.python-version }}
|
|
23
23
|
run: uv python install ${{ matrix.python-version }}
|
|
@@ -39,16 +39,16 @@ jobs:
|
|
|
39
39
|
# runs npm ci and pip install under QEMU.
|
|
40
40
|
timeout-minutes: 45
|
|
41
41
|
steps:
|
|
42
|
-
- uses: actions/checkout@v7
|
|
42
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
43
43
|
|
|
44
44
|
# Registers binfmt handlers so the arm64 half of tests/image/ can build
|
|
45
45
|
# under emulation on an amd64 runner. The arch-selection branch
|
|
46
46
|
# (FR-027/FR-042) has no other way to be exercised here.
|
|
47
|
-
- uses: docker/setup-qemu-action@v4
|
|
47
|
+
- uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
|
|
48
48
|
|
|
49
|
-
- uses: docker/setup-buildx-action@v4
|
|
49
|
+
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
|
50
50
|
|
|
51
|
-
- uses: astral-sh/setup-uv@v7
|
|
51
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
52
52
|
|
|
53
53
|
- name: Install dependencies
|
|
54
54
|
run: uv sync --all-extras
|
|
@@ -68,9 +68,9 @@ jobs:
|
|
|
68
68
|
name: Wheel install smoke test
|
|
69
69
|
runs-on: ubuntu-latest
|
|
70
70
|
steps:
|
|
71
|
-
- uses: actions/checkout@v7
|
|
71
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
72
72
|
|
|
73
|
-
- uses: astral-sh/setup-uv@v7
|
|
73
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
74
74
|
|
|
75
75
|
- name: Build wheel
|
|
76
76
|
run: uv build --wheel
|
|
@@ -92,13 +92,39 @@ jobs:
|
|
|
92
92
|
print("OK: ansible playbooks found in installed wheel")
|
|
93
93
|
EOF
|
|
94
94
|
|
|
95
|
+
fish-completion:
|
|
96
|
+
name: Fish completion (real shell)
|
|
97
|
+
runs-on: ubuntu-latest
|
|
98
|
+
steps:
|
|
99
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
100
|
+
|
|
101
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
102
|
+
|
|
103
|
+
- name: Install fish
|
|
104
|
+
run: |
|
|
105
|
+
sudo apt-get update -qq
|
|
106
|
+
sudo apt-get install -y -qq fish
|
|
107
|
+
|
|
108
|
+
# The activation script shells out to `remo` by name, so it has to be a
|
|
109
|
+
# real binary on PATH — `uv run remo` would never be found by fish.
|
|
110
|
+
- name: Install remo onto PATH
|
|
111
|
+
run: |
|
|
112
|
+
uv sync
|
|
113
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
114
|
+
|
|
115
|
+
# Asserting on the text of the generated script is not enough: the bug
|
|
116
|
+
# this guards against (a2542e9) produced a script that read fine and
|
|
117
|
+
# emitted a screenful of errors the moment fish executed it.
|
|
118
|
+
- name: Run completions in a real fish shell
|
|
119
|
+
run: ./tests/integration/fish_completion.sh
|
|
120
|
+
|
|
95
121
|
lint:
|
|
96
|
-
name: Lint
|
|
122
|
+
name: Lint & Types
|
|
97
123
|
runs-on: ubuntu-latest
|
|
98
124
|
steps:
|
|
99
|
-
- uses: actions/checkout@v7
|
|
125
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
100
126
|
|
|
101
|
-
- uses: astral-sh/setup-uv@v7
|
|
127
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
102
128
|
|
|
103
129
|
- name: Install dependencies
|
|
104
130
|
run: uv sync --all-extras
|
|
@@ -106,6 +132,13 @@ jobs:
|
|
|
106
132
|
- name: Ruff check
|
|
107
133
|
run: uv run ruff check src/remo_cli
|
|
108
134
|
|
|
135
|
+
# mypy analyses against python_version = "3.11" from [tool.mypy], so the
|
|
136
|
+
# result is independent of whichever interpreter uv resolves here. The
|
|
137
|
+
# `web` extra must be installed (it is, via --all-extras) or every
|
|
138
|
+
# src/remo_cli/web/ module degrades to Any and the gate goes blind.
|
|
139
|
+
- name: Mypy check
|
|
140
|
+
run: uv run mypy src/remo_cli
|
|
141
|
+
|
|
109
142
|
frontend:
|
|
110
143
|
name: Frontend (typecheck + unit + build)
|
|
111
144
|
runs-on: ubuntu-latest
|
|
@@ -117,9 +150,9 @@ jobs:
|
|
|
117
150
|
run:
|
|
118
151
|
working-directory: frontend
|
|
119
152
|
steps:
|
|
120
|
-
- uses: actions/checkout@v7
|
|
153
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
121
154
|
|
|
122
|
-
- uses: actions/setup-node@
|
|
155
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
123
156
|
with:
|
|
124
157
|
node-version: "20"
|
|
125
158
|
cache: npm
|
|
@@ -131,6 +164,9 @@ jobs:
|
|
|
131
164
|
- name: Typecheck
|
|
132
165
|
run: npm run lint
|
|
133
166
|
|
|
167
|
+
- name: Check generated types are fresh
|
|
168
|
+
run: npm run check:types-fresh
|
|
169
|
+
|
|
134
170
|
- name: Unit tests
|
|
135
171
|
run: npm run test
|
|
136
172
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
# Static analysis (code scanning) for the repo's compiled/interpreted sources.
|
|
4
|
+
# Results appear under the Security tab and annotate pull requests.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: [main]
|
|
10
|
+
schedule:
|
|
11
|
+
# Weekly full scan so newly published CodeQL queries catch existing code.
|
|
12
|
+
- cron: "27 4 * * 1"
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
analyze:
|
|
19
|
+
name: Analyze (${{ matrix.language }})
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
security-events: write # upload CodeQL results
|
|
23
|
+
packages: read # fetch CodeQL packs
|
|
24
|
+
strategy:
|
|
25
|
+
fail-fast: false
|
|
26
|
+
matrix:
|
|
27
|
+
include:
|
|
28
|
+
- language: python
|
|
29
|
+
build-mode: none
|
|
30
|
+
- language: javascript-typescript
|
|
31
|
+
build-mode: none
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
34
|
+
|
|
35
|
+
- name: Initialize CodeQL
|
|
36
|
+
uses: github/codeql-action/init@4187e74d05793876e9989daffde9c3e66b4acd07 # v3
|
|
37
|
+
with:
|
|
38
|
+
languages: ${{ matrix.language }}
|
|
39
|
+
build-mode: ${{ matrix.build-mode }}
|
|
40
|
+
|
|
41
|
+
- name: Perform CodeQL Analysis
|
|
42
|
+
uses: github/codeql-action/analyze@4187e74d05793876e9989daffde9c3e66b4acd07 # v3
|
|
43
|
+
with:
|
|
44
|
+
category: "/language:${{ matrix.language }}"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Dependency Review
|
|
2
|
+
|
|
3
|
+
# Scans dependency manifest changes on pull requests for known-vulnerable
|
|
4
|
+
# packages and disallowed licenses, blocking the PR before they reach main.
|
|
5
|
+
on:
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
dependency-review:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
16
|
+
- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4
|
|
17
|
+
with:
|
|
18
|
+
fail-on-severity: high
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: dev-build
|
|
2
|
+
|
|
3
|
+
# Build an installable wheel and upload it as a run artifact you can download and
|
|
4
|
+
# test on ANY machine — no git tag, no PyPI, no version reserved.
|
|
5
|
+
#
|
|
6
|
+
# The stamped version always carries a PEP 440 *local* segment (`+g<shortsha>`),
|
|
7
|
+
# which PyPI rejects outright — so a dev build can never leak to PyPI, and every
|
|
8
|
+
# build is uniquely identifiable.
|
|
9
|
+
#
|
|
10
|
+
# Trigger manually:
|
|
11
|
+
# gh workflow run dev-build.yml # -> 2.2.0.dev<run>+g<sha>
|
|
12
|
+
# gh workflow run dev-build.yml -f version=2.3.0rc1 # -> 2.3.0rc1+g<sha>
|
|
13
|
+
#
|
|
14
|
+
# Then, on any machine:
|
|
15
|
+
# gh run download <run-id> -n remo-wheel -D ./dl
|
|
16
|
+
# uv tool install --force ./dl/remo_cli-*.whl
|
|
17
|
+
|
|
18
|
+
on:
|
|
19
|
+
workflow_dispatch:
|
|
20
|
+
inputs:
|
|
21
|
+
version:
|
|
22
|
+
description: "Full base version to stamp (e.g. 2.3.0rc1, 2.3.0). Blank = auto dev version from pyproject. A +g<sha> local segment is always appended."
|
|
23
|
+
required: false
|
|
24
|
+
default: ""
|
|
25
|
+
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
|
|
29
|
+
jobs:
|
|
30
|
+
build:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
34
|
+
with:
|
|
35
|
+
fetch-depth: 0
|
|
36
|
+
|
|
37
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
38
|
+
|
|
39
|
+
- name: Compute dev version
|
|
40
|
+
id: ver
|
|
41
|
+
env:
|
|
42
|
+
INPUT_VERSION: ${{ inputs.version }}
|
|
43
|
+
run: |
|
|
44
|
+
set -euo pipefail
|
|
45
|
+
SHA=$(git rev-parse --short HEAD)
|
|
46
|
+
if [ -n "$INPUT_VERSION" ]; then
|
|
47
|
+
BASE="$INPUT_VERSION"
|
|
48
|
+
else
|
|
49
|
+
# Core X.Y.Z from pyproject, plus a per-run .dev segment.
|
|
50
|
+
CORE=$(grep -m1 '^version = ' pyproject.toml \
|
|
51
|
+
| sed -E 's/version = "([0-9]+\.[0-9]+\.[0-9]+).*"/\1/')
|
|
52
|
+
BASE="${CORE}.dev${GITHUB_RUN_NUMBER}"
|
|
53
|
+
fi
|
|
54
|
+
# Always append the local segment: unique + un-uploadable to PyPI.
|
|
55
|
+
VERSION="${BASE}+g${SHA}"
|
|
56
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
57
|
+
echo "Building version: $VERSION"
|
|
58
|
+
|
|
59
|
+
- name: Stamp version into pyproject.toml
|
|
60
|
+
env:
|
|
61
|
+
VERSION: ${{ steps.ver.outputs.version }}
|
|
62
|
+
run: |
|
|
63
|
+
set -euo pipefail
|
|
64
|
+
sed -i -E "0,/^version = \".*\"/s//version = \"${VERSION}\"/" pyproject.toml
|
|
65
|
+
grep -m1 '^version = ' pyproject.toml
|
|
66
|
+
|
|
67
|
+
- name: Build wheel + sdist
|
|
68
|
+
run: uv build
|
|
69
|
+
|
|
70
|
+
- name: Upload artifact
|
|
71
|
+
# NOTE: SHA-pin to match the repo's action-pinning convention once the
|
|
72
|
+
# v4 commit SHA is available (e.g. `@<sha> # v4`).
|
|
73
|
+
uses: actions/upload-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: remo-wheel
|
|
76
|
+
path: dist/*
|
|
77
|
+
retention-days: 30
|
|
78
|
+
if-no-files-found: error
|
|
@@ -16,10 +16,10 @@ jobs:
|
|
|
16
16
|
|
|
17
17
|
steps:
|
|
18
18
|
- name: Checkout repository
|
|
19
|
-
uses: actions/checkout@v7
|
|
19
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
20
20
|
|
|
21
21
|
- name: Install uv
|
|
22
|
-
uses: astral-sh/setup-uv@v7
|
|
22
|
+
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
23
23
|
|
|
24
24
|
- name: Install Ansible and dependencies
|
|
25
25
|
run: |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: release-please
|
|
2
|
+
|
|
3
|
+
# Automates STABLE releases from Conventional Commits.
|
|
4
|
+
#
|
|
5
|
+
# On every push to main, release-please maintains a "release PR" that bumps the
|
|
6
|
+
# version in pyproject.toml and updates CHANGELOG.md. Merging that PR creates the
|
|
7
|
+
# `vX.Y.Z` tag and a GitHub release — which in turn triggers the existing
|
|
8
|
+
# tag-driven `release.yml` (PyPI + Docker image).
|
|
9
|
+
#
|
|
10
|
+
# RCs / pre-releases are NOT handled here: cut those with a manual `vX.Y.Z-rcN`
|
|
11
|
+
# tag (see CONTRIBUTING.md → Release Process), which `release.yml` publishes as a
|
|
12
|
+
# prerelease. release-please stays out of the RC lane.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches:
|
|
17
|
+
- main
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: write
|
|
21
|
+
pull-requests: write
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
release-please:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
# Mint a short-lived GitHub App installation token when the App is
|
|
28
|
+
# configured (org secrets RELEASE_PLEASE_APP_ID + RELEASE_PLEASE_APP_KEY).
|
|
29
|
+
# An App token — like a PAT, unlike GITHUB_TOKEN — triggers the tag-driven
|
|
30
|
+
# `release.yml`, but it's short-lived, auto-minted (nothing to rotate), and
|
|
31
|
+
# tied to no human account. The step is skipped if the App isn't set up.
|
|
32
|
+
#
|
|
33
|
+
# NOTE: SHA-pin `create-github-app-token` and `release-please-action` to
|
|
34
|
+
# match the repo's action-pinning convention (e.g. `@<sha> # v2`) once the
|
|
35
|
+
# SHAs are available — left as floating tags because they can't be
|
|
36
|
+
# resolved offline.
|
|
37
|
+
- name: Mint GitHub App token
|
|
38
|
+
id: app-token
|
|
39
|
+
if: ${{ vars.RELEASE_PLEASE_APP_ID != '' }}
|
|
40
|
+
uses: actions/create-github-app-token@v2
|
|
41
|
+
with:
|
|
42
|
+
app-id: ${{ vars.RELEASE_PLEASE_APP_ID }}
|
|
43
|
+
private-key: ${{ secrets.RELEASE_PLEASE_APP_KEY }}
|
|
44
|
+
|
|
45
|
+
- uses: googleapis/release-please-action@v4
|
|
46
|
+
with:
|
|
47
|
+
# Token precedence:
|
|
48
|
+
# 1. GitHub App installation token (recommended — see above).
|
|
49
|
+
# 2. RELEASE_PLEASE_TOKEN PAT (if someone set one instead).
|
|
50
|
+
# 3. GITHUB_TOKEN fallback — release-please still opens/maintains the
|
|
51
|
+
# release PR out of the box, but a tag it creates will NOT fire
|
|
52
|
+
# `on: push: tags`, so `release.yml` (PyPI + Docker) won't run
|
|
53
|
+
# until a maintainer re-pushes the tag. Configure the App (or the
|
|
54
|
+
# PAT) to make merge-to-publish automatic.
|
|
55
|
+
token: ${{ steps.app-token.outputs.token || secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
|
56
|
+
config-file: release-please-config.json
|
|
57
|
+
manifest-file: .release-please-manifest.json
|
|
@@ -13,9 +13,9 @@ jobs:
|
|
|
13
13
|
python-version: ["3.11", "3.12", "3.13"]
|
|
14
14
|
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@v7
|
|
16
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
17
17
|
|
|
18
|
-
- uses: astral-sh/setup-uv@v7
|
|
18
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
19
19
|
|
|
20
20
|
- name: Set up Python ${{ matrix.python-version }}
|
|
21
21
|
run: uv python install ${{ matrix.python-version }}
|
|
@@ -38,7 +38,7 @@ jobs:
|
|
|
38
38
|
|
|
39
39
|
steps:
|
|
40
40
|
- name: Checkout
|
|
41
|
-
uses: actions/checkout@v7
|
|
41
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
42
42
|
with:
|
|
43
43
|
fetch-depth: 0
|
|
44
44
|
|
|
@@ -137,7 +137,7 @@ jobs:
|
|
|
137
137
|
fi
|
|
138
138
|
|
|
139
139
|
- name: Create Release
|
|
140
|
-
uses: softprops/action-gh-release@v3
|
|
140
|
+
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3
|
|
141
141
|
with:
|
|
142
142
|
tag_name: ${{ steps.tag.outputs.tag }}
|
|
143
143
|
name: ${{ steps.tag.outputs.tag }}
|
|
@@ -153,15 +153,15 @@ jobs:
|
|
|
153
153
|
environment: pypi
|
|
154
154
|
|
|
155
155
|
steps:
|
|
156
|
-
- uses: actions/checkout@v7
|
|
156
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
157
157
|
|
|
158
|
-
- uses: astral-sh/setup-uv@v7
|
|
158
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
159
159
|
|
|
160
160
|
- name: Build package
|
|
161
161
|
run: uv build
|
|
162
162
|
|
|
163
163
|
- name: Publish to PyPI
|
|
164
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
|
164
|
+
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # release/v1
|
|
165
165
|
|
|
166
166
|
publish-image:
|
|
167
167
|
# Publishes the remo-web container image that docker/compose.example.yml
|
|
@@ -177,16 +177,16 @@ jobs:
|
|
|
177
177
|
timeout-minutes: 60
|
|
178
178
|
|
|
179
179
|
steps:
|
|
180
|
-
- uses: actions/checkout@v7
|
|
180
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
181
181
|
|
|
182
182
|
# Needed for the linux/arm64 half of the manifest: GitHub's runners are
|
|
183
183
|
# amd64, so arm64 is cross-built under emulation.
|
|
184
|
-
- uses: docker/setup-qemu-action@v4
|
|
184
|
+
- uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
|
|
185
185
|
|
|
186
|
-
- uses: docker/setup-buildx-action@v4
|
|
186
|
+
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
|
187
187
|
|
|
188
188
|
- name: Log in to GHCR
|
|
189
|
-
uses: docker/login-action@v4
|
|
189
|
+
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
|
190
190
|
with:
|
|
191
191
|
registry: ghcr.io
|
|
192
192
|
username: ${{ github.actor }}
|
|
@@ -194,7 +194,7 @@ jobs:
|
|
|
194
194
|
|
|
195
195
|
- name: Derive image tags and labels
|
|
196
196
|
id: meta
|
|
197
|
-
uses: docker/metadata-action@v6
|
|
197
|
+
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
|
|
198
198
|
with:
|
|
199
199
|
images: ghcr.io/${{ github.repository_owner }}/remo-web
|
|
200
200
|
# latest=false disables this action's automatic `latest`; the raw
|
|
@@ -207,7 +207,7 @@ jobs:
|
|
|
207
207
|
type=raw,value=latest,enable=${{ needs.release.outputs.is_prerelease == 'false' }}
|
|
208
208
|
|
|
209
209
|
- name: Build and push (amd64 + arm64)
|
|
210
|
-
uses: docker/build-push-action@v7
|
|
210
|
+
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
|
|
211
211
|
with:
|
|
212
212
|
context: .
|
|
213
213
|
file: docker/Dockerfile
|
|
@@ -20,7 +20,7 @@ jobs:
|
|
|
20
20
|
timeout-minutes: 10
|
|
21
21
|
steps:
|
|
22
22
|
- name: Configure AWS credentials (OIDC)
|
|
23
|
-
uses: aws-actions/configure-aws-credentials@v6
|
|
23
|
+
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6
|
|
24
24
|
with:
|
|
25
25
|
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }}
|
|
26
26
|
role-session-name: remo-cleanup-${{ github.run_id }}
|
|
@@ -81,7 +81,7 @@ jobs:
|
|
|
81
81
|
timeout-minutes: 10
|
|
82
82
|
steps:
|
|
83
83
|
- name: Setup hcloud CLI
|
|
84
|
-
uses: hetznercloud/setup-hcloud@v2
|
|
84
|
+
uses: hetznercloud/setup-hcloud@ac9e7d74fb41a3ca44a6a3da123bd5aa70731e3a # v2
|
|
85
85
|
|
|
86
86
|
- name: Delete stale CI servers
|
|
87
87
|
env:
|