[#159] Implement the minimal client interface (ls, activate, attach, destroy) - #434
Conversation
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Free Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds workspace dependencies to Changesminimal2 CLI daemon connectivity and session commands
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as minimal2 CLI
participant Client as client::Client (SSH/UDS)
participant minimald
User->>CLI: minimal activate --path /proj --attach
CLI->>Client: connect(resolve_socket_path())
Client->>minimald: UnixStream + SSH handshake (retry)
minimald-->>Client: authenticated
CLI->>Client: oneshot_rpc(CreateSession)
minimald-->>Client: session_id
CLI->>Client: oneshot_rpc(GetSessionRecord)
minimald-->>Client: session record
CLI->>CLI: exec ssh -o ProxyCommand="minimal proxy <sock>"
note over CLI,minimald: ProxyCommand bridges stdin/stdout to UDS
CLI-->>User: interactive session
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Poem
Note 🎁 Summarized by CodeRabbit FreeYour organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above. Comment |
Build Plan SummaryThis implements the client-side CLI for the Minimal client interface (gominimal/inbox#159). See What this PR delivers (Phases 1-4)Phase 1: Subcommand Structure -- Added Phase 2: SSH Client Transport -- New
Phase 3: Core Commands -- Wired in
Phase 4: Exec-Based Attachment -- Phase 5: Future -- Key design decisions
|
Build Plan Summary :Phase 1: Subcommand Structure and Argument Parsing (DONE)
Phase 2: SSH Client Transport and RPC Wrapper (DONE)
Phase 3: Core Oneshot Commands (DONE)
Phase 4: Interactive Session Attachment (DONE — exec path)
Phase 5: fzf Session Picker (DONE)
Outstanding / Blocked
|
FYI the run in session stuff is already implemented as a shell request, not an exec request. The exec request stuff is really just there for supporting git receive-pack and from when i was figuring out how it all worked- ill probably rip out that path soon. In the short term, you could get around needing to implement management of the local terminal/termios and such just by shelling out to the $> MINIMAL_SESSION_ID=<session uuid> ssh -o SendEnv=MINIMAL_SESSION_ID -o ProxyCommand='socat - UNIX-CONNECT:<socket>' -o 'UserKnownHostsFile=<socket>/../known_hosts' local-0 |
4f4ab38 to
0c53669
Compare
Status updateRebased on What's done
Removed
Still outstanding
|
|
Ready for review. All reviewer feedback applied (ssh ProxyCommand attach, DestroySession RPC, exec_in_session removed), E2E tested, fmt/clippy/tests green. Would appreciate a look when you're back from travels — no rush. |
| use super::super::client::resolve_socket_path; | ||
|
|
||
| /// Timeout for waiting on the UDS after spawning minimald. | ||
| const UDS_POLL_TIMEOUT: Duration = Duration::from_secs(4); |
There was a problem hiding this comment.
Rather than wait 4 seconds on first start, it might be better to look for the PID file, see if that PID is alive, and only if so then timeout waiting for a connect() to succeed.
@norrietaylor do you have the deets on if/where the PID file?
There was a problem hiding this comment.
should be in xdg dir according to mike
There was a problem hiding this comment.
Currently pid files for minvmd are going here: ~/.local/state/minimal/minvmd/.
There was a problem hiding this comment.
Glad to move them though 👍
minimald now writes a PID file at startup. The minimal2 auto-spawn logic checks this file before spawning: if the PID is alive the daemon is already starting (e.g. spawned concurrently), so it waits for the UDS rather than spawning a duplicate. The spawn path uses Child::try_wait to detect a crash during startup and fail fast instead of exhausting the 4s timeout. Addresses review feedback on #434.
5896722 to
7e8a98d
Compare
|
This pull request has no accompanying spec. Comment |
Closes gominimal/inbox#159
Implements the client-side CLI interface in
crates/minimal2to interact withminimaldover the SSH-based control protocol.What's implemented
ls— Lists sessions viaListSessionsRPC.--rawoutputs one session ID per line for scripting (minimal ls --raw | fzf | xargs minimal attach).activate— Creates a session viaCreateSessionRPC with optional--nameand project path.--attachchains into attach after creation.attach— Resolves a session by UUID or name viaGetSessionRecord, then shells out tosshfor interactive PTY attachment.--commandruns a non-interactive command in the session context. Uses a hiddenproxysubcommand as the SSHProxyCommand(nosocat/ncdependency).destroy— Resolves by UUID or name, then callsDestroySessionRPC (feat(minimald): implement session destroy + RPC #462).completions— Shell completion script generation viaclap_complete.Auto-spawn
On Linux, the CLI auto-spawns
minimald runas a detached background process if the daemon UDS isn't connectable, then polls until ready (4s timeout). On macOS, auto-spawnsminvmdvia the existing state machine. No lifecycle state machine orstate.toml— just socket polling. The lifecycle management PR (#435) can layer richer state tracking on top later.Design decisions
minimal2) has zero dependency onminimaldinternals — it talks exclusively through theminimald-rpcwire contract over SSH.--commandattach shell out tosshrather than reimplementing termios/PTY management. The daemon'sshell_requesthandler mints the PTY-backed session shell; ssh handles terminal reconfiguration and cleanup.exec_in_sessionwas removed entirely — per @twitchyliquid64's feedback, it used the daemon's old exec codepath which doesn't hit the sessions module. exec_request remains on the daemon side for git-receive-pack / vscode remote only.Removed
dashsubcommand — temporary fzf-based picker, removed in favor of a future proper TUI.Summary by CodeRabbit
New Features
lscommand to list active sessionsactivatecommand to create and activate new sessionsattachcommand to connect to existing sessionsdestroycommand to remove sessions