CPLAT-12457: add Scratchpad to the daily Produced pane - #170
Merged
Merged
Conversation
The day pane offered All / PRs / Jira / Artifacts / Plans, so the files a
day's sessions actually worked in were invisible at the day level — even
though OutputScratchpad already exists as a kind and the per-session
Outputs digest lists it.
Two things were missing, not one. buildDayOutputRows only reads Refs and
PlanSlugs, both of which the session scan already carries, so adding the
tab alone would have produced a permanently empty one.
Scratchpad is different from the other kinds: it lives on disk and costs
a directory walk per session. Measured across the 25 real scratchpads on
this machine, that is 129ms total and 62ms for the worst single one. A
day can hold 250+ sessions and buildDayOutputRows runs on every cursor
move, tab switch and query keystroke, so collecting inline would stall
the pane on every interaction.
It is therefore dispatched off the UI thread and cached per session ID:
- the pane renders immediately from whatever is cached, and rows fill
in as walks land
- fan-out is capped at 8 in flight, with the remainder picked up as
each completion re-renders the pane — that is what lets a busy day
finish collecting without dispatching hundreds of walks at once
- results survive walking away and back, so re-visiting a date is free
collectScratchpadOutputs is exported as session.ScratchpadOutputs for
this.
Rows carry Path and the session anchor, so Enter (open the conversation),
e (open in $EDITOR) and the copy action all work with no extra wiring.
The walk already reports a cloned repository as one row instead of
descending into it, so the 6,805-file scratchpad measured here collapses
to two rows and the digest stays readable.
Four tests, each verified by reverting the relevant part and confirming
the failure: collection and async arrival, tab filtering, row
actionability, and the fan-out bound.
TestDailyPreviewShowsDaySummary asserted cmd == nil as a proxy for "the
pane is instant". That proxy no longer holds — background enrichment is
now dispatched — but the property it was protecting does, so it asserts
the content is fully rendered on return instead.
|
| Commit | Scanned at | New | Resolved | Net |
|---|---|---|---|---|
d0583fd < |
2026-09-29 07:45 UTC | 0 | 0 | 0 |
Last scanned: d0583fd · 2026-09-29 07:45 UTC
|
| Commit | Scanned at | New | Resolved | Net |
|---|---|---|---|---|
d0583fd < |
2026-09-29 07:45 UTC | 0 | 0 | 0 |
Last scanned: d0583fd · 2026-09-29 07:45 UTC
Kairo-Kim
approved these changes
Sep 29, 2026
10 tasks done
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.
JIRA: https://sendbird.atlassian.net/browse/CPLAT-12457
The daily view's Produced pane offered
All / PRs / Jira / Artifacts / Plans, so the files a day's sessions actually worked in were invisible at the day level — even thoughOutputScratchpadalready exists as a kind and the per-session Outputs digest lists it.Two things were missing, not one
buildDayOutputRowsonly readsRefsandPlanSlugs, both of which the session scan already carries. Adding the tab alone would have produced a permanently empty one — the data had to be collected too.Why it is collected asynchronously
A scratchpad is a directory walk per session. Measured across the 25 real scratchpads on this machine: 129ms total, 62ms for the worst single one. A day can hold 250+ sessions, and
buildDayOutputRowsruns on every cursor move, tab switch and query keystroke — collecting inline would stall the pane on every interaction.So it is dispatched off the UI thread and cached per session ID:
collectScratchpadOutputsis exported assession.ScratchpadOutputsfor this.Notes
Rows carry
Pathand the session anchor, soEnter(open the conversation),e(open in$EDITOR) and the copy action all work with no extra wiring — verified in a test rather than assumed.The walk already reports a cloned repository as one row instead of descending into it, so the 6,805-file scratchpad measured here collapses to two rows and the digest stays readable.
Test plan
go build ./... && go vet ./... && go test ./...greenTestDayPaneCollectsScratchpad— rows appear only after the walk lands (also asserts they are absent before, so the async path is real)TestDayPaneScratchpadTabFilters— All interleaves kinds; the Scratchpad tab shows only scratchpadTestDayPaneScratchpadRowIsActionable—Pathand session anchor present, edit/copy offeredTestDayPaneScratchpadCollectionIsBounded— cap respected, and a later render dispatches the next batch rather than re-dispatchingOne test assertion changed — please check this
TestDailyPreviewShowsDaySummaryassertedcmd == nil, as a proxy for "the day pane is instant, no transcript reads". That proxy no longer holds, since background enrichment is now dispatched. The property it was protecting — the pane is fully rendered by the time the call returns — does still hold, so the test now asserts that directly.I want a second pair of eyes on that: it is the one place where I relaxed an existing guarantee's wording, and I would rather be told I got it wrong than have it slip through.
Security checklist
0.0.0.0/0inbound