Open
Conversation
* docs: add zellij screenshot to docs page * docs: update zellij screenshot
Retina (2x) screenshots look blurry on non-retina displays because browser downscaling produces poor results. This adds a Vite plugin that uses sharp to generate proper half-resolution 1x WebP variants at build time and injects srcset density descriptors into <img> tags automatically. The plugin has two parts: - A transform hook that adds srcset="/_1x/foo.webp 1x, /foo.webp 2x" to all <img> tags with .webp src in markdown files - A buildStart hook that generates half-size images into public/_1x/ using sharp's Lanczos resampling Images with existing srcset or data-no-retina attributes are skipped. No markdown files need editing -- the transform is fully automatic.
close.rs was deriving mode and constructing MuxHandle from raw CLI input instead of resolving through git::find_worktree first. When a user ran 'workmux close feature/foo' but the worktree handle was 'api-foo', it would look up the wrong mode (workmux.worktree.feature/foo.mode instead of workmux.worktree.api-foo.mode) and construct an incorrect target name (wm-feature/foo instead of wm-api-foo). Now find_worktree is called during handle resolution. The actual handle is extracted from the worktree path basename before mode lookup and MuxHandle construction. This matches the pattern already used in workflow::open. Adds integration test that creates a worktree with --name (custom handle) and closes it using the branch name to verify resolution works correctly.
When users click on any content image in the docs, the full-size version now displays in a modal overlay with a dimmed background. Click outside the image or press Escape to dismiss. Implementation uses vanilla JS with document-level event delegation, which handles VitePress SPA route changes automatically without rebinding listeners. Images are filtered to only zoom .vp-doc content images, excluding SVGs and linked images. Retina srcset attributes are preserved in the zoomed view. Includes smooth open/close CSS animations (fade + scale) and body scroll lock while the overlay is open.
- Click on zoomed image now closes the overlay (was blocked before, creating confusing UX with zoom-out cursor) - SVG exclusion uses regex to handle query params/hashes in URLs - Add popstate listener to close overlay on browser back/forward - Guard against double-close race condition during animation - Use window sentinel instead of module var for HMR safety - Don't copy srcset to modal so full-size image always displays (on DPR=1 screens, srcset 1x candidate would be half-size)
wait-timeout was listed in Cargo.toml but never imported or used anywhere in the codebase. Removing dead dependency.
strip-ansi-escapes was used in a single call site (capture.rs). The console crate, already a dependency, provides strip_ansi_codes which does the same thing. Removes a redundant dependency.
fs_extra was used in a single file (setup.rs) for copying files and directories into new worktrees. Replaced with std::fs::copy for files and a small copy_dir_recursive helper for directories. The helper properly handles: - Overwriting existing files/symlinks at the destination - Preserving symlinks (avoids infinite recursion on symlink loops) - Skipping special files like sockets/FIFOs (avoids blocking)
Add Apple Container (`container` binary) as a third container runtime alongside Docker and Podman. This enables sandboxing on macOS using Apple's native container/VM technology (macOS 26+, Apple Silicon). Key changes: - Add `AppleContainer` variant to `SandboxRuntime` with serde name `apple-container` (alias `apple`) - Add capability methods on the enum (`binary_name`, `needs_add_host`, `needs_userns_keep_id`, `needs_deny_mode_caps`, `pull_args`, `supports_file_mounts`) to replace match blocks throughout - Auto-detection prefers `container` > `docker` > `podman` on macOS (gated behind `cfg!(target_os = "macos")` to avoid false positives) - Skip freshness checking for Apple Container (no Docker-buildx equivalent available) - Store runtime in StateStore marker files for cleanup correctness, so containers are stopped with the correct binary even if config changes between start and stop - `stop_containers_for_handle` groups by stored runtime, no longer takes a config parameter - `list_containers` returns `Vec<(String, SandboxRuntime)>` with tolerant parsing (empty marker files default to Docker for backwards compatibility) - `sandbox shell --exec` reads stored runtime from state instead of current config - Apple Container only supports directory mounts (virtiofs), so Claude config uses `~/.claude-sandbox-config/claude.json` with a directory mount and in-container symlink, while Docker/Podman keep the existing `~/.claude-sandbox.json` file mount - `rpc_host` defaults to `192.168.64.1` for Apple Container - Apple Container uses `image pull` subcommand (vs `pull` for others) - Skip `--cap-add=NET_ADMIN` and `--security-opt` in deny mode since Apple Container VMs already have full capabilities as root
Add `workmux update` that downloads and installs the latest release binary from GitHub Releases. Uses curl/tar subprocesses to avoid adding HTTP or archive dependencies. The update flow: - Fetches latest version from GitHub API - Downloads the platform-appropriate tar.gz and .sha256 checksum - Verifies SHA-256 integrity before installing - Replaces the binary atomically with rollback on failure - Detects Homebrew installs and directs to `brew upgrade` instead Spinner shows progress through each phase and cleanly reports success or failure.
On CLI startup, workmux now reads a local cache file to check if a newer version is available and shows a one-line stderr notice at most once per 24 hours. A detached background process (`_check-update`) refreshes the cache by querying the GitHub API, keeping the main command non-blocking. Design choices: - Detached subprocess avoids blocking the main command - Cache at ~/.cache/workmux/update_check.json prevents repeated API calls - Numeric version comparison (not string equality) handles 0.1.10 > 0.1.9 - Suppressed in non-interactive contexts (piped stdout/stderr) - Background curl has 5s connect / 10s max timeout - Spawn failure doesn't suppress future checks (no silent blackout) Disable via config (`auto_update_check: false`) or environment (`WORKMUX_NO_UPDATE_CHECK=1`).
Only check for updates during `workmux add` to avoid unexpected output on other commands. This is the most common entry point and keeps the notification surface minimal.
jq is a fundamental CLI tool that hooks and scripts commonly depend on. Including it in the base image ensures all agent containers (claude, codex, gemini, opencode) have it available without needing per-image installs.
Under parallel pytest load (12 workers), tmux pane startup and script execution can exceed the previous 2-second timeouts. Bump wait_for_file default from 2.0s to 5.0s and run_workmux_command timeout from 5.0s to 10.0s. Remove explicit timeout=2.0 overrides in test_agents.py so they inherit the new default.
Allow TUI agents (Claude Code, opencode) inside sandboxed containers/VMs to paste images via Ctrl+V by proxying clipboard reads to the host. Built-in wl-paste and xclip shims translate Linux clipboard tool CLIs into `workmux clipboard-read` calls. A ClipboardRead RPC request triggers the host to read the clipboard (osascript on macOS, wl-paste/xclip on Linux), write the PNG to the shared worktree filesystem (.workmux/tmp/), and return the absolute path. The guest reads the file, writes raw bytes to stdout, and deletes it. No binary data travels over JSON-lines RPC. Key details: - Only image/png supported for v1 - Clipboard shims use separate ClipboardRead RPC, not host-exec Exec RPC - Shims are regular script files (not symlinks to _shim dispatcher) - 20 MB size limit, stale file pruning >1 hour - xclip write mode rejected with error message
Apple Container's `container build` doesn't resolve "." correctly when the process working directory is set via current_dir. Pass the absolute context path as a positional argument instead, which works with both Apple Container and Docker/Podman.
SOPS stores age secret keys and PGP material in ~/.config/sops/. A compromised guest build file could exfiltrate these via an allowlisted host command. Add the directory to DENY_READ_DIRS so both Seatbelt (macOS) and bwrap (Linux) block access.
The retina images plugin's buildStart hook fires async but Vite's dev server doesn't block module resolution on it. When index.md gets processed, the transform hook injects /_1x/ image references before generateRetina1x has finished creating the files, causing import resolution errors on first run in a new worktree. Store the generation promise and await it in the transform hook so markdown processing is blocked until images exist.
The dashboard rendered tmux style codes like #[fg=#a6e3a1] as literal text because ratatui uses its own styling system, not tmux's. Meanwhile the tmux status bar handled them correctly since tmux interprets its own format codes natively. Add a tmux style parser (parse_tmux_styles) that converts #[...] blocks into ratatui styled spans. Change get_status_display() to return Vec<(String, Style)> instead of (String, Color), matching the pattern already used by git and PR column formatting. Supported tmux attributes: fg=, bg=, default/none. Color formats: hex (#RRGGBB), named colors (red, blue, etc.), indexed (colour0-colour255). Malformed or unknown directives are handled gracefully. Closes raine#66
Owner
|
Thanks! I've included the |
a657335 to
a475cb1
Compare
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.
Summary
workmux addto accept unquoted multi-word branch input and normalize it to kebab-case for ergonomic branch creationauto_name.commandso--auto-namecan invoke agent-specific CLIs likeopencode runorclaude -pinstead of requiringllmTest Plan