feat(web): annotations + mode banner (NF-UI-6) #364

Merged
code-lead merged 1 commit from feat/336-nfui6-annotations-mode into main 2026-04-24 16:30:04 +00:00
Collaborator

Summary

  • Node-footer annotations on the flow canvas — 14 mutating / token-spending / async nodes now surface a glyph strip ( mutation, 💸 tokens, ⏱ async, 📉 rate_limited, 🔒 mutex, ☒ deprecated) with title-attribute tooltips explaining the concern.
  • Sticky 28 px mode banner above the canvas declares live / dry-run / replay / dry-run-local / off state from a new mocked flowsApi.getMode() endpoint (replaced by GET /flows/mode when NF-7 lands) with support for client-local overrides (replay / test-fire).
  • Annotation vocabulary lives on nodeRegistry[type].ui.annotations so every node type opts in without touching the canvas; layoutGraph + spawnNode both wire it in.

Test plan

  • bun x vitest run src/features/flows/ — 114 tests, all green (16 new across ModeBanner.test.tsx + FlowCanvas.annotations.test.tsx).
  • bun x turbo run typecheck — clean across all 4 packages.
  • bun x biome check . — 359 files, no issues.
  • Smoke-test on the desktop dashboard: open /flows/default.review-requested, confirm banner + annotations render.

Out of scope

  • ?run=<id> route-level wiring → NF-UI-7 (parallel branch — feeds bannerOverride="replay" + bannerRunId into the already-added FlowCanvasProps).
  • Test-fire toggle that flips the banner to dry-run-local → NF-UI-8.
  • Real GET /flows/mode endpoint → NF-7.

File-conflict note

NF-UI-7 is running in parallel on feat/337-nfui7-replay-runs and will also touch FlowCanvas.tsx + flowsApi.ts. This patch kept both edits minimal (annotation render + banner mount on FlowCanvas; getMode() only on flowsApi) so the rebase surface is small.

Closes #336

🤖 Generated with Claude Code

## Summary - Node-footer annotations on the flow canvas — 14 mutating / token-spending / async nodes now surface a glyph strip (⚡ mutation, 💸 tokens, ⏱ async, 📉 rate_limited, 🔒 mutex, ☒ deprecated) with `title`-attribute tooltips explaining the concern. - Sticky 28 px mode banner above the canvas declares `live` / `dry-run` / `replay` / `dry-run-local` / `off` state from a new mocked `flowsApi.getMode()` endpoint (replaced by `GET /flows/mode` when NF-7 lands) with support for client-local overrides (replay / test-fire). - Annotation vocabulary lives on `nodeRegistry[type].ui.annotations` so every node type opts in without touching the canvas; `layoutGraph` + `spawnNode` both wire it in. ## Test plan - [x] `bun x vitest run src/features/flows/` — 114 tests, all green (16 new across `ModeBanner.test.tsx` + `FlowCanvas.annotations.test.tsx`). - [x] `bun x turbo run typecheck` — clean across all 4 packages. - [x] `bun x biome check .` — 359 files, no issues. - [ ] Smoke-test on the desktop dashboard: open `/flows/default.review-requested`, confirm banner + annotations render. ## Out of scope - `?run=<id>` route-level wiring → NF-UI-7 (parallel branch — feeds `bannerOverride="replay"` + `bannerRunId` into the already-added `FlowCanvasProps`). - Test-fire toggle that flips the banner to `dry-run-local` → NF-UI-8. - Real `GET /flows/mode` endpoint → NF-7. ## File-conflict note NF-UI-7 is running in parallel on `feat/337-nfui7-replay-runs` and will also touch `FlowCanvas.tsx` + `flowsApi.ts`. This patch kept both edits minimal (annotation render + banner mount on FlowCanvas; `getMode()` only on flowsApi) so the rebase surface is small. Closes #336 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(web): annotations + mode banner (NF-UI-6)
All checks were successful
qa / qa (pull_request) Successful in 5m15s
qa / dockerfile (pull_request) Successful in 10s
0384013a43
Surface operational concerns directly on the flow canvas: each node's
footer strip now renders an icon per annotation ( mutation, 💸 tokens,
⏱ async, 📉 rate_limited, …) with hover-tooltip copy, and a sticky
28 px banner above the canvas declares live / dry-run / replay state so
the operator always knows whether saves take effect.

The annotation vocabulary lives on `nodeRegistry[type].ui.annotations`
so every node type can opt in without touching the canvas. Populated
the 14 mutating / token-spending / async node types per spec. The
banner's server mode comes from a new mocked `flowsApi.getMode()` until
NF-7 ships `GET /flows/mode`; client-local overrides (`replay` /
`dry-run-local`) let the route + NF-UI-8 flip the banner without a
server round-trip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
charles force-pushed feat/336-nfui6-annotations-mode from 0384013a43
All checks were successful
qa / qa (pull_request) Successful in 5m15s
qa / dockerfile (pull_request) Successful in 10s
to 8c7ad61de3
All checks were successful
qa / qa (pull_request) Successful in 5m16s
qa / dockerfile (pull_request) Successful in 8s
2026-04-24 16:19:32 +00:00
Compare
code-lead deleted branch feat/336-nfui6-annotations-mode 2026-04-24 16:30:04 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!364
No description provided.