Add previewsmcp logs subcommand and promote Debugging section#133
Merged
Add previewsmcp logs subcommand and promote Debugging section#133
previewsmcp logs subcommand and promote Debugging section#133Conversation
obj-p
added a commit
that referenced
this pull request
Apr 21, 2026
…rate signal comments Review findings from PR #133 that are worth landing rather than deferring: - Extract `PipeBuffer` (née StderrBuffer) to its own file so both RunCommandTests and the new LogsCommandTests share one thread-safe pipe accumulator. - Replace the 300ms magic sleep in the follow-mode test with a poke-on-every-poll pattern: rewrite the sentinel on each iteration until the stream observes it. Removes the dependency on subprocess-startup timing. - Expand the LogsCommand signal-handling comments to document (a) the narrow benign race between process.run() and signal(SIG_IGN) and (b) why restoring SIG_DFL rather than the prior disposition is safe for this leaf command. - Call out in the README that `previewsmcp logs` honors `PREVIEWSMCP_SOCKET_DIR` only when the variable is actually set for the `logs` invocation — an easy footgun when switching terminals during a debug session. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 21, 2026
…ADME When `run` appears stuck during an iOS host build, consumers had no documented path to diagnose where the failure lives. The daemon's stderr has always been redirected to `~/.previewsmcp/serve.log`, and progress messages stream to the CLI's stderr via MCP log notifications, but none of this was surfaced in the README and there was no one-command shortcut. - `previewsmcp logs` prints the last N lines of the daemon log; `-f` follows. Creates the log file if absent so it works before the daemon has ever started. Forwards SIGINT/SIGTERM to the `tail` child so direct signals to the parent don't orphan it to launchd. - `## Debugging` is now a top-level README section (previously buried as a sub-subsection inside `### Daemon model`), leading with the new subcommand and keeping `tail -F` as the raw-file fallback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rate signal comments Review findings from PR #133 that are worth landing rather than deferring: - Extract `PipeBuffer` (née StderrBuffer) to its own file so both RunCommandTests and the new LogsCommandTests share one thread-safe pipe accumulator. - Replace the 300ms magic sleep in the follow-mode test with a poke-on-every-poll pattern: rewrite the sentinel on each iteration until the stream observes it. Removes the dependency on subprocess-startup timing. - Expand the LogsCommand signal-handling comments to document (a) the narrow benign race between process.run() and signal(SIG_IGN) and (b) why restoring SIG_DFL rather than the prior disposition is safe for this leaf command. - Call out in the README that `previewsmcp logs` honors `PREVIEWSMCP_SOCKET_DIR` only when the variable is actually set for the `logs` invocation — an easy footgun when switching terminals during a debug session. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1c0d09a to
030fa72
Compare
4 tasks
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
previewsmcp logssubcommand — prints the last N lines of~/.previewsmcp/serve.log(default 100), or streams new lines with-f/--follow. Creates the log file if absent so it works before the daemon has ever started.## Debuggingto a top-level README section (previously a sub-subsection inside### Daemon model), leading with the new subcommand and keepingtail -Fas the raw-file fallback.previewsmcp logs -fto the "Enumeration and diagnostics" command list under## Usagefor discoverability.Motivation
Users have no documented diagnostic path when
runhangs during an iOS host build. The daemon stderr has always been redirected to~/.previewsmcp/serve.log, and build-phase progress streams to the CLI's stderr via MCP log notifications, but none of it was surfaced in the README and there was no one-command shortcut.Implementation notes
LogsCommandshells out to/usr/bin/tailrather than reimplementing log-follow in Swift.Processis used directly (notAsyncProcess, which buffers) with stdio wired to the CLI's own TTY handles so tail's output streams live.Signal handling is the only non-trivial piece: after
Process.run(), the parent installsDispatchSource.makeSignalSourcefor SIGINT/SIGTERM on a background queue (becausewaitUntilExitblocks main) and forwards them to thetailchild. Two scenarios covered:tailreceives it on its own; the forward is a redundant, idempotent poke.kill -INT <parent-pid>from a supervisor/script — the signal arrives only at the parent; without forwarding,tailwould be orphaned to launchd.Flag defaults follow
tail/kubectl logs/docker logs/journalctlconvention: snapshot by default, explicit-fto stream.Test plan
swift build— clean build.build/debug/previewsmcp logs --help— expected flags present, discussion mentions the log path and$PREVIEWSMCP_SOCKET_DIRlogswith seeded log +-n 5— returns the last 5 lines, exit 0logswhen log file is missing — creates the file, exits 0, empty stdout (no banner)logs --follow— streams an appended sentinel line within 10s and exits within 5s of SIGINT to the parent PID (covered byLogsCommandTests.followStreamsAndExitsOnSIGINT)PREVIEWSMCP_SOCKET_DIRredirect honored — verified implicitly viaDaemonTestLock-scoped tests targeting an isolated dirswift test --filter CLIIntegrationTests— all 66 tests across 12 suites passOut of scope (follow-ups worth filing)
--verbose/--debugflag threading through existing commandsxcodebuildorswiftcis the one stuck, nothing new lands inserve.loguntil the child exits)🤖 Generated with Claude Code