feat(ag-ui): App-mode promo hero in sidebar mode#737
Conversation
Marketing surface for sidebar mode (App mode off): a preview-led poster with a static Paris map backdrop, Threadplane capability pills (client tools, generative UI, human-in-the-loop, shared state), and a CTA that enables App mode. Replaces the placeholder launcher hint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5 tasks: TDD component (hasMapsKey input / enable output), wire into SidebarMode under the existing gate, e2e (key-independent), static map image with dark fallback + sips processing, verify + ship. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Final-review nits: add an (error) handler so a missing/404 map image hides cleanly to the dark fallback (no broken-image badge on the demo surface), and remove the color/font-size left on .sidebar-mode__background by the deleted launcher hint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @blove's task in 2m 0s —— View job PR Review: feat(ag-ui): App-mode promo hero in sidebar mode
SummaryClean, well-scoped addition. The component is properly isolated (no shell coupling via DI), OnPush with signal inputs/outputs, a11y-aware (real Two minor observations (inline comments posted):
Everything else looks solid:
Result: LGTM with one minor test suggestion. The follow-up for the static map asset ( |
| src="/app-mode-preview.webp" | ||
| alt="Preview of the App-mode map cockpit" | ||
| loading="lazy" | ||
| (error)="promoImg.style.display = 'none'" |
There was a problem hiding this comment.
The direct DOM mutation in the error handler works and avoids a unnecessary component state property for this purely-visual side effect, so this is fine. One thing to be aware of: if the component is destroyed and re-created (e.g. after the @if gate toggles), the style.display = 'none' is gone and the broken image request fires again. Because the image URL is a static asset that either exists or doesn't, this is unlikely to be observed in practice, but if the asset lands later the behavior self-corrects on re-render. No action needed — just documenting the invariant.
| expect(el.querySelectorAll('.promo__pill').length).toBe(4); | ||
| const cta = el.querySelector('.promo__cta') as HTMLButtonElement | null; | ||
| expect(cta).toBeTruthy(); | ||
| expect(cta!.disabled).toBe(false); |
There was a problem hiding this comment.
Consider adding a companion assertion that the title attribute is absent (or empty) when the key is present — the current test only covers the false branch. A one-liner suffices:
| expect(cta!.disabled).toBe(false); | |
| expect(cta!.disabled).toBe(false); | |
| expect(cta!.hasAttribute('title')).toBe(false); |
Not blocking, but it closes the symmetry gap with the third test case.
What
Replaces the placeholder launcher hint in sidebar mode (App mode off) with a preview-led marketing hero that sells the App-mode map cockpit and the Threadplane primitives behind it, with a CTA that enables App mode.
AppModePromoComponent(modes/app-mode-promo.component.ts):hasMapsKeysignal input +enableoutput, OnPush, no shell coupling.object-fit: cover, dark fallback when absent) + an always-dark caption with a "Built with Threadplane" eyebrow, headline, four capability pills — Client tools, Generative UI, Human-in-the-loop, Shared state — and the primary CTA.SidebarModeunder the existing@if (shell.appMode() !== 'on')gate:[hasMapsKey]="shell.hasMapsKey",(enable)="shell.onAppModeChange('on')".GOOGLE_MAPS_API_KEYto enable" note (mirrors the toolbar toggle).<button>, focus-visible ring,aria-hiddenicons,prefers-reduced-motiongate,(error)guard hides a missing image to the dark fallback.Spec:
docs/superpowers/specs/2026-06-25-ag-ui-app-mode-promo-design.mdPlan:
docs/superpowers/plans/2026-06-25-ag-ui-app-mode-promo.mdVerification
enable; no-key disables CTA + shows note + title).app-mode-promo.spec.ts(promo visible in sidebar mode)./sidebar?appmode=oncockpit (map + overlay), promo gone.Follow-up (not blocking)
examples/ag-ui/angular/public/app-mode-preview.webp(drop the raw PNG; I'll resize/convert viasips). Until then the component shows its dark fallback — layout intact, no broken-image badge.🤖 Generated with Claude Code