Skip to content

ADE Code TUI: kill drawer flicker + marketing site refresh#594

Merged
arul28 merged 3 commits into
mainfrom
ade/annoyin-flicker-c0ee62d3
Jun 16, 2026
Merged

ADE Code TUI: kill drawer flicker + marketing site refresh#594
arul28 merged 3 commits into
mainfrom
ade/annoyin-flicker-c0ee62d3

Conversation

@arul28

@arul28 arul28 commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Two workstreams. (Scope corrected — this lane does not touch chat persistence, lanes.suggestName, multi-question approvals, or iOS; those were phantom deletions from diffing against a drifted local main.)

ADE Code (TUI) — kill drawer flicker

  • Single-line lane cards so selecting a lane only adds a violet border (no row reflow = no flicker); a shared ChatRow renders the expanded + compact chat lists identically; drop the CHATS header and timestamps.
  • stableInkViewportRows reserves a row to avoid Ink-5 full-screen clears; terminal-preview frame dedup (sameTerminalPreviewFrame); visible-only PTY buffering (shouldBufferPtyDataForSession) with bounded flush rates.
  • Provider glyphs/colors synced 1:1 to the model picker; per-draft notice scoping (draft:N); simplified cross-terminal mouse baseline; modified-key word-backspace; grid Tab escapes to side panes.

Web — marketing refresh

  • PNG → WebP image migration; HomePage editorial restructure into FeatureGrid / ShipShowcase; new OgImage /_og card; vercel.json cache headers for images/videos; brand + demo media assets.

