FS

fancy-screens

@particle-academy/fancy-screens

Multi-screen application shell with cross-screen agent presence.

TSUI · 2 components2 components
$npm install @particle-academy/fancy-screens
Authoring surface
Humans compose it

Controlled value + onChange, JSON-friendly props, terse defaults — so people (and agents) build it fast.

Inhabited surface
Agents drive it over MCP

A bridge in @particle-academy/agent-integrations exposes typed tools — agents read and mutate state through stable handles, never DOM scraping.

screen_focusscreen_register
Why
Without fancy-screens, Human+ apps must either rebuild screen coordination from scratch or rely on heavyweight framework patterns that hide state from agents. DOM scraping and tab-based solutions aren't addressable or agent-introspectable; Zustand alone doesn't bridge surfaces or enable presence layers. Teams end up reinventing the same affordances — surface registry, state enumeration, cross-surface presence markers, schema-driven rendering — for every new app.
What
fancy-screens is a deliberately minimal (~400 lines) screen registry and coordination layer for apps where humans and agents work in parallel across addressable surfaces. It exports <Screen.System> (the provider), <Screen id title> (self-registering addressable surfaces), useRegisterStore(name, store) (binds Zustand stores to screens so agents enumerate and mutate them), useScreens() (returns a snapshot of every mounted screen and its state), and schema-driven rendering (<Screen schema={...}> + registerSchemaComponent) so an LLM can emit a JSON page and the client renders it. State lives entirely in Zustand; fancy-screens only discovers and surfaces it.
How
Install with npm install @particle-academy/fancy-screens zustand. Wrap your app in <Screen.System>, declare <Screen id="profile"> surfaces, call useRegisterStore("user", useUserStore) inside a screen to bind a Zustand store, and use useScreens() anywhere to read the registry. For schema-driven mode, call registerSchemaComponent("Button", ButtonImpl) once, then pass schema={{type: "Button", ...}} to <Screen>.

Components

2 components · click any tile for a full demo, source, and install snippet.

ScreenSystemOpen →
inbox
compose
Root provider.
ScreenOpen →
screen.id = "profile"
Notifications
storeKeys: [user, prefs]
Individual screen container.