Skip to main content

The Right Rail and the Expanded Rail

Command Center shows AI in two places that share one conversation: a right rail beside the page the person is working on, and the expanded rail, a full page for longer work. The package draws both, frame and all, so an application built on Command Center AI looks exactly like Command Center, and Command Center draws its own with the same components. Its agent skill is compose-command-center-ai-rail.

ComponentWhat it draws
ChatRailThe right rail: the panel with the theme's gradient, tinted edge, and glows; the header with the Agent's icon tile, the assistant's name and subtitle, Expand, and Close; and the body.
ChatLauncherThe floating button that opens the rail.
ChatPageLayoutThe expanded rail: the session explorer, the header with the Agent, the session, and the run status, the page's actions, and the context card.
AgentSessionExplorerThe person's sessions under their Agents, with search, archive, and archived sessions. ChatPageLayout draws it from its explorer props.
ChatThreadThe conversation, with surface="overlay" in the rail and surface="page" in the expanded rail.

Mount one ChatEngineProvider above both, so switching between them keeps the conversation. The same rail and expanded rail work over an Agent on the developer's machine (An Agent on your machine).

The right rail​

import { ChatLauncher, ChatRail, ChatThread } from "@dev-mainsequence/command-center-ai";

{railOpen ? (
<ChatRail
title="Main Sequence AI"
subtitle="Assistant rail."
mode={docked ? "docked" : "overlay"}
onExpand={expand}
onClose={() => setRailOpen(false)}
>
<ChatThread copy={copy} surface="overlay" viewer={viewer} onOpenModelProviderSettings={openProviders} />
</ChatRail>
) : (
<ChatLauncher label="Ask Main Sequence AI" onClick={() => setRailOpen(true)} />
)}
AspectRule
Size and place540px wide, on the right edge, the full height below the application's top bar.
DockedFrom a 1400px viewport: mode="docked" in a column of the layout grid (grid-template-columns: <sidebar> minmax(0, 1fr) 540px), so the page narrows.
OverlayBelow 1400px: mode="overlay" fixes it over the page, min(540px, 100vw - 10px) wide, with a shadow. rightOffset keeps it clear of a column the application holds at the right.
Headertitle and subtitle; detail adds a pill, for example the session; onExpand adds Expand. The tile shows the engine's active Agent unless agentUid names one.
Tonetone="accent" for a rail opened directly on one Agent, as Command Center does for a code repository's Agent.
ClosingClose returns the engine to the default session when another Agent's session was open, then calls onClose.
OpeningA top-bar toggle or ChatLauncher. Show the launcher only while neither the rail nor the expanded rail is on screen.

The expanded rail​

import { ChatPageLayout, ChatThread } from "@dev-mainsequence/command-center-ai";

<div style={{ height: "calc(100dvh - 56px)" }}>
<ChatPageLayout
explorer={{
onOpenSession: (id) => navigate(`/assistant?session=${encodeURIComponent(id)}`),
onOpenSessionDetails: (id) => navigate(`/assistant/sessions/${id}`),
environmentLabel: environment.name,
}}
onCreateSession={() => navigate("/assistant")}
onMinimize={minimizeToRail}
>
<ChatThread copy={copy} surface="page" viewer={viewer} onOpenModelProviderSettings={openProviders} />
</ChatPageLayout>
</div>
AspectRule
RouteExpand remembers where the person was, closes the rail, and opens the expanded rail's route with ?session=<id>. Minimize returns there and reopens the rail. The rail never shows on this route.
HeightChatPageLayout fills its parent; give the parent the height below the top bar.
Explorer320px at the left from 1024px, an overlay with a scrim below, collapsible at every width. Pass agents (uid, name) to list the Agents without recent sessions too.
HeaderThe Agent's name and the session's title, and the run status: Thinking and Responding in the brand colour, Complete, Error, Queued, and Working while the session works.
ActionsNew session (onCreateSession runs after it), Show context (showContext={false} hides it), Collapse, and Minimize (with onMinimize).
BlockingblockingState replaces the page while the application cannot show a session, for example while its default Agent opens.

A composer of your own​

An application that draws its own transcript still takes the composer from the package: ChatComposer has the input, Enter to send (Shift+Enter for a new line), Enter to queue while the Agent works, the send and stop controls, the model row, the queue strip, and the context footer. ChatQueueStrip is the queue strip alone. Never put either beside a ChatThread, which has both.

useChatComposerState() says whether the assistant can take a message now, for a status line, a disabled action elsewhere on the page, or a test:

statusMeaning
readycanSend: Enter sends.
workingThe Agent is working; queues: Enter adds the draft to the queue.
waking, loading, loading-modelsNot yet; a draft already written is kept.
unavailable, models-unavailableThe session, its Agent, or the models cannot take a message.
no-session, choosing-model, stopping, busyNo session is selected, a model must be chosen, a stop is confirming, or a session is being created.

reason carries the words the composer shows for every status but ready, and canWrite says whether the input takes typing. It is the same decision the composer obeys.

Look​

The rail's gradient, tinted edge, and glows are Command Center's look and part of the theme: every colour is a theme variable (--card fading into --background, --primary and --accent for the glows), so each preset draws its own and the stylesheet passes command-center-sdk theme audit. The top sheen and the floating shadow follow the SDK's dark class, which applyThemePresetToRoot sets. Do not restyle the frame; override the package's ms-chat-* classes only with ordinary rules that use theme variables, loaded after its stylesheet. The application's words go through the thread's copy, including a disclaimer that the assistant can make mistakes.

Verify​

Open the rail at 1440×900 (docked) and 1280×800 (overlay); expand, send a message, and minimize, and the conversation is the same in both; check 375×812 in a dark and a light theme; and run the theme audit. The Build an AI application guide covers the scripted stand-in.