Conversation
Topic/develop add lsmux
Topic/develop add term for lsmon
update. add function.
Topic/add lssync
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Release bump to v0.8.0 introducing the new mux UI (lsmux), one-way sync (lssync), conditional config overrides (match / when.*), plus monitor/shell workflow improvements.
Changes:
- Added
lssynccommand + new internal sync engine (internal/sync) and integrations inlsftp/lsshell. - Added
lsmuxpane-based TUI + mux configuration + transfer workflow plumbing. - Added conditional server config overrides (
match/when.*) and enhanced monitoring terminal integration (lsmonCtrl+T,--share-connect).
Reviewed changes
Copilot reviewed 82 out of 242 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| mise.toml | Extend transfer/sysadmin tasks to include lssync/lsmux. |
| internal/version/main.go | Version bump to 0.8.0; maturity updates. |
| internal/sync/run_test.go | Add tests for sync path helper behavior. |
| internal/sync/run.go | Introduce lssync runtime orchestration (local/remote sync modes). |
| internal/sync/plan_test.go | Add plan-building and delete-scope tests for new sync engine. |
| internal/sync/plan.go | Implement sync planning (desired set + delete scopes). |
| internal/sync/path.go | Add destination/relpath helpers for sync plan building. |
| internal/sync/filesystem.go | Provide local + remote filesystem abstraction for sync/plan/apply. |
| internal/sync/execute.go | Implement plan application (copy, chmod, chtimes, delete). |
| internal/sync/command_test.go | Add parsing tests for lssync-style path/flag parsing. |
| internal/sync/command.go | Implement argument + path spec parsing for sync commands. |
| internal/ssh/shell.go | Refactor port forwarding startup to shared helper. |
| internal/ssh/run_parallel_forward_test.go | Add tests for parallel-forward config selection and notices. |
| internal/ssh/run.go | Add shared-start forwarding helper, parallel-forward config helpers, and ShareConnect flag. |
| internal/ssh/connect.go | Tighten ControlPersist vs ControlMaster behavior; set ControlPersist duration. |
| internal/ssh/cmd.go | Refactor port forwarding startup to shared helper. |
| internal/sftp/shell.go | Add sync built-in command + completion support in lsftp shell. |
| internal/sftp/path_resolution_test.go | Add tests for directory-transfer destination semantics. |
| internal/sftp/path_resolution.go | Add copySourceBase helper used by transfer resolution. |
| internal/sftp/main.go | Update PathSet shape to track root + directory-ness. |
| internal/sftp/cmd_sync.go | Implement lsftp sync built-in using internal/sync engine. |
| internal/sftp/cmd_put.go | Refine put path semantics with root-aware base computation. |
| internal/sftp/cmd_get.go | Refine get task base calculation for directory semantics. |
| internal/scp/path_resolution_test.go | Add tests for directory-copy destination semantics. |
| internal/scp/path_resolution.go | Add copySourceBase helper used by SCP path resolution. |
| internal/scp/main.go | Refine scp push/pull semantics with root-aware base computation. |
| internal/pshell/shell.go | Start parallel-safe forwards for per-host parallel shell sessions. |
| internal/pshell/complete.go | Add %sync completion support in lsshell/pshell. |
| internal/pshell/cmd_test.go | Add test coverage for built-in command detection including %sync. |
| internal/pshell/cmd.go | Implement %sync built-in using internal/sync engine. |
| internal/mux/transfer_job.go | Add transfer job tracking + job launching logic for mux transfers. |
| internal/mux/transfer_file.go | Implement file transfer helpers (local<->remote, remote<->remote) for mux. |
| internal/mux/remote.go | Add mux RemoteSession wrapper + session factory for pane connections. |
| internal/mux/keys.go | Add key binding parsing for configurable mux hotkeys. |
| internal/monitor/top_terminal.go | Add top-panel terminal overlay behavior for lsmon (Ctrl+T). |
| internal/monitor/top_overlay.go | Add overlay primitive to render terminal on top of monitor pane. |
| internal/monitor/terminal_bridge.go | Bridge tvxterm into mview primitives for monitor integration. |
| internal/monitor/shared_terminal_test.go | Add tests for shared terminal factory/close behavior. |
| internal/monitor/shared_terminal.go | Implement shared-connection terminal sessions for lsmon --share-connect. |
| internal/monitor/panel_base_servers.go | Trim server text before node lookup. |
| internal/monitor/panel_base.go | Add global input capture for terminal focus and Ctrl+T terminal open. |
| internal/monitor/lib.go | Wire terminal factories + share-connect flag into monitor runtime. |
| internal/list/tview.go | Add new tview-based selector to mirror classic list UI. |
| internal/list/select.go | Add SelectHosts wrapper that supports cancel behavior. |
| internal/list/event.go | Add cancel-aware selectable key loop for classic list UI. |
| internal/config/openssh_test.go | Make identity-file test deterministic using temp files. |
| internal/config/main.go | Add mux config, conditional match resolution, ignore filtering, and config decoder abstraction. |
| internal/config/conf_test.go | Add coverage for conditional match resolution behavior. |
| internal/config/conf_struct_server.go | Add Ignore + Match/When schemas for conditional overrides. |
| internal/config/conf_struct_portforward.go | Extend port forward struct for tcp/unix networks. |
| internal/config/conf_struct_mux.go | Add mux key binding config with defaults. |
| internal/common/common_test.go | Add tests for ParseForwardSpec tcp/unix parsing. |
| internal/common/common.go | Add ParseForwardSpec; minor prompt printing fix. |
| internal/app/lssync/app.go | Add lssync CLI app using internal/sync engine. |
| internal/app/lsshell/app.go | Add NFS reverse forward flag handling. |
| internal/app/lssh/app.go | Add -P mux UI launcher + opts; update local forward parsing. |
| internal/app/lsmux/app.go | Implement full lsmux CLI app and wire to mux manager. |
| internal/app/lsmon/app_test.go | Add test ensuring lsmon exposes share-connect flag. |
| internal/app/lsmon/app.go | Add --share-connect flag and propagate into ssh Run. |
| go.mod | Update dependencies for mux/terminal UI + sshlib upgrades. |
| demo/client/home/.lssh.d/servers_match.toml | Add demo config for conditional match overrides. |
| demo/client/home/.lssh.conf | Include new servers_match.toml demo config. |
| demo/client/Dockerfile | Build/install lsmux in demo client image. |
| demo/README.md | Document conditional match demo config and examples. |
| cmd/lssync/main.go | Add lssync entrypoint. |
| cmd/lssync/README.md | Add lssync documentation. |
| cmd/lsshell/README.md | Document %sync and new forwarding flag. |
| cmd/lssh/README.md | Document -P mux UI, --hold, unix socket forwarding, etc. |
| cmd/lsmux/main.go | Add lsmux entrypoint. |
| cmd/lsmux/README.md | Add lsmux documentation and mux config reference. |
| cmd/lsmon/README.md | Document Ctrl+T terminal + share-connect flag. |
| cmd/lsftp/README.md | Document sync built-in and sync path prefix conventions. |
| cmd/lscp/README.md | Update CLI help output and version strings. |
| cmd/README.md | Add lssync to command list. |
| README.md | Update suite docs: commands list, install layout, match docs, links. |
| Makefile | Build/install lssync as part of default targets. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| footer.SetDynamicColors(true) | ||
| footer.SetText("Ctrl-X[black:#00ffff]ToggleTopPanel[white] ") | ||
| footer.SetText("Ctrl-X[black:#00ffff]ToggleTopPanel[white:none]Ctrl-T[white:#ff00ff]OpenTerminal[white]") |
There was a problem hiding this comment.
The footer color tag sequence looks malformed ([white:none]) and also removes spacing between the two key hints, which can cause incorrect rendering in the TUI. Consider switching back to standard color tags (e.g., [white]) and adding explicit spacing between the Ctrl-X and Ctrl-T segments.
| footer.SetText("Ctrl-X[black:#00ffff]ToggleTopPanel[white:none]Ctrl-T[white:#ff00ff]OpenTerminal[white]") | |
| footer.SetText("Ctrl-X[black:#00ffff]ToggleTopPanel[white] Ctrl-T[white:#ff00ff]OpenTerminal[white]") |
| for _, fw := range config.Forwards { | ||
| if fw == nil { | ||
| continue | ||
| } | ||
| if err := (&Run{}).startPortForward(connect, fw); err != nil { | ||
| errs = append(errs, err) | ||
| } | ||
| } |
There was a problem hiding this comment.
StartParallelForwards calls startPortForward via (&Run{}), which is a code smell and makes it easy to accidentally introduce behavior in startPortForward that depends on Run state. Consider refactoring startPortForward into a package-level helper (no receiver) or making StartParallelForwards a method on Run so it can call r.startPortForward(...) on the actual instance.
| func copySourceBase(sourcePath string, sourceIsDir, preserveSourceName bool) string { | ||
| sourcePath = filepath.Clean(sourcePath) | ||
|
|
||
| if sourceIsDir && !preserveSourceName { | ||
| return sourcePath | ||
| } | ||
|
|
||
| return filepath.Dir(sourcePath) | ||
| } |
There was a problem hiding this comment.
copySourceBase is now implemented in multiple packages (scp, sftp, and sync) with very similar semantics. This increases the chance of subtle drift over time (especially around directory rename rules). If feasible, consider centralizing this logic in a shared internal helper (or at least adding a comment in each implementation noting that they must remain aligned).
| type sharedTerminalLogWriter struct { | ||
| mu sync.Mutex | ||
| file *os.File | ||
| timestamp bool | ||
| removeAnsi bool | ||
| pending string | ||
| } |
There was a problem hiding this comment.
The shared-terminal logging/path construction code largely duplicates similar logic in internal/mux/remote.go (log writer, pending buffer, timestamping, ANSI stripping, log path templating). Consider extracting a shared log writer utility to avoid divergence and simplify future fixes (e.g., buffering, error handling, timestamp format changes).
| func (b keyBinding) match(event *tcell.EventKey) bool { | ||
| if event == nil { | ||
| return false | ||
| } | ||
| if b.key == tcell.KeyRune { | ||
| return event.Key() == tcell.KeyRune && event.Rune() == b.ch | ||
| } | ||
| return event.Key() == b.key | ||
| } |
There was a problem hiding this comment.
keyBinding tracks a modifier mask (mod), but match() ignores it. This is misleading for readers and makes it easy to assume modifiers are enforced when they are not. Either incorporate a modifier check (e.g., only enforce when b.mod != 0) or remove the unused field to keep the model accurate.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
lssh v0.8.0
v0.8.0is a larger minor release fromv0.7.1, bringing together several major feature additions.This release introduces the new TUI multiplexer
lsmuxand the new one-way sync commandlssync. It also includes many practical improvements for day-to-day operations, such as conditional config switching, opening terminals directly fromlsmon, and launching the mux UI fromlssh.Highlights
Added
lsmuxlsshhost inventory as-isAdded
lssyncrsyncon the remote side--deleteAdded conditional config overrides with
match/when.*Improvements
Enhanced
lsmonCtrl + T--share-connectallows terminal sessions to reuse the monitor connectionEnhanced
lssh-Pto launch thelsmux-compatible mux UI directly fromlssh--holdand--allow-layout-changeto improve multi-host command workflowsEnhanced
lsshell%sync, allowing one-way sync operations directly from inside the shellImproved transfer workflows
lscp,lsftp, andlssyncUpdated documentation and packaging
Notes
lssh,lscp, andlsftpare considered stablelssync,lsmon,lsshell, andlsmuxare currently considered betalsmuxandlssyncare the main additions in this release, so feedback is especially welcomeThanks
Main changes included in this release:
lsmuxlssyncmatch/whenlsmonlssh -P