Style as a compact transparent link-like element. Set can_focus=False
so it doesn't steal initial focus from the main content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace bottom-row Back buttons with a top-left "← Back" button
across all screens for consistent navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use border-title panels (General, Email Notifications, SSH, Web
Dashboard) instead of TabbedContent for a cleaner visual layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Organize settings into General, Email, SSH, and Web Dashboard tabs
using TabbedContent. Add test-email CLI command and button that
auto-saves settings then sends a test email via SMTP.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full rename of all user-facing CLI command names and flags across
the entire codebase: bin/gniza, TUI screens, schedule cron generation,
README, and DOCUMENTATION.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace global last-run (based on log file mtime) with per-schedule
LAST_RUN field in the schedule config. New scheduled-run CLI command
runs backup and stamps LAST_RUN only on success.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename all user-facing strings: Target→Source, Remote→Destination across TUI, docs, web dashboard, bash scripts, config examples, and README
- Add go-to-path search input to both FolderPicker and RemoteFolderPicker
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename Targets → Sources, Remotes → Destinations across all screens
- Reorganize main menu with logical groupings and separators
- Add Browse button to Base path field in remote editor (local + SSH)
- Fix RichLog IndexError crash when compositor renders with y=-1
- Fix _sync_crontab accidentally wiping crontab via premature remove
- Per-target locking and auto-create local remote base directory
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Browse button now opens an SSH directory tree picker when source type is
SSH, using the configured credentials. Folders input and Browse button
placed on same row so they're visible without scrolling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rsync exit 23 (partial transfer) now triggers an automatic retry to recover
failed files before accepting with a warning. Also adds a task counter next
to the clock in the header bar showing running job count.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add source.sh for remote source backup support
- Add responsive DocsPanel with layout adaptations for narrow screens
- Running tasks log viewer now shows last 100 lines (tail -f style)
- Add incremental backup explanation to README
- Update backup, transfer, schedule, and snaplog modules
- Add MCP config and logo asset
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When in vertical layout (narrow screens), align content to top
and enable vertical scrolling so the menu list isn't cut off.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Below 100 cols: stack logo on top, menu below (vertical)
- Below 48 cols (~290px): hide logo entirely, show only menu
- 100+ cols: original side-by-side horizontal layout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Auto-hide docs panel when terminal < 100 cols, respects manual F1 toggle
- Hide logo on main menu when terminal < 80 cols
- DataTable: flexible height (auto with min/max) instead of fixed 12
- Dialogs, pickers, wizard: percentage-based widths with max-width caps
- Menu list: flexible height and width constraints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split each screen into two columns: existing controls on the left,
a DocsPanel with Rich-markup documentation on the right (30% width).
Press F1 to toggle the help panel on/off from any screen.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rsync --info=progress2 uses \r without \n, so the entire progress
stream is one long line. Split on both \r and \n to parse each
progress update independently.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --info=progress2 --no-inc-recursive to rsync for overall progress
- Parse rsync progress output (percentage, speed, ETA) from log file
- Show ProgressBar widget and progress label below buttons
- Progress bar auto-hides when job finishes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
View Log now displays the log in a RichLog panel below the buttons
instead of opening a modal screen. The log tails the file in real-time
with a 0.3s poll interval while the job is running.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Detects status from log content: Success (backup completed, no errors),
Failed (ERROR/FATAL markers), OK (lock released), Interrupted (no clean exit).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The settings screen wrote WORK_DIR="/usr/local/gniza/workdir" (root-mode
path) into gniza.conf. load_config then overrode the correct user-mode
path set by detect_mode, causing mktemp and rsync log redirects to fail
with Permission denied — crashing the bash script while rsync continued
as an orphan.
- Remove WORK_DIR from AppSettings model and settings screen
- Re-run detect_mode after config load to restore correct paths
- Removed stale WORK_DIR from user's gniza.conf
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Save finished jobs to registry (24h TTL) so they survive TUI restart
- Fix PermissionError in PID check incorrectly marking alive processes as dead
- Handle CancelledError explicitly to preserve running status on TUI exit
- Tail log files for reconnected running jobs instead of showing stale output
- Detect actual return code from log content; show "?" for unknown status
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Jobs are now saved to gniza-jobs.json in WORK_DIR when they start and
finish. On TUI restart, the registry is loaded and PIDs are checked —
still-running jobs appear in the Running Tasks screen and can be
killed. Reconnected jobs are polled every second to detect completion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Jobs were tied to screen @work tasks, so switch_screen cancelled the
worker and lost the process reference. Now start_job uses
asyncio.create_task so jobs survive screen changes and can be killed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backup and restore operations now run as background jobs instead of
blocking modal screens. Users can navigate away and check progress
from a dedicated Running Tasks screen. OperationLog supports attaching
to running jobs with live output polling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add shquote() to escape single quotes in paths passed to remote_exec,
preventing shell injection via REMOTE_BASE containing single quotes
- Apply shquote to remote_exec calls in remotes.sh, backup.sh, transfer.sh, ssh.sh
- Add DISK_USAGE_THRESHOLD validation in config.sh
- Export SMTP_PASSWORD (was missing from export list)
- Fix WEB_PORT default mismatch: use 2323 consistently in from_conf and settings save
- Narrow exception catch in remotes.py disk info fetch to KeyError/LookupError
- Quote REMOTE_KEY in build_rsync_ssh_cmd for paths with spaces
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Disk usage threshold (default 95%) can now be controlled from
Settings. Set to 0 to disable the check.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add TARGET_INCLUDE field for rsync include patterns (comma-separated)
- Pass TARGET_INCLUDE and TARGET_EXCLUDE to rsync in transfer_folder
- Include mode uses --include='*/' + patterns + --exclude='*' + --prune-empty-dirs
- Abort backup if remote disk usage >= 95%
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Disk info is now shown directly in the table. Speed test and detailed
disk info buttons/commands are no longer needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Disk Info: runs df -h and df -i on remote via SSH (or locally)
- Speed Test: uploads/downloads 10MB test file via rsync, measures Mbps
- Both available as CLI commands: gniza remotes disk-info/speed-test --name=NAME
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Last Run: timestamp of most recent backup log file
- Next Run: calculated from schedule type, time, and day settings
- Handles hourly, daily, weekly, monthly schedule types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Revert from textual-serve back to Flask (textual-serve had WebSocket issues)
- Completely redesigned dashboard: modern dark theme, stat cards, clean tables
- Redesigned login page to match
- Restored API key generation in install script
- Keep API key field in TUI settings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>