Ran /quality + /test: 716 TUI tests green, web typecheck clean. Will sync main (which advanced past this lane's fork point) — keeping main's recent work and dropping this lane's now-stale macOS-VM badge code per main's Remove macOS VM support.

Greptile Summary

  • Updates the ADE Code TUI drawer with single-line lane cards, shared chat row rendering, terminal preview deduping, visible-session PTY buffering, draft-scoped notices, and grid navigation changes.
  • Refreshes the marketing site with new editorial sections, WebP media assets, cache headers, and an /_og preview route.
  • Adds or updates tests and documentation around the drawer layout, app input behavior, media, and ADE Code usage.

Confidence Score: 2/5

Merge safety is reduced by runtime regressions in terminal buffering and grid resizing, plus a smaller marketing lightbox playback issue.

The main concerns affect visible ADE Code terminal behavior during common navigation and constrained-layout flows, so the branch should be fixed before merging.

apps/ade-cli/src/tuiClient/app.tsx and apps/web/src/components/editorial/FeatureGrid.tsx

T-Rex T-Rex Logs

What T-Rex did

  • The verification for hidden terminals lose output was reproduced; ran a focused Node harness simulating the app PTY data handler for a Claude terminal in a hidden grid tile; observed shouldBufferPtyDataForSession returning false and no data buffered.
  • Validated grid resize behavior by running a focused Node harness that mirrors single-view and grid PTY resize effects; observed normal one-tile resize calls with the expected tile dimensions, and in the small-terminal two-tile fallback, canRenderMultiChatGrid was false and no resize happened.
  • Opened and evaluated the real UI lightbox autoplay flow via Playwright; the lightbox opened and the expanded video paused at currentTime 0, with autoplay=true but play() failing.
  • Saved before/after command captures and reviewed trex-artifacts; no contract mismatch was observed because the changed code paths did not execute sufficiently to compare lane card rendering or related UI aspects.
  • Captured before/after screenshots and Playwright logs from trex-artifacts; the head log reported ADE — Agentic Development Environment, FeatureGrid/ShipShowcase checks true, webpCount=26, and failedMedia=[].
  • Inspected OG route and caching behavior; before/after logs show OG_ROUTE false to true and OG_COMPONENT_FILE/OG_COMPONENT_EXPORT becoming true, with media requests returning 200 for image/webp and cache headers configured as CONFIG_CACHE_HEADERS_OK=true.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. apps/ade-cli/src/tuiClient/app.tsx, line 13637-13650 (link)

    P1 Fallback grid skips resize

    This resize effect returns when the grid cannot render multiple tiles, but the single-view resize effect also returns while gridViewActive is true. In a one-tile grid, or on a small terminal where MultiChatGrid falls back to rendering one tile, no code resizes the terminal PTY to the tile size. The terminal can keep its previous dimensions, which makes wrapping and preview rows wrong for the visible tile.

    Artifacts

    Repro: focused resize-effect harness

    • Contains supporting evidence from the run (text/javascript; charset=utf-8).

    Repro: failing harness output with expected and observed resize calls

    • Keeps the command output available without making the summary code-heavy.

    Repro: focused Vitest harness attempted before falling back to Node execution

    • Contains supporting evidence from the run (text/typescript; charset=utf-8).

    View artifacts

    T-Rex Ran code and verified through T-Rex

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/ade-cli/src/tuiClient/app.tsx
    Line: 13637-13650
    
    Comment:
    **Fallback grid skips resize**
    
    This resize effect returns when the grid cannot render multiple tiles, but the single-view resize effect also returns while `gridViewActive` is true. In a one-tile grid, or on a small terminal where `MultiChatGrid` falls back to rendering one tile, no code resizes the terminal PTY to the tile size. The terminal can keep its previous dimensions, which makes wrapping and preview rows wrong for the visible tile.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
apps/ade-cli/src/tuiClient/app.tsx:6970-6977
**Hidden terminals lose output**

This branch drops `pty_data` events for terminal sessions unless they are currently active or visible in the grid. When a Claude Code terminal keeps running after the user switches to another chat, lane, or hides a saved grid, its live output is discarded instead of retained for later replay. Returning to that terminal can show stale or incomplete output because `TerminalPane` depends on `terminalLiveChunks` for incremental xterm updates, and existing grid tiles are not rehydrated when `toggleGridView` flips the grid back on. Please keep a bounded buffer for hidden terminals, or mark them dirty and force a fresh preview/rehydration before rendering them again.

### Issue 2 of 3
apps/ade-cli/src/tuiClient/app.tsx:13637-13650
**Fallback grid skips resize**

This resize effect returns when the grid cannot render multiple tiles, but the single-view resize effect also returns while `gridViewActive` is true. In a one-tile grid, or on a small terminal where `MultiChatGrid` falls back to rendering one tile, no code resizes the terminal PTY to the tile size. The terminal can keep its previous dimensions, which makes wrapping and preview rows wrong for the visible tile.

### Issue 3 of 3
apps/web/src/components/editorial/FeatureGrid.tsx:271-280
**Lightbox autoplay fails**

The expanded demo video uses `autoPlay`, but unlike the tile videos it is not muted. Browsers commonly block autoplay for media that may have audio, so clicking a demo can open the lightbox with a poster or blank frame instead of starting playback. Add `muted` here as well, or remove `autoPlay` and require the user to press play.

```suggestion
        <video
          key={demo.video}
          src={demo.video}
          poster={demo.poster}
          autoPlay
          muted
          loop
          controls
          playsInline
          className="block max-h-[78vh] w-full rounded-[4px] border border-white/10 bg-black shadow-[0_40px_120px_-40px_rgba(0,0,0,0.9)]"
        />
```

Reviews (1): Last reviewed commit: "fix(ci+review): commit README hero asset..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ade Ready Ready Preview, Comment Jun 16, 2026 11:41pm

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@arul28, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 15 minutes and 38 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fc86a276-0833-4ae6-88f1-5576da092c89

📥 Commits

Reviewing files that changed from the base of the PR and between bb261c7 and a62d103.

⛔ Files ignored due to path filters (68)
  • README.md is excluded by !*.md
  • apps/web/public/images/ade-dock-icon.png is excluded by !**/*.png
  • apps/web/public/images/ade-wordmark.png is excluded by !**/*.png
  • apps/web/public/images/competitors/claude-code.png is excluded by !**/*.png
  • apps/web/public/images/competitors/codex.png is excluded by !**/*.png
  • apps/web/public/images/competitors/conductor.png is excluded by !**/*.png
  • apps/web/public/images/competitors/cursor.png is excluded by !**/*.png
  • apps/web/public/images/competitors/factory.png is excluded by !**/*.png
  • apps/web/public/images/competitors/github.png is excluded by !**/*.png
  • apps/web/public/images/competitors/opencode.png is excluded by !**/*.png
  • apps/web/public/images/competitors/paperclip.png is excluded by !**/*.png
  • apps/web/public/images/competitors/superset.png is excluded by !**/*.png
  • apps/web/public/images/competitors/t3-code.png is excluded by !**/*.png
  • apps/web/public/images/features/agent-chat.png is excluded by !**/*.png
  • apps/web/public/images/features/automations.png is excluded by !**/*.png
  • apps/web/public/images/features/cto.png is excluded by !**/*.png
  • apps/web/public/images/features/files.png is excluded by !**/*.png
  • apps/web/public/images/features/git-history.png is excluded by !**/*.png
  • apps/web/public/images/features/lanes.png is excluded by !**/*.png
  • apps/web/public/images/features/linear-sync.png is excluded by !**/*.png
  • apps/web/public/images/features/modelconfig.png is excluded by !**/*.png
  • apps/web/public/images/features/multi-tasking.png is excluded by !**/*.png
  • apps/web/public/images/features/prs.png is excluded by !**/*.png
  • apps/web/public/images/features/run.png is excluded by !**/*.png
  • apps/web/public/images/features/terminals.png is excluded by !**/*.png
  • apps/web/public/images/features/workspacegraph.png is excluded by !**/*.png
  • apps/web/public/images/hero/hero-desktop.png is excluded by !**/*.png
  • apps/web/public/images/hero/hero-mobile.png is excluded by !**/*.png
  • apps/web/public/images/hero/hero-tui.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/Screenshot 2026-04-02 at 2.10.22 PM.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/Screenshot 2026-04-02 at 2.13.22 PM.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/agent-chat.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/cto.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/files copy.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/files.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/git history.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/lanes.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/linear-sync.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/mobile-pr.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/mobile-worktrees.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/multi-tasking.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/prs.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/run.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/workspacegraph.png is excluded by !**/*.png
  • apps/web/public/images/secondPage/lanesDesktop.png is excluded by !**/*.png
  • apps/web/public/images/secondPage/lanesMobile.png is excluded by !**/*.png
  • apps/web/public/images/secondPage/lanesTUI.png is excluded by !**/*.png
  • apps/web/public/og-image.png is excluded by !**/*.png
  • apps/web/public/videos/adecodeDemo.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/autocreateLane.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/browserInspect.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/creatingPRfromChat.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/graphsTab.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/gridViewDemo.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/linearConnection.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/remoteConnect.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/subagentsDemo.mp4 is excluded by !**/*.mp4
  • assets/readme/ade-code-tui.gif is excluded by !**/*.gif, !assets/**
  • assets/readme/auto-worktrees.gif is excluded by !**/*.gif, !assets/**
  • assets/readme/cto.webp is excluded by !assets/**
  • assets/readme/grid-view.gif is excluded by !**/*.gif, !assets/**
  • assets/readme/hero-desktop.png is excluded by !**/*.png, !assets/**
  • assets/readme/hero-iphone.png is excluded by !**/*.png, !assets/**
  • assets/readme/hero.png is excluded by !**/*.png, !assets/**
  • assets/readme/mobile-chat.webp is excluded by !assets/**
  • assets/readme/mobile-pr.webp is excluded by !assets/**
  • assets/readme/pr-review.webp is excluded by !assets/**
  • assets/readme/worktree-graph.webp is excluded by !assets/**
📒 Files selected for processing (65)
  • apps/ade-cli/src/tuiClient/__tests__/Drawer.test.tsx
  • apps/ade-cli/src/tuiClient/__tests__/appInput.test.ts
  • apps/ade-cli/src/tuiClient/__tests__/drawerLayout.test.ts
  • apps/ade-cli/src/tuiClient/app.tsx
  • apps/ade-cli/src/tuiClient/components/Drawer.tsx
  • apps/ade-cli/src/tuiClient/drawerLayout.ts
  • apps/ade-cli/src/tuiClient/theme.ts
  • apps/ade-cli/src/tuiClient/types.ts
  • apps/web/public/images/ade-dock-icon.webp
  • apps/web/public/images/competitors/claude-code.webp
  • apps/web/public/images/competitors/codex.webp
  • apps/web/public/images/competitors/conductor.webp
  • apps/web/public/images/competitors/cursor.webp
  • apps/web/public/images/competitors/factory.webp
  • apps/web/public/images/competitors/github.webp
  • apps/web/public/images/competitors/opencode.webp
  • apps/web/public/images/competitors/paperclip.webp
  • apps/web/public/images/competitors/superset.webp
  • apps/web/public/images/competitors/t3-code.webp
  • apps/web/public/images/hero/hero-desktop.webp
  • apps/web/public/images/hero/hero-mobile.webp
  • apps/web/public/images/hero/hero-tui.webp
  • apps/web/public/images/screenshots/agent-chat.webp
  • apps/web/public/images/screenshots/cto.webp
  • apps/web/public/images/screenshots/lanes.webp
  • apps/web/public/images/screenshots/mobile-pr.webp
  • apps/web/public/images/screenshots/mobile-worktrees.webp
  • apps/web/public/images/screenshots/prs.webp
  • apps/web/public/images/screenshots/run.webp
  • apps/web/public/images/secondPage/chatDesktop.webp
  • apps/web/public/images/secondPage/chatMobile.webp
  • apps/web/public/images/secondPage/chatModelPicker.webp
  • apps/web/public/images/secondPage/chatTui.webp
  • apps/web/public/images/secondPage/lanesDesktop.webp
  • apps/web/public/images/secondPage/lanesMobile.webp
  • apps/web/public/images/secondPage/lanesTUI.webp
  • apps/web/public/images/secondPage/prDesktop.webp
  • apps/web/public/images/secondPage/prMobile.webp
  • apps/web/public/images/secondPage/workBrowser.webp
  • apps/web/public/images/secondPage/workFiles.webp
  • apps/web/public/images/secondPage/workGit.webp
  • apps/web/public/videos/adecodeDemo.webp
  • apps/web/public/videos/autocreateLane.webp
  • apps/web/public/videos/browserInspect.webp
  • apps/web/public/videos/creatingPRfromChat.webp
  • apps/web/public/videos/graphsTab.webp
  • apps/web/public/videos/gridViewDemo.webp
  • apps/web/public/videos/linearConnection.webp
  • apps/web/public/videos/remoteConnect.webp
  • apps/web/public/videos/subagentsDemo.webp
  • apps/web/src/app/SiteRoutes.tsx
  • apps/web/src/app/layout/SiteLayout.tsx
  • apps/web/src/app/pages/HomePage.tsx
  • apps/web/src/components/OgImage.tsx
  • apps/web/src/components/editorial/AnnotatedFigure.tsx
  • apps/web/src/components/editorial/BackCover.tsx
  • apps/web/src/components/editorial/CompetitorEquation.tsx
  • apps/web/src/components/editorial/Cutout.tsx
  • apps/web/src/components/editorial/DeviceComposition.tsx
  • apps/web/src/components/editorial/FeatureGrid.tsx
  • apps/web/src/components/editorial/HeroAgentBadges.tsx
  • apps/web/src/components/editorial/IPhoneFrame.tsx
  • apps/web/src/components/editorial/ShipShowcase.tsx
  • apps/web/src/components/ui/HeroVisual.tsx
  • apps/web/vercel.json
📝 Walkthrough

Walkthrough

Two independent workstreams: the TUI CLI drawer is simplified (single-row LaneCard/ChatRow, removal of hasDiffRow, headerless chat layout, increased chat cap), with new app.tsx helpers for PTY buffering, preview frame deduplication, draft-scoped notices, and Tab navigation. Separately, the web landing page gains an OgImage component/route, rewrites FeatureGrid as a video demo catalog with a lightbox, extends ShipShowcase with new composition types, trims HomePage to hero + catalog, and migrates all hero assets to .webp.

Changes

TUI CLI: Drawer layout, app helpers, and rendering

Layer / File(s) Summary
Drawer layout types and budgeting logic
apps/ade-cli/src/tuiClient/drawerLayout.ts
Removes hasDiffRow from DrawerLaneInput/DrawerLanePlan, increases DRAWER_COMPACT_CHAT_CAP (3→12), reduces CARD_BASE_ROWS (5→4), reworks visibleDrawerChatCount to 1-row-per-chat plus 1 footer, updates computeDrawerLayout to ignore selection for sizing, and rewrites drawerMouseHitForLayout hit geometry for the new row model.
New exported helpers in app.tsx
apps/ade-cli/src/tuiClient/app.tsx, apps/ade-cli/src/tuiClient/types.ts, apps/ade-cli/src/tuiClient/theme.ts
Adds stableInkViewportRows, shouldBufferPtyDataForSession, gridTabNavigationTarget, sameTerminalPreviewFrame, noticeScopeId, and selectVisibleNotices as exported pure functions with PTY flush timing constants; updates LocalNotice scope-field docs; aligns provider brand glyphs/colors to model picker marks.
Drawer component: LaneCard, ChatRow, CompactChatPreview, MiniDrawer
apps/ade-cli/src/tuiClient/components/Drawer.tsx
Removes age/timestamp helpers and sessionProviderFor; drops hasDiffRow from lane input; rewrites LaneCard to a single-line row with a right-side diff/rebasing/no-worktree cluster; introduces ChatRow as a shared single-row component; updates ChatBlock to use ChatRow and render "worktree missing" directly; updates CompactChatPreview without "+ new chat"; simplifies MiniDrawer width calculations.
app.tsx: PTY buffering, preview dedup, viewport rows, mouse tracking
apps/ade-cli/src/tuiClient/app.tsx
Applies stableInkViewportRows at init; adds ptyFlushDelayRef/scheduleFlush for reschedulable PTY flush with separate attached/preview delays; gates pty_data buffering via shouldBufferPtyDataForSession; guards all setTerminalPreview and tile preview hydration with sameTerminalPreviewFrame; refactors mouse tracking to explicit enable/disable sequences; varies diff-stats polling cadence with chatRefreshPollActive.
app.tsx: Draft-scoped notice isolation
apps/ade-cli/src/tuiClient/app.tsx
Adds draftScopeKey state, a monotonic counter ref, and a scope key ref; setDraftChatMode mints or clears scope key on entry/exit; addNotice tags each notice via noticeScopeId; rendering switches to selectVisibleNotices.
app.tsx: Tab navigation, prompt backspace, dependency wiring
apps/ade-cli/src/tuiClient/app.tsx
Extends isPromptWordBackspace with kitty/escape-based modified delete variants; routes Tab handling and right-footer tile-next through gridTabNavigationTarget; adds cyclePaneFocus/rightOpen to affected dependency arrays.
Tests: drawerLayout, Drawer, appInput
apps/ade-cli/src/tuiClient/__tests__/drawerLayout.test.ts, apps/ade-cli/src/tuiClient/__tests__/Drawer.test.tsx, apps/ade-cli/src/tuiClient/__tests__/appInput.test.ts
Updates drawerLayout and Drawer tests for new row geometry and inline diff stats; adds appInput coverage for all new helper exports including notice scoping, PTY buffering, preview frame equality, grid Tab navigation, extended backspace sequences, and mouse tracking sequences.

Web: OgImage route, FeatureGrid video catalog, ShipShowcase, asset migration

Layer / File(s) Summary
OgImage component and /_og routing
apps/web/src/components/OgImage.tsx, apps/web/src/app/SiteRoutes.tsx, apps/web/src/app/layout/SiteLayout.tsx
Adds a 1200×630 OgImage component with background gradients, competitor equation, headline, device trio, and SVG annotations; registers /_og route; extends SiteLayout's chrome-skip to include /_og.
FeatureGrid: video demo catalog with DemoTile and Lightbox
apps/web/src/components/editorial/FeatureGrid.tsx, apps/web/src/app/pages/HomePage.tsx
Replaces the static card grid with Demo/DEMOS data, DemoTile (IntersectionObserver autoplay preview video), and Lightbox (fullscreen video with Escape/backdrop/button dismissal and body scroll lock); HomePage is stripped to hero + FeatureGrid catalog.
ShipShowcase: composition types, new tab layouts, framer-motion progress bar
apps/web/src/components/editorial/ShipShowcase.tsx
Introduces Shot shape and ChatShots/PrShots/ToolsShots; extends ShowcaseTab with new composition fields; adds ChatComposition/PrComposition/WorkToolsComposition render components; replaces interval/reducer progress bar with keyed framer-motion scaleX animation; simplifies auto-advance to useEffect setTimeout.
Animation updates, .webp asset migration, and caching config
apps/web/src/components/editorial/..., apps/web/src/components/ui/HeroVisual.tsx, apps/web/vercel.json, media/README.md
Switches all hero/editorial image sources to .webp; replaces blur filter entrance animations with y-slide/fade (duration 0.9→0.7) in AnnotatedFigure, Cutout, and IPhoneFrame; updates HeroAgentBadges badge positions; adds Vercel immutable Cache-Control headers for /images/* and /videos/*; adds media/README.md documenting library conventions.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • arul28/ADE#325: Both PRs refactor Drawer.tsx lane/chat row rendering and update Drawer.test.tsx assertions around diff-line and selection behavior.
  • arul28/ADE#555: Both PRs rework drawerLayout.ts row-budget and hit-testing contracts and update Drawer.tsx to match the revised layout model.

Suggested labels

web

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.93% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main changes: eliminating drawer flicker in the ADE Code TUI and refreshing the marketing website, which are the primary focuses of the PR across multiple modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/annoyin-flicker-c0ee62d3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@arul28 arul28 changed the title Annoyin Flicker ADE Code TUI flicker fix + chat-transcript simplification + marketing refresh Jun 16, 2026
@arul28

arul28 commented Jun 16, 2026

Copy link
Copy Markdown
Owner Author

@copilot review but do not make fixes

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/web/src/components/editorial/ShipShowcase.tsx (1)

706-719: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Incomplete ARIA tab pattern is misleading for keyboard/screen-reader users.

Line 706 and Line 716 declare tab semantics, but the required tab-panel linkage/keyboard behavior is missing. Either fully implement the tabs pattern or use plain button-group semantics.

Suggested minimal fix (use button-group semantics instead of partial tabs)
-          <div
-            role="tablist"
-            aria-label="Product walkthrough"
-            className="flex flex-wrap gap-2 sm:gap-3"
-          >
+          <div
+            role="group"
+            aria-label="Product walkthrough"
+            className="flex flex-wrap gap-2 sm:gap-3"
+          >
@@
-                role="tab"
-                aria-selected={selected}
+                aria-pressed={selected}
                 onClick={() => selectTab(index)}

As per coding guidelines, "apps/web/**: Web app — check for accessibility, SSR compatibility, and proper React patterns."

Also applies to: 761-773

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/editorial/ShipShowcase.tsx` around lines 706 - 719,
The ShipShowcase component declares incomplete ARIA tab semantics with
role="tablist" on the parent container and role="tab" on individual buttons, but
lacks the required aria-controls linkage to tab-panels and keyboard navigation
behavior, which is misleading for accessibility. Replace the incomplete tab
pattern with simple button-group semantics by removing the role="tablist" from
the parent container and the role="tab" and aria-selected attributes from
individual buttons in the map function, keeping the aria-label on the parent for
context. This approach applies to both the main tab button group (around line
706-719) and the secondary tab group (around line 761-773).

Source: Coding guidelines

apps/ade-cli/src/tuiClient/app.tsx (1)

6927-6971: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid rebinding the PTY stream on refreshState churn.

This subscription uses replay: false, so tearing it down whenever refreshState changes can drop live pty_data emitted during the resubscribe gap. Use the existing refreshStateRef for pty_exit and keep the effect keyed to connection.

Proposed fix
       }
       if (payload.type === "pty_exit") {
-        void refreshState({ hydrateHistory: false }).catch(() => undefined);
+        void refreshStateRef.current({ hydrateHistory: false }).catch(() => undefined);
       }
@@
-  }, [connection, refreshState]);
+  }, [connection]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ade-cli/src/tuiClient/app.tsx` around lines 6927 - 6971, The effect that
subscribes to runtime events with `replay: false` is being torn down and rebound
whenever the `refreshState` function changes (due to its presence in the
dependency array), which causes live pty_data events to be dropped during the
resubscribe gap. Instead of calling `refreshState` directly in the pty_exit
handler, use a ref called `refreshStateRef` to access the function, and remove
`refreshState` from the effect's dependency array. Keep the effect keyed only to
`connection` so the subscription persists across refreshState changes and
prevents losing emitted events during resubscription.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ade-cli/src/tuiClient/app.tsx`:
- Around line 532-559: In the noticeScopeId function, reorder the conditional
checks to prioritize draft scope by checking args.draftChatActive and
args.draftScopeKey before checking args.activeSessionId, ensuring draft notices
take precedence. In the selectVisibleNotices function, add validation when
args.draftChatActive is true to reject the case where args.draftScopeKey is
null, preventing global notices from being matched. Ensure that only notices
with the exact draft scope key are returned when in draft chat mode, with no
fallback to global notices.

In `@apps/web/src/components/editorial/FeatureGrid.tsx`:
- Around line 200-257: The Lightbox component uses proper modal semantics with
role="dialog" and aria-modal="true", but lacks focus management required for
accessible modals. Within the useEffect hook in the Lightbox function, capture
the currently focused element before the dialog opens so it can be restored
later. Then move focus into the dialog when it mounts (typically to the close
button). Implement focus trapping to prevent keyboard navigation from leaving
the dialog to background elements while it is open. Finally, restore focus to
the previously focused element in the cleanup function alongside the existing
removeEventListener and overflow restoration code.

In `@apps/web/vercel.json`:
- Around line 3-16: The Cache-Control headers for both the "/videos/(.*)" and
"/images/(.*)" source patterns include the "immutable" directive, which is
unsafe without content-hashed asset filenames as it forces browsers to cache
assets indefinitely. Remove the "immutable" directive from the Cache-Control
values in both patterns while keeping "public, max-age=31536000", allowing
browsers to eventually revalidate or clear stale assets after expiration rather
than serving them indefinitely after deployment updates.

---

Outside diff comments:
In `@apps/ade-cli/src/tuiClient/app.tsx`:
- Around line 6927-6971: The effect that subscribes to runtime events with
`replay: false` is being torn down and rebound whenever the `refreshState`
function changes (due to its presence in the dependency array), which causes
live pty_data events to be dropped during the resubscribe gap. Instead of
calling `refreshState` directly in the pty_exit handler, use a ref called
`refreshStateRef` to access the function, and remove `refreshState` from the
effect's dependency array. Keep the effect keyed only to `connection` so the
subscription persists across refreshState changes and prevents losing emitted
events during resubscription.

In `@apps/web/src/components/editorial/ShipShowcase.tsx`:
- Around line 706-719: The ShipShowcase component declares incomplete ARIA tab
semantics with role="tablist" on the parent container and role="tab" on
individual buttons, but lacks the required aria-controls linkage to tab-panels
and keyboard navigation behavior, which is misleading for accessibility. Replace
the incomplete tab pattern with simple button-group semantics by removing the
role="tablist" from the parent container and the role="tab" and aria-selected
attributes from individual buttons in the map function, keeping the aria-label
on the parent for context. This approach applies to both the main tab button
group (around line 706-719) and the secondary tab group (around line 761-773).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8cbeacdb-574c-49ae-86b1-dd7c9a2131a5

📥 Commits

Reviewing files that changed from the base of the PR and between 6637b86 and bb261c7.

⛔ Files ignored due to path filters (92)
  • README.md is excluded by !*.md
  • apps/web/public/images/ade-dock-icon.png is excluded by !**/*.png
  • apps/web/public/images/ade-wordmark.png is excluded by !**/*.png
  • apps/web/public/images/competitors/claude-code.png is excluded by !**/*.png
  • apps/web/public/images/competitors/codex.png is excluded by !**/*.png
  • apps/web/public/images/competitors/conductor.png is excluded by !**/*.png
  • apps/web/public/images/competitors/cursor.png is excluded by !**/*.png
  • apps/web/public/images/competitors/factory.png is excluded by !**/*.png
  • apps/web/public/images/competitors/github.png is excluded by !**/*.png
  • apps/web/public/images/competitors/opencode.png is excluded by !**/*.png
  • apps/web/public/images/competitors/paperclip.png is excluded by !**/*.png
  • apps/web/public/images/competitors/superset.png is excluded by !**/*.png
  • apps/web/public/images/competitors/t3-code.png is excluded by !**/*.png
  • apps/web/public/images/features/agent-chat.png is excluded by !**/*.png
  • apps/web/public/images/features/automations.png is excluded by !**/*.png
  • apps/web/public/images/features/cto.png is excluded by !**/*.png
  • apps/web/public/images/features/files.png is excluded by !**/*.png
  • apps/web/public/images/features/git-history.png is excluded by !**/*.png
  • apps/web/public/images/features/lanes.png is excluded by !**/*.png
  • apps/web/public/images/features/linear-sync.png is excluded by !**/*.png
  • apps/web/public/images/features/modelconfig.png is excluded by !**/*.png
  • apps/web/public/images/features/multi-tasking.png is excluded by !**/*.png
  • apps/web/public/images/features/prs.png is excluded by !**/*.png
  • apps/web/public/images/features/run.png is excluded by !**/*.png
  • apps/web/public/images/features/terminals.png is excluded by !**/*.png
  • apps/web/public/images/features/workspacegraph.png is excluded by !**/*.png
  • apps/web/public/images/hero/hero-desktop.png is excluded by !**/*.png
  • apps/web/public/images/hero/hero-mobile.png is excluded by !**/*.png
  • apps/web/public/images/hero/hero-tui.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/Screenshot 2026-04-02 at 2.10.22 PM.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/Screenshot 2026-04-02 at 2.13.22 PM.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/agent-chat.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/cto.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/files copy.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/files.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/git history.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/lanes.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/linear-sync.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/mobile-pr.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/mobile-worktrees.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/multi-tasking.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/prs.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/run.png is excluded by !**/*.png
  • apps/web/public/images/screenshots/workspacegraph.png is excluded by !**/*.png
  • apps/web/public/images/secondPage/lanesDesktop.png is excluded by !**/*.png
  • apps/web/public/images/secondPage/lanesMobile.png is excluded by !**/*.png
  • apps/web/public/images/secondPage/lanesTUI.png is excluded by !**/*.png
  • apps/web/public/og-image.png is excluded by !**/*.png
  • apps/web/public/videos/adecodeDemo.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/autocreateLane.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/browserInspect.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/creatingPRfromChat.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/graphsTab.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/gridViewDemo.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/linearConnection.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/remoteConnect.mp4 is excluded by !**/*.mp4
  • apps/web/public/videos/subagentsDemo.mp4 is excluded by !**/*.mp4
  • assets/readme/ade-code-tui.gif is excluded by !**/*.gif, !assets/**
  • assets/readme/auto-worktrees.gif is excluded by !**/*.gif, !assets/**
  • assets/readme/cto.webp is excluded by !assets/**
  • assets/readme/grid-view.gif is excluded by !**/*.gif, !assets/**
  • assets/readme/hero-desktop.png is excluded by !**/*.png, !assets/**
  • assets/readme/hero-iphone.png is excluded by !**/*.png, !assets/**
  • assets/readme/mobile-chat.webp is excluded by !assets/**
  • assets/readme/mobile-pr.webp is excluded by !assets/**
  • assets/readme/pr-review.webp is excluded by !assets/**
  • assets/readme/worktree-graph.webp is excluded by !assets/**
  • docs/features/ade-code/README.md is excluded by !docs/**
  • media/demos/ade-code-tui.gif is excluded by !**/*.gif
  • media/demos/adecodeDemo.mp4 is excluded by !**/*.mp4
  • media/demos/auto-worktrees.gif is excluded by !**/*.gif
  • media/demos/autocreateLane.mp4 is excluded by !**/*.mp4
  • media/demos/browserInspect.mp4 is excluded by !**/*.mp4
  • media/demos/creatingPRfromChat.mp4 is excluded by !**/*.mp4
  • media/demos/graphsTab.mp4 is excluded by !**/*.mp4
  • media/demos/grid-view.gif is excluded by !**/*.gif
  • media/demos/gridViewDemo.mp4 is excluded by !**/*.mp4
  • media/demos/linearConnection.mp4 is excluded by !**/*.mp4
  • media/demos/remoteConnect.mp4 is excluded by !**/*.mp4
  • media/demos/subagentsDemo.mp4 is excluded by !**/*.mp4
  • media/logos/models/anthropic.svg is excluded by !**/*.svg
  • media/logos/models/claude-color.svg is excluded by !**/*.svg
  • media/logos/models/cohere-color.svg is excluded by !**/*.svg
  • media/logos/models/deepseek-color.svg is excluded by !**/*.svg
  • media/logos/models/gemini-color.svg is excluded by !**/*.svg
  • media/logos/models/grok.svg is excluded by !**/*.svg
  • media/logos/models/meta-color.svg is excluded by !**/*.svg
  • media/logos/models/mistral-color.svg is excluded by !**/*.svg
  • media/logos/models/ollama.svg is excluded by !**/*.svg
  • media/logos/models/openai.svg is excluded by !**/*.svg
  • media/logos/models/perplexity-color.svg is excluded by !**/*.svg
  • media/logos/models/qwen-color.svg is excluded by !**/*.svg
📒 Files selected for processing (128)
  • apps/ade-cli/src/tuiClient/__tests__/Drawer.test.tsx
  • apps/ade-cli/src/tuiClient/__tests__/appInput.test.ts
  • apps/ade-cli/src/tuiClient/__tests__/drawerLayout.test.ts
  • apps/ade-cli/src/tuiClient/app.tsx
  • apps/ade-cli/src/tuiClient/components/Drawer.tsx
  • apps/ade-cli/src/tuiClient/drawerLayout.ts
  • apps/ade-cli/src/tuiClient/theme.ts
  • apps/ade-cli/src/tuiClient/types.ts
  • apps/web/public/images/ade-dock-icon.webp
  • apps/web/public/images/competitors/claude-code.webp
  • apps/web/public/images/competitors/codex.webp
  • apps/web/public/images/competitors/conductor.webp
  • apps/web/public/images/competitors/cursor.webp
  • apps/web/public/images/competitors/factory.webp
  • apps/web/public/images/competitors/github.webp
  • apps/web/public/images/competitors/opencode.webp
  • apps/web/public/images/competitors/paperclip.webp
  • apps/web/public/images/competitors/superset.webp
  • apps/web/public/images/competitors/t3-code.webp
  • apps/web/public/images/hero/hero-desktop.webp
  • apps/web/public/images/hero/hero-mobile.webp
  • apps/web/public/images/hero/hero-tui.webp
  • apps/web/public/images/screenshots/agent-chat.webp
  • apps/web/public/images/screenshots/cto.webp
  • apps/web/public/images/screenshots/lanes.webp
  • apps/web/public/images/screenshots/mobile-pr.webp
  • apps/web/public/images/screenshots/mobile-worktrees.webp
  • apps/web/public/images/screenshots/prs.webp
  • apps/web/public/images/screenshots/run.webp
  • apps/web/public/images/secondPage/chatDesktop.webp
  • apps/web/public/images/secondPage/chatMobile.webp
  • apps/web/public/images/secondPage/chatModelPicker.webp
  • apps/web/public/images/secondPage/chatTui.webp
  • apps/web/public/images/secondPage/lanesDesktop.webp
  • apps/web/public/images/secondPage/lanesMobile.webp
  • apps/web/public/images/secondPage/lanesTUI.webp
  • apps/web/public/images/secondPage/prDesktop.webp
  • apps/web/public/images/secondPage/prMobile.webp
  • apps/web/public/images/secondPage/workBrowser.webp
  • apps/web/public/images/secondPage/workFiles.webp
  • apps/web/public/images/secondPage/workGit.webp
  • apps/web/public/videos/adecodeDemo.webp
  • apps/web/public/videos/autocreateLane.webp
  • apps/web/public/videos/browserInspect.webp
  • apps/web/public/videos/creatingPRfromChat.webp
  • apps/web/public/videos/graphsTab.webp
  • apps/web/public/videos/gridViewDemo.webp
  • apps/web/public/videos/linearConnection.webp
  • apps/web/public/videos/remoteConnect.webp
  • apps/web/public/videos/subagentsDemo.webp
  • apps/web/src/app/SiteRoutes.tsx
  • apps/web/src/app/layout/SiteLayout.tsx
  • apps/web/src/app/pages/HomePage.tsx
  • apps/web/src/components/OgImage.tsx
  • apps/web/src/components/editorial/AnnotatedFigure.tsx
  • apps/web/src/components/editorial/BackCover.tsx
  • apps/web/src/components/editorial/CompetitorEquation.tsx
  • apps/web/src/components/editorial/Cutout.tsx
  • apps/web/src/components/editorial/DeviceComposition.tsx
  • apps/web/src/components/editorial/FeatureGrid.tsx
  • apps/web/src/components/editorial/HeroAgentBadges.tsx
  • apps/web/src/components/editorial/IPhoneFrame.tsx
  • apps/web/src/components/editorial/ShipShowcase.tsx
  • apps/web/src/components/ui/HeroVisual.tsx
  • apps/web/vercel.json
  • media/README.md
  • media/brand/ade-icon.webp
  • media/features/agent-chat/attach-issue.webp
  • media/features/agent-chat/chat-or-cli.webp
  • media/features/agent-chat/chat-tools-button.webp
  • media/features/agent-chat/choose-or-autocreate-lane.webp
  • media/features/agent-chat/grid-view.webp
  • media/features/agent-chat/launch-in-background.webp
  • media/features/agent-chat/model-selection.webp
  • media/features/agent-chat/multi-model-prompt.webp
  • media/features/agent-chat/new-chat-button.webp
  • media/features/agent-chat/run-orchestrator.webp
  • media/features/browser/browser-inspect.webp
  • media/features/cto/subagents.webp
  • media/features/files/choose-worktree.webp
  • media/features/files/preview-or-raw.webp
  • media/features/git/git-actions.webp
  • media/features/linear/linear-connection.webp
  • media/features/mobile/agent-chat.webp
  • media/features/mobile/pull-requests.webp
  • media/features/project/add-project-button.webp
  • media/features/project/add-project-options.webp
  • media/features/pull-requests/commits-section.webp
  • media/features/pull-requests/files-and-ci-checks.webp
  • media/features/pull-requests/make-new-pr.webp
  • media/features/pull-requests/pr-sources.webp
  • media/features/pull-requests/prs-sidebar.webp
  • media/features/pull-requests/rebase-options.webp
  • media/features/pull-requests/review-tab.webp
  • media/features/remote/remote-connect.webp
  • media/features/settings/provider-usage.webp
  • media/features/settings/settings-tab.webp
  • media/features/tui/ade-code.webp
  • media/features/worktrees/manage-lane-button.webp
  • media/features/worktrees/manage-lane-options.webp
  • media/features/worktrees/new-lane-button.webp
  • media/features/worktrees/new-lane-options.webp
  • media/features/worktrees/worktree-graph.webp
  • media/landing/hero/desktop.webp
  • media/landing/hero/mobile.webp
  • media/landing/hero/tui.webp
  • media/landing/showcase/agent-chat-desktop.webp
  • media/landing/showcase/agent-chat-mobile.webp
  • media/landing/showcase/agent-chat-model-picker.webp
  • media/landing/showcase/agent-chat-tui.webp
  • media/landing/showcase/pull-requests-desktop.webp
  • media/landing/showcase/pull-requests-mobile.webp
  • media/landing/showcase/work-tools-browser.webp
  • media/landing/showcase/work-tools-files.webp
  • media/landing/showcase/work-tools-git.webp
  • media/landing/showcase/worktrees-desktop.webp
  • media/landing/showcase/worktrees-mobile.webp
  • media/landing/showcase/worktrees-tui.webp
  • media/logos/competitors/claude-code.webp
  • media/logos/competitors/codex.webp
  • media/logos/competitors/conductor.webp
  • media/logos/competitors/cursor.webp
  • media/logos/competitors/factory.webp
  • media/logos/competitors/github.webp
  • media/logos/competitors/opencode.webp
  • media/logos/competitors/paperclip.webp
  • media/logos/competitors/superset.webp
  • media/logos/competitors/t3-code.webp

Comment thread apps/ade-cli/src/tuiClient/app.tsx
Comment on lines +200 to +257
function Lightbox({ demo, onClose }: { demo: Demo; onClose: () => void }) {
useEffect(() => {
const onKey = (e: KeyboardEvent) => {
if (e.key === "Escape") onClose();
};
window.addEventListener("keydown", onKey);
const prev = document.body.style.overflow;
document.body.style.overflow = "hidden";
return () => {
window.removeEventListener("keydown", onKey);
document.body.style.overflow = prev;
};
}, [onClose]);

return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.2 }}
role="dialog"
aria-modal="true"
aria-label={`${demo.label} demo`}
onClick={onClose}
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/80 p-[clamp(16px,4vw,64px)] backdrop-blur-md"
>
<motion.div
initial={{ scale: 0.96, y: 8 }}
animate={{ scale: 1, y: 0 }}
exit={{ scale: 0.97, y: 6 }}
transition={{ duration: 0.22, ease: [0.22, 1, 0.36, 1] }}
onClick={(e) => e.stopPropagation()}
className="relative w-full max-w-[1180px]"
>
<button
type="button"
onClick={onClose}
aria-label="Close"
className="absolute -top-11 right-0 flex items-center gap-1.5 text-[12px] uppercase tracking-[0.16em] text-white/70 transition-colors hover:text-white"
>
Close <X className="h-4 w-4" />
</button>
<video
key={demo.video}
src={demo.video}
poster={demo.poster}
autoPlay
loop
controls
playsInline
className="block max-h-[78vh] w-full rounded-[4px] border border-white/10 bg-black shadow-[0_40px_120px_-40px_rgba(0,0,0,0.9)]"
/>
<div className="mt-4 flex flex-wrap items-baseline gap-x-4 gap-y-1">
<h3 className="font-serif text-[22px] text-[color:var(--color-cream)]">{demo.label}</h3>
<p className="text-[14px] text-[color:var(--color-cream-muted)]">{demo.blurb}</p>
</div>
</motion.div>
</motion.div>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add focus containment and focus restoration for the lightbox dialog.

Line 215 adds modal semantics, but focus is neither moved into the dialog nor trapped there, so keyboard users can tab into background controls while the modal is open.

Suggested fix
 function Lightbox({ demo, onClose }: { demo: Demo; onClose: () => void }) {
+  const dialogRef = useRef<HTMLDivElement>(null);
+  const closeRef = useRef<HTMLButtonElement>(null);
+  const previousFocusRef = useRef<HTMLElement | null>(null);
+
   useEffect(() => {
+    previousFocusRef.current =
+      document.activeElement instanceof HTMLElement ? document.activeElement : null;
+    closeRef.current?.focus();
+
     const onKey = (e: KeyboardEvent) => {
-      if (e.key === "Escape") onClose();
+      if (e.key === "Escape") {
+        e.preventDefault();
+        onClose();
+        return;
+      }
+      if (e.key === "Tab") {
+        const root = dialogRef.current;
+        if (!root) return;
+        const focusables = root.querySelectorAll<HTMLElement>(
+          'button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"])'
+        );
+        if (!focusables.length) return;
+        const first = focusables[0];
+        const last = focusables[focusables.length - 1];
+        if (e.shiftKey && document.activeElement === first) {
+          e.preventDefault();
+          last.focus();
+        } else if (!e.shiftKey && document.activeElement === last) {
+          e.preventDefault();
+          first.focus();
+        }
+      }
     };
     window.addEventListener("keydown", onKey);
     const prev = document.body.style.overflow;
     document.body.style.overflow = "hidden";
     return () => {
       window.removeEventListener("keydown", onKey);
       document.body.style.overflow = prev;
+      previousFocusRef.current?.focus();
     };
   }, [onClose]);

   return (
     <motion.div
@@
-      <motion.div
+      <motion.div
+        ref={dialogRef}
         initial={{ scale: 0.96, y: 8 }}
         animate={{ scale: 1, y: 0 }}
         exit={{ scale: 0.97, y: 6 }}
@@
-        <button
+        <button
+          ref={closeRef}
           type="button"
           onClick={onClose}
           aria-label="Close"

As per coding guidelines, apps/web/**: Web app — check for accessibility, SSR compatibility, and proper React patterns.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/editorial/FeatureGrid.tsx` around lines 200 - 257,
The Lightbox component uses proper modal semantics with role="dialog" and
aria-modal="true", but lacks focus management required for accessible modals.
Within the useEffect hook in the Lightbox function, capture the currently
focused element before the dialog opens so it can be restored later. Then move
focus into the dialog when it mounts (typically to the close button). Implement
focus trapping to prevent keyboard navigation from leaving the dialog to
background elements while it is open. Finally, restore focus to the previously
focused element in the cleanup function alongside the existing
removeEventListener and overflow restoration code.

Source: Coding guidelines

Comment thread apps/web/vercel.json
Comment on lines +3 to +16
"headers": [
{
"source": "/videos/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
},
{
"source": "/images/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
}
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

immutable is unsafe here without fingerprinted asset filenames.

Line 7 and Line 13 apply year-long immutable browser caching to /images/* and /videos/*, but the site references stable names (not content-hashed), so media updates can remain stale client-side long after deploy.

Safer cache policy while preserving CDN performance
-        { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
+        { "key": "Cache-Control", "value": "public, max-age=0, s-maxage=31536000, must-revalidate" }
@@
-        { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
+        { "key": "Cache-Control", "value": "public, max-age=0, s-maxage=31536000, must-revalidate" }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"headers": [
{
"source": "/videos/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
},
{
"source": "/images/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
}
],
"headers": [
{
"source": "/videos/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=0, s-maxage=31536000, must-revalidate" }
]
},
{
"source": "/images/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=0, s-maxage=31536000, must-revalidate" }
]
}
],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/vercel.json` around lines 3 - 16, The Cache-Control headers for both
the "/videos/(.*)" and "/images/(.*)" source patterns include the "immutable"
directive, which is unsafe without content-hashed asset filenames as it forces
browsers to cache assets indefinitely. Remove the "immutable" directive from the
Cache-Control values in both patterns while keeping "public, max-age=31536000",
allowing browsers to eventually revalidate or clear stale assets after
expiration rather than serving them indefinitely after deployment updates.

ADE Code (TUI):
- Kill drawer flicker: single-line lane cards so selecting a lane only adds a
  violet border (no row reflow); a shared ChatRow renders the expanded + compact
  chat lists identically; drop the CHATS header and timestamps;
  stableInkViewportRows reserves a row to avoid Ink-5 full-screen clears;
  terminal-preview frame dedup; visible-only PTY buffering with bounded flush.
- Sync provider glyphs/colors 1:1 to the model picker; per-draft notice scoping
  (draft:N); simplified cross-terminal mouse baseline; modified-key word
  backspace; grid Tab escapes to side panes.

Web:
- PNG -> WebP image migration; HomePage editorial restructure into FeatureGrid /
  ShipShowcase; new OgImage /_og card; vercel cache headers for images/videos;
  brand + demo media assets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@arul28 arul28 changed the title ADE Code TUI flicker fix + chat-transcript simplification + marketing refresh ADE Code TUI: kill drawer flicker + marketing site refresh Jun 16, 2026
@arul28 arul28 force-pushed the ade/annoyin-flicker-c0ee62d3 branch from bb261c7 to 5f67639 Compare June 16, 2026 23:09
…0ee62d3

# Conflicts:
#	apps/ade-cli/src/tuiClient/components/Drawer.tsx
#	apps/web/src/components/editorial/ShipShowcase.tsx
@mintlify

mintlify Bot commented Jun 16, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
ade-ac1c6011 🟢 Ready View Preview Jun 16, 2026, 11:18 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

- assets/readme/hero.png: force-add the README hero image (gitignored as *.png,
  so validate-docs failed in CI on the missing target while passing locally).
  Matches the existing tracked-PNG pattern (og-image.png, logo.png).
- vercel.json: drop `immutable` for /images + /videos (stable, non-fingerprinted
  filenames) in favor of `max-age=0, s-maxage=31536000, must-revalidate` so the
  CDN still caches a year but browsers pick up media updates.
- FeatureGrid Lightbox: add modal focus containment + restoration (focus the
  close button on open, trap Tab inside the dialog, restore focus on close).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@arul28

arul28 commented Jun 16, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@arul28 arul28 merged commit 0b83d22 into main Jun 16, 2026
26 of 27 checks passed
@arul28 arul28 deleted the ade/annoyin-flicker-c0ee62d3 branch June 16, 2026 23:51

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a62d103839

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +6970 to +6974
if (!shouldBufferPtyDataForSession({
sessionId,
activeSessionId: activeSessionIdRef.current,
multiView: multiViewRef.current,
gridViewActive: gridViewActiveRef.current,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Refresh terminal tiles when resuming a hidden grid

When a Claude terminal is kept as a tile in a dormant grid (multiView exists but gridViewActive is false), this new guard drops every pty_data chunk. The resume paths I checked (toggleGridView only calls setGridView(true)) do not re-run hydrateTerminalTilePreview for existing terminal tiles, so hiding the grid while the terminal keeps running and then reopening it shows the stale seed/live buffer and misses all output produced while hidden.

Useful? React with 👍 / 👎.

const isHome = pathname === "/";
// HomePage renders its own editorial Masthead, and /_og is a bare
// 1200×630 card for screenshotting — both skip the global chrome.
const isHome = pathname === "/" || pathname === "/_og";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the homepage footer after removing BackCover

Because the refreshed HomePage no longer renders BackCover/IndexPage, keeping / inside isHome suppresses the only SiteFooter on the production homepage. Non-home routes still get the footer with Privacy/Terms/license links, but / now ends after FeatureGrid; either render the shared footer for / or add a replacement footer to the home page.

Useful? React with 👍 / 👎.

Comment on lines +4 to +5
* Social link-preview card, rendered at exactly 1200×630 and screenshotted to
* /og-image.png. Mirrors the site hero — the competitor equation, the headline,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 Badge Point the OG generator at the new card

This component is documented as the source for /og-image.png, but the checked-in generator still defaults to apps/web/scripts/og-image.html, whose image tags reference deleted .png assets such as images/competitors/claude-code.png and images/ade-dock-icon.png. Running scripts/generate-og-image.mjs after this asset conversion will regenerate a social card with broken logos instead of this new /_og route.

Useful? React with 👍 / 👎.

Comment on lines +6970 to +6977
if (!shouldBufferPtyDataForSession({
sessionId,
activeSessionId: activeSessionIdRef.current,
multiView: multiViewRef.current,
gridViewActive: gridViewActiveRef.current,
})) {
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Hidden terminals lose output

This branch drops pty_data events for terminal sessions unless they are currently active or visible in the grid. When a Claude Code terminal keeps running after the user switches to another chat, lane, or hides a saved grid, its live output is discarded instead of retained for later replay. Returning to that terminal can show stale or incomplete output because TerminalPane depends on terminalLiveChunks for incremental xterm updates, and existing grid tiles are not rehydrated when toggleGridView flips the grid back on. Please keep a bounded buffer for hidden terminals, or mark them dirty and force a fresh preview/rehydration before rendering them again.

Artifacts

Repro: focused hidden terminal PTY drop harness

  • Contains supporting evidence from the run (text/javascript; charset=utf-8).

Stack trace captured during the T-Rex run

  • Keeps the raw stack trace available without making the summary code-heavy.

Repro: Vitest-focused hidden terminal PTY drop test attempted

  • Contains supporting evidence from the run (text/typescript; charset=utf-8).

Repro Lightbox Autoplay Poster

  • Shows the rendered state that T-Rex checked.

▶ repro-lightbox-autoplay-video.webm

  • Shows the flow or interaction that T-Rex exercised.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/ade-cli/src/tuiClient/app.tsx
Line: 6970-6977

Comment:
**Hidden terminals lose output**

This branch drops `pty_data` events for terminal sessions unless they are currently active or visible in the grid. When a Claude Code terminal keeps running after the user switches to another chat, lane, or hides a saved grid, its live output is discarded instead of retained for later replay. Returning to that terminal can show stale or incomplete output because `TerminalPane` depends on `terminalLiveChunks` for incremental xterm updates, and existing grid tiles are not rehydrated when `toggleGridView` flips the grid back on. Please keep a bounded buffer for hidden terminals, or mark them dirty and force a fresh preview/rehydration before rendering them again.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

Comment on lines +271 to +280
<video
key={demo.video}
src={demo.video}
poster={demo.poster}
autoPlay
loop
controls
playsInline
className="block max-h-[78vh] w-full rounded-[4px] border border-white/10 bg-black shadow-[0_40px_120px_-40px_rgba(0,0,0,0.9)]"
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Lightbox autoplay fails

The expanded demo video uses autoPlay, but unlike the tile videos it is not muted. Browsers commonly block autoplay for media that may have audio, so clicking a demo can open the lightbox with a poster or blank frame instead of starting playback. Add muted here as well, or remove autoPlay and require the user to press play.

Suggested change
<video
key={demo.video}
src={demo.video}
poster={demo.poster}
autoPlay
loop
controls
playsInline
className="block max-h-[78vh] w-full rounded-[4px] border border-white/10 bg-black shadow-[0_40px_120px_-40px_rgba(0,0,0,0.9)]"
/>
<video
key={demo.video}
src={demo.video}
poster={demo.poster}
autoPlay
muted
loop
controls
playsInline
className="block max-h-[78vh] w-full rounded-[4px] border border-white/10 bg-black shadow-[0_40px_120px_-40px_rgba(0,0,0,0.9)]"
/>
Artifacts

Repro: Playwright script that opens the real FeatureGrid lightbox and evaluates the expanded video

  • Contains supporting evidence from the run (text/javascript; charset=utf-8).

Repro: command output showing autoplay=true, muted=false, paused=true, currentTime=0, and play() failure

  • Keeps the command output available without making the summary code-heavy.

▶ Screen recording from the T-Rex run

  • Shows the flow or interaction that T-Rex exercised.

Repro Lightbox Autoplay Poster

  • Shows the rendered state that T-Rex checked.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/src/components/editorial/FeatureGrid.tsx
Line: 271-280

Comment:
**Lightbox autoplay fails**

The expanded demo video uses `autoPlay`, but unlike the tile videos it is not muted. Browsers commonly block autoplay for media that may have audio, so clicking a demo can open the lightbox with a poster or blank frame instead of starting playback. Add `muted` here as well, or remove `autoPlay` and require the user to press play.

```suggestion
        <video
          key={demo.video}
          src={demo.video}
          poster={demo.poster}
          autoPlay
          muted
          loop
          controls
          playsInline
          className="block max-h-[78vh] w-full rounded-[4px] border border-white/10 bg-black shadow-[0_40px_120px_-40px_rgba(0,0,0,0.9)]"
        />
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

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