Skip to content

Plugin Guide v1: in-app plugin API docs with SDK-synced surface map - #2248

Open
brsbl wants to merge 71 commits into
mainfrom
bb/build-bb-plugin-api-docs-thr_7dczktandc
Open

Plugin Guide v1: in-app plugin API docs with SDK-synced surface map#2248
brsbl wants to merge 71 commits into
mainfrom
bb/build-bb-plugin-api-docs-thr_7dczktandc

Conversation

@brsbl

@brsbl brsbl commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds the built-in Plugin Guide (plugins/plugin-api-docs, rendering packages/plugin-api-map): an interactive, annotated map of every public plugin surface, drawn as the real bb UI. Each numbered annotation opens a capability card with the authoritative SDK symbols, first-party usage, and a Copy for agent action that pastes a structured, composable surface reference into the composer.

What's in it

  • Seven pages — app window, command palette, composer, home, settings, Extensions, backend — with 26 sequential annotations over realistic fixtures (real tab rows, menus, message actions, split panes).
  • Responsive by contract: the page list is the only horizontal scroller; every spatial fixture scales as one unit to fit the window and restores authored size up to a cap on large displays.
  • Copy for agent: each card writes Build a plugin that uses + a structured pill + . ; multiple copies paste as distinct, composable pills.
  • A committed public-SDK inventory plus api-sync.test.ts — CI fails if a public SDK export, app.slots.* method, or BbPluginApi property changes without a matching Guide surface.
  • The plugin-guide-maintenance skill ships with the plugin and encodes the fidelity/annotation/copy workflow.
  • Display name is Plugin Guide (Extensions already shows the BB Official tag); the id stays plugin-api-docs.
  • Layout derives, it isn't authored (follow-up commits e97545201..7e2ca90bf): one annotation placement system replaces seven mechanisms — chips take declared variants or measure the element they annotate, the engaged ring is the target's own styling, and transients anchor to what the real menu flips against. Pan carets hug the page list; the stage-to-card gap is clamp(8px, 3cqh, 28px); fixtures scale from both viewport axes up to a 1.3 cap (large displays render them proportionally larger); the 100dvh-minus-chrome guesses are gone. A committed relationship sweep (plugin-guide-maintenance/scripts/verify-guide-chrome.mjs) discovers every annotation at four viewport classes, reconciles against the declared inventory, and asserts relationships instead of exact pixels.

Review

One authorized final review ran on the cumulative branch; its P0/P1 findings are fixed in bc30d52cc, P2 notes are recorded as follow-ups and intentionally not implemented:

  • P0 — full-window /extensions/plugins/:pluginId rendered the plugins overview: the URL is owned by SplitWorkspaceRoute under path="*", so useParams never carried the id. ToolsView now takes an explicit pluginId prop; regression test added under the production catch-all mount.
  • P1 — the upgrade test pinned PLUGIN_SDK_VERSION to 0.4.18; it now asserts the relational contract (newer than the frozen fixture).
  • P1 — three composer highlight rings rendered ~22px below their targets (anchored in a wrapper containing the sub-composer strip); they now render inside the prompt box's own coordinate space.

Verification

