Release v0.1.32: HPC/Slurm pipeline, global machines, monitoring, i18n#6
Merged
Conversation
…nel-up gate
Import a project straight from a GitHub/GitLab URL (`git_clone` lands the
tree, then the ordinary import registers it in place), and reverse the
extend flow with `detach_project_from_remote`.
Remote hosts remember a default path (`remote_{list,get,set}_default_path`),
and the "Save password" opt-in is now the same control in every remote menu
— the Connect modal and the new-project / extend-to-remote dialogs share
`useRemoteSession`. The keychain is keyed by host target, not project id, so
the credential a create/extend dialog authenticated with is handed to that
project's first pooled connect (`stashRemotePassword`, single-use, never on
disk); connecting password-less would otherwise record `key_auth: true` on a
password host.
While a tunnel is up machine-wide, every project-scoped OpenVPN block
collapses to a one-line notice pointing at the header, via the shared
`useVpnSectionVisible` gate + `VpnTunnelUpNotice` — except a tunnel the
dialog itself brought up, which stays expanded so its log and Disconnect
remain where the user started it.
File tree gains per-directory size breakdown (`dir_size_breakdown`) and
drag-out to other apps (`start_file_drag` / `cancel_file_drag`).
Gates: tsc clean, 1358 frontend tests, 915 Rust tests, privacy scan clear.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ag1A6YVQxujZkcnrWahjua
The backend half of the invariant (an unvouched empty layout must not erase a saved one) is already pinned by services_tests.rs. The frontend half was not — and that is where the decision is actually made, so `persistScope`'s hydration logic could regress with CI still green. Covers the three cases that matter: a hydrated scope that genuinely holds no tabs DOES vouch for the clear (a real close-all must persist), a scope that was never hydrated does not, and — the SimpleGNN case — a scope whose tabs all get filtered out as foreign does not, even though the layout it sends is just as empty as a close-all. Also documents why `saveLayout` is the footgun (it pairs the store's live scope with a caller-supplied localFile; no production caller remains), and catches Cargo.lock up to the v0.1.22 bump. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MHkrvVRCBNMFGvNiKkmAWC
Two viewer features, plus the experimental-flag gate they are staged behind.
YAML/JSON structure tree (#88). The tree is a VIEW ON THE TEXT: every edit is a
surgical splice back into the draft, never a re-serialization of the parsed model
— the only way a config file's comments survive an edit, and what lets Tree and
Source be two views on one draft. Both YAML syntaxes are first-class: block, and
flow (`{a: 1}` — i.e. JSON, so a .json file opens as a tree too), and which one a
node is written in decides how it is edited, so `[a, b]` grows to `[a, b, c]` and
is never quietly rewritten into block.
Round out the tree:
- Inline nested sequences (`- - x`) parse instead of failing the whole document.
One such line previously sent the entire file to the Source fallback.
- Fix a corruption bug: an empty placeholder inside a flow collection — and so
every `null` in a .json file — grew as a BLOCK child, splicing a line at column
-1 (a flow node has no column) into the middle of the brackets and tearing the
collection open. It now becomes a collection in place: `{a: null}` -> `{a: [x]}`.
- "+ key" on a list adds an item that IS a mapping (`- name: api`) — the shape a
list of mappings is actually grown by.
- Comments are a node's own, not scenery. A `#` is the only place YAML documents a
key, so each node reads the one behind its value and the run directly above it,
shows it on the key's hover, and can rewrite it where the author already wrote.
The consequence is in the edits: a comment TRAVELS with its node — deleting or
reordering a key takes its description along, rather than leaving it to
re-attach itself to whichever key slid into that place.
- Reorder siblings by dragging the row's grip. Pointer-based, with every handler
bound up front (HTML5 DnD does not work under WebKitGTK, and mid-gesture
listeners get dropped). `moveNodeTo` is the one reorder op: a drag across five
rows is ONE splice, not five swaps — every splice invalidates the offsets after
it.
Python in the code viewer (#87). Run/Debug open a TERMINAL TAB rather than a
bespoke exec path, which is what makes them inherit remote-host and container
locality for free and stay a real interactive terminal. Debug is pdb pre-loaded
with the gutter's breakpoints. Breakpoints snap to executable lines (pdb refuses
blank ones) and remap on every edit above them; go-to-definition is a lexical
import-graph walk, and only names it can actually follow are underlined.
Verified: cargo test green, 1517 frontend tests green, tsc clean. Not yet
exercised in the running app — the drag's geometry in particular has only run in
jsdom, where every row reports a zero-height rect.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ag1A6YVQxujZkcnrWahjua
Add a search box to FileTree — shared by the right-panel Files view and the Files (Project) tab. Two modes: literal case-insensitive filename substring search (list_project_paths) and in-file content search (project_search). Every result can reveal+select the path in the tree (jump-to-path) or open it (content hits open at the matched line). Search is confined to the browsed folder by default, with a root toggle for the whole project; local-source trees only. Snapshot also includes other in-progress work on develop (GPU stat device readout, system monitor, YAML/table viewers, tab plumbing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016RhzuHHNTbXVcMM4yZHS2g
…eter window Work in progress committed to unblock merging origin/main into develop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vy2kXY3h8ApJVFYCS8yJBM
# Conflicts: # Cargo.lock # package.json # src-tauri/Cargo.toml # src-tauri/tauri.conf.json # src/components/files/FileTree.tsx
…apshot Save the docked subwindow file viewer's browsed folder per subwindow on the layout tree's GroupNode (filesFolder), alongside filesOpen/filesWidth — so it persists with the layout, survives a restart, travels with a detach/popout via the streamed `files` edit, and is freed when the subwindow (group) is dropped. ProjectFilesTab gains a persistFolder override + a resync effect so a restore or popout stream wins over local state. Snapshot also carries in-progress work from the ongoing file-viewer refactor (GifView, table/yaml viewers, file browser/sidebar) and related tests.
…shot Broad snapshot across remote, terminal, monitoring, and file-viewer work: - Multi-host remote projects (worker_sync, remote_usage, RemoteMachinesWindow) - tmux-backed persistent shell sessions (local + remote), Sessions view - System monitoring: gpustat/sysstat/net_usage expansion, SystemMonitorPane - Custom agents (CustomAgentDialog/CustomAgents), shell-script run flow - File viewer refactor (CompareView, FileViewerPane, SyncMergeView, FileTree) - Remote-usage warnings, local-loss surfacing, terminal control/bus plumbing Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TecnBhmTjeuHqbBxJfLdxk
CI: the Windows backend build failed with E0432 (unresolved import `windows::Win32::System::Pipes`) — services/openvpn.rs uses PeekNamedPipe / SetNamedPipeHandleState for the OpenVPN Interactive Service named-pipe IPC but the `Win32_System_Pipes` feature was never enabled on the target-gated `windows` dep. Add it. GitChangeTree flyout on-screen clamp: measure the box with its own transform cleared instead of `rect − shiftX`, so the correction is a fixed reference and converges in one pass. `rect − shiftX` converges in a real browser but diverges by `margin` every render in an env that doesn't reflect the transform into layout (jsdom under test) — an infinite render loop that reddened 4 tests. Also carries in-progress work already in the tree: tab-close is now a non-destructive tmux detach (kill only via the Sessions view ×), tmux session names minted in split/detach paths, table-viewer column resize, and the tmux-reattach identity-reply suppression in TerminalView. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TecnBhmTjeuHqbBxJfLdxk
`local_discovery_finds_every_venv_in_the_tree_not_only_the_root` built its expected nested path from a `"services/api/.venv"` literal, which keeps forward slashes on Windows — but discovery emits the relative path with the OS separator (backslash), so the string compare failed there. Build the expected path from PathBuf components so it matches on every platform. Test-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TecnBhmTjeuHqbBxJfLdxk
…ewers - Slurm job submission/monitoring + HPC pipeline wizard (commands/slurm.rs, lib/slurm.ts, stores/hpcJobs.ts, hpcPipeline.ts, HpcPipelineWizard.tsx) - Global machines registry + header MachinesIndicator (global_machines.rs, schema/global_machine.rs, stores/globalMachines.ts) - Remote folder browser + reusable browse hook (RemoteFolderBrowser.tsx, useRemoteBrowse.ts, lib/remoteHosts.ts, stores/runHostPref.ts) - Tab locality badges + per-host run preference (TabLocalityBadges.tsx) - New viewers: YAML grid (YamlGrid.tsx, viewers/yamlGrid.ts), PDF outline (pdf/outline.ts), presentation overlay (PresentationOverlay.tsx) - System monitor + remote-usage warning refinements - Tests for Slurm, YamlGrid, PdfOutline, YamlViewer The HPC wizard and slurm glue are cluster-agnostic: no institution-specific hostnames, presets, or identifiers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0184T6Pj4JrxFgjtaij9uE9n
Frontend - Add an i18n layer (src/lib/i18n.ts) with a language setting in Settings. - Global machine monitoring: GlobalMachineMonitorDialog plus a dedicated store, surfaced from the Machines menu. - Machine list import/export and reordering (src/lib/machineSync.ts); the export writes host/port/label only, never a username or password. - Remote auto-reconnect (src/lib/remoteAutoReconnect.ts) and a hostBusy store so a working host reads as busy rather than idle. - File tree shows directory sizes, with a per-view setting. - Theme work: fancy_dark becomes the default colour scheme. Backend - Global machine commands, remote usage sampling and sysstat session parsing; OpenVPN and SSH command updates. Fixes - globalMachines.load(): .catch guards a rejection but not a command that resolves to nothing, which left `machines` non-iterable and crashed RemoteUsageWarningDialog. Guard with Array.isArray. - Update the settings default-colour-scheme test to fancy_dark. Privacy - gitignore eldrun-machines.json: the Machines menu export defaults to that name and had dropped a file of real hostnames into the repo root. - Drop a named HPC cluster from three comments; keep the wording cluster-agnostic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merges
developintomainfor the v0.1.32 release.Highlights
HPC / Slurm — pipeline wizard, interactive
srunon a compute node (never the login node), sbatch directive parsing.Global machines — machines are managed at the machine level (the VPN-tunnel pattern applied to SSH): a monitoring dialog, import/export of a machine list, reordering, and per-machine auto-connect. Export carries host/port/label only, never a username or password.
Remote — auto-reconnect for remote hosts, a
hostBusystore so a working host reads as busy rather than idle, and remote usage sampling surfaced through the usage-warning dialog.Viewers & files — YAML grid and PDF outline viewers; the file tree now shows directory sizes behind a per-view setting.
i18n — a translation layer with a language setting in Settings.
Theming —
fancy_darkbecomes the default colour scheme.Fixes
globalMachines.load()used.catch(() => []), which guards a rejection but not a command that resolves to nothing — leavingmachinesnon-iterable and crashingRemoteUsageWarningDialog. Guarded withArray.isArray.fancy_dark.Privacy
eldrun-machines.jsonis now gitignored: the Machines menu export defaults to that filename and had dropped a file of real hostnames into the repo root. Never committed.Verification
tsc --noEmitclean ·cargo test1025 passed ·vitest1781 passed ·npm run buildclean.CI green on
test,test-windows,test-macos.Note: features are code-complete but largely unverified in live UI use.
🤖 Generated with Claude Code