Docs / Developer / UI component catalog
UI component catalog
Auto-generated by scripts/hooks/component-catalog.ts from exported UI entries undersrc/ui (.tsx React components, ADR-008) and exported create/build/swatch/inject helpers insrc/ui/_shared (.ts). Do not hand-edit: regenerate withbun run scripts/hooks/component-catalog.ts. A
pre-commit gate (--check) fails the commit when this file drifts from the real exports.
Use this for
The answer for the common needs, before searching the table below. For buttons, color pickers and fonts, lint and the style guard block the alternatives.
| Need | Use |
|---|---|
| Any action with text | Button (src/ui/components/button): primary once per view, danger for destructive, quiet for low emphasis |
| An icon-only action | IconButton with a label |
| One (or several) of a few options | Segmented |
| Sections of a room or editor | Tabs |
| A small on/off filter or tag | Chip |
| A row in a list, rail or picker | ListRow |
| A row in a popup menu | MenuItem |
| A header that opens and closes a section | Disclosure |
| A small square (rail icon, swatch, thumb, app, add) | Tile |
| A larger clickable surface (choice, art, entry, file drop) | Card |
| A pager dot, canvas port or handle | Dot |
| A value inside text that edits on click | InlineValue |
| The click-away layer behind a wing or menu | Scrim |
| A document tab | DocTab |
| An icon | Ic (src/ui/_shared/ic.tsx) |
| A color | SwatchRow; solid or gradient fill: PaintPicker |
| An on/off switch | Toggle (card for a whole-row setting card) |
| A dialog | InkDialog or DialogCore |
| Fonts | var(--font-fancy) titles, var(--font-body) text, var(--font-mono) code; never a font name |
Components (React, .tsx)
| Name | File | Signature | Doc | Styles |
|---|---|---|---|---|
| AccentRow | src/ui/apps/scenes/scene-accent-row.tsx | ({ prefs, colors, onSet }: { prefs: { get(key: string): unknown }; colors: PieceColors; onSet(key: string, value: unk... | ||
| AccessChip | src/ui/apps/scenes/compendium/tabs/settings/access-chip.tsx | ({ ctx, chat, bookId, bookName, onChat }: { ctx: AppContext; chat: Chat; bookId: string; bookName: string; onChat(cha... | ||
| AccessibilityRows | src/ui/apps/settings/sections/accessibility-rows.tsx | ({ prefs }: { prefs: Prefs }) | ||
| Act | src/ui/apps/scenes/stage-act.tsx | ({ id, title, status, open, onToggle, children }: { id: string; title: string; status: string; open: boolean; onToggl... | ||
| ActionRow | src/ui/apps/scenes/messenger/frames/settings-rows.tsx | ({ label, description, value, action, onAction, variant = "secondary" }: RowCopy & { value?: string; action: string; ... | A value and a button ("Name shown to the model, Mina, Edit"), or just a button when there is no value. | |
| ActivityCard | src/ui/apps/scenes/compendium/activity-card.tsx | ({ row, now, actions }: { row: ActivityRow; now: number; actions: CardActions }) | ||
| ActivityLine | src/ui/apps/scenes/props/story-director/director-parts.tsx | ({ entry, now, open, onToggle, clamp }: { entry: DirectorActivity; now: number; open?: boolean; onToggle?: () => void... | One line of the feed: the result dot, the type in its color, the turn, the time and the description (RoleCall's ActivityEntryCard and the floating popover's row). | |
| ActivityTab | src/ui/apps/scenes/compendium/tabs/activity.tsx | ({ ctx, chatId, feed, extra = [], extraWhy, pop }: { ctx: AppContext; chatId: string; feed: Receipts; extra?: readonl... | ||
| ActivityTab | src/ui/apps/scenes/props/story-director/tab-activity.tsx | ({ entries, now, onClear, locked }: { entries: readonly DirectorActivity[]; now: number; onClear(): void; locked: boo... | ||
| AddByModel | src/ui/apps/scenes/props/trackers/items/generate-kit.tsx | ({ ctx, chatId, ask, label, noun, namePlaceholder, guidePlaceholder, labels, preview, accept }: AddProps) | RoleCall's "Add ..." form: a dashed button that opens a name and a guide, then Generate. | |
| AddEnemy | src/ui/apps/scenes/props/trackers/battle/battle-parts.tsx | ({ onAdd, onCancel }: { onAdd(e: Omit<Enemy, "id">): void; onCancel(): void }) | ||
| AdditionalLayout | src/ui/apps/scenes/layouts/additional-layout.tsx | (p: LayoutProps) | ||
| AddMenu | src/ui/apps/workbench/nodes/Board.tsx | ({ disabled, onAdd }: { disabled: boolean; onAdd(type: "note" | "frame"): void }) | .view .head .grow .addWrap .addMenu .area .canvas .world ... | |
| AddParticipant | src/ui/apps/scenes/cast/add-participant.tsx | ({ rows, onChange, messenger }: { rows: readonly Pick<RosterRow, "name">[]; onChange(c: ParticipantChange): void; mes... | ||
| AddPopover | src/ui/apps/scenes/scene-lore-books.tsx | ({ library, inScene, onPick, onCreate, onClose }: { library: StudioEntitySummary[] | null; inScene: ReadonlySet<strin... | The dashed button's popover: "+ New Lorebook" (name it first, then Create) over the library list. | |
| AdvancedBody | src/ui/apps/scenes/messenger/settings/scene/memory-rows.tsx | ({ env }: { env: SceneEnv }) | The summary model's own settings: method, reasoning, limits and the prompt template. | |
| AgentControls | src/ui/apps/scenes/final-cut/fc-agent.tsx | ({ ctx, pass, lib, onChange }: { ctx: AppContext; pass: FinalCutPass; lib: FinalCutLibrary; onChange: Change }) | ||
| AgentEditor | src/ui/apps/workbench/promptbook/agent-editor.tsx | ({ entity, revision, ctx, piece, topRight }: KindEditorProps) | .root .toolbar .layout .main .phaseList .phase .rehearsal .recipes ... | |
| AgentPage | src/ui/apps/scenes/messenger/settings/scene/finalcut-agent.tsx | ({ env }: { env: SceneEnv }) | ||
| AgentRoom | src/ui/apps/agent/room.tsx | ({ ctx, onClose }: { ctx: AppContext; onClose?: () => void }) | Shows the screen the agent can see, and talks to whichever model the vault has. | |
| AiPanel | src/ui/apps/scenes/compendium/storyboards/dossier-parts.tsx | ({ ai, included, onOff, onMode, onRadius }: { ai: DossierAiContext; included: boolean; onOff(): void; onMode(mode: Co... | ||
| AiTabs | src/ui/apps/scenes/scene-ai-tabs.tsx | ({ model, generation, initialTab, single }: { model: JSX.Element; generation?: JSX.Element; initialTab?: string; sing... | ||
| AiWing | src/ui/apps/scenes/scene-ai-wing.tsx | ({ ctx, chat, onPicked, onClose }: { ctx: AppContext; chat: Chat; onPicked(chat: Chat): void; onClose?(): void }) | ||
| AllowRows | src/ui/apps/scenes/messenger/settings/scene/compendium-passes.tsx | ({ a }: { a: WingArgs }) | What Compendium may file: one switch per entry type. | |
| AllowSection | src/ui/apps/scenes/compendium/tabs/settings/filing.tsx | ({ compendium, set }: SectionProps) | ||
| AltFields | src/ui/components/alt-fields/index.tsx | ({ value, onChange }: AltFieldsProps) | .wrap .section .gtitle | |
| AnalysisTab | src/ui/apps/scenes/props/story-director/tab-analysis.tsx | ({ state }: { state: DirectorState }) | ||
| AnimatedThemeToggler | src/ui/components/animated-theme-toggler/index.tsx | ({ theme, onToggle, duration = 400, fromCenter = false, id, }: AnimatedThemeTogglerProps) | Switch between paper and stage with a reveal that grows from the control. | .iconStack .hidden .shown |
| AntiSlopCard | src/ui/apps/scenes/final-cut/fc-anti-slop.tsx | ({ pass, models, onToggle, onChange }: { pass: FinalCutPass | undefined; models: SceneModels; onToggle(): void; onCha... | ||
| AntiSlopPage | src/ui/apps/scenes/messenger/settings/scene/finalcut-antislop.tsx | ({ env }: { env: SceneEnv }) | ||
| AntiSlopSetPage | src/ui/apps/scenes/messenger/settings/scene/finalcut-antislop.tsx | ({ env, raw }: { env: SceneEnv; raw: string }) | ||
| App | src/ui/shell/App.tsx | ({ forceSkipTitle = false, testListRetryDelaysMs, pieces: injectedPieces }: AppProps = {}) | .shellContainer .shell .appContents .studio-app-surface .studio-app-room .tourHelp .dirty | |
| AppCatalog | src/ui/apps/app-catalog/index.tsx | ({ ctx }: { ctx: AppContext }) | Browse and open every official app packaged in this build. | .room .grid .card .cardHead .mark .name .description .cardFoot ... |
| AppMark | src/ui/components/app-mark/index.tsx | ({ markSvg, className }: AppMarkProps) | Render one sanitized application mark. | |
| AppRooms | src/ui/shell/AppRooms.tsx | ({ app, activeAppId, workspaceAppId, overlayAppId, workspace, overlay, overlayOpen, ctx }: { app: BunzaiApp | null; a... | ||
| ArcsTab | src/ui/apps/scenes/props/story-director/tab-arcs.tsx | ({ state, onResolve, locked }: { state: DirectorState; onResolve(id: string): void; locked: boolean }) | ||
| Area | src/ui/apps/scenes/final-cut/fc-controls.tsx | ({ label, value, placeholder, onChange }: { label: string; value: string; placeholder?: string; onChange(next: string... | ||
| AssetCard | src/ui/apps/library/rc-cards.tsx | (props: CardProps) | AssetCard (RC's library AssetCard, vertical, a fixed 520px): lorebooks get the square book cover | |
| AssetManager | src/ui/components/asset-manager/index.tsx | ({ assets, onChange, onOpenSprites, uploadAsset }: AssetManagerProps) | .wrap .group .ghead .handoff .tiles .tile .preview .img ... | |
| AttachLoreDialog | src/ui/components/attach-lore-dialog/index.tsx | ({ books, alreadyLinked, onConfirm, onDismiss, }: AttachLoreDialogProps) | .sheet .body .kick .h .p .empty .list .row ... | |
| AttachPanel | src/ui/components/sprite-pack/dialog-panels.tsx | ({ packCatalog, attachId, attachBusy, onAttachId, onAttach, }: { packCatalog: readonly PackCatalogEntry[]; attachId: ... | .sheet .bar .lbl .sel .meta .grid .gridViewport .gridSpace ... | |
| AutoRetryRow | src/ui/apps/scenes/props/story-director/director-runtime.tsx | ({ panel, save }: { panel: DirectorPanel; save: Save }) | ||
| AutoUpdate | src/ui/apps/scenes/props/story-director/auto-update.tsx | ({ ctx, chat, panel, save, onChat }: { ctx: AppContext; chat: Chat; panel: DirectorPanel; save: Save; onChat?: (chat:... | ||
| AutoUpdateBooth | src/ui/apps/scenes/props/story-director/auto-update.tsx | ({ panel, save }: { panel: DirectorPanel; save: Save }) | The Booth's part: the switch, and one quiet line with the way to the settings. No trackers and no call budget here. | |
| AutoUpdateLine | src/ui/apps/scenes/props/story-director/tracker-update-ui.tsx | ({ view, dm }: { view: Pick<TrackerView, "module" | "stored">; dm: TrackerUpdateLine }) | What the tracker's menu says about automatic updates: read only. | |
| Avatar | src/ui/apps/scenes/messenger/messenger-parts.tsx | ({ name, art }: { name: string; art?: ReactNode }) | ||
| AvatarCrop | src/ui/components/avatar-crop/index.tsx | ({ value, onChange, imageSrc }: AvatarCropProps) | .wrap .help .meta .actions .row .canvas .img .sel ... | |
| BackdropLayer | src/ui/apps/scenes/scene-backdrop-layer.tsx | ({ ctx, backdrop, character }: { ctx: AppContext; backdrop: ChatBackdrop | undefined; character?: CharacterBackdrop |... | backdrop is the scene's pick; character is the card's pinned background, shown only while the scene has no pick of its own (RoleCall useCharacterLoad.ts:556-577). |
|
| BackdropPicker | src/ui/apps/scenes/scene-backdrop-picker.tsx | ({ ctx, backdrop, onPick, onClose }: { ctx: AppContext; backdrop: ChatBackdrop | undefined; onPick(backdrop: ChatBack... | ||
| BackdropRow | src/ui/apps/scenes/scene-backdrop-wing.tsx | ({ ctx, chat, cardPinned, onChat }: { ctx: AppContext; chat: Chat; cardPinned?: boolean; onChat(chat: Chat): void }) | ||
| BackdropThumb | src/ui/apps/scenes/scene-backdrop-layer.tsx | ({ refValue, mime, className }: { refValue: string; mime?: string; className?: string }) | A small picture of a pack item, for the picker's tiles and the Stage wing's row. It asks for a thumbnail and falls back to the full picture when the server cannot make one; a video shows its first frame. | |
| BackdropVideo | src/ui/apps/scenes/scene-backdrop-layer.tsx | ({ sha, rate, className, style }: { sha: string; rate: number; className?: string; style?: CSSProperties }) | A looping muted video from the asset route; it holds still while the tab is hidden, so it costs nothing unseen. | |
| Badge | src/ui/apps/scenes/props/story-director/director-parts.tsx | ({ tone = "mute", children, title }: { tone?: "ok" | "info" | "warn" | "mute" | "danger" | "select"; children: ReactN... | ||
| BankPicker | src/ui/apps/scenes/final-cut/fc-bank-picker.tsx | ({ pass, onChange }: { pass: FinalCutPass; onChange: Change }) | ||
| BenchImport | src/ui/apps/workbench/regex/bench-import.tsx | ({ ctx, sample, existingRules, onImportPicked, }: BenchImportProps) | .wrap .hiddenInput .drop .dropOver .summary .impRow .impEffect .impCell ... | |
| BenchPane | src/ui/apps/workbench/regex/bench-pane.tsx | ({ ctx, rules, initialTab = "try", onClose, onImportPicked, }: BenchPaneProps) | .pane .phead .pheadB .pbody .sampleCard .schead .scheadB .scheadI ... | |
| BentoCard | src/ui/components/bento-card/index.tsx | ({ title, icon, aff, filled, off, offMode = "dim", missing, onMove, children }: BentoCardProps) | One card of the editor bento. Folds from its chevron; lens states per vs-editor-2. | .card .off .head .mark .title .aff .dot .full ... |
| BentoView | src/ui/apps/workbench/presenters/bento-view.tsx | ({ bcard, leftCard, sealedCard, macroCard, columns, spanRow, styles }: BentoViewProps) | ||
| BiblePane | src/ui/apps/macro-lab/bible-pane.tsx | ({ lens, onInsert, }: { lens: MacroDialect; onInsert: (token: string) => void; }) | .room .lenses .inst .boxes .stack .box .boxHead .boxTitle ... | |
| BinderSide | src/ui/apps/workbench/lore/binder-side.tsx | ({ sidePane, setSidePane, body, baseline, entry, notes, styles, setSession, extraFindings, }: BinderSideProps) | ||
| Block | src/ui/apps/scenes/props/trackers/items/item-parts.tsx | ({ title, children }: { title: string; children: ReactNode }) | A labelled block of a card's body: a small heading over its content. | |
| BlockContent | src/ui/apps/workbench/preset/block-content.tsx | ({ block, onPatch }: BlockContentProps) | .root .workspace .listCol .list .listInner .listRow .autosaveStalled .empty ... | |
| BlockList | src/ui/apps/workbench/preset/block-list.tsx | ({ blocks, groups = [], collapsedGroups, onToggleGroup, totalBlocks, tab, query, onClearQuery, onShowAll, selectedId,... | .root .workspace .listCol .list .listInner .listRow .autosaveStalled .empty ... | |
| BlockRow | src/ui/apps/workbench/preset/block-row.tsx | ({ block, focusKey, index, depth, posinset, setsize, active, selected, expanded, onSelectRow, onToggleCheck, onToggle... | Memoized: editing one block must re-render only that block's row, not | .rowWrapOpen .prow .rowIndent .prowActive .prowSel .prowOff .check .checkOn ... |
| BoardLayer | src/ui/apps/workbench/nodes/Board.tsx | (p: BoardLayerProps) | .view .head .grow .addWrap .addMenu .area .canvas .world ... | |
| BondsPanel | src/ui/apps/scenes/props/trackers/bonds/bonds-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| BookAccessRows | src/ui/apps/scenes/messenger/settings/scene/compendium-books.tsx | ({ a }: { a: WingArgs }) | One access choice per book, as in the Compendium's access chip. | |
| BookBar | src/ui/apps/scenes/compendium/compendium-shell.tsx | ({ books, bookId, onBook, access, chip }: { books: readonly SceneLoreBook[]; bookId: string; onBook(id: string): void... | ||
| BookBoard | src/ui/apps/workbench/promptbook/book-board.tsx | ({ phases, selected, onSelect, onChange, ctx, bookId }: { phases: readonly BookPhase[]; selected: string; onSelect(id... | .root .toolbar .layout .main .phaseList .phase .rehearsal .recipes ... | |
| BookCards | src/ui/apps/workbench/promptbook/book-cards.tsx | ({ phase, ctx, onChange, expanded }: { phase: BookPhase; ctx: AppContext; onChange(p: BookPhase): void; expanded: boo... | .root .toolbar .layout .main .phaseList .phase .rehearsal .recipes ... | |
| BookCover | src/ui/apps/library/book-cover.tsx | ({ title, choice }: { title: string; choice: BookCoverChoice }) | .cover .dialog .editor .fields | |
| BookCoverDialog | src/ui/apps/library/book-cover.tsx | ({ title, initial, onSave, onDismiss }: { title: string; initial: BookCoverChoice | null; onSave(choice: BookCoverCho... | .cover .dialog .editor .fields | |
| BookList | src/ui/apps/scenes/scene-lore-books.tsx | ({ books, characterName, selectedId, onSelect, onToggle, onRemove, onAdd, lastTurn }: { books: readonly SceneLoreBook... | ||
| BooksSection | src/ui/apps/scenes/compendium/tabs/settings/books.tsx | ({ ctx, chat, compendium, lore, set }: SectionProps) | ||
| BootErrorScreen | src/ui/shell/BootErrorScreen.tsx | ({ problem }: { problem: BootProblem | null }) | ||
| BoothFallbackRow | src/ui/apps/scenes/booth-fallback-row.tsx | ({ ctx, models }: { ctx: AppContext; models: SceneModels }) | ||
| BoothGeneration | src/ui/apps/scenes/booth-preset-row.tsx | ({ chat, preset, own, windowTokens }: { chat: Chat; preset: BoothPreset; own: ScenePresetOwn; windowTokens: number | ... | ||
| BoothLoreRow | src/ui/apps/scenes/booth-lore-row.tsx | ({ ctx, chatId }: { ctx: AppContext; chatId: string }) | ||
| BoothModelPicker | src/ui/apps/scenes/booth-model-picker.tsx | ({ current, models, onPick }: { current: ChatConnection | undefined; models: SceneModels; onPick(c: ChatConnection): ... | ||
| BoothModelRow | src/ui/apps/scenes/booth-model-row.tsx | ({ ctx, chat, models }: { ctx: AppContext; chat: Chat; models: SceneModels }) | ||
| BoothNavigator | src/ui/apps/scenes/booth-navigator.tsx | ({ ctx, scene, art }: { ctx: AppContext; scene: OpenScene; art: JSX.Element }) | ||
| BoothPresetCard | src/ui/apps/scenes/booth-preset-row.tsx | ({ chat, preset, own, onOpen }: { chat: Chat; preset: BoothPreset; own: ScenePresetOwn; onOpen(): void }) | ||
| BoothReadout | src/ui/apps/scenes/booth-readout.tsx | ({ ctx, scene }: { ctx: AppContext; scene: OpenScene }) | ||
| BoothSummaryRow | src/ui/apps/scenes/booth-summary-row.tsx | ({ ctx, chat, onOpen }: { ctx: AppContext; chat: Chat; onOpen(): void }) | ||
| BoothWing | src/ui/apps/scenes/scene-booth-wing.tsx | ({ ctx, scene, busy, art, onChat, onSettings, onOpen }: { ctx: AppContext; scene: OpenScene; busy: boolean; art: JSX.... | ||
| BottomSheet | src/ui/components/bottom-sheet/index.tsx | ({ title, ariaLabel, onDismiss, titleAction, footerAction, children }: BottomSheetProps) | A scrim + grab-handle sheet docked to the pane's bottom; clicking the scrim dismisses. | .overlay .sheet .grab .titleRow .title .body .footer |
| BranchTree | src/ui/apps/scenes/scene-tree.tsx | ({ ctx, chatId, onBack, onOpen }: { ctx: AppContext; chatId: string; onBack(): void; onOpen(): void }) | ||
| Browse | src/ui/apps/scenes/compendium/tabs/browse.tsx | ({ model, bookName, state, onState, tree }: { model: BookModel; bookName: string; state: BrowseState; onState(next: P... | ||
| Bubble | src/ui/apps/scenes/scene-bubble.tsx | (p: BubbleProps) | ||
| BudgetRows | src/ui/apps/scenes/messenger/settings/user/budget-rows.tsx | ({ ctx }: { ctx: AppContext }) | ||
| BulkBar | src/ui/apps/workbench/preset/bulk-bar.tsx | ({ count, onClear, onEnable, onDisable, onDuplicate, onDelete }: BulkBarProps) | .toolbar .topRow .searchWrap .searchIcon .search .stats .statNum .actions ... | |
| Button | src/ui/components/button/index.tsx | ({ children, variant = "secondary", size = "md", icon, block, menu, tone, vars, "data-part": part, type = "button", .... | .btn .seg .tab .chip .primary .danger .quiet .sm ... | |
| CallDetail | src/ui/apps/scenes/context/this-turn-call.tsx | ({ row, trace }: { row: CallRow; trace: SceneTrace }) | ||
| Card | src/ui/components/button/surfaces.tsx | ({ kind, heading, subtitle, art, kicker, children, selected, mark = "Picked", accent, primary, onFiles, vars, "data-p... | .tile .card .dot .icon .swatch .thumb .mark .app ... | |
| CardNotice | src/ui/apps/scenes/scene-card.tsx | ({ card, onRevert }: { card: CardState; onRevert(): void }) | ||
| CardRow | src/ui/apps/library/card-row.tsx | ({ pieces, layout, vctx, peeks, meta, now, newTile }: { pieces: readonly StudioEntitySummary[]; layout: ShelfLayout; ... | ||
| CardsView | src/ui/apps/workbench/lore/cards-view.tsx | ({ entries, writeFor, onSelect, onPatch, onAdd, }: CardsViewProps) | .grid .gridSpace .gridRow .ecard .ecardOff .echead .etitle .esnip ... | |
| CastBody | src/ui/apps/scenes/compendium/storyboards/dossier-views.tsx | ({ d, open, ai }: { d: CastDossier; open: Open; ai: JSX.Element }) | ||
| CastConfirm | src/ui/apps/scenes/cast/cast-dialogs.tsx | ({ from, to, onCancel, onConfirm }: { from: string | null; to: string | null; onCancel(): void; onConfirm(): void }) | The confirm before the scene plays someone else: what changes and what does not. | |
| CastFooter | src/ui/apps/scenes/cast/cast-parts.tsx | ({ dirty, saving, busy, note, what, saveLabel, onSave, children }: { dirty: boolean; saving: boolean; busy: boolean; ... | The pinned footer: the note about the last save, the tab's own buttons, then Save (Saved when clean). | |
| CastHero | src/ui/apps/scenes/cast/cast-parts.tsx | ({ icon, eyebrow, title, emphasis, sub }: { icon: IconName; eyebrow: string; title: string; emphasis: string; sub?: s... | The wing's hero card: icon, eyebrow, a title with its accent word, and a subtitle. | |
| CastInspector | src/ui/apps/scenes/messenger/panels/cast/cast-inspector.tsx | ({ program, onOpenProgram, children }: { program: EditorId; onOpenProgram(id: string): void; children: ReactNode }) | ||
| CastPortrait | src/ui/apps/scenes/cast/cast-parts.tsx | ({ art, standIn, chip, name, lines, topLeft, upload, onPick, children }: { art: JSX.Element | null; standIn: ReactNod... | The tall portrait column: art or a stand-in, a change-image button, the now chip, and the caller's captions. | |
| CastWing | src/ui/apps/scenes/scene-cast-wing.tsx | ({ ctx, scene, busy, card, onScene, onUpdate, onRevert, initialTab, single }: { ctx: AppContext; single?: boolean; in... | The Cast wing's three tabs (Character, Persona, Participants) and everything that changes who is in the scene. | |
| Catalogue | src/ui/apps/scenes/compendium/browse/catalogue.tsx | ({ model, sub, onSub, query, onQuery, selectedId, onOpen, tree }: { model: BookModel; sub: SubTab; onSub(s: SubTab): ... | ||
| CatchThinking | src/ui/apps/scenes/generation/catch-thinking.tsx | ({ value, prefill, onChange }: { value: ReasoningCapture | undefined; prefill: string | undefined; onChange(next: Rea... | ||
| Cell | src/ui/apps/scenes/compendium/cells/cell.tsx | ({ title, dot, wide, children }: { title?: string; dot?: string; wide?: boolean; children: ReactNode }) | ||
| ChainsSheet | src/ui/apps/scenes/props/trackhare/chains-sheet.tsx | ({ sheetRef, lore, replyNumber, onClose }: { sheetRef: RefObject<HTMLElement | null>; lore: SceneTrace["lore"]; reply... | ||
| ChangeBlock | src/ui/apps/scenes/messenger/transcript/reply-changes.tsx | ({ trackers, onOpen, onMarker }: { trackers: readonly TrackerChanged[]; onOpen(trackerId: string): void; onMarker(): ... | The trackers one reply changed, each in its own style. Nothing at all when none of them draws anything. | |
| ChangesPane | src/ui/apps/workbench/lore/changes-pane.tsx | ({ baseline, body, onRevertField, onRestoreEntry, onUndoSwap, onJumpEntry, onClose, }: ChangesPaneProps) | .pane .head .clean .block .field .fieldK .diffCols .dFrom ... | |
| ChangesRow | src/ui/apps/scenes/messenger/settings/scene/changes-row.tsx | ({ a }: { a: WingArgs }) | ||
| CharacterCard | src/ui/apps/library/rc-cards.tsx | (props: CardProps) | ContentCharacterCard (RC's DiscoveryCharacterCardV3 in library mode), for characters and | |
| CharacterDefaultRows | src/ui/apps/scenes/messenger/settings/character-defaults.tsx | ({ a }: { a: WingArgs }) | ||
| CharacterEditor | src/ui/apps/workbench/Editor.tsx | ({ entity, revision, ctx, piece, topRight }: CharacterEditorProps) | .room .stage .soon .ghostRoom .ghostErr .skel .ghostActions .recents ... | |
| CharacterEditorView | src/ui/apps/workbench/presenters/character-editor-view.tsx | ({ ctx, piece, topRight, prefs, bodyViews, coverage, platformLabel, chips, nativeStub, setNativeStub, workshop, setWo... | ||
| CharacterFilter | src/ui/apps/scenes/scene-lore-advanced.tsx | ({ entry, onPatch }: { entry: LorebookEntry; onPatch: Patch }) | ||
| CharacterFilterBlock | src/ui/apps/workbench/lore/platforms/filter-block.tsx | ({ entry, styles, onPatch, }: { entry: LorebookEntry; styles: Readonly<Record<string, string>>; onPatch: (patch: Part... | ||
| CharacterForm | src/ui/apps/scenes/cast/cast-character-tab.tsx | ({ ctx, id, chatId, chat, editor, summary, art, version, variants, variantId, busy, onVariant }: { ctx: AppContext; i... | The Character tab: the card's fields in RoleCall's order, the look strip, and the pinned Save. | |
| CharacterHero | src/ui/apps/scenes/messenger/settings/character-stats.tsx | ({ a }: { a: WingArgs }) | ||
| CharacterLibrary | src/ui/apps/scenes/booth-navigator.tsx | ({ ctx, currentId, onClose, onStarted }: { ctx: AppContext; currentId: string; onClose(): void; onStarted?(): void }) | onStarted runs once the new scene exists, just before the page moves to it (the Messenger drops its cached scene list there). |
|
| CharacterTextControl | src/ui/apps/workbench/controls/character-text-control.tsx | ({ field, value, onChange, styles, id, disabled, readOnly, maxLength, onFocus, defaultRendered }: { field: Pick<Field... | ||
| ChatLayoutRow | src/ui/apps/settings/sections/chat-layout-row.tsx | ({ prefs }: { prefs: { get(key: string): unknown; set(key: string, value: unknown): void } }) | .grid | |
| Check | src/ui/apps/scenes/final-cut/fc-controls.tsx | ({ label, checked, onChange }: { label: string; checked: boolean; onChange(next: boolean): void }) | ||
| Checkbox | src/ui/components/rc-controls/index.tsx | ({ className, ...rest }: Omit<InputHTMLAttributes, "type">) | .sr-only .field .area .chip .check .tipWrap .tip | |
| CheckedText | src/ui/apps/scenes/messenger/settings/scene/drafts.tsx | ({ saved, write, check, rows, delay = SAVE_MS, ...copy }: RowCopy & { saved: string; rows?: number; delay?: number; c... | A text area that saves what was typed once it rests, unless check names what is wrong with it. |
|
| Chevron | src/ui/apps/scenes/props/story-director/director-parts.tsx | ({ open }: { open: boolean }) | ||
| Chip | src/ui/components/button/index.tsx | ({ children, pressed, color, count, muted, tone, vars, "data-part": part, type = "button", ...rest }: ChipProps) | .btn .seg .tab .chip .primary .danger .quiet .sm ... | |
| Chip | src/ui/components/rc-controls/index.tsx | ({ className, ...rest }: HTMLAttributes) | .sr-only .field .area .chip .check .tipWrap .tip | |
| Chips | src/ui/apps/scenes/props/trackers/items/item-parts.tsx | ({ items, bad }: { items: readonly string[]; bad?: boolean }) | ||
| ChoiceBody | src/ui/_shared/field-bodies.tsx | ({ field, update, startsAt }: { field: BodyField; update: Update; startsAt: boolean }) | .toc .module .css .title .rows .add .page .pager ... | |
| ChoiceList | src/ui/agent/kit-choice.tsx | ({ choices, answered, busy, onSend, }: { choices: AskChoices; answered?: string | undefined; busy?: boolean; onSend: ... | ||
| ChoicesRow | src/ui/apps/scenes/scene-choices.tsx | ({ ctx, chat, body, choices }: { ctx: AppContext; chat: Chat; body: PresetBody; choices: SceneChoices }) | ||
| ChoiceWalkthrough | src/ui/apps/scenes/scene-choice-walkthrough.tsx | ({ groups, selections, onSelect, onSave, onClose, readme, presetName, peeks, startAt = 0, onStep }: { groups: ChoiceG... | ||
| ChromeAct | src/ui/apps/scenes/stage-chrome-act.tsx | ({ look, set }: StageActProps) | ||
| ClosePieceDialog | src/ui/shell/ClosePieceDialog.tsx | () | ||
| ClosePiecePrompt | src/ui/shell/ClosePieceDialog.tsx | ({ name, onDiscard, onKeep, }: ClosePiecePromptProps) | ||
| CodeEditor | src/ui/components/code-editor/index.tsx | (props: CodeEditorProps) | .wrap .gutter .stack .pre .ta .macro .string .comment ... | |
| CodexPanel | src/ui/apps/scenes/props/trackers/codex/codex-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| CodexSections | src/ui/apps/scenes/props/trackers/codex/codex-parts.tsx | ({ e, stats }: { e: Shared; stats?: { label: string; s: Partial<Record<"hp" | "maxHp" | "mp" | "maxMp" | "attack" | "... | ||
| CollectionsBar | src/ui/apps/library/collections-bar.tsx | (input: CollectionsBarInput) | ||
| ColorEditor | src/ui/apps/scenes/cast/participant-colors.tsx | ({ row, enabled, onColors, palette = [] }: { row: RosterRow; enabled: boolean; onColors(colors: string[] | null): voi... | ||
| ColorPicker | src/ui/components/color-picker/index.tsx | ({ value, onChange }: ColorPickerProps) | .cp .sv .hue .thumb .foot .chip .hex | |
| ColourRows | src/ui/apps/scenes/messenger/settings/user/appearance.tsx | ({ a, env, part }: { a: WingArgs; env: RowEnv; part: "text" | "accent" }) | Message colours, scene accent, studio colour. Preferences are not reactive, so a write counts a repaint of this list and the page. | |
| CombatLog | src/ui/apps/scenes/props/trackers/battle/battle-parts.tsx | ({ log, onClear }: { log: readonly string[]; onClear(): void }) | ||
| CombatPanel | src/ui/apps/scenes/props/trackers/battle/battle-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| CompareDialog | src/ui/apps/scenes/scene-compare.tsx | ({ api, target, onClose, onStale, setStatus }: { api: AppContext["api"]; target: CompareTarget; onClose(): void; onSt... | ||
| CompendiumRows | src/ui/apps/scenes/messenger/settings/scene/world.tsx | ({ a, open }: { a: WingArgs; open: OpenProgram }) | One access choice per book, as in the Compendium's access chip, and the way to the Compendium. | |
| CompendiumSettingsTab | src/ui/apps/scenes/compendium/tabs/settings/index.tsx | ({ ctx, chat, onChat, bookId }: { ctx: AppContext; chat: Chat; onChat(chat: Chat): void; bookId?: string }) | ||
| CompendiumWing | src/ui/apps/scenes/compendium/compendium-wing.tsx | ({ ctx, chat, books, activity, settings, headerActions, chip, recentWrites, notice, banner, onChat }: CompendiumWingP... | ||
| CompendiumWithFiling | src/ui/apps/scenes/compendium/compendium-mounts.tsx | ({ ctx, chat, books, settings, chip, onChat = () => undefined }: { ctx: AppContext; chat: Chat; books: readonly Scene... | ||
| Compose | src/ui/apps/scenes/context/tabs-request.tsx | ({ trace, highlight, onClear }: { trace: SceneTrace; highlight: Highlight; onClear(): void }) | ||
| ComposerTools | src/ui/apps/scenes/scene-composer-tools.tsx | ({ open, rows, onToggle, onPick, onExpand }: ComposerToolsProps) | ||
| ConfirmSwitch | src/ui/apps/settings/sections/updates-dialogs.tsx | ({ installed, target, kind, onConfirm, onCancel, }: { installed: string; target: string; kind: "update" | "rollback";... | Confirm a switch. Rollbacks read as danger; a rollback to a pre-feature version says so plainly. | .wrap .module .css .blurb .card .hero .cardTitle .cardBody ... |
| ConnectionRows | src/ui/apps/scenes/messenger/settings/user/connection.tsx | ({ open }: { open: OpenProgram }) | ||
| ConstraintsSection | src/ui/apps/scenes/compendium/tabs/settings/tree.tsx | ({ ctx, chat, bookId, set }: SectionProps) | ||
| ContentCard | src/ui/apps/workbench/persona/persona-cards.tsx | ({ body, onBody, writeFor, }: { body: PersonaBody; onBody: OnBody; writeFor: PersonaWriteForProfile; }) | The flat identity text (the whole persona on section-less platforms). | .root .body .idRow .honest .traits .traitsHead .traitAdd .stops ... |
| ContextMenu | src/ui/apps/scenes/messenger/frames/context-menu.tsx | ({ items, at, label = "Context menu", onClose, bounds = viewportNow }: ContextMenuProps) | ||
| ContextMenuButton | src/ui/_shared/context-menu-button.tsx | ({ name, className }: { name: string; className: string }) | ||
| ContextSection | src/ui/apps/scenes/context/context-wing.tsx | ({ wing, resize, ...props }: ContextProps & { wing: Wing; resize?: WingResize; initialTab?: string; single?: boolean }) | The wing's panel: the section RoleCall draws, in the frame every wing shares (its width and drag edge are the page's: use-wing-widths.ts). | |
| ContextWing | src/ui/apps/scenes/context/context-wing.tsx | ({ initialTab, single, ...props }: ContextProps & { initialTab?: string; single?: boolean }) | ||
| Contract | src/ui/apps/scenes/final-cut/fc-contract.tsx | ({ passes, rulebook }: { passes: readonly FinalCutPass[]; rulebook: readonly RulebookEntry[] }) | ||
| ControlsBody | src/ui/apps/scenes/messenger/settings/scene/memory-rows.tsx | ({ env }: { env: SceneEnv }) | How summaries run: automatic or manual, how often, with which model and window, and the manual run. | |
| Conversation | src/ui/apps/table-read/conversation.tsx | ({ session, drafts, busy, running, now, change, reader }: { session: TableReadSession; drafts: TableReadDraftStore; b... | .room .setup .readerGrid .readerPortrait .readerSelect .tempos .setupBody .setupAside ... | |
| CopyableBand | src/ui/agent/kit-bands.tsx | ({ className, text, onNotice, onClick, children, }: { className: string; text?: string; onNotice?: (message: string) ... | A band with a copy corner. | |
| CoreGroup | src/ui/apps/scenes/generation/core-group.tsx | ({ env, params, searching }: { env: GenerationEnv; params: readonly ParamDef[]; searching: boolean }) | The Core cards that match the search (all of them when it is blank). | |
| CoreWing | src/ui/apps/scenes/scene-core-wing.tsx | ({ ctx, scene }: { ctx: AppContext; scene: OpenScene }) | ||
| CorrectionTools | src/ui/apps/scenes/scene-correct.tsx | ({ api, chatId, message, selection, onApply, onClose }: { api: Pick<ScenesApi, "runSceneDraft" | "listGuides">; chatI... | ||
| CorruptionPanel | src/ui/apps/scenes/props/trackers/corruption/corruption-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| Creature | src/ui/apps/scenes/compendium/cells/cells-featured.tsx | ({ m, onOpen }: { m: BookModel } & Open) | ||
| CrossEntryBoost | src/ui/apps/scenes/scene-lore-advanced.tsx | ({ entry, candidates, onPatch }: { entry: LorebookEntry; candidates: readonly { id: string; title: string }[]; onPatc... | RoleCall's Cross-Entry Boosting: when this entry fires, the listed entries of this book are likelier to (core/lore/engine/boosting.ts). | |
| CrossRefCell | src/ui/apps/scenes/compendium/cells/cell-graph.tsx | ({ m, onOpen }: { m: BookModel; onOpen(id: string): void }) | ||
| CssAdvancedPane | src/ui/components/css-workshop/advanced-pane.tsx | ({ value, onChange, doc, selected, onSelectRule, onRuleChange, onChip, }: CssAdvancedPaneProps) | Code + breakdown split for advanced authors. | .root .banner .packRow .row .packLabel .knobLabel .sourceLabel .importFlash ... |
| CssAssistPane | src/ui/components/css-workshop/assist-pane.tsx | ({ pack, doc, selected, onSelectRule, onAddRule, onRuleChange, onDeleteRule, }: CssAssistPaneProps) | Structured assist over one rule at a time. | .root .banner .packRow .row .packLabel .knobLabel .sourceLabel .importFlash ... |
| CssSourcePane | src/ui/components/css-workshop/source-pane.tsx | ({ value, onChange, onChip }: CssSourcePaneProps) | Source tab: chips assist, editor is the sheet. | .root .banner .packRow .row .packLabel .knobLabel .sourceLabel .importFlash ... |
| CssStarters | src/ui/components/css-workshop/starters.tsx | ({ packId, packBlurb, onApply }: CssStartersProps) | Recipe list filtered by active target pack. | .root .banner .packRow .row .packLabel .knobLabel .sourceLabel .importFlash ... |
| CssWorkshop | src/ui/components/css-workshop/index.tsx | ({ value, onChange, defaultPackId = "universal", onPackChange, note = DEFAULT_NOTE, mode: modeProp, onModeChange, ini... | Main assisted CSS editor shell. | .root .banner .packRow .row .packLabel .knobLabel .sourceLabel .importFlash ... |
| CssWorkshopRoom | src/ui/apps/css-workshop/room.tsx | ({ ctx }: CssWorkshopRoomProps) | Full app canvas for the CSS Workshop dock tile. | .room .stage .flash .clearSheet .clearTitle .clearBody .clearActs |
| CueGrid | src/ui/components/stage-dossier/index.tsx | ({ values, onChange, flubbed = [], label = "Your cues", }: { values: readonly string[]; onChange: (next: string[]) =>... | The cue grid: twelve inputs for typing the words back. Pasting all twelve into any cue fills the | .dossier .hero .head .act .marquee .flourish .direction .paren ... |
| CustomRequestParams | src/ui/apps/scenes/generation-params-custom.tsx | ({ samplers, onSave }: { samplers: SceneGeneration; onSave(key: Field, text: string): void }) | ||
| CustomTagRows | src/ui/apps/scenes/messenger/settings/scene/writing-tags.tsx | ({ prompting }: { prompting: PromptingView }) | ||
| CutFromDialog | src/ui/apps/scenes/scene-cuts.tsx | ({ onCancel, onConfirm }: { onCancel(): void; onConfirm(): void }) | ||
| CutLine | src/ui/apps/scenes/scene-cuts.tsx | ({ count, onRestore }: { count: number; onRestore(): void }) | One line where a cut was: every message of one cut shares it. | |
| CutOff | src/ui/apps/scenes/scene-turn-parts.tsx | ({ busy, onRegenerate }: { busy: boolean; onRegenerate(): void }) | ||
| CutSceneDialog | src/ui/apps/scenes/scenes-dialogs.tsx | ({ scenes, onCancel, onCut }: { scenes: Pick<SceneSummary, "title">[]; onCancel(): void; onCut(): void }) | ||
| CyclesPanel | src/ui/apps/scenes/props/trackers/cycles/cycles-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| DamageNotice | src/ui/apps/library/damage-notice.tsx | (props: { entries: readonly StudioDamagedEntry[]; studioDir?: string; prefs?: { get(key: string): unknown; set(key: s... | ||
| Dark | src/ui/apps/scenes/props/story-director/director-shared.tsx | () | ||
| Dashboard | src/ui/apps/scenes/compendium/tabs/dashboard.tsx | ({ model, bookName, onOpen, onTree, headerActions, banner, recentWrites = [], maintenance }: { model: BookModel; book... | ||
| DataRows | src/ui/apps/scenes/messenger/settings/user/data.tsx | () | ||
| DebugTab | src/ui/apps/scenes/props/story-director/tab-debug.tsx | ({ panel, onEdit, locked }: { panel: DirectorPanel; onEdit: EditFn; locked: boolean }) | ||
| DefaultPersona | src/ui/apps/scenes/messenger/settings/scene/persona-rows.tsx | ({ ctx }: { ctx: AppContext }) | The persona new scenes start with: the pref the Cast wing's "Set as default" writes. The Cast wing cannot clear it, so there is no empty choice once one is set. | |
| DefaultsSection | src/ui/apps/scenes/cast/cast-defaults.tsx | ({ ctx, chat }: { ctx: Pick<AppContext, "prefs" | "api">; chat: Pick<OpenScene["chat"], "backdrop" | "preset" | "cast... | ||
| DeleteEntryDialog | src/ui/apps/scenes/scene-lore-entries.tsx | ({ title, onCancel, onConfirm }: { title: string; onCancel(): void; onConfirm(): void }) | ||
| DeleteFolderDialog | src/ui/apps/scenes/scenes-dialogs.tsx | ({ name, onCancel, onDelete }: { name: string; onCancel(): void; onDelete(): void }) | ||
| DeleteMenu | src/ui/apps/scenes/scene-cuts.tsx | ({ onPick }: { onPick(scope: CutScope, skipConfirm: boolean): void }) | ||
| DeleteNote | src/ui/apps/scenes/messenger/panels/lore/lore-list.tsx | ({ w, bookName }: { w: LoreApi; bookName: string }) | The inline delete confirmation (panels.html 3f), shared by the list and the inspector. It asks before confirmDeleteEntry removes the entry from its book. |
|
| DeleteTakeDialog | src/ui/apps/scenes/scene-takes.tsx | ({ take, onCancel, onConfirm }: { take: TakeSummary; onCancel(): void; onConfirm(): void }) | ||
| Desktop98 | src/ui/apps/scenes/layouts/desktop98.tsx | (p: LayoutProps) | ||
| DesktopNoticeRow | src/ui/apps/scenes/messenger/settings/user/desktop-notice.tsx | ({ a }: { a: WingArgs }) | ||
| DetailHint | src/ui/apps/scenes/scene-lore-entries.tsx | ({ empty, onAdd }: { empty: boolean; onAdd(): void }) | The editor pane while no entry is open (RoleCall's "Select an Entry" and "Empty Lorebook"). | |
| DiagnosticsSection | src/ui/apps/scenes/compendium/tabs/settings/diagnostics.tsx | ({ ctx, chat, compendium, lore }: SectionProps) | ||
| DialogCore | src/ui/components/dialog-core/index.tsx | ({ children, placement, ariaLabel, onDismiss, overlayClassName, className, labelledBy, tabIndex, as = "div", sheetRef... | Shared modal shell. Visual wrappers select placement/classes and keep their own content lifecycle. | .overlay .center .pane-bottom .fullscreen .embedded |
| DialogFooter | src/ui/components/ink-dialog/chrome.tsx | ({ onCancel, onApply, separated = false, }: { onCancel(): void; onApply(): void; separated?: boolean; }) | .head .title .foot .separated | |
| DialogHeader | src/ui/components/ink-dialog/chrome.tsx | ({ title, onClose }: { title: string; onClose(): void }) | .head .title .foot .separated | |
| Dice | src/ui/apps/scenes/props/trackers/battle/battle-parts.tsx | ({ history, onRoll, onClear }: { history: readonly DiceRoll[]; onRoll(expression: string): void; onClear(): void }) | ||
| DiceEditor | src/ui/apps/workbench/pieces/dice-editor.tsx | ({ entity, revision, ctx, piece, topRight, rand = Math.random }: KindEditorProps & { rand?: () => number }) | .root .problem .cols .flush .colsPair .rail .railTitle .section ... | |
| DiceTable | src/ui/apps/workbench/pieces/dice-table.tsx | ({ rows, lit, result, canRoll, onChange, onRoll }: { rows: readonly DiceRow[]; lit: number | undefined; result: strin... | .root .problem .cols .flush .colsPair .rail .railTitle .section ... | |
| DiffSections | src/ui/apps/scenes/props/trackers/refresh/refresh-diff.tsx | ({ diff, skipped }: { diff: ModuleDiff; skipped: readonly Skipped[] }) | ||
| Direction | src/ui/components/stage-dossier/index.tsx | ({ children }: { children: ReactNode }) | The parenthesised stage direction: the one theatrical aside, in plain words. | .dossier .hero .head .act .marquee .flourish .direction .paren ... |
| DirectorBody | src/ui/apps/scenes/props/story-director/director-shared.tsx | ({ chatId, tab, panel, now, locked, edit }: { chatId?: string; tab: DirectorTabId; panel: DirectorPanel; now: number;... | The open tab's body: the feed always, the empty stage when nothing is saved yet, else the tab. locked turns every edit control off (a save in flight, or an earlier turn on show). |
|
| DirectorBooth | src/ui/apps/scenes/props/story-director/director-booth.tsx | ({ ctx, chat, busy, onProps }: { ctx: AppContext; chat: Chat; busy: boolean; onProps(): void }) | ||
| DirectorCommandMode | src/ui/apps/scenes/props/story-director/director-model.tsx | ({ panel, save }: { panel: DirectorPanel; save: Save }) | ||
| DirectorFab | src/ui/apps/scenes/props/story-director/director-fab.tsx | ({ ctx, chat }: { ctx: AppContext; chat: Chat }) | ||
| DirectorModel | src/ui/apps/scenes/props/story-director/director-model.tsx | ({ ctx, chat, panel, save, label, description }: { ctx: AppContext; chat: Chat; panel: DirectorPanel; save: Save; lab... | ||
| DirectorModelRow | src/ui/apps/scenes/messenger/settings/scene/director-model-row.tsx | ({ a, settings, save }: { a: WingArgs; settings: DirectorPanel["settings"]; save(patch: DirectorSettingsPatch): Promi... | ||
| DirectorNotes | src/ui/apps/scenes/props/story-director/director-shared.tsx | ({ viewing, turn, on, live, note, onDismiss }: { viewing: boolean; turn: number; on: boolean; live: DirectorLive; not... | The notes under the toolbar: reading an earlier turn, the Director off, a plan in flight, a plan that failed, and the last edit's refusal. | |
| DirectorPanelView | src/ui/apps/scenes/props/story-director/director-panel.tsx | ({ ctx, chat, id, popOut }: PopoutContext) | ||
| DirectorReasoning | src/ui/apps/scenes/props/story-director/director-model.tsx | ({ panel, save }: { panel: DirectorPanel; save: Save }) | ||
| DirectorSettings | src/ui/apps/scenes/props/story-director/director-settings.tsx | ({ ctx, chat, onChat }: { ctx: AppContext; chat: Chat; onChat?(chat: Chat): void }) | ||
| DirectorTour | src/ui/apps/scenes/props/story-director/director-tour.tsx | ({ ctx }: { ctx: AppContext }) | ||
| DirectorUpdateLine | src/ui/apps/scenes/props/story-director/tracker-update-ui.tsx | ({ dm }: { dm: TrackerUpdateLine }) | ||
| Disclosure | src/ui/apps/scenes/context/memory-controls.tsx | ({ open, onToggle, icon, title, hint, children }: { open: boolean; onToggle(open: boolean): void; icon: IconName; tit... | ||
| Disclosure | src/ui/components/button/rows.tsx | ({ open, label, summary, leading, trailing, variant = "section", depth = 0, chevron = true, vars, "data-part": part, ... | .row .item .fold .lead .text .clip .sub .meta ... | |
| Dividers | src/ui/apps/scenes/messenger/transcript/use-transcript-decor.tsx | ({ day, fresh }: { day: string | undefined; fresh: boolean }) | ||
| DocContent | src/ui/apps/docs/doc-content.tsx | ({ doc, docs, figures, body, anchor, loading, onPick }: DocContentProps) | .host .room .mobileHead .mobileTitle .desktopNav .desktopToc .mobileSheet .nav ... | |
| Dock | src/ui/shell/Dock.tsx | ({ onNavigate, pendingAppId }: { onNavigate?: () => void; pendingAppId?: string } = {}) | .lane .bar .apps .mark .divider .collapse .nav .handle ... | |
| DockedHead | src/ui/apps/agent/premiere-frame.tsx | ({ model, watching, standingOn }: { model: string; watching: boolean; standingOn: string | null }) | The docked header: the shared RoomHeader, with the live dot and the model in its kicker. | |
| DockedSurface | src/ui/apps/scenes/messenger/shell/surface-host.tsx | ({ ctx, program, holder, pinned, onTogglePin, onClose }: HostProps & { pinned: boolean; onTogglePin(): void }) | ||
| DocNav | src/ui/apps/docs/doc-nav.tsx | ({ docs, activeId, query, onQuery, onPick }: DocNavProps) | .host .room .mobileHead .mobileTitle .desktopNav .desktopToc .mobileSheet .nav ... | |
| DocsRoom | src/ui/apps/docs/room.tsx | ({ ctx }: { ctx: AppContext }) | .host .room .mobileHead .mobileTitle .desktopNav .desktopToc .mobileSheet .nav ... | |
| DocTab | src/ui/components/button/index.tsx | ({ children, kind, selected, accent, onClose, closeLabel = "Close", vars, "data-part": part, type = "button", ...rest... | A document tab in the Workbench strip: selectable, closable, draggable, with a context menu (all native props pass). | .btn .seg .tab .chip .primary .danger .quiet .sm ... |
| DocToc | src/ui/apps/docs/doc-toc.tsx | ({ anchors, activeSlug, onJump }: DocTocProps) | .host .room .mobileHead .mobileTitle .desktopNav .desktopToc .mobileSheet .nav ... | |
| Dossier | src/ui/components/stage-dossier/index.tsx | ({ act, title, accent, hero, children, }: { act: string; title: string; accent?: string; hero?: boolean; children: Re... | A dossier: the act label, a marquee with one colored word, the flourish, then the body. | .dossier .hero .head .act .marquee .flourish .direction .paren ... |
| Dot | src/ui/components/button/surfaces.tsx | ({ kind = "pager", label, current, pressed, color, vars, title, "data-part": part, type = "button", ...rest }: DotProps) | .tile .card .dot .icon .swatch .thumb .mark .app ... | |
| DraftStatusStrip | src/ui/apps/scenes/scene-draft-status.tsx | ({ drafts, persona }: { drafts: ComposerDrafts; persona: string }) | ||
| DramaturgSettings | src/ui/apps/scenes/props/dramaturg/dramaturg-settings.tsx | ({ ctx, chat }: { ctx: AppContext; chat: Chat }) | ||
| Drawer | src/ui/apps/scenes/compendium/standardize/standardize-cards.tsx | ({ run, onCancel }: { run: RunSnapshot; onCancel(): void }) | ||
| DrillRow | src/ui/apps/scenes/messenger/frames/settings-rows.tsx | ({ label, description, value, onOpen }: RowCopy & { value?: string; onOpen(): void }) | A row that opens a deeper page: value and chevron. | |
| DropVeil | src/ui/shell/DropVeil.tsx | () | ||
| EditBox | src/ui/apps/scenes/scene-edit-box.tsx | ({ value, onChange, onSave, onCancel }: { value: string; onChange(text: string): void; onSave(): void; onCancel(): vo... | ||
| EditorArrangement | src/ui/apps/workbench/presenters/editor-modebar.tsx | (p: { mode: ModeProps["mode"]; editorLayout: "bento" | "playbill"; setEditorLayout(layout: "bento" | "playbill"): voi... | ||
| EditorChrome | src/ui/apps/workbench/presenters/editor-chrome.tsx | (p: EditorChromeProps) | ||
| EditorConflict | src/ui/apps/workbench/editor-conflict.tsx | ({ what, onTakeTheirs, onKeepMine }: EditorConflictProps) | .bar .text .title .actions | |
| EditorControls | src/ui/apps/scenes/final-cut/fc-editor.tsx | ({ pass, onChange }: { pass: FinalCutPass; onChange: Change }) | ||
| EditorDialogs | src/ui/apps/workbench/presenters/editor-dialogs.tsx | ({ exportOpen, setExportOpen, spritesOpen, setSpritesOpen, setSpritesFocusLabel, spritesFocusLabel, namedOpen, setNam... | ||
| EditorEhead | src/ui/components/editor-ehead/index.tsx | ({ mark, kind, deck, name, onNameChange, namePlaceholder, nameAriaLabel, meta, dirty, saving, onSave, saveTitle = "Sa... | .ehead .spine .spineMark .spineText .kind .spineName .spineMeta .num ... | |
| EditorField | src/ui/apps/workbench/layout/editor-field.tsx | ({ label, hint, required, htmlFor, meter, wide, children }: EditorFieldProps) | .dim .dot .full .rail .hint | |
| EditorLayout | src/ui/apps/workbench/layout/editor-layout.tsx | ({ label, sections, rail, active: activeProp, onActiveChange, railWidth = "narrow" }: EditorLayoutProps) | .dim .dot .full .rail .hint | |
| EditorLeftCard | src/ui/apps/workbench/presenters/editor-left.tsx | ({ artUrl, draft, piece, vary, styles, setField, mediaCaps, spriteCount, namedCount, setSpritesOpen, setSpritesFocusL... | ||
| EditorModeSwitch | src/ui/apps/workbench/presenters/editor-modebar.tsx | ({ mode, setMode }: ModeProps) | ||
| EditorPage | src/ui/apps/scenes/messenger/settings/scene/finalcut-editor.tsx | ({ env }: { env: SceneEnv }) | ||
| EffectReview | src/ui/extensions/effect-review.tsx | ({ value }: { value: unknown }) | .review .group .value | |
| EmojiPicker | src/ui/apps/scenes/cast/emoji-picker.tsx | ({ anchor, onPick, onClose }: { anchor: HTMLElement | null; onPick(emoji: string): void; onClose(): void }) | RoleCall's emoji picker, portaled under its button and loaded when first opened. | |
| Empty | src/ui/apps/scenes/compendium/cells/cell.tsx | ({ children }: { children: ReactNode }) | ||
| Empty | src/ui/apps/scenes/compendium/storyboards/dossier-parts.tsx | ({ children }: { children: ReactNode }) | ||
| Empty | src/ui/apps/scenes/props/trackers/items/item-parts.tsx | ({ icon, title, hint }: { icon: IconName; title: string; hint: string }) | ||
| EnemyCard | src/ui/apps/scenes/props/trackers/battle/battle-parts.tsx | ({ enemy, current, onDamage, onHeal, onRemove }: { enemy: Enemy; current: boolean; onDamage(n: number): void; onHeal(... | ||
| EnginePane | src/ui/apps/macro-lab/engine-pane.tsx | ({ engine, lensLabel, state, onResolve, }: { engine: MacroEngineInfo | null; lensLabel: string; state: EngineState; o... | .room .lenses .inst .boxes .stack .box .boxHead .boxTitle ... | |
| EngineRoots | src/ui/apps/settings/sections/engines.tsx | () | One row per engine Bunzai can drive: where its checkout is, and whether one answered. | .field .path .acts .note .good .said |
| EntriesPanel | src/ui/apps/scenes/scene-lore-entries.tsx | ({ entries, selectedId, query, onQuery, bookId, lastTurn, saving, host, actions, onAddEntry, onOpenBook, children }: ... | ||
| EntryBody | src/ui/apps/scenes/compendium/fields/blocks.tsx | ({ type, data }: { type: EntryType; data: Rec }) | Every type's body: tiles, blocks, then Other Fields (what no block names and the header does not show). | |
| EntryCounts | src/ui/apps/scenes/compendium/cells/cells-lists.tsx | ({ d }: { d: Dashboard }) | ||
| EntryEditor | src/ui/apps/scenes/scene-lore-entry.tsx | ({ entry, globalScanDepth, boostCandidates, groups, advancedOpen, onToggleAdvanced, note, onPatch, onClose }: { entry... | ||
| EntryPage | src/ui/apps/scenes/compendium/entry-page.tsx | ({ m, id, bookName, onOpen }: { m: BookModel; id: string; bookName: string; onOpen(id: string): void }) | ||
| EntryPicker | src/ui/apps/scenes/compendium/browse/tree-menu.tsx | ({ title, entries, exclude, onPick, onCancel }: { title: string; entries: readonly CompendiumEntry[]; exclude: string... | ||
| EntryTocItem | src/ui/apps/workbench/lore/entry-toc-item.tsx | ({ entry, writeFor, styles, categories, onPatch, onOpen, onDuplicate, onDelete, onOpenBeside, }: EntryTocItemProps) | ||
| EntryWhenWhere | src/ui/apps/workbench/lore/entry-when-where.tsx | ({ entry, writeFor, styles, onPatch, folds, onFoldToggle, }: EntryWhenWhereProps) | ||
| ErrorRow | src/ui/agent/kit-bands.tsx | ({ text, onNotice, }: { text: string; onNotice?: (message: string) => void; }) | A failure, as a band rather than as a loose paragraph. | |
| EventsPanel | src/ui/apps/scenes/props/trackers/events/events-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| ExampleMode | src/ui/apps/workbench/regex/example-mode.tsx | ({ exampleText, styles, onChangeExamples }: ExampleModeProps) | ||
| ExpandBox | src/ui/components/expand/index.tsx | ({ label, children, onExpandedChange }: ExpandBoxProps) | Wraps one editor with an expand control and the fullscreen sheet it expands into. | .frame .inlineToggle .away .scrim .sheet .head .title .hint ... |
| ExpandTextarea | src/ui/components/expand/index.tsx | ({ label, grow = false, ...rest }: ExpandTextareaProps) | A textarea that can go fullscreen: drop-in for a raw one, same props, same value ownership. | .frame .inlineToggle .away .scrim .sheet .head .title .hint ... |
| ExportButton | src/ui/apps/scenes/compendium/export-button.tsx | ({ ctx, bookId, bookName }: { ctx: AppContext; bookId: string; bookName: string }) | ||
| ExportDialog | src/ui/components/export-dialog/index.tsx | ({ ctx, entity, name, hasPackage = false, onClose, }: ExportDialogProps) | .sheet .title .sub .chips .chip .list .honesty .line ... | |
| ExpressionGroups | src/ui/components/expression-map/groups.tsx | ({ value, onChange }: ExpressionGroupsProps) | .wrap .group .head .name .add | |
| ExpressionMap | src/ui/components/expression-map/index.tsx | ({ value, onChange, hideEnabled }: ExpressionMapProps) | .wrap .note .row .k .lbl .sel .gtitle | |
| ExpressionStage | src/ui/components/expression-stage/index.tsx | ({ pack, profile }: ExpressionStageProps) | .wrap .seal .row .face .moods .ta .hit | |
| ExtensionManager | src/ui/apps/settings/sections/extensions.tsx | ({ ctx }: { ctx: AppContext }) | .manager .module .css .review .import .requirement .catalog .title ... | |
| ExtensionRenderer | src/ui/extensions/renderer.tsx | ({ packageId, packageName, descriptor, declaredCommands, assets = {}, disabled = false, onCommand }: ExtensionRendere... | Renders only the shared bounded descriptor language, with package commands checked at the host boundary. | .root .stack .row .text .control .list .image |
| ExtensionSettingsEditor | src/ui/extensions/settings-editor.tsx | ({ id, packageName, enabled, recoveryRequired, canWrite, api }: { id: string; packageName: string; enabled: boolean; ... | ||
| FailCard | src/ui/apps/scenes/scene-turn-parts.tsx | ({ code, message, draft, onDismiss, onRetry }: { code: string; message: string; draft: string; onDismiss(): void; onR... | RoleCall's failure card: the draft shows, and is not saved. Retry asks again for the same message. | |
| FailureModeSelect | src/ui/apps/scenes/final-cut/fc-pass-chrome.tsx | ({ value, onChange }: { value: FailureMode; onChange(next: FailureMode): void }) | ||
| FailureRow | src/ui/apps/scenes/messenger/settings/scene/finalcut-kit.tsx | ({ value, onChange }: { value: FinalCutPass["failureMode"]; onChange(next: FinalCutPass["failureMode"]): void }) | ||
| FavoriteModels | src/ui/apps/scenes/messenger/settings/scene/models-page.tsx | ({ env }: { env: SceneEnv }) | ||
| FavoriteRow | src/ui/apps/scenes/messenger/settings/scene/overview-rows.tsx | ({ a }: { a: WingArgs }) | The star on the scene: shown in the Scenes list's Fan Favorites shelf. | |
| FeaturedCast | src/ui/apps/scenes/compendium/cells/cells-featured.tsx | ({ m, onOpen }: { m: BookModel } & Open) | ||
| FeatureNode | src/ui/apps/workbench/nodes/EngineNodes.tsx | (p: FeatureNodeProps) | A feature that splices into the request (trackers, library trackers, storyboards). Its port is a piece node's port: drag a wire to a block to put its marker there. | .view .head .grow .addWrap .addMenu .area .canvas .world ... |
| Field | src/ui/apps/scenes/context/memory-controls.tsx | ({ label, hint, children }: { label: string; hint?: ReactNode; children: ReactNode }) | ||
| Field | src/ui/apps/scenes/stage-controls.tsx | ({ icon, label, help, children }: { icon: IconName; label: string; help?: string; children: ReactNode }) | ||
| FieldBlock | src/ui/apps/scenes/compendium/fields/blocks.tsx | ({ label, children, tile }: { label: string; children: ReactNode; tile?: boolean }) | ||
| FieldEdit | src/ui/apps/scenes/messenger/panels/trackers/library-edit.tsx | ({ field, record, set, disabled }: { field: TrackerField; record: TrackerRecord; set: SetField; disabled?: boolean }) | One field's editor, with its icon and name; disabled while there is nothing to attach a change to. |
|
| FieldEditor | src/ui/_shared/field-editor.tsx | ({ tool = false, fields, make, onChange, above }: { tool?: boolean; fields: readonly F[]; make(name: string): F; onCh... | .toc .module .css .title .rows .add .page .pager ... | |
| FieldForm | src/ui/components/field-form/index.tsx | ({ fields, value, onChange }: FieldFormProps) | .grid .field .half .label .text .num .sel .rmax ... | |
| FieldIcon | src/ui/apps/scenes/messenger/panels/trackers/library-draw.tsx | ({ icon }: { icon?: string | undefined }) | A field's icon, or nothing when the id is not one the build draws. | |
| FieldRead | src/ui/apps/scenes/messenger/panels/trackers/library-draw.tsx | ({ view }: { view: FieldView }) | One field as the card draws it: a bar with "7/20", the number, pips with the current one lit, one pip, or the quoted text. | |
| FilingRows | src/ui/apps/scenes/messenger/settings/scene/compendium-passes.tsx | ({ a }: { a: WingArgs }) | After a reply: filing on, what to preserve, the Guide, how often and when. | |
| FilingSection | src/ui/apps/scenes/compendium/tabs/settings/filing.tsx | ({ compendium, guides, set }: SectionProps) | ||
| Filters | src/ui/apps/scenes/props/trackers/items/item-parts.tsx | ({ options, value, onChange, icons }: { options: readonly T[]; value: T; onChange(v: T): void; icons?: Partial<Record... | ||
| FinalCutActivity | src/ui/apps/scenes/final-cut/fc-activity.tsx | ({ api, chatId, messageId, enabled, onApply, onApplyRerun, onClose }: { api: Pick<ScenesApi, "getFinalCutRun" | "reru... | ||
| FinalCutBody | src/ui/apps/scenes/messenger/settings/scene/writing-lists.tsx | ({ env }: { env: SceneEnv }) | ||
| FinalCutTab | src/ui/apps/scenes/final-cut/final-cut-tab.tsx | ({ ctx, chat, onChanged }: { ctx: AppContext; chat: Chat; onChanged(chat: Chat): void }) | ||
| FinalCutWing | src/ui/apps/scenes/scene-final-cut.tsx | ({ ctx, chat, onChanged, initialTab, single }: { ctx: AppContext; chat: Chat; onChanged(chat: Chat): void; initialTab... | ||
| FindPanel | src/ui/apps/scenes/scene-find.tsx | (p: FindPanelProps) | ||
| FinePrint | src/ui/apps/workbench/regex/fine-print.tsx | ({ rule, rules, writeFor, styles, onPatch }: FinePrintProps) | ||
| Finished | src/ui/apps/scenes/compendium/standardize/standardize-cards.tsx | ({ run, reverting, canRevert, onDismiss, onRevert }: { run: RunSnapshot; reverting: boolean; canRevert: boolean; onDi... | The finished run: Complete, or Stopped when Cancel ended it. | |
| FirstLanding | src/ui/apps/library/first-landing.tsx | ({ css, damaged, studioDir, onDrop, onPickImport, onStartFresh, overlay, }: DoorsBase & { onDrop: (evt: DragEvent<HTM... | FIRST LANDING (locked): two massive door-cards, verbatim copy, nothing else competing. | |
| Fld | src/ui/apps/scenes/messenger/panels/lore/lore-inspector.tsx | ({ label, hint, aside, children }: { label: string; hint?: string; aside?: ReactNode; children: ReactNode }) | ||
| FloatingAgent | src/ui/agent/floating-agent.tsx | ({ ctx, open, onClose, }: { ctx: AppContext; open: boolean; onClose: () => void; }) | .panel .panelDrag .bar .grip .title .body .handle .hn ... | |
| FloatingSurface | src/ui/apps/scenes/messenger/shell/surface-host.tsx | ({ ctx, program, holder, onClose, workshop }: HostProps & { workshop?: WorkshopScene }) | workshop is what the workshop layer shows of the scene; without it every layer is the plain titled page. |
|
| Flow | src/ui/apps/scenes/context/tabs-request.tsx | ({ trace }: { trace: SceneTrace }) | ||
| FlowView | src/ui/apps/workbench/presenters/flow-view.tsx | (props: FlowViewProps) | ||
| FocusToggle | src/ui/components/focus-toggle/index.tsx | ({ focused, onToggle }: FocusToggleProps) | The expand/shrink icon button. Static first-party markup parsed via DOMParser + importNode | .btn |
| FoldedSay | src/ui/agent/kit-bands.tsx | ({ text, onToggle }: { text: string; onToggle: () => void }) | A long reply, folded to one line. | |
| FolderInspector | src/ui/apps/workbench/lore/folder-inspector.tsx | ({ category, categories, edges, collapsed, styles, onRename, onMove, onToggleEnabled, onClone, onToggleCollapse, onDe... | ||
| FolderNameDialog | src/ui/apps/scenes/scenes-dialogs.tsx | ({ mode, initial, onCancel, onSave }: { mode: "new" | "rename"; initial: string; onCancel(): void; onSave(name: strin... | ||
| FolderRow | src/ui/apps/scenes/messenger/settings/scene/overview-rows.tsx | ({ a }: { a: WingArgs }) | The story folder the scene sits in; "No folder" takes it out. | |
| FoldoutTabs | src/ui/apps/scenes/scene-foldout.tsx | ({ area, group, tabs, active, onSelect }: { area: string; group: string; tabs: readonly FoldoutTab[]; active: Id;... | The tab strip over a wing panel: the breadcrumb and one square tile per panel, the open one marked. | |
| FollowDialog | src/ui/shell/FollowDialog.tsx | () | ||
| FontPreview | src/ui/components/sealed-media/font-preview.tsx | ({ sha, name }: { sha: string; name: string }) | .box .img .audio .video .none .font | |
| ForkDialog | src/ui/apps/scenes/scene-takes.tsx | ({ number, defaultName, retake, onCancel, onCreate }: { number: number; defaultName: string; retake?: boolean; onCanc... | retake is Retake from here: the same dialog, told that a fresh reply is written on the new take (message number is the one it answers). |
|
| FormSection | src/ui/apps/scenes/cast/cast-parts.tsx | ({ title, icon, tone, note, expand, children, "data-part": part }: { title: string; icon: IconName; tone: string; not... | A titled form card with a tone from one deck token and an optional expand button. | |
| FormulaEditor | src/ui/apps/workbench/pieces/formula-editor.tsx | ({ entity, revision, ctx, piece, topRight }: KindEditorProps) | .root .problem .cols .flush .colsPair .rail .railTitle .section ... | |
| FullChatWings | src/ui/apps/scenes/layouts/full-chat-wings.tsx | ({ wing, side, extra, onWing, renderWing }: { wing: string | null; side: "l" | "r" | undefined; extra: readonly Wing[... | ||
| FullscreenLayer | src/ui/apps/scenes/fullscreen-layer.tsx | ({ children, label }: { children: ReactNode; label: string }) | ||
| GalleryGrid | src/ui/apps/scenes/stage-gallery-grid.tsx | ({ items, onOpen }: { items: readonly GalleryItem[]; onOpen(item: GalleryItem): void }) | ||
| GalleryLightbox | src/ui/apps/scenes/stage-gallery-lightbox.tsx | ({ item, busy = false, onUse, onClose }: { item: GalleryItem; busy?: boolean; onUse?(): void; onClose(): void }) | onUse is absent where the picture is only for looking at (a message portrait), and the button goes with it. |
|
| GalleryPane | src/ui/apps/workbench/regex/gallery-pane.tsx | ({ onPick, onStartBlank, onClose }: GalleryPaneProps) | .pane .phead .pheadB .pheadKick .grid .cat .cards .ba ... | |
| GateCard | src/ui/agent/gate-card.tsx | ({ request, busy, onAnswer, }: { request: GateView | null; busy?: boolean; onAnswer: (choice: GateAnswerChoice) => vo... | ||
| GenerationParamGroups | src/ui/apps/scenes/generation-params-groups.tsx | ({ own, presetSamplers, provider, model, query = "", thinking }: { own: ScenePresetOwn; presetSamplers: PresetSampler... | ||
| GenerationTab | src/ui/apps/scenes/generation/generation-tab.tsx | ({ ctx, chat, onChat }: { ctx: AppContext; chat: Chat; onChat(chat: Chat): void }) | ||
| GhostButton | src/ui/components/stage-dossier/index.tsx | ({ onClick, disabled, children }: { onClick: () => void; disabled?: boolean; children: ReactNode }) | A quiet choice: the dashed button that never competes with the call to action. | .dossier .hero .head .act .marquee .flourish .direction .paren ... |
| GradientControl | src/ui/apps/workbench/controls/color-controls.tsx | ({ value, onChange, styles }: GradientControlProps) | ||
| GraphDetail | src/ui/apps/scenes/compendium/graph/graph-side.tsx | ({ node, connections, total, onPick, onOpen }: DetailProps) | ||
| GraphExploreModal | src/ui/apps/scenes/compendium/graph/graph-explore.tsx | ({ m, onOpen, onClose, layoutOf = sharedLayoutOf }: GraphExploreProps) | ||
| GraphSide | src/ui/apps/scenes/compendium/graph/graph-side.tsx | ({ f, onF, counts, query, onQuery, hits, edgeLabels, onEdgeLabels }: SideProps) | ||
| GreetingPicker | src/ui/apps/scenes/scene-greeting-picker.tsx | ({ count, index, onPick }: { count: number; index: number; onPick(i: number): void }) | ||
| Group | src/ui/apps/scenes/scene-lore-advanced.tsx | ({ entry, groups, onPatch }: { entry: LorebookEntry; groups: readonly string[]; onPatch: Patch }) | ||
| Guidance | src/ui/apps/scenes/compendium/tabs/settings/recall.tsx | ({ value, guide, guides, onText, onGuide, copy = RECALL_COPY }: { value: string; guide: string | undefined; guides: S... | RoleCall's PhaseGuidanceEditor (:433-493): inline guidance, and the Guide whose current text is sent first. Typing is saved once it rests, and when the tab closes. |
|
| GuideEditor | src/ui/apps/scenes/scene-guide-editor.tsx | ({ draft, creating, on, busy, error, onChange, onToggleOn, onDuplicate, onDelete, onCancel, onSave }: { draft: GuideI... | ||
| GuidesBody | src/ui/apps/scenes/messenger/settings/scene/writing-lists.tsx | ({ env }: { env: SceneEnv }) | ||
| HareHits | src/ui/apps/scenes/props/trackhare/hare-hits.tsx | ({ trace, group, sort, showMisses }: { trace: SceneTrace; group: boolean; sort: SortMode; showMisses: boolean }) | ||
| HareLogo | src/ui/apps/scenes/props/trackhare/hare-logo.tsx | ({ size = 26 }: { size?: number }) | ||
| HareOptions | src/ui/apps/scenes/props/trackhare/hare-options.tsx | ({ panelRef, group, sort, misses, onSetGroup, onSetSort, onSetMisses, onResetPlace }: { panelRef: RefObject<HTMLDivEl... | ||
| HarePopover | src/ui/apps/scenes/props/trackhare/hare-popover.tsx | ({ panelRef, traceState, density, group, sort, showMisses, pop, onToggleDensity, onPickReply, onOpenTokens, onOpenCha... | ||
| HareRows | src/ui/apps/scenes/messenger/settings/scene/prop-pref-rows.tsx | ({ a }: { a: WingArgs }) | ||
| HareStage | src/ui/apps/scenes/props/trackhare/hare-stage.tsx | ({ ctx, chat }: { ctx: AppContext; chat: Chat }) | ||
| Header | src/ui/apps/scenes/messenger/shell/header.tsx | (p: HeaderProps) | ||
| HealthPane | src/ui/apps/workbench/lore/health-pane.tsx | ({ body, onTransform, onJumpEntry, onClose, extraFindings = [], }: HealthPaneProps) | .pane .head .clean .gedge .gfirst .glast .gitem .ghead ... | |
| HealthPane | src/ui/apps/workbench/regex/health-pane.tsx | ({ findings, rules, onClose, onGoTo, onFix }: HealthPaneProps) | .pane .phead .pheadB .pheadKick .allClear .groups .groupTitle .row ... | |
| HealthReport | src/ui/apps/settings/sections/health-report.tsx | () | The Check my library card: nothing until asked, then the job's state. | .wrap .module .css .card .cardTitle .cardBody .subtle .actions ... |
| HeldCard | src/ui/apps/scenes/scene-turn-parts.tsx | ({ draft, onDiscard, onKeep }: { draft: string; onDiscard(): void; onKeep(): void }) | Bunzai: the take changed while the reply was written; the reply waits to be added or discarded. | |
| HelpDot | src/ui/apps/workbench/preset/help-dot.tsx | ({ help }: { help: FieldHelp }) | .sideHead .sideHeadTitle .sideEmpty .sideEmptyTitle .sideEmptyHint .sideBody .sideRow .sideHintLine ... | |
| HelperInstalledLine | src/ui/apps/settings/sections/helper-card.tsx | ({ h }: { h: HelperControls }) | Shown on the off card: which helper is installed, and a way to fetch it again. |
.wrap .module .css .blurb .card .hero .cardTitle .cardBody ... |
| HelperMissingCard | src/ui/apps/settings/sections/helper-card.tsx | ({ detail, h }: { detail?: string; h: HelperControls }) | Recovery when a helper is unavailable: offer a pinned download where published, otherwise LAN. | .wrap .module .css .blurb .card .hero .cardTitle .cardBody ... |
| Hero | src/ui/apps/scenes/compendium/compendium-shell.tsx | () | ||
| HiddenWorld | src/ui/apps/scenes/props/story-director/debug-hidden.tsx | ({ arcs, notes, onEdit, locked }: { arcs: readonly DirectorInvisibleArc[]; notes: readonly DirectorNote[]; onEdit: Ed... | ||
| HistorianRows | src/ui/apps/scenes/messenger/settings/scene/compendium-tools.tsx | ({ a }: { a: WingArgs }) | Historian summaries: interval, context overlap and summary-aware truncation. | |
| HistorianSection | src/ui/apps/scenes/compendium/tabs/settings/historian.tsx | ({ compendium, set }: SectionProps) | ||
| HistoryList | src/ui/apps/scenes/scene-history.tsx | ({ history, onRestore }: { history: HistoryView; onRestore(index: number): void }) | The Edit history popover: the text now, then each earlier text newest first with Restore. | |
| HorizonBadge | src/ui/apps/scenes/props/story-director/director-parts.tsx | ({ horizon }: { horizon: DirectorHorizon }) | ||
| HostCommandMenu | src/ui/extensions/host-command-menu.tsx | ({ api, resources, onActivate }: HostCommandMenuProps) | .commandScroll .commandRows | |
| HtmlDocEditor | src/ui/apps/workbench/htmldoc-editor.tsx | ({ entity, revision, ctx, piece, topRight }: HtmlDocEditorProps) | .room .head .name .summary .split .grip .pane .paneHead ... | |
| HtmlView | src/ui/apps/html-view/index.tsx | ({ ctx }: { ctx: AppContext }) | .room .body .quiet .frame .big .expand | |
| Ic | src/ui/_shared/ic.tsx | ({ name, size = 16, fill = false, className }: { name: IconName; size?: number; fill?: boolean; className?: string }) | fill draws a lucide glyph solid, as RoleCall does for the Booth bolt and the stop square; mdi glyphs are always solid. |
|
| Icon | src/ui/apps/library/icon.tsx | ({ svg }: { svg: string }) | ||
| IconBox | src/ui/components/icon-box/index.tsx | ({ svg, size = 2 }: IconBoxProps) | A bordered square that parses and mounts a static SVG mark. | .box |
| IconButton | src/ui/components/button/index.tsx | ({ label, icon, variant = "secondary", size = "md", badge, tone, vars, "data-part": part, type = "button", title, ...... | .btn .seg .tab .chip .primary .danger .quiet .sm ... | |
| IconPicker | src/ui/components/icon-picker/index.tsx | ({ value, onChange, label = "Icon" }: { value: string | undefined; onChange(next: string | undefined): void; label?: ... | .root .row .list .scroll | |
| IdentityCard | src/ui/apps/workbench/persona/persona-cards.tsx | ({ body, onBody }: { body: PersonaBody; onBody: OnBody }) | Identity: tagline + pronouns/height/age + the BRIEF with its never-injected honesty line. | .root .body .idRow .honest .traits .traitsHead .traitAdd .stops ... |
| ImagePromptEditor | src/ui/components/image-prompt/index.tsx | ({ value, onChange }: ImagePromptEditorProps) | .wrap .section .lbl .input .ta .rows .row .add | |
| ImportOverlay | src/ui/apps/library/import-sheet.tsx | ({ state, onCommit, onCancel, onAddMore, }: { state: ImportState; onCommit: (checkedIndexes: number[]) => void; onCan... | ||
| IngestRows | src/ui/apps/scenes/messenger/settings/scene/compendium-tools.tsx | ({ a, open }: { a: WingArgs; open: OpenProgram }) | Import chat history: the options the run reads, and the way to the run itself. | |
| IngestSection | src/ui/apps/scenes/compendium/tabs/settings/ingest.tsx | ({ ctx, chat, compendium, bookId, set }: SectionProps) | ||
| Injection | src/ui/apps/scenes/scene-lore-advanced.tsx | ({ entry, groups, onPatch }: { entry: LorebookEntry; groups: readonly string[]; onPatch: Patch }) | ||
| InjectionCard | src/ui/apps/workbench/persona/injection-card.tsx | ({ body, onBody, stops, labels, showWrapper, locked = false, lens = false }: InjectionCardProps) | .root .body .idRow .honest .traits .traitsHead .traitAdd .stops ... | |
| InjectionStatus | src/ui/apps/scenes/cast/cast-injection.tsx | ({ scan }: { scan: PresetScan }) | RoleCall's status over the stops: scanning, "Auto-injecting via ", or the plain invitation. | |
| InkDialog | src/ui/components/ink-dialog/index.tsx | ({ children, onDismiss, ariaLabel, sheetClassName }: InkDialogProps) | A centered modal sheet over a dark scrim; clicking the scrim or pressing Escape calls onDismiss. | .overlay .sheet |
| InlineValue | src/ui/components/button/controls.tsx | ({ children, vars, "data-part": part, type = "button", ...rest }: InlineValueProps) | A value read inside prose; clicking it is the caller's cue to swap in an input. Keeps the text's own font. | .toggle .whole .track .knob .on .mixed .sm .inline ... |
| Input | src/ui/components/rc-controls/index.tsx | ({ className, ...rest }: InputHTMLAttributes) | .sr-only .field .area .chip .check .tipWrap .tip | |
| Inspector | src/ui/apps/workbench/nodes/Inspector.tsx | (p: InspectorProps) | .view .head .grow .addWrap .addMenu .area .canvas .world ... | |
| InspectorShell | src/ui/apps/scenes/context/inspector-shell.tsx | ({ bodies, tab, onTab, onReview }: { bodies: InspectorBodies; tab: InspectorTab; onTab(tab: InspectorTab): void; onRe... | ||
| InterviewScene | src/ui/apps/table-read/interview-scene.tsx | ({ pending, questionId, reader }: { pending: boolean; questionId?: string; reader: ReaderArt }) | .scene .dialogue .art .spotlight .figure .nameplate .table .papers ... | |
| InventoryPanel | src/ui/apps/scenes/props/trackers/inventory/inventory-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| ItemCard | src/ui/apps/scenes/props/trackers/items/item-parts.tsx | ({ color, icon, title, meta, right, preview, under, foot, chip, veil, mod, badge, open, onToggle, removed, children }... | ||
| ItemList | src/ui/apps/scenes/props/trackers/items/item-parts.tsx | ({ items, render }: { items: readonly T[]; render: (item: T) => ReactNode }) | The cards of one tracker, windowed: a tracker holds up to 300 expandable cards. The cards keep their own open state in the panel. | |
| ItemTiles | src/ui/apps/scenes/messenger/panels/trackers/library-draw.tsx | ({ tiles, onPick, tail }: { tiles: readonly ItemTile[]; onPick(name: string): void; tail?: JSX.Element }) | The tiles of a list tracker's rows: a windowed grid in its own scroll box, so a list of any length stays light. Every tile is a button: it picks the row. | |
| KeyHints | src/ui/agent/kit-widgets.tsx | ({ hints }: { hints: readonly { key: string; label?: string }[] }) | A row of keyboard hints: a bright key, then a muted label. Kit's CLI signature. | |
| KeyValues | src/ui/apps/scenes/props/story-director/director-parts.tsx | ({ data }: { data: Record<string, unknown> }) | RoleCall's generic key and value block (Turn Analysis, Pacing Analysis): a string, a list, or a field set, under a small heading each. | |
| KeywordChips | src/ui/apps/workbench/lore/keyword-chips.tsx | ({ triggers, onChange, styles, placeholder, ariaLabel, advanced = false, pickedIndex, onPick, entryProbability = 100,... | ||
| KitCommandBand | src/ui/agent/kit-command-bands.tsx | ({ title, widget, onSend, onRewind, }: { title: string; widget: KitWidget; onSend: (line: string) => void; onRewind: ... | Draw whatever this line carried. | |
| KitMarkdown | src/ui/agent/kit-markdown.tsx | ({ text }: { text: string }) | A whole reply. | |
| KnowledgePanel | src/ui/apps/scenes/props/trackers/knowledge/knowledge-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| KnowledgeRail | src/ui/apps/workbench/lore/KnowledgeRail.tsx | ({ ctx, refs, onChange }: KnowledgeRailProps) | .rail .head .empty .row .rowMissing .attach .pick .pickBook | |
| LanCard | src/ui/apps/settings/sections/lan-card.tsx | ({ ctx, hidden, redacted, }: { ctx: AppContext; hidden: boolean; redacted: boolean; }) | .wrap .module .css .blurb .card .hero .cardTitle .cardBody ... | |
| LanguageSection | src/ui/apps/scenes/compendium/tabs/settings/language.tsx | ({ compendium, set }: SectionProps) | ||
| Lasso | src/ui/apps/library/lasso.tsx | ({ box }: { box: { left: number; top: number; right: number; bottom: number } | null }) | ||
| LastAsUserRow | src/ui/apps/scenes/scene-last-as-user-row.tsx | ({ ctx, chat, onChanged }: { ctx: AppContext; chat: Chat; onChanged(chat: Chat): void }) | ||
| LastTurnFoot | src/ui/apps/scenes/scene-lore-books.tsx | ({ lastTurn }: { lastTurn: LastTurn }) | ||
| Layer | src/ui/apps/scenes/messenger/frames/layer.tsx | ({ label, onClose, children }: LayerProps) | ||
| LayoutChooser | src/ui/apps/scenes/layout-chooser/index.tsx | ({ onChoose }: { onChoose: (layout: ChatLayout) => void }) | .page .dialog .title .sr .backdrop .veil .rays .content ... | |
| LayoutGate | src/ui/apps/scenes/layout-chooser/layout-gate.tsx | ({ ctx, children }: { ctx: AppContext; children: ReactNode }) | ||
| LeavingGate | src/ui/components/leaving-gate/index.tsx | () | .scrim .card .kicker .lede .badge .tile .globe .pname ... | |
| LensRail | src/ui/components/lens-rail/index.tsx | ({ platforms, selected, onToggle, onClear, offTarget, onOffTarget }: LensRailProps) | One-line sideways-scrolling lens chips; Bunzai (full card) first, off-target mode at the tail. | .rail .scroll .offt .fade |
| LibraryCard | src/ui/apps/scenes/messenger/panels/trackers/library-draw.tsx | ({ tracker, onOpen }: { tracker: SceneTracker; onOpen(): void }) | The card of one linked tracker: its name, the Library tag, the reply that last changed it, and its fields or items. Clicking the head opens it. | |
| LibraryDetail | src/ui/apps/scenes/messenger/panels/trackers/library-detail.tsx | ({ ctx, data, tracker, edit, running, onBack }: { ctx: AppContext; data: SceneTrackers; tracker: SceneTracker; edit: ... | ||
| LibraryExtensionCommandMenu | src/ui/apps/library/extension-command-menu.tsx | ({ ctx, pieces }: { ctx: AppContext; pieces: readonly StudioEntitySummary[] }) | ||
| LibraryGate | src/ui/shell/library-gate.tsx | ({ children, pieces: injectedPieces }: { children: ReactNode; pieces?: PieceStore }) | .stage .inner .row .rowText .rowLabel .rowHint .proof .count ... | |
| LibraryPick | src/ui/apps/scenes/messenger/panels/trackers/library-pick.tsx | ({ ctx, chat, linked, bodies, builtIn, builtInOn, onChat, onBack }: { ctx: AppContext; chat: Chat; linked: readonly s... | ||
| LibraryPicker | src/ui/apps/scenes/scene-lore-books.tsx | ({ library, inScene, onPick }: { library: StudioEntitySummary[] | null; inScene: ReadonlySet; onPick(id: stri... | My Library, searchable. A book the scene already reads is listed but cannot be added twice. | |
| LibraryRail | src/ui/apps/library/rail.tsx | (props: LibraryRailProps) | ||
| LightRays | src/ui/components/light-rays/index.tsx | ({ followMouse = true, mouseInfluence = .35, fog = true }: { followMouse?: boolean; mouseInfluence?: number; fog?: bo... | .rays .canvas .fallback | |
| Line | src/ui/apps/scenes/final-cut/fc-controls.tsx | ({ label, value, onChange }: { label: string; value: string; onChange(next: string): void }) | ||
| LineField | src/ui/apps/scenes/cast/cast-parts.tsx | ({ label, value, onChange, placeholder, tone, disabled }: { label: string; value: string; onChange(v: string): void; ... | A labelled one-line input. | |
| Lines | src/ui/components/stage-dossier/index.tsx | ({ heading, children }: { heading: string; children: ReactNode }) | The lines box with its accent spine. | .dossier .hero .head .act .marquee .flourish .direction .paren ... |
| LinkedScenes | src/ui/apps/workbench/pieces/linked-scenes.tsx | ({ ctx, kind, id }: { ctx: AppContext; kind: string; id: string }) | .root .problem .cols .flush .colsPair .rail .railTitle .section ... | |
| LinkedSets | src/ui/apps/workbench/preset/linked-sets.tsx | (props: LinkedSetsProps) | .groups .group .title .module .css .choices .choice .empty | |
| LinkOut | src/ui/components/link-out/index.tsx | ({ icon, title, meta, action, onAction, empty, emptyLabel }: LinkOutProps) | .row .ic .body .title .meta .pending .empty | |
| ListEditor | src/ui/components/list-editor/index.tsx | ({ items, fields, onChange, addLabel, itemTitle, makeItem }: ListEditorProps) | .wrap .item .ihead .ititle | |
| ListRow | src/ui/components/button/rows.tsx | ({ label, subtitle, leading, meta, trailing, variant = "plain", selected, depth = 0, accent, wrap, vars, "data-part":... | .row .item .fold .lead .text .clip .sub .meta ... | |
| ListToolbar | src/ui/apps/workbench/preset/list-toolbar.tsx | ({ counts, query, onQuery, tab, onTab, onExpandAll, onCollapseAll, onAdd, onAddCategory, placedSlots, onAddMarker, }:... | .toolbar .topRow .searchWrap .searchIcon .search .stats .statNum .actions ... | |
| LiveBubble | src/ui/apps/scenes/scene-turn-parts.tsx | ({ n, who, tone, art, live, format, prefs, speakers }: { speakers?: readonly Speaker[] | undefined; n: number; who: s... | The reply being written, in its own bubble: no message id yet, so none of Bubble's edit/branch/cut | |
| LiveBuild | src/ui/apps/workbench/preset/live-build.tsx | ({ body, onSelect }: LiveBuildProps) | .wrap .head .headline .module .css .weight .empty .list ... | |
| LivePreview | src/ui/apps/scenes/cast/cast-injection.tsx | ({ body, character, scan }: { body: PersonaBody; character: CharacterBody; scan: PresetScan }) | RoleCall's Live Preview: the eye, where it lands, the block as sent, and the token count. | |
| LivePreview | src/ui/apps/workbench/preset/live-preview.tsx | ({ body, onPatchContent, onSelect }: LivePreviewProps) | .wrap .head .headline .module .css .volatile .empty .list ... | |
| LiveSwitch | src/ui/apps/scenes/final-cut/fc-anti-slop.tsx | ({ on, onToggle }: { on: boolean; onToggle(): void }) | ||
| LivingCard | src/ui/apps/table-read/living-card.tsx | ({ session, drafts, change }: { session: TableReadSession; drafts: TableReadDraftStore; change(command: TableReadComm... | .room .setup .readerGrid .readerPortrait .readerSelect .tempos .setupBody .setupAside ... | |
| LoadoutBanner | src/ui/apps/scenes/loadout/loadout-banner.tsx | ({ receipt, now, working, busy, onUndo }: { receipt: LoadoutReceipt; now: number; working: boolean; busy: boolean; on... | ||
| LoadoutBar | src/ui/apps/scenes/loadout/loadout-bar.tsx | ({ ctx, scene, busy, onSettings, now = Date.now, tickMs = 15_000 }: { ctx: AppContext; scene: OpenScene; busy: boolea... | ||
| LoadoutReview | src/ui/apps/scenes/loadout/loadout-review.tsx | ({ ctx, chatId, loadout, applying, onCancel, onApply }: { ctx: AppContext; chatId: string; loadout: LoadoutRecord; ap... | ||
| LoadoutSaveDialog | src/ui/apps/scenes/loadout/loadout-save-dialog.tsx | ({ ctx, chatId, loadouts, onSaved, onClose }: { ctx: AppContext; chatId: string; loadouts: readonly LoadoutRecord[]; ... | ||
| LoadoutSwitcher | src/ui/apps/scenes/loadout/loadout-switcher.tsx | ({ ctx, chatId, list, active, busy, onApply, onSaveCurrent, onRetry, onClose }: { ctx: AppContext; chatId: string; li... | ||
| LockNotice | src/ui/apps/scenes/compendium/standardize/standardize-cards.tsx | () | ||
| LogitBiasManager | src/ui/apps/scenes/generation-params-bias.tsx | ({ entries, model, onChange }: { entries: BiasEntry[]; model: string | undefined; onChange(entries: BiasEntry[]): voi... | ||
| Lore | src/ui/apps/scenes/context/tab-lore.tsx | ({ trace }: { trace: SceneTrace }) | ||
| LoreAdvanced | src/ui/apps/scenes/messenger/panels/lore/lore-inspector-advanced.tsx | ({ entry, groups, candidates, onPatch }: { entry: LorebookEntry; groups: readonly string[]; candidates: readonly { id... | ||
| LorebookEditor | src/ui/apps/workbench/LorebookEditor.tsx | ({ entity, revision, ctx, piece, topRight }: LorebookEditorProps) | .room .stage .soon .ghostRoom .ghostErr .skel .ghostActions .recents ... | |
| LorebookRows | src/ui/apps/scenes/messenger/settings/scene/world.tsx | ({ a, open }: { a: WingArgs; open: OpenProgram }) | One switch per lorebook the scene reads, plus the way to the Lorebooks program. The Control Booth page shows the same rows. | |
| LoreBooks | src/ui/apps/scenes/messenger/panels/lore/lore-books.tsx | ({ w, characterName }: { w: LoreApi; characterName: string }) | ||
| LoreBookSettings | src/ui/apps/workbench/lore/book-settings.tsx | ({ body, styles, onBook }: BookSettingsProps) | ||
| LorebooksSection | src/ui/apps/scenes/cast/cast-lorebooks.tsx | ({ ctx, chatId, onOpenEditor }: { ctx: AppContext; chatId: string; onOpenEditor(): void }) | ||
| LoreBulkBar | src/ui/apps/workbench/lore/bulk-bar.tsx | ({ count, styles, onEnable, onDelete, onClear, onMove, }: BulkBarProps) | ||
| LoreCategories | src/ui/components/lore-categories/index.tsx | ({ categories, onChange }: LoreCategoriesProps) | .wrap .head .label .empty .list .row .name .id ... | |
| LoreEntryPage | src/ui/apps/workbench/lore/entry-page.tsx | ({ entry, writeFor, styles, onPatch, index, count, onPrev, onNext, tokenEstimate, prefs, }: EntryPageProps) | ||
| LoreEntryRail | src/ui/apps/workbench/lore/entry-rail.tsx | ({ body, focusedId, entries, notes, styles, onOpenHealth, onOpenChanges, onOpenRehearsal, onSelectEntry, }: EntryRail... | ||
| LoreEntryToc | src/ui/apps/workbench/lore/entry-toc.tsx | ({ bookId, searchRevision, draftChanged, search, entries, focusedId, writeFor, styles, categories = [], onSelect, onA... | ||
| LoreHeader | src/ui/apps/scenes/scene-lore-books.tsx | ({ title, stats, onBack, onLibrary }: { title: string; stats?: string; onBack?(): void; onLibrary?(): void; }) | ||
| LoreHelp | src/ui/apps/scenes/lore-fields.tsx | ({ title, text }: { title: string; text: string }) | RoleCall's "?" help button: the title and its description ride the hover text. | |
| LoreInspector | src/ui/apps/scenes/messenger/panels/lore/lore-inspector.tsx | ({ w, book, entry }: { w: LoreApi; book: SceneLoreBook; entry: LorebookEntry }) | ||
| LoreList | src/ui/apps/scenes/messenger/panels/lore/lore-list.tsx | ({ w }: { w: LoreApi }) | ||
| LoreNode | src/ui/apps/workbench/nodes/EngineNodes.tsx | (p: LoreNodeProps) | .view .head .grow .addWrap .addMenu .area .canvas .world ... | |
| LoreNum | src/ui/apps/scenes/lore-fields.tsx | ({ value, onChange, fallback, min, max, step, float, className, label }: { value: number; onChange(n: number): void; ... | ||
| LorePanel | src/ui/apps/scenes/messenger/panels/lore/lore-panel.tsx | ({ ctx, chat, characterName, onLore }: { ctx: AppContext; chat: Chat; characterName: string; onLore(books: SceneLoreB... | ||
| LoreSpecialTriggers | src/ui/components/lore-special-triggers/index.tsx | ({ triggers, onChange, advanced = false, }: LoreSpecialTriggersProps) | .wrap .menu .section .note .badge | |
| LoreState | src/ui/apps/scenes/context/lore-state.tsx | ({ ctx, chat, state }: { ctx: AppContext; chat: Chat; state: TraceState }) | ||
| LoreSwitch | src/ui/apps/scenes/lore-fields.tsx | ({ on, onChange, label }: { on: boolean; onChange(on: boolean): void; label: string }) | ||
| LoreWing | src/ui/apps/scenes/scene-lore-wing.tsx | ({ ctx, chat, characterName, onLore }: { ctx: AppContext; chat: Chat; characterName: string; onLore(books: SceneLoreB... | The Lorebook wing for Full Chat. | |
| LoreWorkshopDialog | src/ui/apps/library/lore-workshop-dialog.tsx | ({ ctx, state, onDone, onDismiss, }: LoreWorkshopDialogProps) | ||
| MachineRows | src/ui/apps/scenes/messenger/settings/user/studio.tsx | ({ ctx }: { ctx: AppContext }) | Whole-machine tools (remote access, updates, the engine checkouts, about) are the Settings app's own pages. | |
| MacroAssist | src/ui/apps/workbench/workshop/macros/chips.tsx | ({ value, onInsert, vars }: MacroAssistProps) | .macroAssist .macroChips .macroPreview | |
| MacroChips | src/ui/apps/workbench/pieces/macro-chips.tsx | ({ macros, onInsert, children }: { macros: readonly MacroHint[]; onInsert(snippet: string): void; children?: ReactNod... | .root .problem .cols .flush .colsPair .rail .railTitle .section ... | |
| MacroErrors | src/ui/apps/scenes/context/tab-macros.tsx | ({ errors }: { errors: MacroReport["errors"] }) | The failed macros, each as written with the engine's message (shared with State's Macro Errors tile). | |
| MacroLab | src/ui/apps/macro-lab/index.tsx | ({ ctx }: { ctx: AppContext }) | .room .lenses .inst .boxes .stack .box .boxHead .boxTitle ... | |
| MacroPreview | src/ui/apps/scenes/macro-preview.tsx | ({ content, prefs }: { content: string; prefs: AppContext["prefs"] }) | ||
| MacroReference | src/ui/apps/workbench/preset/macro-reference.tsx | ({ groups }: MacroReferenceProps) | .macros .macrosHead .macrosLabel .module .css .macrosHint .macroScroll .macroGroup ... | |
| Macros | src/ui/apps/scenes/context/tab-macros.tsx | ({ trace }: { trace: SceneTrace }) | ||
| MapBody | src/ui/apps/scenes/compendium/storyboards/dossier-views.tsx | ({ d, open, ai }: { d: MapDossier; open: Open; ai: JSX.Element }) | ||
| MarinaraFolderToc | src/ui/apps/workbench/lore/folder-toc.tsx | ({ entries, categories, edges, focusedId, selectedFolderId, collapsed, writeFor, styles, bookName, onSelectEntry, onS... | ||
| MarkerMenu | src/ui/apps/workbench/preset/marker-menu.tsx | ({ placed, onAdd }: { placed: ReadonlySet; onAdd(slot: string): void }) | .toolbar .topRow .searchWrap .searchIcon .search .stats .statNum .actions ... | |
| MasterSection | src/ui/apps/scenes/compendium/tabs/settings/master.tsx | ({ compendium, set }: SectionProps) | ||
| MemberFace | src/ui/apps/scenes/messenger/panels/cast/member-face.tsx | ({ row, big }: { row: RosterRow; big?: boolean }) | ||
| MemberRow | src/ui/apps/scenes/messenger/panels/cast/member-row.tsx | ({ chatId, row, onProfile, onChange }: MemberRowProps) | ||
| Members | src/ui/apps/scenes/messenger/shell/members.tsx | ({ ctx, scene, name, canOpen, drawer = false, onOpen, onClose }: MembersProps) | ||
| MembersPanel | src/ui/apps/scenes/messenger/panels/cast/members-panel.tsx | ({ ctx, scene, onOpenProgram }: { ctx: AppContext; scene: OpenScene; onOpenProgram(id: string): void }) | ||
| MemoriesPanel | src/ui/apps/scenes/props/trackers/memories/memories-panel.tsx | ({ ctx, chat, onChat, popOut }: PopoutContext) | ||
| MemoryDefaultRows | src/ui/apps/scenes/messenger/settings/user/memory-defaults.tsx | ({ ctx }: { ctx: AppContext }) | ||
| MemoryTab | src/ui/apps/scenes/context/memory-tab.tsx | ({ ctx, scene, onChat }: ContextProps) | ||
| Menu | src/ui/shell/Menu.tsx | () | ||
| MenuItem | src/ui/components/button/rows.tsx | ({ children, icon, hint, danger, checked, description, accent, vars, "data-part": part, type = "button", role = "menu... | .row .item .fold .lead .text .clip .sub .meta ... | |
| MenuList | src/ui/apps/scenes/messenger/frames/context-menu.tsx | ({ items, label, onDone, onEscape, autoFocus = true }: MenuListProps) | ||
| MessageAct | src/ui/apps/scenes/stage-message-act.tsx | ({ look, set, prefs, onSet }: StageActProps) | ||
| MessageFormatField | src/ui/apps/settings/sections/models-message-format.tsx | ({ value, onChange }: { value: MessageFormat; onChange(next: MessageFormat): void }) | .list .empty .row .rowActive .pick .name .model .key ... | |
| Messenger | src/ui/apps/scenes/messenger/messenger.tsx | ({ args, ...props }: Omit<MessengerChromeProps, "renderSettings" | "renderPersonaSwap" | "onChat"> & { args: WingArgs... | args is what the settings content reads of the page; null while the scene loads, which leaves the settings layer unopened. |
|
| MessengerBooth | src/ui/apps/scenes/messenger/panels/booth/messenger-booth.tsx | ({ args, open }: { args: WingArgs; open(programId: string): void }) | ||
| MessengerChrome | src/ui/apps/scenes/messenger/messenger-chrome.tsx | ({ ctx, chatId, scene, name, personaName, programs, request, actions, loreBooks, onBack, onTake, onSurface, renderPro... | ||
| MessengerDirectorPanel | src/ui/apps/scenes/messenger/panels/director/director-view.tsx | ({ ctx, chat, id, popOut, onChat }: PopoutContext) | ||
| MessengerTrackersPanel | src/ui/apps/scenes/messenger/panels/trackers/trackers-panel.tsx | ({ ctx, chat, onChat, ids }: PopoutContext & { ids: readonly string[] }) | ||
| MetaRow | src/ui/apps/scenes/scene-meta.tsx | (p: MetaFacts & { versions?: { index: number; count: number; isNew: boolean; busy: boolean; onPrev(): void; onNext():... | ||
| Meter | src/ui/apps/scenes/compendium/storyboards/dossier-parts.tsx | ({ label, value, max = 100, tone }: { label: string; value: number; max?: number; tone: Tone }) | ||
| MeterBar | src/ui/agent/kit-meters.tsx | ({ tokens, maxContext, }: { tokens: Tokens; maxContext: number | undefined; }) | The composed row, which is the single widget the window drops in. | |
| MiniSelect | src/ui/apps/workbench/workshop/mini-select.tsx | ({ opts, value, onChange }: MiniSelectProps) | .shell .rail .railhead .icoSealed .editor .ehead .sub .add ... | |
| MobileEditorHead | src/ui/components/mobile-editor-head/index.tsx | ({ name, sub, dirty, saving, onBack, onSave, menu }: MobileEditorHeadProps) | Back / name / save / kebab at 2.2rem touch targets; the kebab holds the long tail. | .head .name .kebabWrap .menu |
| ModeGuided | src/ui/apps/workbench/regex/mode-guided.tsx | ({ rule, writeFor, styles, onPatch, onEscape }: ModeGuidedProps) | ||
| ModelChoice | src/ui/apps/workbench/promptbook/model-choice.tsx | ({ ctx, value, onChange }: { ctx: AppContext; value: ChatConnection | undefined; onChange(c: ChatConnection): void }) | ||
| ModelPick | src/ui/apps/scenes/final-cut/fc-pass-chrome.tsx | ({ pass, models, onChange }: { pass: FinalCutPass; models: SceneModels; onChange: Change }) | ||
| ModelRow | src/ui/apps/scenes/messenger/settings/scene/finalcut-kit.tsx | ({ label, description, current, models, onPick }: { label: string; description: string; current: FinalCutPass["connec... | A model of the scene's connections, or "the scene's model" (nothing set). The select twin of Full Chat's model picker; the pick is the same connection field. |
|
| ModelSection | src/ui/apps/scenes/compendium/tabs/settings/model.tsx | ({ chat, compendium, models, set }: SectionProps) | ||
| ModelSelect | src/ui/apps/scenes/messenger/settings/scene/model-select.tsx | ({ models, current, none, onPick, ...copy }: RowCopy & { models: SceneModels; current: ChatConnection | undefined | n... | none is the empty choice's words; current is the saved model, if any. A pick of the empty choice calls onPick(null). |
|
| ModeSelect | src/ui/apps/workbench/lore/entry-toc-mode.tsx | ({ mode, vectorOk, styles, onChange, }: { mode: EntryFireMode; vectorOk: boolean; styles: Readonly<Record<string, str... | ||
| ModeWords | src/ui/apps/workbench/regex/mode-words.tsx | ({ rule, styles, onPatch }: ModeWordsProps) | ||
| MonoTag | src/ui/components/mono-tag/index.tsx | ({ children, dim }: MonoTagProps) | A mono, uppercase, letter-spaced meta label. | .tag .tagDim |
| MoodDot | src/ui/apps/scenes/props/story-director/director-parts.tsx | ({ mood }: { mood: string }) | RoleCall's MoodIndicator: red for danger, amber for tense, green for calm, violet otherwise. | |
| MotionAct | src/ui/apps/scenes/stage-motion-act.tsx | ({ look, set, prefs, onSet }: StageActProps) | ||
| MoveToFolderDialog | src/ui/apps/scenes/scenes-dialogs.tsx | ({ scene, folders, onCancel, onPick }: { scene: Pick<SceneSummary, "title" | "folderId">; folders: (SceneFolder & { c... | ||
| MusicDrills | src/ui/apps/scenes/messenger/settings/user/music.tsx | ({ open, library }: { open: OpenProgram; library: boolean }) | ||
| MusicMini | src/ui/apps/scenes/stage-music-mini.tsx | ({ ctx, player = sharedMusic, onExpand = () => openStageTab("music") }: { ctx: AppContext; player?: MusicPlayer; onEx... | ||
| MusicPanel | src/ui/apps/scenes/stage-music-panel.tsx | ({ ctx, player = sharedMusic }: { ctx: AppContext; player?: MusicPlayer }) | ||
| MusicTabRow | src/ui/apps/scenes/props/mood-music/music-tab-row.tsx | ({ ctx }: { ctx: AppContext; chat: Chat }) | ||
| NamedAssets | src/ui/components/named-assets/index.tsx | ({ value, onChange, assetFiles, macroHint = true, upload, onUploadGrant, }: NamedAssetsProps) | .sheet .table .assetScroll .thead .tbody .spacer .virtualRow .kind ... | |
| NamedAssetsDialog | src/ui/components/named-assets/dialog.tsx | ({ characterName, value, upload, assetFiles, onApply, discardUploads, pinUploads, unpinUploads, onClose, }: NamedAsse... | .sheet .table .assetScroll .thead .tbody .spacer .virtualRow .kind ... | |
| NamedSwatches | src/ui/apps/scenes/cast/cast-palette.tsx | ({ value, onChange, signature, onSignature, signatureCaption, lockSignatureName }: { value: readonly NamedSwatch[]; o... | ||
| NavigationOverlay | src/ui/shell/NavigationOverlay.tsx | ({ onNavigate, ctx, Widgets, onSurfaceTarget }: { onNavigate(): void; ctx?: AppContext; Widgets?: BunzaiApp["OverlayW... | .scrim .sheet .layout .appSurface .header .panel .quick .body ... | |
| NewInDeckButton | src/ui/apps/library/new-in-deck-button.tsx | ({ kind, ctx, onCreated, compact = false, tile = false }: NewInDeckButtonProps) | ||
| NewPersona | src/ui/apps/scenes/cast/cast-dialogs.tsx | ({ busy, onCreate, onCancel }: { busy: boolean; onCreate(input: { name: string; content: string }, cast: boolean): vo... | The New persona form: a name and the identity text, then Create or Create and cast. | |
| NewStoryCard | src/ui/apps/scenes/scenes-cards.tsx | ({ characterName, onStart }: { characterName: string; onStart(): void }) | ||
| NextSend | src/ui/apps/scenes/context/next-send.tsx | ({ state }: { state: ForecastState }) | ||
| NodeCanvas | src/ui/apps/workbench/nodes/NodeCanvas.tsx | (p: NodeCanvasProps) | .view .head .grow .addWrap .addMenu .area .canvas .world ... | |
| NodesView | src/ui/apps/workbench/nodes/NodesView.tsx | ({ ctx, pieces, onView }: { ctx: AppContext; pieces: readonly StudioEntitySummary[]; onView(view: View): void }) | .view .head .grow .addWrap .addMenu .area .canvas .world ... | |
| NoMatchNotice | src/ui/apps/library/search-bar.tsx | ({ query, deckPlural, deckTotal, elsewhere, onJump, onClear, }: NoMatchNoticeProps) | ||
| NovelAiBiasBlock | src/ui/apps/workbench/lore/platforms/novelai-bias.tsx | ({ entry, styles, onPatch, }: { entry: LorebookEntry; styles: Readonly<Record<string, string>>; onPatch: (patch: Part... | ||
| NumberBody | src/ui/_shared/field-bodies.tsx | ({ field, tops, update }: { field: BodyField; tops: readonly string[]; update: Update }) | .toc .module .css .title .rows .add .page .pager ... |
Shared UI helpers (src/ui/_shared, .ts)
| Name | File | Signature | Doc | Styles |
|---|---|---|---|---|
| buildTimeline | src/ui/_shared/version-history.ts | ( releases: readonly ReleaseInfo[], installed: string, hasMore = false, ) | Build the timeline against the running version. Relation and behind-count come from the SIGN of | |
| createArtCache | src/ui/_shared/art-cache.ts | ( limits: { maxEntries?: number; maxBytes?: number } = {}, deps: Partial = {}, ) | In-flight requests reserve the route's full 32 MiB maximum until the actual Blob size is known. |