Head 8a6bb0ac3 = review fixes + display-name rename + the layout-derivation overhaul + clean merges of current main (SDK 0.4.22 inventory regenerated; the Guide's AiBrowser icon mapped to an SF Symbol for the new mobile gate).

  • Tests: @bb/plugin-api-map 73/73 (incl. api-sync and the migrated structural annotation contracts), app routing 30/30, clipboard/paste/mention 120/120, server plugins 29/29 on Node 22; Turbo typechecks pass; exact-checkout plugin build passes.
  • Relationship sweep — PASS at the exact head across 390×844, 768×900, 1440×900, and 2030×1100: every rendered annotation in bounds and topmost, inventory reconciled, engaged rings on targets, transient clearances, caret adjacency ≤8px, scale within (0, 1.3] with zero page overflow, gap within its clamp, and the wide fill gate (record).
  • Chrome for Testing 151 — root-contracts PASS at candidate 8656827: all 7 pages and 26 cards, responsive states 390×844 → 3440×1440, sole-scroller and clearance contracts, highlight-ring geometry (each ring contains its target's center inside the prompt box), command-palette flow, and the full-window detail page. Later commits on the head are main-only merges (no UI/Guide files).
  • Safari 26.5.2 — responsive contract with hard reload and sustained motion, tab overlays, composer transients, highlight alignment, window fit (no horizontal overflow), and the full-window detail page PASS at bc30d52cc.
  • Records: Chrome root-contracts · Safari responsive · Safari review-fix

Screenshots

Wide display: the fixture fills the grown content column, carets hug the page list, tab chips ride the measured lane Command palette: a plugin action over a realistic thread
Full-size app-window page Command palette page
Composer: the engaged ring is the target's own box, chips measured from their targets Copy for agent: two composable pills with editable framing
Composer highlight ring Composable surface pills
Mobile (390×844): one-line page scroller, whole fixture fits Full-window plugin detail page (review fix, renamed)
Mobile responsive fixture Full-window plugin detail

No linked issue.

BB-Thread-ID: thr_7dczktandc

BB-Thread-ID: thr_7f4g7pd89a

BB-Thread-ID: thr_n5zzpc884f

AGENT GENERATED: by GPT-5.6-Sol

brsbl and others added 28 commits August 19, 2026 02:38
Documents the bb plugin API as an annotated map of the product plus the
generated reference behind it.

- apps/web/scripts/generate-plugin-api-docs.mjs parses the SDK's committed
  bundled declarations into a committed model; --check fails when stale.
- packages/plugin-api-map holds the surface inventory, the bb UI skeletons,
  and the annotation cards, shared so the docs page and the in-app plugin
  cannot disagree about what bb can be extended with.
- plugins/plugin-api-docs renders that map inside bb as a nav panel, with the
  host's real composer embedded in the composer and home diagrams.
- The docs page leads with the reference; the diagram sits below it as a
  supporting explainer.
- An anatomy manifest pins the skeletons to the real app component order, and
  apps/app's docs-anatomy-manifest test fails when the app reorders.
- apps/web route changes animate through the View Transition API, content
  only, with reduced motion falling back to an instant swap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
These changes were already uncommitted in this worktree when the plugin API
docs work began and are unrelated to it: blog rendering, landing analytics
and endpoints, connect/auth routes, server token handling, and small web UI
primitive tweaks. Committed separately so they can be reviewed or dropped on
their own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The bb Plugin Guide (plugins/plugin-api-docs, rendering
packages/plugin-api-map) becomes bb's only plugin API documentation:
six slides — annotated skeletons of the app window, composer, home,
settings, and Extensions plugin pages, plus a backend capability grid —
with a reviewed card per surface, cross-references, and "Used by" links.
packages/plugin-api-map/test/api-sync.test.ts fails the build when the
map and the SDK drift apart; the apps/web docs route, generated API
model, and generator are deleted in its favor.

Host and SDK changes the guide rides on, all additive:
- experimental_suppressPluginUi on experimental_NewThreadComposer,
  plumbed through the new-thread prompt box path, so an embedded
  composer can render without other plugins' composer UI (a prompt
  improver's action was landing inside the diagrams and rewriting the
  persisted example draft).
- Route anchors inside plugin UI navigate client-side; links to a
  plugin's Extensions page open it beside the current pane.
- New plugin-detail pane kind so a plugin's Extensions page can live in
  a split; ordinary navigation to it stays full-window.
- Plugin CSS is awaited before registrations publish, removing the
  unstyled first-paint flash on plugin load and reload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-ready-thr_kg7xb7qipg

# Conflicts:
#	apps/web/src/styles.css
…l-fixes-thr_7f4g7pd89a

# Conflicts:
#	apps/app/package.json
#	pnpm-lock.yaml
brsbl added a commit that referenced this pull request Aug 24, 2026
brsbl and others added 30 commits August 25, 2026 04:25
Review of the cumulative Plugin Guide branch found three defects:

- P0: the full-window /extensions/plugins/:pluginId page rendered the
  plugins overview instead of the detail page. SplitWorkspaceRoute owns
  that URL under a path="*" route, so ToolsView's useParams() could
  never see the plugin id. ToolsView now takes the id as an explicit
  prop (like PluginDetailPaneView already does) and SplitWorkspaceRoute
  passes the id it derives from the URL. Regression test added under
  the production catch-all mount.
- P1: the persisted-0.4.8-scaffold upgrade test pinned
  PLUGIN_SDK_VERSION to 0.4.18 and failed against main's 0.4.20. The
  assertion is now relational (newer than the frozen fixture), which is
  what the upgrade test actually means.
- P1: the composer-plus-menu, provider-picker, and composer-actions
  highlight rings were authored in the prompt box's coordinate space
  but rendered in a wrapper whose bottom edge is the sub-composer
  strip, landing ~22px below their targets. The rings now render inside
  the prompt box's own relative context in StaticEmbeddedComposer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Extensions page already labels the plugin BB Official, so the bb
prefix in the display name was redundant. The plugin id, package, and
route (plugin-api-docs) are unchanged; only the user-visible name, the
mention label, the clipboard pill context, and the maintenance-skill
heading change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…y-thr_6n85axkwev

# Conflicts:
#	apps/app/src/components/ui/app-route-anchor.tsx
- Add the fidelity sources wireframes.test.ts and maintenance-skill.test.ts
  actually read (ThreadDetailView.tsx, plugins/plugin-api-docs/**) to the
  @bb/plugin-api-map#test turbo inputs, so edits to them can no longer
  cache-hit a stale pass.
- Delete the dead ComposerWireframe export (replaced by
  RealComposerAnnotated; the package is private and it had no consumers).
- Reorder the flat headless surface array to match the rendered section
  order, so card Previous/Next never jumps between sections; assert order
  equality in surfaces.test.ts.
- Open a followed cross-reference's card on the pan's own transitionend
  (state-driven, superseded by any newer pan and cleaned up on unmount)
  instead of an uncancelled setTimeout that duplicated the CSS duration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collapse the Guide's seven annotation mechanisms into one placement
system with zero per-instance coordinates:

- Mark/RegionMark chips take a declared placement variant (corner,
  corner-inset, side, outside-above) from one CHIP_PLACEMENT_CLASS
  owner, replacing every authored chipClassName offset.
- MeasuredBadge replaces GuideBadge, OverlayMark, RightPanelTabBadge and
  its geometry-duplicating layer, and CommandPaletteActionBadge:
  exterior, lane, and floating chips measure the element they annotate
  (in layout coordinates, invariant under the scale-together transform)
  and derive their column from the window frame's own box.
- GuideHighlight is gone: the engaged ring is the target element's own
  styling, so it wraps content by construction. Content scripts tint
  the frame itself.
- The composer draft line renders in flow inside the prompt box (no
  hand-synced overlay/reservation pair), and both composer menus anchor
  to the element the real menu flips against instead of authored
  offsets.
- The app-shell fixture keeps one width owner (the gutter floor).

Static tests assert existence and placement declarations; runtime-
measured geometry is verified by the rendered QA sweep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The caret+label group shrink-wraps and centers as one unit, so the
  pan carets hug the page list and only reach the row's edges on real
  overflow. The scroller keeps sole horizontal-scroll ownership.
- One content-width token (the map column) sizes the column, stage, and
  card so their edges align, and grows on wide displays.
- The stage-to-card gap is clamp(8px, 3cqh, 28px), driven by the
  consumer-declared container on the plugin's scrollport; without a
  declared container the 8px floor holds.
- spatialFixtureScale derives from both axes with a 1.3 legibility cap:
  fixtures shrink under pressure and grow on roomy panels (the
  squished-on-large-displays fix). Available height is measured
  scroll-invariantly from the declared scrollport, strictly upstream of
  anything the scale resizes, and the height reserve is unconditional.
- Fixtures declare one authored height each; the 100dvh-minus-chrome
  clamps (frozen guesses of app chrome) are gone.
- The maintenance skill's geometry checklist now states the derivation
  contracts (variant/measured chip placement, two-axis scale, derived
  gap) instead of the retired constants.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ship scripts/verify-guide-chrome.mjs with the maintenance skill: a
Chrome-for-Testing sweep that discovers every rendered annotation on
every page at four viewport classes, reconciles them against the
declared inventory (a missing annotation cannot pass silently), and
asserts relationships — badge bounds and topmost hit-tests, engaged
rings on targets, transient clearance, caret-to-label adjacency, scale
bounds with zero page overflow, the 8-28px gap clamp on the in-flow
card, and the wide-viewport fill gate.

Two placement fixes the sweep caught on its first run:
- A measured badge whose container sits inside the clipping window
  frame (the palette dialog on a narrow panel) now clamps into the
  frame's interior instead of hanging past its edge into nothing.
- The composer + menu's bottom margin is the outside-above chip lane
  (CHIP_SIZE + CHIP_GAP), so the open menu clears the draft line's
  chips by construction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Main's 0.40.0 release prep advanced @get-bb/plugin-sdk to 0.4.22 with
declaration changes in ., ./app, and ./testing/app (no new public
export — every subpath still maps to its Guide surface, 73/73 including
api-sync). The stale-inventory failure only surfaced now because the
turbo-inputs fix invalidated the cache that had been serving pre-bump
declarations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Main's iOS-first mobile redesign now requires every mobile icon name
except the brand marks to map to an SF Symbol; this PR's AiBrowser
(the Plugin Guide's sidebar glyph) predates that gate. 888/888 mobile
tests pass with the mapping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Opening a card pinned its bottom flush to the fold at every size — the
fixture consumed all available height, so the card's visible band was a
viewport constant (reading as a fixed-height card) and opening one
scrolled the page chrome away.

The open in-flow card's footprint (height plus its gap margin) now
subtracts from the fixture's available height, so the fixture makes
room, the card ends where its content ends, and the page never scrolls
on open. The sweep asserts both: open card fully above the fold and
scrollTop stays 0 at desktop widths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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