fabro/docs/superpowers
Bryan Helmkamp 9201ef9fe6
Some checks are pending
Rust / Clippy (push) Waiting to run
Rust / Format (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
TypeScript / Build (push) Waiting to run
feat(web): add Ask Fabro assistant page (#334)
## Summary

Adds `/ask-fabro`, a prototype route that brings the right-docked "Ask
Fabro" assistant into the real web app. It graduates the sidebar design
from the `docs/superpowers/prototypes/2026-05-16-chats-new` prototype: a
placeholder workspace page with an "Ask Fabro" trigger that toggles an
animated 420px docked panel. The panel streams scripted, **fake** AI
replies through assistant-ui — no real model calls — matching the
behavior of the existing `/chats` prototype.

## What changed

- **`routes/ask-fabro.tsx`** — the route. A placeholder "Runs" workspace
(stat cards + recent-runs list) whose only job is to host the trigger
button, plus the docked sidebar. Uses `handle = { hideHeader,
fullHeight, wide }` and the edge-bleed wrapper copied from the shipping
`chats-layout`.
- **`components/chats/ask-fabro-sidebar.tsx`** — animated-width 420px
assistant panel rendering assistant-ui's `<Thread>`.
- **`components/chats/sidebar-composer.tsx`** — compact single-line
composer pill for the narrow column.
- **`app.css`** — the `.ask-fabro-sidebar` CSS block (narrow-column
overrides, layered into `assistant-ui` to beat its unlayered defaults),
ported verbatim from the prototype.
- **`router.tsx`** — registers the route under the AppShell.

The components and CSS are faithful, near-verbatim ports of the
prototype, which was carefully constructed. The runtime is fully reused
— `chats-runtime`, `chats-script`, `chats-types`, and `tool-fallback`
already graduated with `/chats`, so this PR adds no new chat plumbing.

## Decisions

- **Route-local state, not context.** The prototype used an app-level
`AskFabroContext` so the sidebar could mount above the top nav. This
route is self-contained, so a plain `useState` passed as props is
simpler and equivalent.
- **Sidebar sits below the top nav** (within the route), rather than
spanning the full window like the prototype. Intentional — keeps the
route self-contained.
- **Not added to the nav.** Reachable directly at `/ask-fabro`; it is
not `demoOnly`, so it renders regardless of demo mode.

## Verification

- `bun run typecheck`, `bun test` (403 pass), and `bun run build` all
clean.
- Rendered side-by-side against the prototype's `/sample`: empty state
and active thread (user bubble + streamed markdown assistant reply)
match.

---

[![Compound Engineering
v2.60.0](https://img.shields.io/badge/Compound_Engineering-v2.60.0-6366f1)](https://github.com/EveryInc/compound-engineering-plugin)
🤖 Generated with Claude Opus 4.7 (1M context, extended thinking) via
[Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 21:11:54 -04:00
..
plans feat(server): add run pairing API (#312) 2026-05-20 18:58:38 -04:00
specs feat(fabro-web): port /chats/new + /chats/:id from prototype (#289) 2026-05-16 17:10:16 -04:00