Skip to content

feat(web): tool progress toasts + persist all per-screen state across navigation (#1414, #1417)#1420

Open
cliffhall wants to merge 3 commits into
v2/mainfrom
feat/1414-progress-toasts-persist-tool-state
Open

feat(web): tool progress toasts + persist all per-screen state across navigation (#1414, #1417)#1420
cliffhall wants to merge 3 commits into
v2/mainfrom
feat/1414-progress-toasts-persist-tool-state

Conversation

@cliffhall
Copy link
Copy Markdown
Member

@cliffhall cliffhall commented Jun 2, 2026

Closes #1414. Closes #1417.

This PR delivers two related pieces of v2 state-persistence work.

#1414 — Tool progress toasts

Incoming notifications/progress are surfaced as toasts (the v2 replacement for v1's always-visible "Server Notifications" shelf) so progress is visible while staying on the tool view. Toasts are keyed per progress stream and updated (not stacked) per tick so a chatty server doesn't flood the corner. The full history still lives in the History tab.

#1417 — Persist per-screen selection / search / filter / scroll across navigation

The screens unmount on tab switch, so all their local state used to be lost. This lifts every screen's session state into App as controlled props (controlled "dumb" components, per #1417), cleared only on disconnect (resetSessionScopedUiState) or an explicit user action — never on plain navigation.

Lifted per screen:

  • Tools — selected tool, form values, result (result/selection landed under Show tool progress notifications as toasts (and stop clearing tool selection/results on navigation) #1414), sidebar search
  • Prompts — selected prompt, argument values, submitted marker, search
  • Resources — selected resource/template URI, originating-template marker, search, accordion open-sections
  • Apps — selected app, form values, search (running/maximized stay local — they're tied to the live iframe/bridge that's torn down on unmount, so persisting the flag without its runtime would render a broken app)
  • Tasks — search + status filter
  • Logs — filter text + visible-level set
  • History — search + method filter
  • Network — filter text + visible-category set

The four sidebar *Controls became controlled for search; ResourceControls also controls accordion open-sections.

ScrolluseScrollMemory (a module-keyed hook) remembers each list's scroll offset across unmount/remount and is cleared on disconnect; wired into the Logs/History/Network/Tasks list panels and the Tools/Prompts/Apps sidebars. Pagination already persists (it lives in the App-level Paged*State managers), so no work was needed there.

Acceptance criteria (#1417)

Testing

  • npm run validate (format:check + lint + build + test:coverage) — passes; per-file coverage gate satisfied (1474 unit tests).
  • npm run test:storybook — 329 passed (controlled screens/controls got stateful story hosts).

🤖 Generated with Claude Code

…s navigation (#1414)

Surface incoming notifications/progress as toasts so the user can watch a
long-running tool's progress without leaving the tool view — the v2 replacement
for v1's always-visible "Server Notifications" shelf. Toasts are keyed by
progress stream and updated (not stacked) per tick so a chatty server updates
one toast rather than flooding the corner. Progress notifications still land in
the History tab via the existing transport-level tracking.

Companion change: lift the selected tool and its form values into App.tsx
alongside the already-lifted toolCallState, make ToolsScreen controlled, and
drop the clear-on-unmount effect. Leaving the Tools tab and returning now
preserves selection, inputs, and result. All three reset together on
disconnect via resetSessionScopedUiState, preserving the #1368/#1394 behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cliffhall cliffhall added the v2 Issues and PRs for v2 label Jun 2, 2026
@cliffhall
Copy link
Copy Markdown
Member Author

Tool progress in toast

Screenshot 2026-06-02 at 7 58 21 PM

cliffhall and others added 2 commits June 2, 2026 22:39
…on (#1417)

Lift every screen's selection, form, search, and filter state out of the
screen components into session-scoped state owned by App, passed down as
controlled props. The screens unmount on tab switch, so this is what keeps
the user's context in place when they navigate away and back within a live
session. State is cleared only on disconnect (resetSessionScopedUiState) or
an explicit user action — never on plain navigation.

Lifted per screen:
- Tools: sidebar search (selection/form/result were lifted in #1414)
- Prompts: selected prompt, argument values, submitted marker, search
- Resources: selected resource/template URI, originating-template marker,
  search, accordion open-sections
- Apps: selected app, form values, search (running/maximized stay local —
  they're tied to the live iframe/bridge that is torn down on unmount)
- Tasks: search + status filter
- Logs: filter text + visible-level set
- History: search + method filter
- Network: filter text + visible-category set

The four sidebar *Controls (Tool/Prompt/App/Resource) become controlled for
search; ResourceControls also controls accordion open-sections. Level/category
default maps move to logLevels.ts / fetchCategories.ts so the screen files
keep a single component export.

Pagination already persists (it lives in the App-level Paged*State managers),
so no work was needed there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ts (#1417)

Add useScrollMemory: a module-keyed hook that remembers a Mantine ScrollArea's
offset across unmount/remount (the screens unmount on tab switch). Scroll lives
in a module-scope map rather than threaded App state — it's ephemeral DOM state,
and threading ~16 more props would balloon the surface for no benefit. App calls
clearScrollMemory() in resetSessionScopedUiState so offsets clear on disconnect
alongside the lifted selection/filter state.

Wired into the four main list panels (Logs, History, Network, Tasks) and the
Tools/Prompts/Apps sidebar lists. Pagination already persists via the App-level
Paged*State managers.

Tests: useScrollMemory unit test (save/restore, key isolation, clear), and the
App disconnect test now also exercises representative lifted UI state (tool
search, prompt selection, log filter) clearing on disconnect.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cliffhall cliffhall changed the title feat(web): tool progress toasts + persist tool selection/result across navigation (#1414) feat(web): tool progress toasts + persist all per-screen state across navigation (#1414, #1417) Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Issues and PRs for v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant