Merge develop into main: v0.1.0 → v0.1.40#9
Open
fseiffarth wants to merge 133 commits into
Open
Conversation
Sync develop into main: README + privacy tooling
The Windows backend never compiled: Unix-only fs APIs were used unconditionally and the windows-crate calls targeted a pre-0.61 API. - openvpn.rs: cfg(unix)-gate the 0600 askpass/permission code so the module compiles on Windows (VPN stays a Unix-only feature). - platform/windows.rs: port to windows 0.61 (HWND.0 is now *mut c_void; IsWindow takes Option<HWND>; GetParent/GetWindow/GetWindowDesktopId return Result; BOOL moved to windows::core). - commands/apps.rs: port IShellLinkW/IPersistFile shortcut resolution to the 0.61 GetPath/GetIconLocation/Load signatures. - Cargo.toml: add Win32_Storage_FileSystem feature (gates GetPath). - ci-cd.yml: also look for Linux AppImage/deb bundles under the project-root target/ (rust-cache overrides CARGO_TARGET_DIR), and mark pre-1.0 GitHub Releases as prerelease (alpha). Verified: cargo check passes for x86_64-pc-windows-msvc and native Linux; cargo test green (25 passed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFHPkVpagZvJszVt4Avm6G
box_links_block built member doc links with Path::join, which on Windows splices in a `\`, producing malformed markdown link URLs (and failing box_links_block_lists_members_with_matching_md on the Windows runner). Join with a literal `/` so generated markdown is identical on every host. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFHPkVpagZvJszVt4Avm6G
import_project's "move" mode used a bare fs::rename, which fails across drives/filesystems (EXDEV on Unix, os error 17 on Windows) — e.g. importing from a different drive than the eldrun projects root. Fall back to copy-then-remove (reusing copy_dir_all) when rename fails, matching the existing move_path behavior. Fixes the Windows runner's projects_commands integration tests (the move panic also poisoned the shared test lock, cascading into two unrelated failures). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFHPkVpagZvJszVt4Avm6G
Windows build support + first alpha (v0.1.0)
The upload steps list two path patterns (src-tauri/target and the project-root target/ that rust-cache's CARGO_TARGET_DIR override uses), which makes upload-artifact root each artifact at the workspace dir. The bundles therefore download nested (target/release/bundle/.../*) rather than at the artifact root, so the release job's flat globs matched nothing and v0.1.0 published with no assets attached (uploaded manually after the fact). Use recursive `**` globs so future releases self-attach. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFHPkVpagZvJszVt4Avm6G
- Screenshot global app now captures an interactive region into the active project's screenshots/ folder, driving the configured tool's output path there with a native region-capture fallback. - New in-app viewers: diff, notebook, table/sheets, html, media, odt, sqlite, and image annotator. - Project search panel + fuzzy quick-open; sqlite/sheets backends. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TQYYMRLqFX53RFaJBonzp3
Backend: Worktree struct, parse_worktree_porcelain helper, and
git_worktree_{list,add,remove,prune} commands in commands/git.rs,
registered in lib.rs. Frontend: a "Worktrees" section in GitHistory
(list, create-from-branch, remove; main worktree non-removable), with
an aria-label on the remove control. Adds Rust unit/integration tests
and GitWorktree.test.tsx. "Open worktree as project" deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…andbox - Add gitDirty store + GitDirtyState tests for tracking uncommitted state - Add tabLand store and cross-subwindow tab drag (CrossSubwindowTabDrag, DetachedSplit tests); expand TabBar/commitDrop and detached center panel - Add agent-sandbox Docker image + services/sandbox.rs - Viewer width reflow handling (ViewerWidthReflow test), TeX/markdown viewer tweaks - Refresh app icons + icon-source.svg, expand themes.css - Misc: RightPanel git status/history, ProjectDialog/ProjectPill updates Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts: # Cargo.lock # src-tauri/Cargo.toml # src-tauri/src/commands/git.rs # src-tauri/src/lib.rs
Detached subwindows gain divider resize and cross-group tab merge by reusing the shared pure layout paths (applyResize, moveKeyInTree). A dedicated outer title bar keeps the window controls pinned top-right regardless of splits. Includes regenerated icons and a hot-reload dev launcher script. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Each git action button in the right panel now only renders when it has work: Add when there are unstaged/untracked changes, Commit when changes are staged, Push when commits are ahead of the remote. The action bar hides entirely for a clean, pushed repo. Buttons gain live counts in their labels and titles. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Detached popouts re-implemented their tab bar, so split/merge drags diverged from the main window: a plain 80px reorder margin instead of the dashed drop-placeholder + .drop-target wash, and no drop-in landing flourish on merge/split/move. Reuse the same code in both windows: - Extract the drop-placeholder into a shared TabDropPlaceholder used by TabBar and DetachedCenterPanel; drop the REORDER_GAP margin. - Wire useTabLandStore into DetachedCenterPanel on the same cross-group rules commitDrop uses (merge/split/move land; same-group reorder does not). - Carry an optional landedKey on the detached seed so a tab docked INTO a popout from another window plays the landing too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ndow drop
Two multi-pane ("Phase 4") popout fixes:
1. Restart respawn — a SPLIT popout was persisted untagged
(withDetachedDocked only tagged single-group popouts), so on restart it
re-docked into the main panel instead of reopening as a floating window.
Now split nodes carry the detached tag through prune/deserialize, the
liveIds filter checks splits too, and detachGroup re-detaches a whole
split subtree by id (new findSplit/removeNodeById helpers).
2. Cross-window drop into a split popout — dropping a tab/file from the
main window always landed in the first pane and highlighted the whole
window. The host now resolves the pane under the cursor SYNCHRONOUSLY
from the popout's reported geometry (DETACHED_PANES_REQUEST/PANES +
resolvePaneTarget) — no release round-trip race — and docks into that
specific pane via dockTabIntoDetached(target)/placeKeyInTree (body edge
splits, bar merges). The popout renders the host-resolved target as its
per-pane preview; the whole-window highlight is now an outline only.
Shared detachedDropTargets.ts session drives both tab (TabBar) and file
(FileTree/commitFileDrop) drops. Tests: SplitPopoutRespawn,
FileDropIntoPopout, ResolvePaneTarget, plus targeted-dock cases in
SubwindowDetach and an updated DetachedSplit assertion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the per-Ollama-model tab list with one active local model: - Add a Local Model button in the header, left of the global-apps button (LocalModelMenu) — hover to pick from installed models (reusing the existing list_ollama_models / ollama_is_installed commands); selecting writes settings.ollama_model. Only shown when Ollama is installed. - TabBar's add menu now offers ONE "Local Model" entry that launches the active model, instead of listing every installed model (drops the list_ollama_models fetch + ollamaModels/loading/error state). - Expose ollama_model in the frontend Settings type (the backend field already round-trips through save_settings/get_settings). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add agent-CLI registry/install flow (commands/agents.rs) and expand the Ollama command surface to launch local Ollama-backed agent tabs (Claude Code, Hermes, OpenClaw, OpenCode) alongside the existing vibe local agent. Add per-file-type autocomplete completion modes (Sentence/Block/Scope) across the native viewers, with live Shift+Tab cycling and word-by-word accept. Drop StatusLamp; update LocalModelMenu, settings panels, themes, and types accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3S32t1qajiDAFoCtfBz3Q
…cker Add in-app markdown editing (markdownEdit), viewer formatting helpers (viewers/format), and an Ollama-backed grammar/format command path. Add a context file picker for embeds, expand FileViewerPane, and drop the unused HtmlView. Wire new settings field and tab/right-panel hooks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014KtzbfNxf4S4KJMcz3e5dX
Wire OpenClaw into the Ollama local-model pipeline as a launch-only LOCAL_DRIVERS entry (`ollama launch openclaw --model <m>`; no hand-rolled fallback — `ollama launch` installs and stands up its gateway against the local endpoint). Also register OpenClaw as a standalone installable agent in commands/agents.rs (`npm install -g openclaw`, bin `openclaw`) and in AGENT_ITEMS/AGENT_CMDS so it shows in the regular agent add-menu. Update the settings glossary and module docs to list it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3S32t1qajiDAFoCtfBz3Q
Bump version to 0.1.5 across package.json, src-tauri/Cargo.toml, tauri.conf.json (+Cargo.lock), and source the header's displayed version from package.json so the UI tracks every bump. Release the GitHub Release job on every v* tag, not just v0.<minor>.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Bfukb8GNY3z64ibZ8Yc98
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Bfukb8GNY3z64ibZ8Yc98
Use a real grep binary and fail loudly on scan-tool error, so a shell that shadows grep (ugrep wrapper) can no longer make the scan silently pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Bfukb8GNY3z64ibZ8Yc98
pdfjs-dist's package.json exposes only `main` (no `exports`/`module`),
which Vite's package-entry resolver handles inconsistently across
platforms and fails on Windows ("Failed to resolve entry for package
pdfjs-dist"). Add a regex-anchored resolve.alias so the bare specifier
points straight at the file `main` references, leaving the `?url` worker
subpath import untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the only/last tab of a subwindow is dragged, that subwindow now closes live during the drag (siblings reflow to fill) instead of lingering until the drop: - dragPreview.ts: pure `dragPreviewLayout` helper that prunes the lone-tab source group from the rendered tree (no-op for multi-tab sources, the only subwindow, non-tab drags, or while fullscreen). - CenterPanel: render + measure off this preview layout. Render-only — the store layout is untouched, so an aborted drag restores instantly and the dragged tab's pane stays mounted (PTY survives). - TabBar: hold the drag's pointer capture on the document root, not the dragged tab, so collapsing (unmounting) the source mid-gesture can't drop the capture / fire a spurious pointercancel on Win/macOS. - DragPreviewCollapse.test.ts: unit coverage for the helper. Also bundles in-progress cross-platform (Windows) work already present in the working tree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…aths Make the cross-platform paths actually work on Windows: - detach: apply restore geometry as PHYSICAL px (frontend canonical space) so popouts land on-screen on scaled displays; marshal show/resize nudge onto the main thread. - agent_session: PowerShell SessionStart hook + `powershell -File` command on Windows; POSIX sh unchanged. - openvpn: real best-effort tunnel management on Windows (resolve openvpn.exe, askpass flow, taskkill teardown) replacing the stub. - ssh_mount: drive SSHFS-Win/WinFsp; cfg-gate fusermount/proc-mounts to unix, add Windows mount-state/teardown. - tex.ts: route path math through lib/paths helpers so backslash/Windows absolute paths resolve correctly; tests added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…c Windows support - subwindow: make detach_subwindow async — a sync command blocks the main thread that WebView2's create_controller callback needs, deadlocking the popout into a blank white window on Windows (wry#583/tauri#4121). - DetachedCenterPanel: move borderless popouts via the native OS window drag on Windows (the custom poll+setPosition gesture can't move the window there); swap heavy pane content for a cheap placeholder during the native move so WebView2 keeps the surface aligned with the frame. - SetDefaultAppDialog: lazily resolve and show per-app icons (Windows shell icon / Linux theme icon) for the apps currently filtered. - themes.css: move-placeholder + app-row icon/button styling. - README: document native Windows support (workspace parking, app launch, default apps, downloads, OpenVPN, SSHFS-Win, agent resume) and refresh viewer/platform status. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a navigable 3D project/box cloud as a new tab kind ("projects3d"),
offered from the + menu in the root scope when projects exist and seeded
as the default tab when the root scope is entered. Cards orbit/zoom via
CSS 3D transforms (no new dependency); clicking a project activates it and
a box opens it. Bumps package.json, Cargo.toml, and tauri.conf.json to
0.1.6, plus the current working-tree state.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The frontend tests had drifted behind the components they cover, plus jsdom was missing shims the newer UI code relies on. Fix all 19 real failures and the exit-code-1 left by uncaught Tauri-API rejections. - Add src/test-setup.ts (wired via vitest setupFiles) with global jsdom shims: a ResizeObserver no-op (TabBar overflow tracking), a CSS.escape polyfill (TabBar drag hit-testing — its absence silently broke the split pipeline), and inert __TAURI_INTERNALS__ / __TAURI_EVENT_PLUGIN_INTERNALS__ stubs so unmocked listen()/invoke() calls don't throw uncaught rejections that fail the run's exit code. Also raise Testing Library's asyncUtilTimeout to absorb load spikes. - vitest.config.ts: bump testTimeout/hookTimeout to 20s — heavy viewer renders and real-timer polls were tripping the 5s default under the full suite's parallel CPU load. - AppShellClose: mock the new win.onScaleChanged listener. - DragDropSplit: mock @tauri-apps/api/window + /event (CenterPanel's detached-drag effect needs getCurrentWindow/listen/cursorPosition). - FileTreeNav: New File moved to the file-tree background context menu; right-click there, and mock git_unpushed_commits (null -> .length crash). - AutoReload/ImageAutoReload: widen the real-timer poll waitFor budgets. All 89 files / 713 tests pass; tsc --noEmit clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0161dwKecZYT2fc3EVizQqPV
Add an onboarding tour with coachmarks (TourHost/TourCoachmark, tour store + lib), a Lessons menu, and a tree-style git change view (GitChangeTree). Introduce a platform abstraction and file-access helper, plus macOS entitlements/config and CI packaging updates. Themes, viewers, paths, shortcuts, and SSH/OpenVPN services refined. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013s8uJKV8A99ZcqUVNYtWC4
…on, blob polish - Add sftp service + remoteConnect helper for remote project browsing - Rename github.rs → git_publish.rs; generalize publish flow - Refactor SSH command/mount/exec surface and remote project section - Add docker-sandbox lesson to the catalog (+ test) - Expand ProjectBlobPane 3D root tab and theme styling - OpenVPN service updates, settings/UI and capability schema sync Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmvRfNfesikVofoaREZHnV
…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>
…a polls Severe hangs, all with the same shape: a synchronous Tauri command aimed at a peer that will never answer, blocking until ssh's own keepalive gives up (~45s) — and the file tree issues one per visible folder. VPN drop gating - vpnStatus.refresh now distinguishes a tunnel that died on its own from one torn down deliberately (every deliberate teardown forgets the config first, so only an unplanned death reaches the new branch). - A dropped tunnel clears the status of the projects that were holding it, which flips useRemoteBlocked so probes are never dispatched rather than each paying the timeout. Scoped to the tunnel's holders: a project that never claimed the config reaches its host another way. - The pooled backend session is deliberately left alone — reaping it is the pooled reader's job, and a teardown issued here would itself be a call over the dead connection. Directory sizes (src/lib/dirSizeGuard.ts) - Folder sizes are a best-effort display aid, so they are safe to bound aggressively: timeout, concurrency cap, and a per-project circuit breaker that opens after repeated failures. Ollama status (src/lib/ollamaStatus.ts) - Collapse the per-component polls into one app-wide timer. Also: run-host preference handling for shell/python runs, and backend project/git/openvpn updates. Tests: DirSizeGuard, VpnDropGating, ShellScriptRun. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
prerelease - Every release was published with `prerelease: true`, and GitHub never marks a pre-release as "Latest". `/releases/latest` therefore 404s — the exact link README.md:121 sends users to for a download. Publish as a full release; the notes still say alpha, this flag is about discoverability. macOS asset name - The DMG was renamed to `Eldrun-<sha>-universal.dmg` while the AppImage, deb and exe all carry the version, leaving the one asset a user couldn't tie to a release at a glance. Name it `Eldrun_<version>_universal.dmg`. - The move is now guarded: Tauri may already emit exactly that name, and `mv x x` fails. The upload glob widens to `*universal.dmg` so it matches either separator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…emote-features opt-in - OpenVPN: every tunnel Eldrun starts now carries a loopback management socket so disconnect asks the daemon to SIGTERM itself instead of a second pkexec prompt; falls back to the old kill path when the socket can't be used. - Big folders: one-time census (local + host du) on new/imported/ extended remote projects, defaulting giant folders to excluded from byte-sync rather than silently hauling them into the mirror. - VPN/machines indicators are now gated behind an explicit opt-in (Settings' "Remote features"), prompted once via RemoteFeaturesPrompt. - Misc: i18n additions, file-tree row cap, terminal theme renderer test. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QJxJaJuNGEt9jn8jnXYHFW
config_declaring_management_is_detected calls arm_management, which is unix-only — the test compiled fine on Linux/macOS but broke the Windows test build. Matches the cfg(unix)/cfg(target_os = "linux") pattern already used by the neighboring management-socket tests in this file. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QJxJaJuNGEt9jn8jnXYHFW
…, i18n groundwork Snapshot of accumulated work on develop: - Deck presenter: native *.eldeck.json editing and presenting (stage, slide view, inspector, notes, TeX panel, icon picker, snap/transform, export, sidecar, GIF playback) plus the dual-window audience view behind open_presenter_window. - HPC support: hpc_hosts tag and careful_hosts classification, HPC guard dialog and prompt store, remote workspace commands (hpc_ws), and the toggles that drive them. - Credentials: keyring helpers, credential paste bar, host-key confirmation dialog and store for first contact, terminal sign-in toggle. - Git: fork command (git_fork), publish-from selection for work-remote projects. - i18n: translation groundwork and TODO group N with the plan doc. - docs/context/*: per-subsystem design rationale split out of CLAUDE.md. Test fixes: - AppShellClose test mocked useSettingsStore without getState, which the auto-reconnect sweep reads imperatively; the resulting unhandled rejection is gone. - Scrubbed a real home path and username from the i18n plan doc and two test fixtures ahead of the privacy check. Verified: tsc clean, 2016 vitest tests pass, all cargo test suites pass, scripts/privacy-check.sh reports only expected matches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hi5Wn4w71MJezWadstSnrY
- ShellScriptRun test used a real lab machine label as its run-host fixture; now a generic worker id, matching the alice/gpu fixtures around it. - The careful-mode doc attributed its quoted usage rules to a named university; the reasoning is not site-specific, so the attribution is now generic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hi5Wn4w71MJezWadstSnrY
… tests Privacy: - Test fixtures and incident comments named a real project. Renamed to a neutral placeholder across the frontend tests, the Rust service tests, and the comments in tabs.ts / terminal_service.rs / git_peer.rs. Flaky tests: - sysstat's cache-mechanics tests seed a synthetic DESCENDANT_CACHE entry under a private CACHE_TEST_LOCK, but terminal::tests::kill_reaps_the_child_ subtree spawns a PTY and calls invalidate_descendant_cache in a poll loop — in the same test binary, on another thread, unable to take a lock private to sysstat::tests. A concurrent generation bump turns the seeded cache hit into a miss and the assertion fails. - The lock is now module-level and pub(crate), and the PTY test takes it too. - Acquisition goes through lock_cache_for_test, which tolerates poisoning: one genuine assertion failure used to poison the lock and fail every later cache test on the poison rather than on its own behaviour, which is why these always failed in pairs. Verified: tsc clean, 2016 vitest tests pass, all cargo suites pass, privacy-check reports nothing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hi5Wn4w71MJezWadstSnrY
remote_tmux_list only scoped by host, never by project, so two remote projects sharing a login node saw each other's tmux sessions. Session names now embed the owning project id (eldrun-<projectId>--<uuid>), and remote_tmux_list filters the host's tmux ls output down to the requesting project's own sessions plus unattributable ones (foreign hand-started sessions, legacy pre-scoping eldrun-<uuid> sessions). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPdhSvAcWJyBc5K9C5sgGz
…machine sync Closes three reported bugs in the remote-connect path: - An HPC-tagged login node was dialled unattended. `ssh_common` now carries an authorization registry so a background dial at a tagged target is refused, and the refusal is surfaced (`ELDRUN_HPC_GUARD`) rather than swallowed. - An ordinary connect destroyed an already-saved SSH password. The saved- credential read is now a tri-state (`saved` / `notSaved` / `unreadable`) via `remote_saved_password_state` + `useSavedCredential`, so a locked keyring no longer reads as "nothing saved" and no longer licenses a clearing write. - A global machine turned green while the project holding it stayed disconnected. `lib/machineSync` reconciles on a subscription over the machine's `status` rather than at the two call sites that used to do it by hand, and `reachable` (a probe) is kept distinct from `status` (a session this app opened). Also: first-contact host-key confirmation (`lib/hostKeyOnce`), the shared `SavePasswordRow` / `autoConnectEligibility` pieces behind the connect dialogs, and i18n coverage for the machines/VPN surfaces. `useSavedCredential` no longer destructures the keychain answer blind — an empty answer from the bridge read as an unhandled rejection inside an unawaited promise, leaving the row on "checking" with nothing on screen. Deferred follow-ups from the audit are recorded as TODO G.24. Gates: tsc clean, cargo test 1138 passed, vitest 2017 passed (0 unhandled errors), privacy scan reviewed — all hits are param/field names or fixtures. Not manually tested against a live cluster; see the G.24 manual-QA item. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPdhSvAcWJyBc5K9C5sgGz
`scripts/bump-version.sh` rewrites package.json, src-tauri/Cargo.toml and tauri.conf.json but not the lockfile that records the same version, so the tree comes back dirty after every auto-bumped push. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPdhSvAcWJyBc5K9C5sgGz
The bump rewrote package.json, src-tauri/Cargo.toml and tauri.conf.json but not Cargo.lock, which records the same version for the workspace's own package. Cargo rewrites that entry the next time it runs, so every auto-bumped push committed a lockfile one version behind and handed the tree back dirty — the bump commit and the lockfile could never both be clean. The lockfile edit is matched on the block's own `name = "eldrun"`, never on the version string, so a dependency sitting at the same version is not rewritten with us. A missing lockfile is skipped rather than fatal: it is a generated file, and a fresh clone must still be able to bump. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPdhSvAcWJyBc5K9C5sgGz
bump-version.sh now rewrites the lockfile's own package entry, but the hook staged only the other three files — so the bump commit went out without it and left the very dirty tree the previous commit set out to stop. Kept to an explicit file list (behind `--`): a push must never sweep up whatever else happens to be sitting in the working tree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPdhSvAcWJyBc5K9C5sgGz
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.
Brings
mainup todevelopat v0.1.40.mainhas been sitting at v0.1.0 while release tags (v0.1.21, v0.1.36, v0.1.40) were cut fromdevelop, so this closes a 133-commit gap.Merges cleanly —
main's only two unique commits are prior merges ofdevelop, so it carries no content of its own (git diff origin/develop...origin/mainis empty) andmerge-treereports no conflicts.Scope
629 files changed, +207,645 / −13,799. 50
feat, 17fix, plus chores/docs/tests.Remote & SSH — mount-free SSH/SFTP-native remote projects (replacing sshfs), git-aware local↔remote lockstep sync, selective byte-sync with a big-folder census, multi-host compute machines, connection-status lamps, SSH host-key TOFU, password auth via an OpenSSH askpass shim, and tmux-backed session persistence.
HPC — SLURM pipeline wizard, workspace allocation/expiry handling, careful mode for login nodes, and the dial guard that keeps background probes off tagged hosts.
Platforms — Windows support (SEH crash hook, unelevated OpenVPN via the interactive service, popout drag, position_window) and macOS parity (OpenVPN daemon, system monitor, workspace backend, DMG packaging).
Viewers & UI — YAML/JSON tree and card viewers, PDF page tools and outline, table/CSV, GIF, line-diff compare, in-tree file search, git blame, native system monitor, network traffic tab, calendar tab, project containers, popout/detached subwindows, usage recap, and i18n groundwork (en/de/es/fr/it).
Verification
tscclean ·cargo test1138 passed ·vitest2017 passed (0 unhandled errors) · privacy scan reviewed clean. CI is green on Linux, Windows and macOS for the tagged v0.1.40 build.Caveats
Most of this is code-complete but not manually validated — per the project's standing "done ≠ tested" position, automated gates are the only checks that have run. The remote-connect hardening in particular has not been exercised against a live cluster; deferred follow-ups and the manual-QA list are tracked as TODO G.24.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KPdhSvAcWJyBc5K9C5sgGz