feat(export): wire History + Logs export JSON handlers (#1354)#1367
Conversation
Replaces the `todoNoop` placeholders in App.tsx with real handlers that serialize the current entries and trigger a browser download via the existing `downloadJsonFile` helper. - Adds `buildExportFilename(kind, serverId, now?)` next to the download helper. Produces sortable, filesystem-safe names like `inspector-history-alpha-2026-03-17T10-00-42.123Z.json` (URL-encodes server ids that contain slashes / spaces / colons, swaps `:` for `-` in the ISO timestamp so the file is safe on Windows). - Wires `onExportHistory` (full MessageEntry list) and `onExportLogs` (the LogEntryData list the screen renders). - Routes the existing Network export through the same filename helper for consistency. Unit tests cover the filename builder, including the no-server-id fallback, special-character encoding, and the default-`now` shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@claude review |
|
Claude finished @cliffhall's task in 2m 2s —— View job Code Review
Overall this is a clean, tightly-scoped PR. The three handlers mirror each other, the helper is well-documented, and the test coverage is solid for the new surface. The Network handler being switched over to the shared helper is a nice consistency win on top of the stated scope. A few notes below — none are blockers. Findings1.
export type ExportKind = "history" | "logs" | "network";
export function buildExportFilename(
kind: ExportKind,
serverId: string | undefined,
now: Date = new Date(),
): string { ... }Genuinely minor — drop if you prefer to keep the helper as a generic primitive. Fix this → 2.
3. Empty-string
4. No handler-level tests —
Things I checked and was happy with
VerdictLGTM with the optional |
- Introduce an `ExportKind = "history" | "logs" | "network"` union and use it as the type of the `kind` parameter. Typos like "hisotry" now fail at compile time and the supported export kinds are documented inline. - Clarify the JSDoc: the segment is omitted when `serverId` is falsy (undefined OR empty string), matching the existing `serverId ? ... : undefined` check. New test pins the empty-string branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Thanks for the review! Responses inline, addressed in 49c1150. #1 #2 #3 Empty-string #4 No handler-level App.tsx tests — Acknowledged, no change. The new |
|
@claude review |
|
Claude finished @cliffhall's task in 1m 5s —— View job Code Review — follow-up to 49c1150
Tight, focused follow-up commit. Both of the actionable items from the prior review are addressed cleanly; the two acknowledged-only items are reasonable to leave for later. No blockers, no new findings. Verification of prior-review responses#1 — #2 — #3 — Empty-string #4 — Handler-level App.tsx tests ✅ Acknowledged-only, no change. Consistent with the existing coverage approach for Spot-checks on this commit
VerdictLGTM, ready to merge once the manual smoke test (last unchecked box in the PR description: connect → exercise calls + logging → click Export on each screen → verify JSON re-opens) is done. Nothing in the review-feedback round needs another pass. |
Export now produces the same JSON the Copy All button used to dump to the clipboard, so the button is redundant. History and Network panels have no equivalent — dropping Copy All also brings Logs into parity. Removes the prop from LogStreamPanel + LoggingScreen + InspectorView + App.tsx, and updates the matching tests/stories. Tests now assert the button is *not* in the document so a future re-introduction would have to update the assertion deliberately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Closes #1354.
Replaces the
todoNoopplaceholders for History / Logs export with real handlers that serialize the current in-memory entries to JSON and trigger a browser download via the existingdownloadJsonFilehelper. Also routes the Network export through the same filename helper for consistency.Filename
New
buildExportFilename(kind, serverId, now?)helper next todownloadJsonFile. Produces sortable, filesystem-safe names like:```
inspector-history-alpha-2026-03-17T10-00-42.123Z.json
inspector-logs-alpha-2026-03-17T10-00-42.123Z.json
inspector-network-alpha-2026-03-17T10-00-42.123Z.json
```
/, spaces,:etc. (since ids are user-supplied):for-in the ISO timestamp so the filename is safe on WindowsExport shapes
MessageEntryobjects (direction, timestamp, message, response, duration). Full structured data for offline review.LogEntryDataobjects (thenotifications/messageentries the screen consumes). Same shape the UI renders.FetchRequestEntryobjects (unchanged from Surface backend-side HTTP fetch log in a Network screen #1355).All three skip the download when the source list is empty (matches the disabled-button state in the panels).
Test plan
npm run validate— 1811 unit + integration tests passnpm run test:storybook— 320 stories passbuildExportFilenametests cover: kind + server id + ISO swap, undefined server id fallback, special-character encoding, default-nowshapeOut of scope (per the issue)