remo-cli 2.2.0rc8__tar.gz → 2.2.0rc10__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-2.2.0rc8 → remo_cli-2.2.0rc10}/PKG-INFO +1 -1
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docs/web-session-interface.md +5 -2
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/package-lock.json +46 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/package.json +1 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/SessionRail.css +0 -8
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/SessionRail.tsx +0 -4
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/TerminalCard.css +37 -9
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/TerminalCard.tsx +35 -40
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/WorkspacePane.tsx +94 -64
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/pyproject.toml +1 -1
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/uv.lock +1 -1
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-analyze/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-checklist/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-clarify/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-constitution/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-converge/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-git-commit/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-git-feature/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-git-initialize/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-git-remote/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-git-validate/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-implement/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-plan/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-specify/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-tasks/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.claude/skills/speckit-taskstoissues/SKILL.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.devcontainer/devcontainer.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.dockerignore +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.github/dependabot.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.github/workflows/ci.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.github/workflows/provision.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.github/workflows/release.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.github/workflows/smoke-test-cleanup.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.github/workflows/smoke-test.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.github/workflows/teardown.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.gitignore +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.maverick/checkpoints/feature/implementation_complete.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.maverick/checkpoints/feature/phase_${{ index }}_complete.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.maverick/checkpoints/feature/validation_complete.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/.registry +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/README.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/commands/speckit.git.commit.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/commands/speckit.git.feature.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/commands/speckit.git.initialize.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/commands/speckit.git.remote.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/commands/speckit.git.validate.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/config-template.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/extension.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/git-config.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/scripts/bash/auto-commit.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/scripts/bash/create-new-feature.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/scripts/bash/git-common.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/scripts/bash/initialize-repo.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/scripts/powershell/create-new-feature.ps1 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/scripts/powershell/git-common.ps1 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/feature.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/init-options.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/integration.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/integrations/claude.manifest.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/integrations/speckit.manifest.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/memory/constitution.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/scripts/bash/check-prerequisites.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/scripts/bash/common.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/scripts/bash/create-new-feature.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/scripts/bash/setup-plan.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/scripts/bash/setup-tasks.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/scripts/bash/update-agent-context.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/templates/agent-file-template.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/templates/checklist-template.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/templates/constitution-template.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/templates/plan-template.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/templates/spec-template.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/templates/tasks-template.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/workflows/speckit/workflow.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/workflows/workflow-registry.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/AGENTS.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/CLAUDE.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/CONTRIBUTING.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/Dockerfile +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/LICENSE +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/README.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/.ansible-lint +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/README.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/ansible.cfg +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/aws_configure.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/aws_resize.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/aws_site.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/aws_teardown.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/group_vars/all.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/group_vars/incus_containers.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/group_vars/proxmox_containers.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/hetzner_configure.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/hetzner_provision.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/hetzner_resize.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/hetzner_site.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/hetzner_teardown.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/incus_bootstrap.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/incus_configure.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/incus_provision.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/incus_resize.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/incus_site.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/incus_teardown.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/inventory/hosts.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/inventory/incus_containers.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/proxmox_bootstrap.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/proxmox_configure.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/proxmox_provision.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/proxmox_resize.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/proxmox_site.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/proxmox_teardown.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/requirements.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/aws_server/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/aws_server/tasks/ebs.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/aws_server/tasks/ec2.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/aws_server/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/aws_server/tasks/patch_manager.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/aws_server/tasks/preflight.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/aws_server/tasks/security_group.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/deacon/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/deacon/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/devcontainers/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/docker/handlers/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/docker/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/fzf/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/github_cli/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/hetzner_server/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/hetzner_server/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_bootstrap/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_bootstrap/handlers/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_bootstrap/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_container/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_container/handlers/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_container/meta/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_container/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_container/tasks/preflight.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_container_teardown/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_container_teardown/meta/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/incus_container_teardown/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/nodejs/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/nodejs/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_bootstrap/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_bootstrap/meta/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_bootstrap/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_container/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_container/handlers/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_container/meta/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_container/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_container/tasks/preflight.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_container_teardown/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_container_teardown/meta/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/proxmox_container_teardown/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/user_setup/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/user_setup/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/user_setup/templates/devshell.sh.j2 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/user_setup/templates/project-launch.sh.j2 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/user_setup/templates/project-menu.sh.j2 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/user_setup/templates/remo-host.sh.j2 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/zellij/defaults/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/zellij/tasks/main.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/zellij/templates/config.kdl.j2 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/roles/zellij/templates/layouts/minimal.kdl.j2 +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/ansible/tasks/configure_dev_tools.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docker/Dockerfile +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docker/compose.example.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docker/entrypoint.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docs/aws.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docs/hetzner.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docs/incus.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docs/install.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docs/proxmox.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docs/remo-web-speckit-input.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/docs/remo-web.html +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/index.html +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/public/README.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/public/dist__ghostty-vt.wasm +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/public/ghostty-vt.wasm +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/scripts/copy-ghostty-wasm.mjs +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/api/client.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/AppRoot.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/AppShell.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/AppShell.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/AwaitingAdoption.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/AwaitingAdoption.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/OfflineOverlay.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/OfflineOverlay.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/PairToSync.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/PairToSync.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/SettingsPage.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/SettingsPage.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/ShortcutsModal.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/ShortcutsModal.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/TopBar.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/TopBar.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/WorkspacePane.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/providerMeta.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/components/railModel.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/lib/clipboard.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/lib/fullscreen.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/main.tsx +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/state/discovery.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/state/fonts.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/state/health.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/state/settings.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/state/useConsoleKeyboard.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/state/workspace.test.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/state/workspace.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/.gitkeep +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/GhosttyRenderer.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/RendererAdapter.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/TerminalConnection.test.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/TerminalConnection.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/XtermRenderer.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/defaultRenderer.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/keymap.test.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/terminal/keymap.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/test/setup.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/theme/fonts.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/src/theme/tokens.css +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/tsconfig.json +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/frontend/vite.config.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/install.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/maverick.yaml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/playwright.config.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/project-menu.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/remo +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/run.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/scripts/setup-aws-oidc.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/checklists/validation.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/contracts/playbook-interface.yaml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/contracts/role-interface.yaml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/data-model.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/plan.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/quickstart.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/research.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/spec.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/001-bootstrap-incus-host/tasks.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/contracts/playbook-interface.yaml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/contracts/role-interface.yaml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/data-model.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/plan.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/quickstart.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/research.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/spec.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/002-incus-container-support/tasks.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/003-python-cli-rewrite/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/003-python-cli-rewrite/data-model.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/003-python-cli-rewrite/plan.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/003-python-cli-rewrite/quickstart.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/003-python-cli-rewrite/research.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/003-python-cli-rewrite/spec.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/003-python-cli-rewrite/tasks.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/004-proxmox-container-support/spec.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/005-provider-snapshots/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/005-provider-snapshots/contracts/cli-surface.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/005-provider-snapshots/data-model.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/005-provider-snapshots/plan.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/005-provider-snapshots/quickstart.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/005-provider-snapshots/research.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/005-provider-snapshots/spec.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/005-provider-snapshots/tasks.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/contracts/remo-host-protocol.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/contracts/rest-api.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/contracts/terminal-websocket.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/data-model.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/plan.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/quickstart.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/research.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/spec.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/010-web-session-interface/tasks.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/checklists/requirements.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/contracts/cli-web-adopt.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/contracts/setup-api.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/data-model.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/plan.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/quickstart-results.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/quickstart.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/research.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/spec.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/011-web-adopt/tasks.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/contracts/cli-web-adopt.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/contracts/pairing-api.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/contracts/setup-api.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/data-model.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/plan.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/quickstart.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/research.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/spec.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/specs/012-web-adopt-pairing/tasks.md +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/__main__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/cp.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/main.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/providers/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/providers/aws.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/providers/hetzner.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/providers/incus.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/providers/proxmox.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/shell.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/cli/web.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/ansible_runner.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/completion.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/config.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/known_hosts.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/output.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/picker.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/remo_host_client.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/rsync.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/ssh.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/validation.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/version.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/core/web_adopt.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/models/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/models/capability.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/models/discovery.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/models/host.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/models/session_target.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/models/snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/providers/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/providers/aws.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/providers/hetzner.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/providers/incus.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/providers/proxmox.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/api/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/api/hosts.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/api/pairing.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/api/setup.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/api/terminals.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/app.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/check.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/config.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/discovery.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/health.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/logging_config.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/models.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/operator_auth.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/pairing.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/ssh_master.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/state.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/terminal.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/terminal_registry.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/src/remo_cli/web/tokens.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/ansible/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/ansible/test_remo_host_idempotency.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/conftest.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/e2e/fixtures.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/e2e/ghostty-shell-io.spec.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/e2e/ghostty-tui-compatibility.spec.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/e2e/keyboard-routing.spec.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/e2e/mobile.spec.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/e2e/reconnect.spec.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/e2e/workspace-layout.spec.ts +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/image/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/image/test_docker_image.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/_nine_terminal_fixture.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/orbstack-cloud-init.yml +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/orbstack.sh +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/test_nine_terminals.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/test_nine_terminals_soak.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/test_remo_host_e2e.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/test_security_rejections.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/test_terminal_attach.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/test_web_adopt_e2e.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/integration/test_web_cli_parity.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/perf/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/perf/test_latency.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/providers/test_aws_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/providers/test_hetzner_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/providers/test_incus_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/providers/test_proxmox_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/test_cp.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/test_main.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/test_shell.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/cli/test_web_adopt_cmd.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_ansible_runner.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_config.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_known_hosts.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_output.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_picker.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_remo_host_client.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_rsync.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_ssh.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_ssh_controlpath.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_ssh_identity_opts.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_validation.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_version.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_web_adopt_authorize.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_web_adopt_code.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_web_adopt_payload.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_web_adopt_trust.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/core/test_web_push.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/models/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/models/test_capability.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/models/test_discovery.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/models/test_session_target.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/providers/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/providers/test_aws_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/providers/test_hetzner_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/providers/test_incus_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/providers/test_proxmox_devcontainer_runtime.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/providers/test_proxmox_snapshot.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/test_ansible_templates.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/test_host_model.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/__init__.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/_pairing_support.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/conftest.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_backpressure.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_check.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_csp.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_discovery.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_health_states.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_hosts_mapping.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_lazy_import.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_log_redaction.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_mint_gating.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_operator_auth.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_pairing.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_pairing_origin.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_setup_api.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_setup_auth.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_setup_dormancy.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_state.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_terminal_resize.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_terminals_api.py +0 -0
- {remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/tests/unit/web/test_tokens.py +0 -0
|
@@ -100,8 +100,11 @@ The SPA is a two-pane **web console**:
|
|
|
100
100
|
target as a grid.
|
|
101
101
|
- **Terminal pane** (right). Clicking a row opens that target **solo** (single view); ⌘/Ctrl-click a
|
|
102
102
|
row (or its `+` button) **adds** it to a responsive grid (1/2/3 columns by count). In a grid, **drag
|
|
103
|
-
a tile's header onto another to swap their positions**
|
|
104
|
-
|
|
103
|
+
a tile's header onto another to swap their positions** — a window outline follows the cursor and the
|
|
104
|
+
swap target shows a dashed outline (mouse or touch press-and-hold; keyboard-accessible via the
|
|
105
|
+
handle); the arrangement persists until the grid is rebuilt. In a grid, **hovering a tile focuses it**
|
|
106
|
+
(focus-follows-mouse) so keystrokes go where the pointer is — no click needed. The **◻** control solos
|
|
107
|
+
a tile; **Esc** collapses the grid back to the focused terminal;
|
|
105
108
|
number keys **1–9** jump to the numbered sessions (⌘ 1–9 add to the grid). Hidden terminals stay
|
|
106
109
|
connected and keep their scrollback. Each terminal header shows `provider · instance · region`
|
|
107
110
|
(doubling as the drag handle), connection state, and a
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"name": "remo-web-frontend",
|
|
9
9
|
"version": "0.0.0",
|
|
10
10
|
"dependencies": {
|
|
11
|
+
"@dnd-kit/core": "^6.3.1",
|
|
11
12
|
"@fontsource/fira-code": "^5.2.7",
|
|
12
13
|
"@fontsource/ibm-plex-mono": "^5.2.7",
|
|
13
14
|
"@fontsource/jetbrains-mono": "^5.2.8",
|
|
@@ -559,6 +560,45 @@
|
|
|
559
560
|
"node": ">=20.19.0"
|
|
560
561
|
}
|
|
561
562
|
},
|
|
563
|
+
"node_modules/@dnd-kit/accessibility": {
|
|
564
|
+
"version": "3.1.1",
|
|
565
|
+
"resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
|
|
566
|
+
"integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
|
|
567
|
+
"license": "MIT",
|
|
568
|
+
"dependencies": {
|
|
569
|
+
"tslib": "^2.0.0"
|
|
570
|
+
},
|
|
571
|
+
"peerDependencies": {
|
|
572
|
+
"react": ">=16.8.0"
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
"node_modules/@dnd-kit/core": {
|
|
576
|
+
"version": "6.3.1",
|
|
577
|
+
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
|
|
578
|
+
"integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
|
|
579
|
+
"license": "MIT",
|
|
580
|
+
"dependencies": {
|
|
581
|
+
"@dnd-kit/accessibility": "^3.1.1",
|
|
582
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
583
|
+
"tslib": "^2.0.0"
|
|
584
|
+
},
|
|
585
|
+
"peerDependencies": {
|
|
586
|
+
"react": ">=16.8.0",
|
|
587
|
+
"react-dom": ">=16.8.0"
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
"node_modules/@dnd-kit/utilities": {
|
|
591
|
+
"version": "3.2.2",
|
|
592
|
+
"resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz",
|
|
593
|
+
"integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==",
|
|
594
|
+
"license": "MIT",
|
|
595
|
+
"dependencies": {
|
|
596
|
+
"tslib": "^2.0.0"
|
|
597
|
+
},
|
|
598
|
+
"peerDependencies": {
|
|
599
|
+
"react": ">=16.8.0"
|
|
600
|
+
}
|
|
601
|
+
},
|
|
562
602
|
"node_modules/@esbuild/aix-ppc64": {
|
|
563
603
|
"version": "0.21.5",
|
|
564
604
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
|
|
@@ -3462,6 +3502,12 @@
|
|
|
3462
3502
|
"node": ">=20"
|
|
3463
3503
|
}
|
|
3464
3504
|
},
|
|
3505
|
+
"node_modules/tslib": {
|
|
3506
|
+
"version": "2.8.1",
|
|
3507
|
+
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
|
3508
|
+
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
|
3509
|
+
"license": "0BSD"
|
|
3510
|
+
},
|
|
3465
3511
|
"node_modules/typescript": {
|
|
3466
3512
|
"version": "5.9.3",
|
|
3467
3513
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
|
@@ -244,14 +244,6 @@
|
|
|
244
244
|
color: var(--accent);
|
|
245
245
|
flex: none;
|
|
246
246
|
}
|
|
247
|
-
.rail-row-num {
|
|
248
|
-
font-family: var(--font-mono);
|
|
249
|
-
font-size: 10px;
|
|
250
|
-
color: var(--text-faint);
|
|
251
|
-
width: 12px;
|
|
252
|
-
text-align: right;
|
|
253
|
-
flex: none;
|
|
254
|
-
}
|
|
255
247
|
.rail-row-name {
|
|
256
248
|
font-family: var(--font-mono);
|
|
257
249
|
font-size: 12.5px;
|
|
@@ -228,7 +228,6 @@ function RailInstance({
|
|
|
228
228
|
<RailSessionRow
|
|
229
229
|
key={row.target.id}
|
|
230
230
|
target={row.target}
|
|
231
|
-
num={row.num}
|
|
232
231
|
providerColor={meta.color}
|
|
233
232
|
attached={attached.includes(row.target.id)}
|
|
234
233
|
visible={visible.includes(row.target.id)}
|
|
@@ -243,7 +242,6 @@ function RailInstance({
|
|
|
243
242
|
|
|
244
243
|
interface RailSessionRowProps {
|
|
245
244
|
target: SessionTarget;
|
|
246
|
-
num: number | null;
|
|
247
245
|
providerColor: string;
|
|
248
246
|
attached: boolean;
|
|
249
247
|
visible: boolean;
|
|
@@ -254,7 +252,6 @@ interface RailSessionRowProps {
|
|
|
254
252
|
|
|
255
253
|
function RailSessionRow({
|
|
256
254
|
target,
|
|
257
|
-
num,
|
|
258
255
|
attached,
|
|
259
256
|
visible,
|
|
260
257
|
focused,
|
|
@@ -282,7 +279,6 @@ function RailSessionRow({
|
|
|
282
279
|
onClick={(e) => onSelect(target, e)}
|
|
283
280
|
>
|
|
284
281
|
<span className="rail-row-mark">{mark}</span>
|
|
285
|
-
<span className="rail-row-num">{num ?? ""}</span>
|
|
286
282
|
<span className="rail-row-name">{target.project}</span>
|
|
287
283
|
<span className="rail-row-glyphs">
|
|
288
284
|
{target.git_dirty && (
|
|
@@ -53,26 +53,54 @@
|
|
|
53
53
|
.terminal-card--grid .terminal-card-grip {
|
|
54
54
|
gap: 8px;
|
|
55
55
|
}
|
|
56
|
-
.terminal-card-grip
|
|
56
|
+
.terminal-card-grip--handle {
|
|
57
57
|
cursor: grab;
|
|
58
|
+
touch-action: none; /* let the TouchSensor own press-and-hold drags */
|
|
58
59
|
}
|
|
59
|
-
.terminal-card-grip
|
|
60
|
+
.terminal-card-grip--handle:active {
|
|
60
61
|
cursor: grabbing;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
/* Reorder drag feedback.
|
|
64
|
+
/* Reorder drag feedback. The source tile dims; the tile the drop will land on
|
|
65
|
+
* (swap target) gets a bold dashed outline showing where the window will go. */
|
|
64
66
|
.terminal-card--dragging {
|
|
65
|
-
opacity: 0.
|
|
67
|
+
opacity: 0.4;
|
|
66
68
|
}
|
|
67
69
|
.terminal-card--drop-target {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
outline: 2px dashed color-mix(in oklch, var(--accent) 85%, white);
|
|
71
|
+
outline-offset: -3px;
|
|
72
|
+
background: color-mix(in oklch, var(--accent) 12%, var(--bg-term));
|
|
70
73
|
}
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
/* The floating window-outline ghost rendered in the dnd-kit DragOverlay while
|
|
76
|
+
* dragging. Fills the overlay box (sized to the dragged tile), so it reads as
|
|
77
|
+
* the window itself following the cursor. */
|
|
78
|
+
.terminal-drag-ghost {
|
|
79
|
+
width: 100%;
|
|
80
|
+
height: 100%;
|
|
81
|
+
box-sizing: border-box;
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: flex-start;
|
|
84
|
+
border-radius: var(--radius-lg);
|
|
85
|
+
border: 2px dashed color-mix(in oklch, var(--accent) 80%, white);
|
|
86
|
+
background: color-mix(in oklch, var(--accent) 16%, transparent);
|
|
87
|
+
box-shadow: 0 12px 30px oklch(0 0 0 / 0.35);
|
|
88
|
+
cursor: grabbing;
|
|
89
|
+
overflow: hidden;
|
|
90
|
+
}
|
|
91
|
+
.terminal-drag-ghost-title {
|
|
92
|
+
margin: 8px 12px;
|
|
93
|
+
padding: 3px 10px;
|
|
73
94
|
font-family: var(--font-mono);
|
|
74
|
-
font-
|
|
75
|
-
|
|
95
|
+
font-weight: 600;
|
|
96
|
+
font-size: 12px;
|
|
97
|
+
color: var(--text);
|
|
98
|
+
background: color-mix(in oklch, var(--bg-header) 85%, transparent);
|
|
99
|
+
border-radius: 6px;
|
|
100
|
+
white-space: nowrap;
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
text-overflow: ellipsis;
|
|
103
|
+
max-width: calc(100% - 24px);
|
|
76
104
|
}
|
|
77
105
|
|
|
78
106
|
.terminal-card-provider-dot {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// terminal surface (which would tear down the live connection).
|
|
11
11
|
|
|
12
12
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
13
|
+
import { useDraggable, useDroppable } from "@dnd-kit/core";
|
|
13
14
|
import type { SessionTarget, TypedError } from "../api/client";
|
|
14
15
|
import { providerMeta } from "./providerMeta";
|
|
15
16
|
import {
|
|
@@ -42,18 +43,6 @@ export type TerminalCardMode = "single" | "grid";
|
|
|
42
43
|
* Drives the window-control cluster's active/disabled state. */
|
|
43
44
|
export type TerminalViewState = "normal" | "grid" | "fullscreen";
|
|
44
45
|
|
|
45
|
-
/** Drag-to-reorder wiring for a grid tile. Present only when reordering is
|
|
46
|
-
* possible (a grid of two-plus); the header acts as the drag handle and the
|
|
47
|
-
* whole tile is a drop target — dropping swaps the two tiles' positions. */
|
|
48
|
-
export interface TerminalReorder {
|
|
49
|
-
isDragging: boolean;
|
|
50
|
-
isDropTarget: boolean;
|
|
51
|
-
onDragStart: () => void;
|
|
52
|
-
onDragEnter: () => void;
|
|
53
|
-
onDrop: () => void;
|
|
54
|
-
onDragEnd: () => void;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
46
|
interface TerminalCardProps {
|
|
58
47
|
target: SessionTarget;
|
|
59
48
|
/** Registry region for this target's instance (badge only). */
|
|
@@ -63,13 +52,12 @@ interface TerminalCardProps {
|
|
|
63
52
|
isVisible: boolean;
|
|
64
53
|
/** Whether this card currently receives keyboard input + the focus ring. */
|
|
65
54
|
isFocused: boolean;
|
|
66
|
-
/** 1-based position label shown on a grid tile. */
|
|
67
|
-
num?: number;
|
|
68
55
|
/** The display mode this card is currently in (window-control cluster state). */
|
|
69
56
|
viewState: TerminalViewState;
|
|
70
57
|
onClose: () => void;
|
|
71
|
-
/**
|
|
72
|
-
|
|
58
|
+
/** When true, the header acts as a dnd-kit drag handle and the tile is a drop
|
|
59
|
+
* target (grid reorder). The DndContext + swap live in WorkspacePane. */
|
|
60
|
+
reorderEnabled?: boolean;
|
|
73
61
|
/** Window-control "Normal": solo this terminal into the single view. */
|
|
74
62
|
onNormal: () => void;
|
|
75
63
|
/** Window-control "Grid": show the grid — omitted when none is available. */
|
|
@@ -78,6 +66,9 @@ interface TerminalCardProps {
|
|
|
78
66
|
onToggleFullscreen: () => void;
|
|
79
67
|
/** Called when the user clicks into the surface (focus this terminal). */
|
|
80
68
|
onFocusRequest?: () => void;
|
|
69
|
+
/** Focus-follows-mouse: called when the pointer enters this tile (grid only),
|
|
70
|
+
* so hovering changes focus without a click. No-op'd mid-drag by the caller. */
|
|
71
|
+
onHoverFocus?: () => void;
|
|
81
72
|
/** Called when output arrives while this card is hidden (rail activity dot). */
|
|
82
73
|
onActivity?: () => void;
|
|
83
74
|
/** Called when the remote process exits (session may have ended) or the
|
|
@@ -100,14 +91,14 @@ export function TerminalCard({
|
|
|
100
91
|
mode,
|
|
101
92
|
isVisible,
|
|
102
93
|
isFocused,
|
|
103
|
-
num,
|
|
104
94
|
viewState,
|
|
105
95
|
onClose,
|
|
106
|
-
|
|
96
|
+
reorderEnabled,
|
|
107
97
|
onNormal,
|
|
108
98
|
onGrid,
|
|
109
99
|
onToggleFullscreen,
|
|
110
100
|
onFocusRequest,
|
|
101
|
+
onHoverFocus,
|
|
111
102
|
onActivity,
|
|
112
103
|
onEnded,
|
|
113
104
|
}: TerminalCardProps): JSX.Element {
|
|
@@ -133,6 +124,22 @@ export function TerminalCard({
|
|
|
133
124
|
const [needsManualReconnect, setNeedsManualReconnect] = useState(false);
|
|
134
125
|
const [error, setError] = useState<TypedError | null>(null);
|
|
135
126
|
|
|
127
|
+
// dnd-kit reorder: the tile is both a draggable (handle = header grip, below)
|
|
128
|
+
// and a droppable (swap target). Disabled outside a reorderable grid. We use
|
|
129
|
+
// the DragOverlay pattern (WorkspacePane), so the source stays put (dimmed)
|
|
130
|
+
// and we never apply `draggable.transform`.
|
|
131
|
+
const draggable = useDraggable({ id: target.id, disabled: !reorderEnabled });
|
|
132
|
+
const droppable = useDroppable({ id: target.id, disabled: !reorderEnabled });
|
|
133
|
+
const setDraggableRef = draggable.setNodeRef;
|
|
134
|
+
const setDroppableRef = droppable.setNodeRef;
|
|
135
|
+
const setTileRef = useCallback(
|
|
136
|
+
(node: HTMLDivElement | null) => {
|
|
137
|
+
setDraggableRef(node);
|
|
138
|
+
setDroppableRef(node);
|
|
139
|
+
},
|
|
140
|
+
[setDraggableRef, setDroppableRef],
|
|
141
|
+
);
|
|
142
|
+
|
|
136
143
|
useEffect(() => {
|
|
137
144
|
isFocusedRef.current = isFocused;
|
|
138
145
|
}, [isFocused]);
|
|
@@ -302,42 +309,30 @@ export function TerminalCard({
|
|
|
302
309
|
const prov = providerMeta(target.instance_type);
|
|
303
310
|
const badge = [prov.label, target.instance_name, region].filter(Boolean).join(" · ");
|
|
304
311
|
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
312
|
+
const isDragging = draggable.isDragging;
|
|
313
|
+
// Highlight the tile the drop will land on (swap target) — but not the source.
|
|
314
|
+
const isDropTarget = Boolean(reorderEnabled) && droppable.isOver && !isDragging;
|
|
315
|
+
const dragClasses = `${isDragging ? " terminal-card--dragging" : ""}${isDropTarget ? " terminal-card--drop-target" : ""}`;
|
|
308
316
|
|
|
309
317
|
return (
|
|
310
318
|
<div
|
|
319
|
+
ref={setTileRef}
|
|
311
320
|
className={`terminal-card terminal-card--${mode}${isFocused ? " terminal-card--focused" : ""}${dragClasses}`}
|
|
312
321
|
data-testid={`terminal-card-${target.id}`}
|
|
313
322
|
data-focused={isFocused}
|
|
314
323
|
data-connection-state={connectionState}
|
|
315
324
|
style={{ display: isVisible ? undefined : "none" }}
|
|
316
|
-
|
|
317
|
-
onDragOver={reorder ? (e) => e.preventDefault() : undefined}
|
|
318
|
-
onDragEnter={reorder ? (e) => { e.preventDefault(); reorder.onDragEnter(); } : undefined}
|
|
319
|
-
onDrop={reorder ? (e) => { e.preventDefault(); reorder.onDrop(); } : undefined}
|
|
325
|
+
onMouseEnter={onHoverFocus}
|
|
320
326
|
>
|
|
321
327
|
<header className="terminal-card-header">
|
|
322
328
|
{/* The header (left of the controls) is the drag handle for reordering
|
|
323
329
|
* grid tiles; it no longer solos on click — the ◻ control does that. */}
|
|
324
330
|
<div
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
? (e) => {
|
|
330
|
-
e.dataTransfer.setData("text/plain", target.id);
|
|
331
|
-
e.dataTransfer.effectAllowed = "move";
|
|
332
|
-
reorder.onDragStart();
|
|
333
|
-
}
|
|
334
|
-
: undefined
|
|
335
|
-
}
|
|
336
|
-
onDragEnd={reorder ? () => reorder.onDragEnd() : undefined}
|
|
331
|
+
ref={reorderEnabled ? draggable.setActivatorNodeRef : undefined}
|
|
332
|
+
className={`terminal-card-grip${reorderEnabled ? " terminal-card-grip--handle" : ""}`}
|
|
333
|
+
{...(reorderEnabled ? draggable.listeners : {})}
|
|
334
|
+
{...(reorderEnabled ? draggable.attributes : {})}
|
|
337
335
|
>
|
|
338
|
-
{mode === "grid" && num !== undefined && (
|
|
339
|
-
<span className="terminal-card-num">{num}</span>
|
|
340
|
-
)}
|
|
341
336
|
<span className="terminal-card-provider-dot" style={{ background: prov.color }} />
|
|
342
337
|
<div className="terminal-card-identity">
|
|
343
338
|
<span className="terminal-card-project">{target.project}</span>
|
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
// laid out as a single view (one visible) or a responsive grid (two-plus).
|
|
4
4
|
|
|
5
5
|
import { useMemo, useState } from "react";
|
|
6
|
+
import {
|
|
7
|
+
DndContext,
|
|
8
|
+
DragOverlay,
|
|
9
|
+
KeyboardSensor,
|
|
10
|
+
PointerSensor,
|
|
11
|
+
TouchSensor,
|
|
12
|
+
closestCenter,
|
|
13
|
+
useSensor,
|
|
14
|
+
useSensors,
|
|
15
|
+
type DragEndEvent,
|
|
16
|
+
type DragStartEvent,
|
|
17
|
+
} from "@dnd-kit/core";
|
|
6
18
|
import type { SessionTarget } from "../api/client";
|
|
7
19
|
import { requestBrowserFullscreen } from "../lib/fullscreen";
|
|
8
20
|
import { useWorkspace } from "../state/workspace";
|
|
@@ -46,10 +58,16 @@ export function WorkspacePane({
|
|
|
46
58
|
const workspace = useWorkspace();
|
|
47
59
|
const { attached, visible, focusedId, prevGrid, maximizedId } = workspace;
|
|
48
60
|
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
const [
|
|
52
|
-
const
|
|
61
|
+
// dnd-kit reorder: `activeId` is the tile currently being dragged (drives the
|
|
62
|
+
// floating DragOverlay ghost). Only the resulting order (`visible`) persists.
|
|
63
|
+
const [activeId, setActiveId] = useState<string | null>(null);
|
|
64
|
+
const sensors = useSensors(
|
|
65
|
+
// A small move starts a drag, so plain clicks (buttons, focus) still work.
|
|
66
|
+
useSensor(PointerSensor, { activationConstraint: { distance: 6 } }),
|
|
67
|
+
// Touch: a short press-and-hold starts a drag, leaving taps/scroll intact.
|
|
68
|
+
useSensor(TouchSensor, { activationConstraint: { delay: 180, tolerance: 8 } }),
|
|
69
|
+
useSensor(KeyboardSensor),
|
|
70
|
+
);
|
|
53
71
|
|
|
54
72
|
// Render visible tiles in `visible` order (so the grid layout follows the
|
|
55
73
|
// reorderable order + the number badges), then the hidden-but-attached cards
|
|
@@ -99,9 +117,6 @@ export function WorkspacePane({
|
|
|
99
117
|
visible.filter((id) => attached.includes(id)).length > 1 ||
|
|
100
118
|
(prevGrid ?? []).filter((id) => attached.includes(id)).length > 1;
|
|
101
119
|
|
|
102
|
-
// 1-based position for each visible id (grid tile number badge).
|
|
103
|
-
const visibleIndex = new Map(visible.map((id, i) => [id, i + 1]));
|
|
104
|
-
|
|
105
120
|
const toggleFullscreen = (id: string): void => {
|
|
106
121
|
if (maximized === id) {
|
|
107
122
|
workspace.restore();
|
|
@@ -114,70 +129,85 @@ export function WorkspacePane({
|
|
|
114
129
|
|
|
115
130
|
// Reordering is possible only within a real grid (two-plus visible tiles).
|
|
116
131
|
const reorderable = !maximized && mode === "grid" && visible.length > 1;
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
132
|
+
const activeTarget = activeId ? targetsById.get(activeId) : undefined;
|
|
133
|
+
|
|
134
|
+
const onDragStart = (e: DragStartEvent): void => setActiveId(String(e.active.id));
|
|
135
|
+
const onDragEnd = (e: DragEndEvent): void => {
|
|
136
|
+
const { active, over } = e;
|
|
137
|
+
setActiveId(null);
|
|
138
|
+
if (over && active.id !== over.id) {
|
|
139
|
+
workspace.swapVisible(String(active.id), String(over.id));
|
|
140
|
+
}
|
|
120
141
|
};
|
|
121
142
|
|
|
122
143
|
return (
|
|
123
144
|
<main className="workspace" data-testid="workspace">
|
|
124
|
-
<
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`,
|
|
131
|
-
}
|
|
132
|
-
: undefined
|
|
133
|
-
}
|
|
145
|
+
<DndContext
|
|
146
|
+
sensors={sensors}
|
|
147
|
+
collisionDetection={closestCenter}
|
|
148
|
+
onDragStart={onDragStart}
|
|
149
|
+
onDragEnd={onDragEnd}
|
|
150
|
+
onDragCancel={() => setActiveId(null)}
|
|
134
151
|
>
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const reorder =
|
|
140
|
-
reorderable && isVisible
|
|
152
|
+
<div
|
|
153
|
+
className={`workspace-body workspace-body--${mode}${maximized ? " workspace-body--maximized" : ""}`}
|
|
154
|
+
style={
|
|
155
|
+
mode === "grid"
|
|
141
156
|
? {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
onDragStart: () => setDragId(id),
|
|
145
|
-
onDragEnter: () => {
|
|
146
|
-
if (dragId && dragId !== id) {
|
|
147
|
-
setOverId(id);
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
onDrop: () => {
|
|
151
|
-
if (dragId && dragId !== id) {
|
|
152
|
-
workspace.swapVisible(dragId, id);
|
|
153
|
-
}
|
|
154
|
-
clearDrag();
|
|
155
|
-
},
|
|
156
|
-
onDragEnd: clearDrag,
|
|
157
|
+
gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`,
|
|
158
|
+
gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`,
|
|
157
159
|
}
|
|
158
|
-
: undefined
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
160
|
+
: undefined
|
|
161
|
+
}
|
|
162
|
+
>
|
|
163
|
+
{orderedTargets.map((target) => {
|
|
164
|
+
const id = target.id;
|
|
165
|
+
const isVisible = maximized ? id === maximized : visible.includes(id);
|
|
166
|
+
const viewState =
|
|
167
|
+
maximized === id ? "fullscreen" : mode === "grid" ? "grid" : "normal";
|
|
168
|
+
return (
|
|
169
|
+
<TerminalCard
|
|
170
|
+
key={id}
|
|
171
|
+
target={target}
|
|
172
|
+
region={regionByKey.get(`${target.instance_type}::${target.instance_name}`)}
|
|
173
|
+
mode={mode}
|
|
174
|
+
isVisible={isVisible}
|
|
175
|
+
isFocused={focusedId === id}
|
|
176
|
+
viewState={viewState}
|
|
177
|
+
reorderEnabled={reorderable && isVisible}
|
|
178
|
+
onClose={() => workspace.closeTerm(id)}
|
|
179
|
+
onNormal={() => workspace.soloTile(id)}
|
|
180
|
+
onGrid={canGrid ? workspace.backToGrid : undefined}
|
|
181
|
+
onToggleFullscreen={() => toggleFullscreen(id)}
|
|
182
|
+
onFocusRequest={() => workspace.setFocused(id)}
|
|
183
|
+
onHoverFocus={
|
|
184
|
+
mode === "grid" && !maximized
|
|
185
|
+
? () => {
|
|
186
|
+
// Focus-follows-mouse: hovering a grid tile focuses it,
|
|
187
|
+
// but never while dragging (would fight the reorder).
|
|
188
|
+
if (!activeId && focusedId !== id) {
|
|
189
|
+
workspace.setFocused(id);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
: undefined
|
|
193
|
+
}
|
|
194
|
+
onActivity={() => workspace.markUnread(id)}
|
|
195
|
+
onEnded={() => onTerminalEnded(target)}
|
|
196
|
+
/>
|
|
197
|
+
);
|
|
198
|
+
})}
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
{/* Floating "window outline" ghost that follows the cursor while dragging
|
|
202
|
+
* a grid tile. dropAnimation off — the tiles swap instantly on drop. */}
|
|
203
|
+
<DragOverlay dropAnimation={null}>
|
|
204
|
+
{activeTarget ? (
|
|
205
|
+
<div className="terminal-drag-ghost" aria-hidden="true">
|
|
206
|
+
<span className="terminal-drag-ghost-title">{activeTarget.project}</span>
|
|
207
|
+
</div>
|
|
208
|
+
) : null}
|
|
209
|
+
</DragOverlay>
|
|
210
|
+
</DndContext>
|
|
181
211
|
</main>
|
|
182
212
|
);
|
|
183
213
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.maverick/checkpoints/feature/implementation_complete.json
RENAMED
|
File without changes
|
|
File without changes
|
{remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.maverick/checkpoints/feature/validation_complete.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remo_cli-2.2.0rc8 → remo_cli-2.2.0rc10}/.specify/extensions/git/commands/speckit.git.commit.md
RENAMED
|
File without changes
|