# User guide `hosts` is a keyboard-first terminal application for inspecting and editing the system Hosts File. It starts in Read-only Mode and requires explicit sudo authorization before it can change `/etc/hosts`. > [!WARNING] > `hosts` is alpha software. Read [Persistence and recovery](#persistence-and-recovery) > before entering Privileged Mode. In particular, sorting and save > failures can currently leave the interface and `/etc/hosts` out of sync. ## Before you begin You need macOS or Linux, Python 3.13 or newer, `sudo`, and [uv](https://docs.astral.sh/uv/). The normal user entry point runs the current revision from the project's default branch: ```bash uvx git+https://git.s1q.dev/phg/hosts.git ``` The project does not yet publish versioned releases. The `uvx` command can therefore run newer code on a later invocation. ## Inspect the Hosts File safely The application opens in Read-only Mode. In this mode you can: - select a Host Entry and inspect all of its hostnames, comment, state, and DNS details; - search by hostname, IP address, or comment; - use `Ctrl+F` to combine status, entry-type, DNS-resolution, and search filters; - sort by IP address or Canonical Hostname; - show or hide Default Entries from the configuration screen; and - reload `/etc/hosts` from disk. The footer shows `Read-only` while system-file mutations are blocked. Press `?` for in-application help. ### A warning about sorting Sorting is intended as a view operation, but currently reorders the in-memory Hosts File. If you later enter Privileged Mode and save or perform an auto-saved mutation, that sorted order can be written to `/etc/hosts`. Reload with `Ctrl+R` before entering Privileged Mode if you sorted only for inspection. ## Enter Privileged Mode Press `Ctrl+E`. The application first checks for existing sudo authorization. If authorization is not already available, it temporarily returns control of the terminal to `sudo` and its configured PAM authentication method. Before enabling mutations it verifies write access and creates a Pre-edit Backup. If authorization, permission validation, or backup creation fails, the application remains in Read-only Mode. The footer shows `PRIVILEGED` while Privileged Mode is active. This label is separate from the Entry Editor used to change one Host Entry. ## Change a Host Entry In Privileged Mode: - Press `n` to add a Host Entry. - Press `Shift+N` to add a Host Entry based on the selected Host Entry. In a terminal without the Kitty enhanced keyboard protocol, uppercase `N` is the fallback, so Caps Lock also triggers this action. - Select a non-default Host Entry and press `e` to open the Entry Editor. - Press `d` and confirm to delete the selected Host Entry. - Press `Space` to activate or deactivate the selected Host Entry. - Press `Shift+Up` or `Shift+Down` to change its file order. A Host Entry requires a valid IPv4 or IPv6 address, at least one valid hostname, and may include a comment. The first hostname is its Canonical Hostname; any additional hostnames are Aliases. Default Entries represent protected baseline localhost or broadcasthost mappings. They cannot be changed, deleted, activated, deactivated, or moved. Successful mutations are saved to `/etc/hosts` immediately. Read the status message after every action. If saving fails, the application restores the Host Entries, visible selection, and undo/redo history from before the action. ## Use a DNS Entry Choose the DNS Name Entry type when adding or editing an entry, then provide: - the DNS name whose address should be resolved; and - one or more local hostnames that should map to that address. The application resolves the DNS name in the background. A successful result replaces the entry's stored IP address, records DNS metadata in the serialized comment, activates a newly created DNS Entry, and saves the Hosts File. DNS refresh is manual rather than continuous: - Press `r` to refresh the selected DNS Entry. - Press `Shift+R` to refresh all DNS Entries. Both actions require Privileged Mode because a successful result changes `/etc/hosts`. A failed lookup reports the failure and keeps the previously stored mapping. ## Import and export Host Entries Press `Ctrl+X` to export the current in-memory Host Entries. Choose hosts, JSON, or CSV and enter a destination path. The workflow validates the destination and requires explicit confirmation before an existing file is overwritten. Press `Ctrl+O` in Privileged Mode to import a hosts, JSON, or CSV file. Choose the format explicitly, then select the source path. A successful import replaces the current Host Entries and saves the Hosts File; parse and save errors remain visible in the message rail and leave the current file unchanged. ## Verify what is on disk The details shown by the application normally match the last successful save. To discard in-memory state and read `/etc/hosts` again, press `Ctrl+R`. You can also inspect the file from another terminal: ```bash sed -n '1,240p' /etc/hosts ``` Remember that saving is normalized rather than byte-preserving. The serializer aligns fields, groups comments, removes original blank-line placement, and adds a management header while retaining the modeled Host Entries and comments. ## Persistence and recovery ### What saves immediately Adding, editing, deleting, moving, activating, deactivating, undoing, redoing, and successfully refreshing DNS Entries save immediately. `Ctrl+S` explicitly saves the entire current in-memory Hosts File. If an immediate save fails, the application restores the complete pre-action in-memory state, visible selection, and undo/redo history. A later mutation therefore cannot accidentally persist the failed change. ### Restore the session Pre-edit Backup Entering Privileged Mode creates one timestamped Pre-edit Backup below the operating system's temporary directory. While that Privileged Mode session is active, press `b` to open the restore review. It displays the exact backup source path and `/etc/hosts` target path, then shows a Git-style diff of the current Hosts File (before) and Pre-edit Backup (after restoration). At 120 or more columns the diff is side by side; at smaller supported sizes it is a unified diff. Use `[` and `]` to move between changed hunks, `f` to toggle the full diff, and `r` to refresh it. Choose **Restore Hosts File** only when those paths are the ones you intend. The application copies the displayed backup over the Hosts File, reloads the on-disk contents into the interface, and clears undo/redo history. If the copy fails, the current Hosts File and interface remain unchanged and the status message names the failure. The application checks both displayed files again when you confirm; if either changed, it refreshes the diff and requires a new confirmation. Cancel leaves both files unchanged. The TUI does not list old backups, apply retention rules, or retain the session association after leaving Privileged Mode. For recovery outside that session, locate and restore a backup manually. Ask Python for the temporary directory on your system: ```bash python3 -c 'import tempfile; print(tempfile.gettempdir() + "/hosts-manager-backups")' ``` List the directory printed by that command. Backup files are named `hosts.backup.`: ```bash ls -lt /path/printed/by/the/previous/command ``` The application does not remove old Pre-edit Backups, apply retention rules, or record which file belongs to a later session. Do not choose a backup solely because it is the newest; inspect its timestamp and contents first. ### Restore manually outside the session To restore a backup that is no longer associated with an active Privileged Mode session: 1. Leave the application or return it to Read-only Mode. 2. Locate and inspect the intended Pre-edit Backup. 3. Copy that explicit file over `/etc/hosts` with sudo. 4. Relaunch the application or press `Ctrl+R` to verify the restored contents. For example, after replacing the placeholder with the exact file you inspected: ```bash sudo cp /exact/path/to/hosts.backup.TIMESTAMP /etc/hosts ``` This replaces the current Hosts File. Never paste a guessed path or automate selection of the newest backup without inspecting it. ## Leave Privileged Mode Press `Ctrl+E` again. The application clears its undo/redo history and forgets which Pre-edit Backup belongs to the session. The backup file remains in the temporary directory. It does not alter your cached sudo timestamp, including authorization used by other terminal sessions. ## Configuration Press `c` to open configuration. The supported screen controls whether Default Entries are visible; they are hidden by default. The setting is stored at `~/.config/hosts-manager/config.json`. Other values may exist in that file but are internal until their behavior is reachable through the TUI. Editing them manually is not a supported workflow. ## Troubleshooting ### Privileged Mode needs authentication This is expected when no cached sudo authorization is available. `hosts` first shows a temporary authentication notice, then `sudo` and PAM present any configured authentication method, such as Touch ID or a password prompt. `hosts` never collects credentials. Canceling authentication leaves the application in Read-only Mode. ### Privileged Mode cannot be enabled The application requires all three safety gates: valid sudo authorization, write access to `/etc/hosts`, and successful creation of a Pre-edit Backup. A failure in any gate leaves mutations disabled. Read the status message for the specific failure. ### The display differs from `/etc/hosts` This can occur after a failed save or sorting followed by other actions. Press `Ctrl+R` to discard in-memory state and reload the file. If an unwanted change reached disk, follow the manual restoration procedure above. ### DNS resolution fails DNS resolution uses the operating system resolver and a per-query timeout. A failure can result from an invalid DNS name, resolver failure, timeout, or no address being returned. The application reports the failure rather than continually retrying it. ## Key reference ### General | Key | Action | | --- | --- | | `Up` / `Down` | Select a Host Entry | | `Home` / `End` | Select the first or last visible Host Entry | | `Page Up` / `Page Down` | Move by one page | | `i` | Sort by IP address | | `h` | Sort by Canonical Hostname | | `Ctrl+R` | Reload `/etc/hosts` | | `Ctrl+F` | Open advanced filters | | `c` | Open configuration | | `Ctrl+X` | Export Host Entries | | `?` | Show help | | `q` or `Ctrl+C` | Quit | | `Ctrl+E` | Enter or leave Privileged Mode | ### Privileged Mode | Key | Action | | --- | --- | | `n` | Add a Host Entry | | `Shift+N` | Add a Host Entry based on the selected Host Entry (`N` fallback without enhanced keyboard support; Caps Lock also triggers it) | | `e` | Open the selected Host Entry in the Entry Editor | | `d` | Delete the selected Host Entry | | `Space` | Activate or deactivate the selected Host Entry | | `Shift+Up` / `Shift+Down` | Move the selected Host Entry | | `r` | Refresh the selected DNS Entry | | `Shift+R` | Refresh all DNS Entries | | `Ctrl+Z` / `Ctrl+Y` | Undo or redo and save the result | | `Ctrl+S` | Save the current in-memory state | | `b` | Review session backup changes and confirm restoration | | `Ctrl+O` | Import Host Entries from hosts, JSON, or CSV | Within the Entry Editor, use `Tab` and `Shift+Tab` to move between fields and `Escape` to leave the form. If values changed, the application asks whether to save, discard, or continue editing.