Repository navigation
Breadcrumb Copy And Log Diagnostics - #14
Merged
Merged
Conversation
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.
1. Purpose & Motivation
Description
Two things the desktop app could not do. A request's location was displayed above the editor but
could not be taken anywhere — quoting it in a ticket or a chat meant retyping three names. And the
log the app writes could only be read by leaving the app: open the folder, open a 2MB file in
whatever the OS thinks owns
.log, scroll to the end, and hope the editor reloaded. That loopanswers "what happened before it broke" adequately and "what happens when I do this" not at all.
This PR makes the breadcrumb one click that copies
Collection > Folder > Request, and puts thelog in the Diagnostics tab: a switch that shows the last 500 lines and then keeps up with the
writer, searchable, resizable, and selectable.
Context & Flow
The tail read and the start of forwarding happen in one synchronous turn on main's single thread,
so no line can be written between them and be missed by both.
2. Key Changes
Description
The breadcrumb copies. The whole row is one button.
breadcrumbPath()joins the ancestors andthe request name with
>; a transient check and "Copied" confirm it. The crumbs still do notnavigate — one target, not one per crumb.
Main can tee its log to the window.
main/logstream.tsis a new module that batches lines on a100ms timer and forwards them over a new
logLineschannel, gated bywatchLog. It holds nothingwhile it is off.
main/diagnostics.tsgainedreadTail(limit)andparseLog(), which reads backthe format it writes: a line with no timestamp stamp is treated as a continuation of the record
above it, so a stack trace survives the round trip as one record.
The Diagnostics tab renders it. A 500-line ring buffer in a renderer store, subscribed at the
top of
App.tsxrather than in the pane, so the stream survives leaving the sub-tab and closingSettings — which is the point, since everything worth watching a log for happens somewhere other
than the Settings pane. Search highlights in place with next/previous and a match counter rather
than filtering. The box is resizable by drag or arrow keys, its height remembered in the store, and
its text is selectable.
The section's controls became glyphs. Stream, Reveal, Clear, the search and Check now are
IconButtons. The consequential update actions — Skip, Download, Restart and install — keep theirwords.
Technical Decisions
mean watching it, reassembling a partial last line, and noticing the rename at
LOG_MAX_BYTES—three ways to display something other than what was written, in exchange for nothing.
press or the fourth, with no re-read block in the middle of a list that reads as continuous.
preman.log. Padding a short tail frompreman.log.1would put a gap ofunknown size in a list with no seam drawn in it.
deletes exactly the neighbouring lines that answer it.
made the amendment safe is 035's own: what may be written is still fixed and still excludes URLs,
headers, bodies and variable values, so a window that draws the file decides nothing about
redaction that the writer had not already decided. Recorded in
docs/decisions/056.Critical Modules/Files
packages/desktop/src/main/logstream.ts— the synchronous seam between the tail read and thestart of live forwarding. An async read here would drop exactly one line under load.
packages/desktop/src/main/diagnostics.ts—parseLog()makes the log stamp a contract withitself. Continuation handling is what keeps stack traces intact.
packages/desktop/src/renderer/panes/SettingsPane.tsx— the largest diff.LogStreamholds thesearch state, the pin-to-bottom ref and the resize handle. Its Escape handler must call
preventDefault(), or the pane's own window-level Escape closes Settings behind it.packages/desktop/src/preload/bridge.ts— the newLogBatchcontract and two channels.Recommended Review Order
packages/desktop/src/preload/bridge.ts— the contract everything else is written againstpackages/desktop/src/main/diagnostics.tsandmain/logstream.ts— the tail and the teepackages/desktop/src/main/main.ts— where the tee is installed innote()packages/desktop/src/renderer/model/log.tsandstores/log.ts— the pure logic and the storepackages/desktop/src/renderer/panes/SettingsPane.tsxandpanes/DocumentChrome.tsx— the viewsdocs/decisions/056-the-log-can-be-watched-while-it-is-written.md— the argument, and what itamends
3. Verification & Testing
Provide reproducible inputs or steps for each test case, followed by the result and supporting evidence.
Clicking the breadcrumb row on a nested request copies
Collection > Folder > Requestand shows a transient "Copied"Opened
payment / nested / Deep Echoin a built app and clicked the breadcrumb row.navigator.clipboard.readText()returned exactlypayment > nested > Deep Echo, and the rowshowed a check with "Copied" at its end.
Enabling the stream fills the box with the tail of
preman.log, then appends new lines liveAgainst a full log the switch produced exactly 500 rows, the cap. The screenshot below is against
a deliberately short log — 29 rows, every line in the file — so the evidence carries no local
paths beyond this repo's own fixtures. New lines appended live as workspaces were opened.
The stream outlives the pane, and a second enable replaces the view rather than duplicating it
Went Diagnostics → Protos → Diagnostics with the stream on: the button still read "Stop" and the
lines were still arriving. Stopping and starting again re-read the tail and replaced the contents
rather than appending a second copy.
Search highlights every match, reports n/total, steps and wraps; Escape closes only the search
Typing
engine host startedbanded every occurrence and reported1/69against the full log.Next moved to
2/69; two Previous presses wrapped to68/69. Escape closed the search and leftSettings open — a bug found by eye during this work, fixed by claiming the event, and now covered
by a regression test.
The log box resizes by drag and by arrow keys, clamps at 96px, and its text is selectable
Dragging the handle took the box from 256px to 556px; dragging hard upward stopped at exactly
96px, the floor. Eight ArrowDown presses on the handle moved it 96 → 288, exactly 8 × 24px. The
box computes
user-select: textand a double-click selects a word.4. Impact and Scope
Desktop app only.
@preman/coreand the CLI are untouched; no engine, workspace-file orrequest-execution behaviour changes.
IPC surface. Two new channels,
logLines(main → renderer push) andwatchLog(renderer →main). Additive; no existing channel changes shape.
Performance. No new periodic work — the clock driving the stream is whatever the app was already
doing. While off, the cost is one branch per logged line and no retained buffer. While on, a
batching timer between a line and its delivery, plus one bounded 2MB file read per press. The idle
cost that ADR 040 protected is untouched.
Security and privacy. The log still contains no URLs, headers, bodies or variable values — ADR
035's invariant is unchanged and is the reason rendering it is safe. It does name workspace paths,
so anyone screenshotting this pane for a bug report is showing their home directory; that is stated
in ADR 056's consequences.
Accessibility. The controls became icon-only but keep accessible names through
IconButton'srequired
label. The log box is arole="log"region and the resize handle a focusablerole="separator"witharia-valuenow, so the height is reachable without a pointer. Matchhighlighting uses two new tokens derived from the accent at the same 14%/30% mixes the editor
already uses, chosen because
--color-selectedreads at about 1.2:1 and WCAG 1.4.11 asks 3:1.Tests. 2062 passing. New suites for the tail parser, the stream, the breadcrumb path and the
search;
typecheck,lintandformat:checkclean.