servonaut 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. servonaut-2.1.0/.github/PULL_REQUEST_TEMPLATE.md +31 -0
  2. servonaut-2.1.0/.github/workflows/ci.yml +38 -0
  3. servonaut-2.1.0/.github/workflows/publish.yml +46 -0
  4. servonaut-2.1.0/.gitignore +51 -0
  5. servonaut-2.1.0/CLAUDE.md +113 -0
  6. servonaut-2.1.0/CONTRIBUTING.md +45 -0
  7. servonaut-2.1.0/LICENSE +21 -0
  8. servonaut-2.1.0/PKG-INFO +175 -0
  9. servonaut-2.1.0/README.md +142 -0
  10. servonaut-2.1.0/docs/architecture.md +125 -0
  11. servonaut-2.1.0/docs/configuration.md +185 -0
  12. servonaut-2.1.0/docs/troubleshooting.md +106 -0
  13. servonaut-2.1.0/install.ps1 +264 -0
  14. servonaut-2.1.0/install.sh +413 -0
  15. servonaut-2.1.0/pyproject.toml +54 -0
  16. servonaut-2.1.0/src/servonaut/__init__.py +3 -0
  17. servonaut-2.1.0/src/servonaut/app.css +758 -0
  18. servonaut-2.1.0/src/servonaut/app.py +75 -0
  19. servonaut-2.1.0/src/servonaut/config/__init__.py +14 -0
  20. servonaut-2.1.0/src/servonaut/config/manager.py +344 -0
  21. servonaut-2.1.0/src/servonaut/config/migration.py +92 -0
  22. servonaut-2.1.0/src/servonaut/config/schema.py +94 -0
  23. servonaut-2.1.0/src/servonaut/main.py +63 -0
  24. servonaut-2.1.0/src/servonaut/screens/__init__.py +25 -0
  25. servonaut-2.1.0/src/servonaut/screens/command_overlay.py +417 -0
  26. servonaut-2.1.0/src/servonaut/screens/command_picker.py +195 -0
  27. servonaut-2.1.0/src/servonaut/screens/file_browser.py +136 -0
  28. servonaut-2.1.0/src/servonaut/screens/help.py +159 -0
  29. servonaut-2.1.0/src/servonaut/screens/instance_list.py +396 -0
  30. servonaut-2.1.0/src/servonaut/screens/key_management.py +330 -0
  31. servonaut-2.1.0/src/servonaut/screens/main_menu.py +169 -0
  32. servonaut-2.1.0/src/servonaut/screens/scan_results.py +163 -0
  33. servonaut-2.1.0/src/servonaut/screens/scp_transfer.py +205 -0
  34. servonaut-2.1.0/src/servonaut/screens/server_actions.py +283 -0
  35. servonaut-2.1.0/src/servonaut/screens/settings.py +286 -0
  36. servonaut-2.1.0/src/servonaut/services/__init__.py +39 -0
  37. servonaut-2.1.0/src/servonaut/services/aws_service.py +137 -0
  38. servonaut-2.1.0/src/servonaut/services/cache_service.py +158 -0
  39. servonaut-2.1.0/src/servonaut/services/command_history.py +163 -0
  40. servonaut-2.1.0/src/servonaut/services/connection_service.py +181 -0
  41. servonaut-2.1.0/src/servonaut/services/interfaces.py +388 -0
  42. servonaut-2.1.0/src/servonaut/services/keyword_store.py +159 -0
  43. servonaut-2.1.0/src/servonaut/services/scan_service.py +241 -0
  44. servonaut-2.1.0/src/servonaut/services/scp_service.py +159 -0
  45. servonaut-2.1.0/src/servonaut/services/ssh_service.py +284 -0
  46. servonaut-2.1.0/src/servonaut/services/terminal_service.py +321 -0
  47. servonaut-2.1.0/src/servonaut/utils/__init__.py +25 -0
  48. servonaut-2.1.0/src/servonaut/utils/formatting.py +90 -0
  49. servonaut-2.1.0/src/servonaut/utils/match_utils.py +53 -0
  50. servonaut-2.1.0/src/servonaut/utils/platform_utils.py +72 -0
  51. servonaut-2.1.0/src/servonaut/utils/ssh_utils.py +72 -0
  52. servonaut-2.1.0/src/servonaut/widgets/__init__.py +17 -0
  53. servonaut-2.1.0/src/servonaut/widgets/command_output.py +56 -0
  54. servonaut-2.1.0/src/servonaut/widgets/instance_table.py +109 -0
  55. servonaut-2.1.0/src/servonaut/widgets/progress_indicator.py +30 -0
  56. servonaut-2.1.0/src/servonaut/widgets/remote_tree.py +342 -0
  57. servonaut-2.1.0/src/servonaut/widgets/status_bar.py +84 -0
  58. servonaut-2.1.0/tests/__init__.py +0 -0
  59. servonaut-2.1.0/tests/conftest.py +87 -0
  60. servonaut-2.1.0/tests/test_cache_service.py +104 -0
  61. servonaut-2.1.0/tests/test_command_history.py +121 -0
  62. servonaut-2.1.0/tests/test_config_manager.py +132 -0
  63. servonaut-2.1.0/tests/test_config_migration.py +48 -0
  64. servonaut-2.1.0/tests/test_config_schema.py +93 -0
  65. servonaut-2.1.0/tests/test_connection_service.py +198 -0
  66. servonaut-2.1.0/tests/test_formatting.py +76 -0
  67. servonaut-2.1.0/tests/test_keyword_store.py +109 -0
  68. servonaut-2.1.0/tests/test_match_utils.py +73 -0
  69. servonaut-2.1.0/tests/test_platform_utils.py +40 -0
  70. servonaut-2.1.0/tests/test_scp_service.py +93 -0
  71. servonaut-2.1.0/tests/test_ssh_service.py +204 -0
  72. servonaut-2.1.0/tests/test_ssh_utils.py +69 -0
