Skip to content

Embed plan review surface and fix cross-surface issues#758

Open
backnotprop wants to merge 11 commits into
feat/frontend-code-review-surfacefrom
feat/frontend-plan-review-surface
Open

Embed plan review surface and fix cross-surface issues#758
backnotprop wants to merge 11 commits into
feat/frontend-code-review-surfacefrom
feat/frontend-plan-review-surface

Conversation

@backnotprop
Copy link
Copy Markdown
Owner

Summary

Layer 7 in the daemon stack. Embeds the plan review component alongside the code review, covering all five session modes (plan, review, annotate, archive, goal-setup). Also fixes cross-surface issues discovered during adversarial review.

  • 9 missed shared UI components migrated to useSessionFetch — Settings, InlineMarkdown, AttachmentsButton, ExportModal, HooksTab, GoalSetupSurface, PlanDiffViewer, useLinkedDoc. Plus window.__PLANNOTATOR_API_BASE__ set in SessionProvider for <img src> paths.
  • Plan review fetch + providers — 10 fetch calls shadowed, ThemeProvider/TooltipProvider/Toaster stripped, PlanAppEmbedded exported with headerLeft prop
  • Silent draft auto-restoreuseAnnotationDraft rewritten with onRestore callback (same as code review). Restore dialog removed, toast notification added.
  • Keyboard shortcut cross-fire fixed — Both surfaces add visibility guards (getComputedStyle(rootRef).visibility) to all window/document keyboard listeners. Hidden surfaces no longer respond to shortcuts.
  • CSS cleanup — Duplicate Tailwind build stripped from plan review CSS. Dead .animate-in/.fade-in classes removed from code review CSS (conflicted with tailwindcss-animate).
  • SessionSurface simplifiedreview → ReviewAppEmbedded, everything else → PlanAppEmbedded

Stack

Layer PR Branch
L1 #733 feat/single-server-runtime
L2 #734 feat/plannotator-daemon-runtime
L3 #738 feat/runtime-frontend-shell
L4 #744 feat/websocket-event-hub
L5 #753 feat/frontend-initial-view
L6 #755 feat/frontend-code-review-surface
L7 this feat/frontend-plan-review-surface

Test plan

  • bun run dev:frontend — daemon + frontend start
  • Code review still works (no regression)
  • Plan review renders — approve/deny buttons, annotations, sidebar, sharing all work
  • Annotate mode renders (if testable)
  • Archive mode renders
  • Navigate between plan + code review sessions — keep-alive works, keyboard shortcuts only fire on visible surface
  • Mod+Enter on code review does NOT trigger plan review submit
  • Draft auto-restores silently with toast on page refresh
  • bun run --cwd apps/frontend check passes
  • bun run typecheck passes
  • bun test — 1,463 pass, 0 fail

8 component/hook files in packages/ui/ still had bare fetch('/api/...')
calls that weren't caught during the code review migration:

- Settings.tsx, InlineMarkdown.tsx, AttachmentsButton.tsx, ExportModal.tsx
- settings/HooksTab.tsx, goal-setup/GoalSetupSurface.tsx
- plan-diff/PlanDiffViewer.tsx, hooks/useLinkedDoc.ts

Also set window.__PLANNOTATOR_API_BASE__ in SessionProvider so
non-hook consumers (apiPath for <img src> in ImageThumbnail) get
session-scoped paths.
Rewrite useAnnotationDraft with onRestore callback pattern (same as
useCodeAnnotationDraft). Legacy tuple format preserved. Toast on
restore. ConfirmDialog removed from plan review App.tsx.
Strip ThemeProvider, TooltipProvider, Toaster when __embedded.
h-full instead of h-screen. headerLeft prop passed through to
AppHeader for sidebar trigger. App.d.ts type declaration added.
When keep-alive hides a surface with visibility:hidden, its keyboard
listeners on window/document stay active. Without guards, Mod+Enter
on the visible code review would also fire the hidden plan review's
submit handler.

Both App.tsx files now check getComputedStyle(rootRef).visibility
at the start of every keyboard handler. If hidden, return early.
All session modes now render production surfaces:
- review → ReviewAppEmbedded
- plan, annotate, archive, goal-setup → PlanAppEmbedded

Added @plannotator/plan-review dependency, Vite aliases, and styles.
SessionSurface simplified — review gets code review, everything else
gets plan review (which determines its mode from /api/plan response).
@backnotprop backnotprop force-pushed the feat/frontend-plan-review-surface branch from 1322905 to b0d3534 Compare May 19, 2026 16:23
… mode

When running inside the frontend app (__embedded), the CompletionOverlay
blocked the entire viewport including the sidebar. Now:
- Embedded surfaces show a CompletionBanner (colored bar below the header)
- Action buttons hide after submission (plan review hides via AppHeader
  submitted prop, code review hides via !submitted guard)
- Standalone mode keeps the original full-screen overlay with auto-close
- No window.close() fires in embedded mode since useAutoClose lives
  inside CompletionOverlay which is skipped
@backnotprop backnotprop force-pushed the feat/frontend-plan-review-surface branch 2 times, most recently from 6255fa5 to 7d2a626 Compare May 19, 2026 17:31
The daemon now serves the production frontend HTML (apps/frontend/) at
session URLs. The debug frontend is only loaded when PLANNOTATOR_DEBUG_SHELL=1,
read from disk at runtime — never bundled in the compiled binary.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant