feat(cli): logs list/tail work against a remote/separate daemon#82
Merged
Conversation
`llmux logs list`/`logs tail` (local mode) read log-buffer.ts's in-process ring buffer — populated only by console.* calls made within the SAME process. Since a fresh CLI invocation is always a separate process from an already-running daemon (the normal deployment shape), these commands silently showed nothing against a live daemon, with zero indication why. The existing code comment claiming "remote tailing goes through the SSE client in client.ts" was aspirational — that client command never existed. Two parts: 1. `--server <url>` now actually works for `logs list`/`logs tail`, mirroring how every other noun already routes remote calls. The backend already had everything needed: GET /api/logs (one-shot) and GET /api/logs/stream (SSE) were implemented and auth-gated but had no CLI client. Added `logs`/`logstail` ClientCommands: `logs list` does a plain authenticated GET; `logs tail` prints the buffered entries then opens a hand-rolled SSE reader (not EventSource — same reason the WS client is hand-rolled: EventSource can't set the Authorization header this endpoint requires). 2. Local mode, when the buffer is empty: a quick /health probe on the configured port detects whether a daemon is already running separately, and if so, points at the now-working --server path instead of printing nothing (`logs list`) or hanging forever waiting for entries that structurally cannot arrive (`logs tail` — now exits immediately with the same pointer instead of hanging). ## Verification typecheck + build clean. Live against the running daemon: - local `logs list`/`logs tail` (buffer empty, daemon running separately) -> correct hint, `tail` exits immediately instead of hanging - `logs list --server ... --token ...` -> real startup-banner entries from the daemon's actual buffer - `logs tail --server ... --token ...`: printed the buffered entries, then an intentionally-triggered request (idempotent no-op write to /api/settings/init-prompts, verified beforehand + after that it didn't change the on-disk overlay) produced a real live log line that streamed through correctly - cleaned up all test tokens created during verification Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Au8T9RPCb6wbgiEecQrBfZ
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
The last open finding from the multi-pass sweep:
llmux logs list/logs tailin local mode read an in-process ring buffer that's empty in a fresh CLI invocation whenever the daemon runs as a separate process (the normal deployment). A code comment claimed remote tailing already worked via an SSE client — it didn't; that client was never built.--server <url>now actually works for both verbs, using the backend's existing (already auth-gated)GET /api/logsandGET /api/logs/stream./healthprobe and points at--serverinstead of printing nothing or (fortail) hanging forever waiting for entries that can't arrive.Test plan
npm run typecheck/npm run buildcleanlogs list/logs tailwith an empty buffer + daemon running separately → correct hint;tailexits immediately instead of hanginglogs list --server ... --token ...→ real entries from the daemon's actual bufferlogs tail --server ...: printed buffered entries, then a live-triggered log line streamed through correctly (verified the trigger request was a true no-op — same overlay file, unchanged content, before/after)🤖 Generated with Claude Code
https://claude.ai/code/session_01Au8T9RPCb6wbgiEecQrBfZ