@@ -0,0 +1,31 @@
1
+ Thank you for contributing to Servonaut!
2
+
3
+ Please provide a clear description of your changes and link to any relevant issues.
4
+
5
+ **Before submitting, please ensure you have:**
6
+ - [ ] Read the [CONTRIBUTING.md](https://github.com/zb-ss/ec2-ssh/blob/master/CONTRIBUTING.md) guide.
7
+ - [ ] Based your changes on the `main` branch (or the relevant development branch).
8
+ - [ ] Ensured your code follows the project's coding style.
9
+ - [ ] Added tests for your changes (if applicable).
10
+ - [ ] Updated documentation (e.g., `README.md`) if your changes require it.
11
+ - [ ] Added a clear and descriptive title for your pull request.
12
+ - [ ] Written a clear summary of the changes in the "Description" section below.
13
+
14
+ ---
15
+
16
+ **Description of Changes:**
17
+
18
+ *(Please provide a detailed description of the changes you've made.)*
19
+
20
+ **Related Issues:**
21
+
22
+ *(Link to any relevant issues using `#issue_number`)*
23
+
24
+ ---
25
+
26
+ **Checklist for Reviewers (Optional - for maintainer use):**
27
+ - [ ] Code is well-formatted and easy to understand.
28
+ - [ ] Changes achieve the intended purpose.
29
+ - [ ] Tests pass (if applicable).
30
+ - [ ] Documentation is updated (if applicable).
31
+ - [ ] No new major issues are introduced.
@@ -0,0 +1,38 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.8", "3.10", "3.12", "3.13"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Set up Python ${{ matrix.python-version }}
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+
23
+ - name: Install dependencies
24
+ run: pip install -e ".[test]"
25
+
26
+ - name: Run tests
27
+ run: pytest --tb=short -q
28
+
29
+ - name: Run tests with coverage
30
+ if: matrix.python-version == '3.12'
31
+ run: pytest --cov=servonaut --cov-report=term-missing --cov-report=xml
32
+
33
+ - name: Upload coverage
34
+ if: matrix.python-version == '3.12'
35
+ uses: actions/upload-artifact@v4
36
+ with:
37
+ name: coverage-report
38
+ path: coverage.xml
@@ -0,0 +1,46 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ id-token: write
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install dependencies
22
+ run: pip install -e ".[test]"
23
+
24
+ - name: Run tests
25
+ run: pytest --tb=short -q
26
+
27
+ publish:
28
+ needs: test
29
+ runs-on: ubuntu-latest
30
+ environment: pypi
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+
34
+ - name: Set up Python
35
+ uses: actions/setup-python@v5
36
+ with:
37
+ python-version: "3.12"
38
+
39
+ - name: Install build tools
40
+ run: pip install build
41
+
42
+ - name: Build package
43
+ run: python -m build
44
+
45
+ - name: Publish to PyPI
46
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,51 @@
1
+ .aider*
2
+ # Python
3
+ __pycache__/
4
+ *.pyc
5
+ *.pyo
6
+ *.pyd
7
+ *.so
8
+
9
+ # Build artifacts
10
+ build/
11
+ dist/
12
+ *.egg-info/
13
+ *.egg
14
+ *.whl
15
+
16
+ # Virtual environments
17
+ .venv/
18
+ venv/
19
+ ENV/
20
+ env/
21
+
22
+ # IDE / Editor specific
23
+ .vscode/
24
+ .idea/
25
+ *.project
26
+ *.pydevproject
27
+ *.sublime-workspace
28
+ *.sublime-project
29
+
30
+ # OS specific
31
+ .DS_Store
32
+ Thumbs.db
33
+
34
+ # Configuration files (if any local, non-committed ones are used)
35
+ # .env
36
+
37
+ # Test artifacts
38
+ .pytest_cache/
39
+ .coverage
40
+ htmlcov/
41
+ nosetests.xml
42
+ coverage.xml
43
+ *.cover
44
+ *.log
45
+
46
+ # Hatchling specific (build backend)
47
+ .hatch/
48
+
49
+ # Projectile marker file
50
+ .projectile
51
+ /local/
@@ -0,0 +1,113 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Servonaut is a Terminal User Interface (TUI) for managing servers. Built with Python and Textual, it provides SSH connections, SCP file transfer, remote file browsing, command execution, and keyword-based server scanning across all AWS regions.
8
+
9
+ ## Development Commands
10
+
11
+ ```bash
12
+ # Run directly without installing (primary dev workflow)
13
+ PYTHONPATH=src python3 -m servonaut.main
14
+
15
+ # Or run the script directly
16
+ python src/servonaut/main.py
17
+
18
+ # Run with debug logging (prints to stderr + log file)
19
+ PYTHONPATH=src python3 -m servonaut.main --debug
20
+
21
+ # Install via pipx (production)
22
+ pipx install .
23
+
24
+ # Update existing pipx installation after changes
25
+ pipx install . --force
26
+
27
+ # Install editable for development
28
+ pip install -e .
29
+ ```
30
+
31
+ Tests use pytest. Run with `pip install -e ".[test]" && pytest`. CI runs on push/PR to master via GitHub Actions.
32
+
33
+ ## Architecture
34
+
35
+ Modular TUI built on Textual, organized into five packages under `src/servonaut/`:
36
+
37
+ - **`config/`** — Configuration management: `AppConfig` dataclass hierarchy (`schema.py`), JSON load/save/validate (`manager.py`), v1→v2 migration (`migration.py`)
38
+ - **`services/`** — Business logic with abstract interfaces (`interfaces.py`). Each service implements its interface. Key services: `AWSService` (boto3 EC2 API), `CacheService` (stale-while-revalidate), `SSHService` (key management, command building), `ConnectionService` (bastion/ProxyJump resolution), `ScanService` + `KeywordStore` (keyword scanning), `TerminalService` (terminal detection/launch), `SCPService` (file transfer)
39
+ - **`screens/`** — Textual `Screen` subclasses for each view (main menu, instance list, server actions, file browser, command overlay, SCP transfer, scan results, settings, key management, search, help)
40
+ - **`widgets/`** — Reusable Textual widgets: `InstanceTable` (DataTable), `RemoteTree` (Tree for remote fs), `StatusBar`, `ProgressIndicator`, `CommandOutput` (RichLog)
41
+ - **`utils/`** — Helpers: `formatting.py`, `platform_utils.py`, `ssh_utils.py`, `match_utils.py` (instance matching with conditions like `name_contains`, `region`, `name_regex`)
42
+
43
+ ### Service Initialization and Access
44
+
45
+ All services are created in `ServonautApp._init_services()` (in `app.py`) during `on_mount`. Services are stored as attributes on the app instance. Screens access them via `self.app.<service>` (e.g., `self.app.ssh_service`, `self.app.connection_service`).
46
+
47
+ Service dependency chain:
48
+ ```
49
+ ConfigManager → config
50
+ ├── CacheService(ttl_seconds=config.cache_ttl_seconds)
51
+ │ └── AWSService(cache_service)
52
+ ├── SSHService(config_manager)
53
+ ├── ConnectionService(config_manager)
54
+ ├── ScanService(config_manager)
55
+ ├── KeywordStore(config.keyword_store_path)
56
+ ├── TerminalService(preferred=config.terminal_emulator)
57
+ ├── SCPService()
58
+ └── CommandHistoryService(config.command_history_path)
59
+ ```
60
+
61
+ ### Screen Navigation
62
+
63
+ Screens use `self.app.push_screen()` / `self.app.pop_screen()`. Shared instance data lives in `self.app.instances` (list of dicts with keys: `id`, `name`, `type`, `state`, `public_ip`, `private_ip`, `region`, `key_name`).
64
+
65
+ ### Async Pattern
66
+
67
+ Long-running operations (AWS API, SSH) are async and run via `self.run_worker()` to avoid blocking the TUI. Workers notify the UI via `self.notify()`.
68
+
69
+ ### Styling
70
+
71
+ All CSS is in a single `app.css` file using Textual's CSS-like syntax with design tokens (`$surface`, `$primary`, `$accent`, etc.). Screen-specific styles are organized into labeled sections within this file.
72
+
73
+ ## Key Design Decisions
74
+
75
+ **SSH Connection Strategy:**
76
+ - ProxyJump (`-J`) when no separate bastion key; ProxyCommand when `bastion_key` is set (allows different key for bastion vs target)
77
+ - `IdentitiesOnly=yes` only added when `-i` flag is present
78
+ - Key auto-discovery searches `~/.ssh/` with multiple patterns (exact match, `.pem`, fuzzy)
79
+ - External SSH sessions launch in new terminal window via wrapper script that keeps terminal open on failure
80
+
81
+ **Instance Caching (stale-while-revalidate):**
82
+ - Cache at `~/.servonaut/cache.json` with configurable TTL (default 3600s)
83
+ - Startup: show stale data immediately, refresh in background if expired
84
+ - `CacheService.load()` respects TTL; `load_any()` ignores TTL; `is_fresh()` checks TTL
85
+ - Force refresh via `R` key in instance list
86
+
87
+ **Configuration:**
88
+ - JSON at `~/.servonaut/config.json`, dataclass-based schema (`AppConfig`, `ScanRule`, `ConnectionProfile`, `ConnectionRule`)
89
+ - Schema versioning (`CONFIG_VERSION = 2`) with automatic v1→v2 migration
90
+ - Connection rules evaluated in order — first match wins
91
+
92
+ **Instance Matching (`match_utils.py`):**
93
+ - Used by both scan rules and connection rules
94
+ - Supports: `name_contains`, `name_regex`, `region`, `id`, `type_contains`, `has_public_ip`
95
+ - All conditions are AND-ed together
96
+
97
+ ## Runtime Files
98
+
99
+ All runtime files are under `~/.servonaut/`:
100
+
101
+ - `~/.servonaut/config.json` — Main configuration
102
+ - `~/.servonaut/cache.json` — Cached instance list
103
+ - `~/.servonaut/keywords.json` — Scan results store
104
+ - `~/.servonaut/command_history.json` — Saved commands and command history
105
+ - `~/.servonaut/logs/servonaut.log` — Application log
106
+ - `~/.servonaut/logs/servonaut_*.sh` — Temporary SSH wrapper scripts
107
+
108
+ ## Dependencies
109
+
110
+ - `boto3` — AWS EC2 API
111
+ - `tabulate` — Table formatting (legacy)
112
+ - `textual>=0.40.0` — TUI framework
113
+ - Python 3.8+ required
@@ -0,0 +1,45 @@
1
+ # Contributing to Servonaut
2
+
3
+ First off, thank you for considering contributing to Servonaut! Your help is appreciated.
4
+
5
+ This document provides guidelines for contributing to this project.
6
+
7
+ ## How Can I Contribute?
8
+
9
+ ### Reporting Bugs
10
+ * Ensure the bug was not already reported by searching on GitHub under [Issues](https://github.com/zb-ss/ec2-ssh/issues).
11
+ * If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/zb-ss/ec2-ssh/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample or an executable test case** demonstrating the expected behavior that is not occurring.
12
+
13
+ ### Suggesting Enhancements
14
+ * Open a new issue to discuss your enhancement. Clearly describe the proposed enhancement and its potential benefits.
15
+ * Provide a step-by-step description of the suggested enhancement in as many details as possible.
16
+
17
+ ### Pull Requests
18
+ 1. **Fork the repository**: Click the "Fork" button at the top right of the repository page.
19
+ 2. **Clone your fork**: `git clone https://github.com/zb-ss/ec2-ssh.git`.
20
+ 3. **Create a new branch**: `git checkout -b name-of-your-new-feature-or-fix`
21
+ 4. **Make your changes**: Make your changes in your local repository.
22
+ 5. **Follow coding style**:
23
+ * Ensure your code adheres to the existing style.
24
+ * If you are adding new features, try to include tests if applicable.
25
+ * Update documentation (e.g., `README.md`) if your changes affect usage or add new features.
26
+ 6. **Commit your changes**: Use clear and descriptive commit messages.
27
+ ```bash
28
+ git add .
29
+ git commit -m "feat: Add new feature X"
30
+ # or "fix: Resolve bug Y"
31
+ # or "docs: Update README for feature Z"
32
+ ```
33
+ 7. **Push to your fork**: `git push origin name-of-your-new-feature-or-fix`
34
+ 8. **Open a Pull Request**: Go to the original repository on GitHub and click the "New pull request" button. Fill out the pull request template.
35
+
36
+ ## Development Setup
37
+ Please refer to the `README.md` for instructions on setting up your development environment and installing dependencies.
38
+
39
+ ## Code of Conduct
40
+ Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. For now, please be respectful and constructive in all interactions.
41
+
42
+ ## License
43
+ By contributing to Servonaut, you agree that your contributions will be licensed under its MIT License.
44
+
45
+ Thank you for your contribution!
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 zb-ss
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.4
2
+ Name: servonaut
3
+ Version: 2.1.0
4
+ Summary: Interactive TUI for managing servers — SSH, SCP, scanning & more
5
+ Project-URL: Homepage, https://github.com/zb-ss/ec2-ssh
6
+ Project-URL: Repository, https://github.com/zb-ss/ec2-ssh
7
+ Project-URL: Issues, https://github.com/zb-ss/ec2-ssh/issues
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: System :: Systems Administration
25
+ Requires-Python: >=3.8
26
+ Requires-Dist: boto3
27
+ Requires-Dist: tabulate
28
+ Requires-Dist: textual>=0.40.0
29
+ Provides-Extra: test
30
+ Requires-Dist: pytest-cov>=4.0; extra == 'test'
31
+ Requires-Dist: pytest>=7.0; extra == 'test'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # Servonaut
35
+
36
+ A modern Terminal User Interface (TUI) for managing servers — SSH, SCP, scanning & more.
37
+
38
+ ## Quick Install
39
+
40
+ **Linux / macOS:**
41
+
42
+ ```bash
43
+ curl -sSL https://raw.githubusercontent.com/zb-ss/ec2-ssh/master/install.sh | bash
44
+ ```
45
+
46
+ **Windows (PowerShell):**
47
+
48
+ ```powershell
49
+ irm https://raw.githubusercontent.com/zb-ss/ec2-ssh/master/install.ps1 | iex
50
+ ```
51
+
52
+ **Or install directly via pipx / pip:**
53
+
54
+ ```bash
55
+ pipx install servonaut
56
+ ```
57
+
58
+ **Manual install from source:**
59
+
60
+ ```bash
61
+ git clone https://github.com/zb-ss/ec2-ssh.git
62
+ cd ec2-ssh
63
+ pipx install .
64
+ ```
65
+
66
+ ## Features
67
+
68
+ - **Interactive TUI** with mouse and keyboard support powered by [Textual](https://textual.textualize.io/)
69
+ - **List and search** EC2 instances across all AWS regions
70
+ - **SSH into instances** — launches in new terminal window with auto-detected emulator
71
+ - **Run remote commands** via overlay panel with real-time streaming output, persistent history, and saved command favorites
72
+ - **Browse remote file systems** — interactive file tree navigation
73
+ - **SCP file transfer** — upload/download files and directories
74
+ - **Keyword-based server scanning** — search file contents across instances
75
+ - **Bastion host / jump server support** via ProxyJump or ProxyCommand
76
+ - **SSH key management** with auto-discovery and per-instance configuration
77
+ - **Instance caching** with stale-while-revalidate for fast startup
78
+ - **Fully configurable** — all settings in `~/.servonaut/config.json`
79
+
80
+ ## Prerequisites
81
+
82
+ - Python 3.8+
83
+ - AWS CLI configured (`~/.aws/credentials` and `~/.aws/config`)
84
+ - SSH client (standard on Linux/macOS, OpenSSH on Windows)
85
+ - `pipx` for isolated installation (recommended)
86
+
87
+ Your AWS credentials need `ec2:DescribeInstances` and `ec2:DescribeRegions` permissions.
88
+
89
+ ## Usage
90
+
91
+ ```bash
92
+ servonaut # Launch the TUI
93
+ servonaut --debug # Launch with debug logging to stderr
94
+ ```
95
+
96
+ ### Keyboard Shortcuts
97
+
98
+ | Context | Key | Action |
99
+ |---------|-----|--------|
100
+ | Global | `Q` | Quit |
101
+ | Global | `?` | Help screen |
102
+ | Global | `Escape` | Go back / close |
103
+ | Instance List | `/` | Focus search |
104
+ | Instance List | `R` | Force-refresh from AWS |
105
+ | Instance List | `S` | SSH to selected instance |
106
+ | Instance List | `B` | Browse remote files |
107
+ | Instance List | `C` | Run command overlay |
108
+ | Instance List | `T` | SCP transfer |
109
+ | Command Overlay | `Ctrl+C` | Stop running command |
110
+ | Command Overlay | `Ctrl+R` | Command picker (saved + recent) |
111
+ | Command Overlay | `Ctrl+S` | Save command to favorites |
112
+ | Command Overlay | `Up/Down` | Command history |
113
+
114
+ ### What You Can Do
115
+
116
+ 1. **List Instances** — View all EC2 instances with search/filter
117
+ 2. **Search** — Filter instances by name, type, region, or state; search scan results
118
+ 3. **Manage SSH Keys** — Configure default and per-instance SSH keys
119
+ 4. **Scan Servers** — Run keyword scans across running instances
120
+ 5. **Settings** — Configure connection profiles, scan rules, preferences
121
+
122
+ When you select a server: browse files, run commands, SSH connect, SCP transfer, or view scan results. Command history persists across sessions — use `Ctrl+R` to search history and saved commands, `Ctrl+S` to save favorites.
123
+
124
+ ### Instance Caching
125
+
126
+ | Scenario | Behavior |
127
+ |----------|----------|
128
+ | First launch (no cache) | Fetches from AWS with progress indicator |
129
+ | Restart within TTL (default 1h) | Instant load from cache |
130
+ | Restart after TTL | Shows stale data immediately, refreshes in background |
131
+ | Press `R` | Force-refresh from AWS |
132
+
133
+ ### Configuration
134
+
135
+ All configuration lives in `~/.servonaut/config.json`, created automatically on first run.
136
+
137
+ See [Configuration Guide](docs/configuration.md) for the full reference including connection profiles, scan rules, and match conditions.
138
+
139
+ ## Development
140
+
141
+ ```bash
142
+ # Run directly (primary dev workflow)
143
+ PYTHONPATH=src python3 -m servonaut.main
144
+
145
+ # Run with debug logging
146
+ PYTHONPATH=src python3 -m servonaut.main --debug
147
+
148
+ # Install editable
149
+ pip install -e .
150
+
151
+ # Update pipx installation after changes
152
+ pipx install . --force
153
+ ```
154
+
155
+ ```bash
156
+ # Run tests
157
+ pip install -e ".[test]"
158
+ pytest
159
+ ```
160
+
161
+ See [Architecture](docs/architecture.md) for codebase structure and design patterns.
162
+
163
+ ## Troubleshooting
164
+
165
+ See [Troubleshooting Guide](docs/troubleshooting.md) for help with SSH connections, bastion hosts, key management, and AWS credentials.
166
+
167
+ ## Logging
168
+
169
+ Logs are always written to `~/.servonaut/logs/servonaut.log`. Use `--debug` for verbose stderr output.
170
+
171
+ When SSH fails, the terminal window stays open showing the error and exit code.
172
+
173
+ ## License
174
+
175
+ This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,142 @@
1
+ # Servonaut
2
+
3
+ A modern Terminal User Interface (TUI) for managing servers — SSH, SCP, scanning & more.
4
+
5
+ ## Quick Install
6
+
7
+ **Linux / macOS:**
8
+
9
+ ```bash
10
+ curl -sSL https://raw.githubusercontent.com/zb-ss/ec2-ssh/master/install.sh | bash
11
+ ```
12
+
13
+ **Windows (PowerShell):**
14
+
15
+ ```powershell
16
+ irm https://raw.githubusercontent.com/zb-ss/ec2-ssh/master/install.ps1 | iex
17
+ ```
18
+
19
+ **Or install directly via pipx / pip:**
20
+
21
+ ```bash
22
+ pipx install servonaut
23
+ ```
24
+
25
+ **Manual install from source:**
26
+
27
+ ```bash
28
+ git clone https://github.com/zb-ss/ec2-ssh.git
29
+ cd ec2-ssh
30
+ pipx install .
31
+ ```
32
+
33
+ ## Features
34
+
35
+ - **Interactive TUI** with mouse and keyboard support powered by [Textual](https://textual.textualize.io/)
36
+ - **List and search** EC2 instances across all AWS regions
37
+ - **SSH into instances** — launches in new terminal window with auto-detected emulator
38
+ - **Run remote commands** via overlay panel with real-time streaming output, persistent history, and saved command favorites
39
+ - **Browse remote file systems** — interactive file tree navigation
40
+ - **SCP file transfer** — upload/download files and directories
41
+ - **Keyword-based server scanning** — search file contents across instances
42
+ - **Bastion host / jump server support** via ProxyJump or ProxyCommand
43
+ - **SSH key management** with auto-discovery and per-instance configuration
44
+ - **Instance caching** with stale-while-revalidate for fast startup
45
+ - **Fully configurable** — all settings in `~/.servonaut/config.json`
46
+
47
+ ## Prerequisites
48
+
49
+ - Python 3.8+
50
+ - AWS CLI configured (`~/.aws/credentials` and `~/.aws/config`)
51
+ - SSH client (standard on Linux/macOS, OpenSSH on Windows)
52
+ - `pipx` for isolated installation (recommended)
53
+
54
+ Your AWS credentials need `ec2:DescribeInstances` and `ec2:DescribeRegions` permissions.
55
+
56
+ ## Usage
57
+
58
+ ```bash
59
+ servonaut # Launch the TUI
60
+ servonaut --debug # Launch with debug logging to stderr
61
+ ```
62
+
63
+ ### Keyboard Shortcuts
64
+
65
+ | Context | Key | Action |
66
+ |---------|-----|--------|
67
+ | Global | `Q` | Quit |
68
+ | Global | `?` | Help screen |
69
+ | Global | `Escape` | Go back / close |
70
+ | Instance List | `/` | Focus search |
71
+ | Instance List | `R` | Force-refresh from AWS |
72
+ | Instance List | `S` | SSH to selected instance |
73
+ | Instance List | `B` | Browse remote files |
74
+ | Instance List | `C` | Run command overlay |
75
+ | Instance List | `T` | SCP transfer |
76
+ | Command Overlay | `Ctrl+C` | Stop running command |
77
+ | Command Overlay | `Ctrl+R` | Command picker (saved + recent) |
78
+ | Command Overlay | `Ctrl+S` | Save command to favorites |
79
+ | Command Overlay | `Up/Down` | Command history |
80
+
81
+ ### What You Can Do
82
+
83
+ 1. **List Instances** — View all EC2 instances with search/filter
84
+ 2. **Search** — Filter instances by name, type, region, or state; search scan results
85
+ 3. **Manage SSH Keys** — Configure default and per-instance SSH keys
86
+ 4. **Scan Servers** — Run keyword scans across running instances
87
+ 5. **Settings** — Configure connection profiles, scan rules, preferences
88
+
89
+ When you select a server: browse files, run commands, SSH connect, SCP transfer, or view scan results. Command history persists across sessions — use `Ctrl+R` to search history and saved commands, `Ctrl+S` to save favorites.
90
+
91
+ ### Instance Caching
92
+
93
+ | Scenario | Behavior |
94
+ |----------|----------|
95
+ | First launch (no cache) | Fetches from AWS with progress indicator |
96
+ | Restart within TTL (default 1h) | Instant load from cache |
97
+ | Restart after TTL | Shows stale data immediately, refreshes in background |
98
+ | Press `R` | Force-refresh from AWS |
99
+
100
+ ### Configuration
101
+
102
+ All configuration lives in `~/.servonaut/config.json`, created automatically on first run.
103
+
104
+ See [Configuration Guide](docs/configuration.md) for the full reference including connection profiles, scan rules, and match conditions.
105
+
106
+ ## Development
107
+
108
+ ```bash
109
+ # Run directly (primary dev workflow)
110
+ PYTHONPATH=src python3 -m servonaut.main
111
+
112
+ # Run with debug logging
113
+ PYTHONPATH=src python3 -m servonaut.main --debug
114
+
115
+ # Install editable
116
+ pip install -e .
117
+
118
+ # Update pipx installation after changes
119
+ pipx install . --force
120
+ ```
121
+
122
+ ```bash
123
+ # Run tests
124
+ pip install -e ".[test]"
125
+ pytest
126
+ ```
127
+
128
+ See [Architecture](docs/architecture.md) for codebase structure and design patterns.
129
+
130
+ ## Troubleshooting
131
+
132
+ See [Troubleshooting Guide](docs/troubleshooting.md) for help with SSH connections, bastion hosts, key management, and AWS credentials.
133
+
134
+ ## Logging
135
+
136
+ Logs are always written to `~/.servonaut/logs/servonaut.log`. Use `--debug` for verbose stderr output.
137
+
138
+ When SSH fails, the terminal window stays open showing the error and exit code.
139
+
140
+ ## License
141
+
142
+ This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.