Releases: fedonman/sqwatch
v0.1.1
Added
-
Three operations that previously blocked the main thread and froze the UI —
scontrol show joblookups, periodicsqueuerefreshes, and script file loading with optionalbathighlighting — were moved into dedicated background threads. A newJobDetailResolverruns a singlescontrolcall 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 newJobFetcherrunssqueuein its own lightweight tokio runtime so the 1-second auto-refresh and filter-apply no longer stall rendering; the old synchronousreload_jobswas split intoreload_jobs_sync(used once at startup) and a non-blockingsubmit_reloadpath whose results are picked up on the next timer tick. The script widget'sload_contentwas similarly offloaded to a background thread so that file reads andbatinvocations never touch the render path, with a newpoll_updatesmethod 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 consecutiveTimerevents 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+Cwhile 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, andEscremains the key for returning focus to the table. The script widget gainedPageUp/PageDownandCtrl+U/Ctrl+Dscrolling to match the other widgets, and all four content widget types now showPgUp/Dn ScrollandCtrl+C Copyhints 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 nowCtrl+W, column config isCtrl+C, select-all isCtrl+A, cancel isCtrl+X, and reset isCtrl+Rin 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 fromsinfoinstead of a free-text field. The squeue query now always passes--alland--states=allso every job state shows up, including the newly recognizedSUSPENDEDandOUT_OF_MEMORY. Cancelling jobs throughscancelnow 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 fromEntertos, theqshortcut was dropped from overlays in favor ofEsc, andPageUp/PageDown/Ctrl+U/Ctrl+Dwere 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 thesearchpopup 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 (pressw) lets you toggle each panel on or off. The script viewer was renamed fromscript_panetoscript_widgetsince it is now a proper layout citizen rather than a floating overlay. Which panels are visible is saved to~/.config/sqwatch/layout.jsonso 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 forbathighlighting is now compiled once at startup usingLazyLockinstead of being rebuilt every frame,color_eyre::install()is called so that panics and errors actually produce useful reports, and theOrderingenum was renamed toSortDirectionto stop shadowingstd::cmp::Ordering. TheHashMapthat held squeue sort fields was swapped for aVecso 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, andeverything_marked()was fixed to correctly returnfalseon an empty job list. A good amount of duplicated code was cleaned up along the way: the identicalscontrol show jobcalls and key-value parsers that lived separately in the output and script widgets were pulled into a sharedscontrol_show_job()function with a properJobDetailreturn type, the nearly identical user and name regex filter blocks were combined into oneapply_regex_filter()helper, the three copy-pasted Shift+Up/Down handlers collapsed into a singleon_widget_key()method, the XDG config path logic that was repeated three times became onesqwatch_config_dir()call, and color constants scattered across four files were gathered into aviews/theme.rsmodule. All dead code was removed, including several unused_-prefixed functions that had been lingering since early development, and the retained-for-lifetime fields onInputLoopwere given proper_tx/_workernames with documentation explaining why they exist. PR #3