Skip to content

Releases: fedonman/sqwatch

v0.1.1

26 Mar 20:15
757b833

Choose a tag to compare

Added

  • Three operations that previously blocked the main thread and froze the UI — scontrol show job lookups, periodic squeue refreshes, and script file loading with optional bat highlighting — were moved into dedicated background threads. A new JobDetailResolver runs a single scontrol call per job and caches up to 64 results, replacing the duplicate per-widget calls that each blocked for 100–500 ms; widgets now show a "Loading…" placeholder until the detail arrives, and the resolver deduplicates rapid requests by draining the channel and keeping only the latest job ID. A new JobFetcher runs squeue in its own lightweight tokio runtime so the 1-second auto-refresh and filter-apply no longer stall rendering; the old synchronous reload_jobs was split into reload_jobs_sync (used once at startup) and a non-blocking submit_reload path whose results are picked up on the next timer tick. The script widget's load_content was similarly offloaded to a background thread so that file reads and bat invocations never touch the render path, with a new poll_updates method that mirrors the pattern already used by the output and custom widgets. The input processing loop now drains all pending signals on each iteration and collapses consecutive Timer events into a single tick, which eliminates the multi-second freeze that occurred when switching back to the terminal after the window had been unfocused and hundreds of stale timers had piled up in the channel. Ctrl+C while any content widget (script, stdout, stderr, or custom) is focused now copies the widget's content to the system clipboard via the OSC 52 escape sequence and flashes a confirmation in the titlebar; the binding works over SSH and inside tmux without requiring X11 or Wayland, and Esc remains the key for returning focus to the table. The script widget gained PageUp/PageDown and Ctrl+U/Ctrl+D scrolling to match the other widgets, and all four content widget types now show PgUp/Dn Scroll and Ctrl+C Copy hints in the statusbar. PR #5

  • Added CI/CD infrastructure so that every pull request and push to main is automatically checked for formatting, linting, test correctness, minimum supported Rust version compatibility (1.85.0), and dependency license and vulnerability audits via cargo-deny. Pull requests now require a changelog entry before merging. A separate manually-triggered release workflow handles version validation, publishing to crates.io, and creating GitHub Releases with the relevant changelog section as release notes. PR #1

Changed

  • Refreshed the visual theme and tightened keybindings ahead of the first release. Every widget now has its own accent color when focused — cyan for the script viewer, green for stdout, red for stderr, purple for custom panels, and orange for the filter sidebar — and focused borders switched from rounded to double so the active panel is immediately obvious. Marked job rows use an inverted style (dark text on a colored background) instead of the old underline, the cursor symbol changed from a filled circle to a triangle, and the base palette was nudged darker overall. Several single-key shortcuts that conflicted with text input were moved behind Ctrl: widget selector is now Ctrl+W, column config is Ctrl+C, select-all is Ctrl+A, cancel is Ctrl+X, and reset is Ctrl+R in both the field and filter dialogs; the same treatment was applied to the add (Ctrl+A) and delete (Ctrl+D) actions in the widget selector. The layout engine was reworked so the right column holds up to three widgets and any overflow spills into the left column below the table on an aligned grid, replacing the earlier scheme that squeezed up to four panels on the right and tacked extras onto a half-height bottom strip; the total visible panel cap is now five (2×3−1) to guarantee the table always keeps at least one grid row. Widget titles were simplified by dropping the job ID suffix, and the "Execution Script" label was shortened to "Script". The README was rewritten with a full keybinding reference split by context, an updated architecture tree, and expanded feature descriptions. PR #6

  • Reworked the filter pane and titlebar to give each piece of information its own space. The titlebar now has four clear sections for the brand, logged-in user, active filters, and a flash notification area that fills whatever room is left. Filters and column settings are saved to ~/.config/sqwatch/ so they survive restarts. User filtering switched from exact match to regex, and the node filter became a selectable list pulled live from sinfo instead of a free-text field. The squeue query now always passes --all and --states=all so every job state shows up, including the newly recognized SUSPENDED and OUT_OF_MEMORY. Cancelling jobs through scancel now actually checks exit status and surfaces errors in the flash bar rather than swallowing them. Your cursor position and any selected jobs are preserved across the 1-second auto-refresh by tracking job IDs. The statusbar was cleaned up with keybinding hints on the left and job count statistics on the right, and a handful of bindings changed: script viewing moved from Enter to s, the q shortcut was dropped from overlays in favor of Esc, and PageUp/PageDown/Ctrl+U/Ctrl+D were removed from the script pane. Sort indicators in column headers no longer change color. PR #2

  • Replaced the overlay-based layout with a configurable split-pane design. The old output_pane, which crammed stdout and stderr into one tabbed view, and the search popup dialog for filters are both gone. Instead, stdout and stderr now live as independent widgets stacked vertically in the right panel, filters moved into a persistent sidebar with regex-validated text fields and checkbox lists for states, nodes, partitions, and QoS, and a new widget selector (press w) lets you toggle each panel on or off. The script viewer was renamed from script_pane to script_widget since it is now a proper layout citizen rather than a floating overlay. Which panels are visible is saved to ~/.config/sqwatch/layout.json so your preferred arrangement sticks between sessions. The titlebar was streamlined down to just the brand, a flash message area, and your username, while the statusbar shows context-aware keybinding hints that change depending on which widget has focus. Tab and Shift+Tab cycle only through panels that are actually visible, and Shift+Up/Down lets you flip through the job list from any right-side widget without losing your place. The license was changed from MIT to Apache-2.0 and the README was rewritten with a proper architecture overview, developer setup guide, and updated keybinding table. On the code quality side, a thorough pass was made to bring everything in line with Rust 2024 edition best practices. The ANSI escape regex for bat highlighting is now compiled once at startup using LazyLock instead of being rebuilt every frame, color_eyre::install() is called so that panics and errors actually produce useful reports, and the Ordering enum was renamed to SortDirection to stop shadowing std::cmp::Ordering. The HashMap that held squeue sort fields was swapped for a Vec so the sort order sent to SLURM is deterministic, all string truncation now works on character boundaries instead of raw bytes to avoid panics on multi-byte UTF-8, and everything_marked() was fixed to correctly return false on an empty job list. A good amount of duplicated code was cleaned up along the way: the identical scontrol show job calls and key-value parsers that lived separately in the output and script widgets were pulled into a shared scontrol_show_job() function with a proper JobDetail return type, the nearly identical user and name regex filter blocks were combined into one apply_regex_filter() helper, the three copy-pasted Shift+Up/Down handlers collapsed into a single on_widget_key() method, the XDG config path logic that was repeated three times became one sqwatch_config_dir() call, and color constants scattered across four files were gathered into a views/theme.rs module. All dead code was removed, including several unused _-prefixed functions that had been lingering since early development, and the retained-for-lifetime fields on InputLoop were given proper _tx/_worker names with documentation explaining why they exist. PR #3