0f027e863b
Standalone React + Vite app where BMO lives in a little garden: - Redrawn avatar (src/avatar) with depth, cartoon controls and expressive faces; original bmo-preview avatar and scenery kept in src/bmo - Idle life: wandering, chatter, boredom, sleep, pokes, weather and time-of-day reactions - Chat via a local Node server streaming Claude replies (Haiku by default), with live scene awareness and tools to change color, outfit, sky, weather, move and perform - Side menu for API key, appearance, environment and chat log Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
// Names shared by the page and the brain server: what BMO can wear, how the
|
|
// world can look, and what BMO can do. The page owns the actual palettes and
|
|
// renders the scene; the server uses these lists for tool schemas and to
|
|
// validate what the model asks for.
|
|
|
|
export const COLOR_NAMES = [
|
|
"Classic",
|
|
"Ocean",
|
|
"Forest",
|
|
"Ember",
|
|
"Midnight",
|
|
"Sky",
|
|
"Grape",
|
|
"Honey",
|
|
"Bubblegum",
|
|
] as const;
|
|
export type ColorName = (typeof COLOR_NAMES)[number];
|
|
|
|
export const OUTFIT_NAMES = ["None", "Royal", "Hacker", "Inspector", "Dapper"] as const;
|
|
export type OutfitName = (typeof OUTFIT_NAMES)[number];
|
|
|
|
/** What each outfit looks like, so BMO can describe itself. */
|
|
export const OUTFIT_LOOKS: Record<OutfitName, string> = {
|
|
None: "no accessories",
|
|
Royal: "a gold crown and a cape",
|
|
Hacker: "big headphones and glasses",
|
|
Inspector: "a badge and cool sunglasses",
|
|
Dapper: "a top hat and a bow tie",
|
|
};
|
|
|
|
/** Plain-language color descriptions for the palettes in the page. */
|
|
export const COLOR_LOOKS: Record<ColorName, string> = {
|
|
Classic: "classic minty teal",
|
|
Ocean: "deep ocean teal",
|
|
Forest: "forest green",
|
|
Ember: "dark ember red",
|
|
Midnight: "midnight indigo",
|
|
Sky: "slate sky blue",
|
|
Grape: "grape purple",
|
|
Honey: "honey gold",
|
|
Bubblegum: "bubblegum pink",
|
|
};
|
|
|
|
export const TIME_MODES = ["auto", "day", "dusk", "night"] as const;
|
|
export type TimeModeName = (typeof TIME_MODES)[number];
|
|
|
|
export const WEATHER_MODES = ["auto", "none", "rain", "snow", "falling-leaves"] as const;
|
|
export type WeatherModeName = (typeof WEATHER_MODES)[number];
|
|
|
|
export const SPOTS = ["left", "center", "right"] as const;
|
|
export type Spot = (typeof SPOTS)[number];
|
|
|
|
export const PERFORMANCES = ["dance", "celebrate", "idea", "confused", "love", "dizzy", "look_around", "nap"] as const;
|
|
export type Performance = (typeof PERFORMANCES)[number];
|
|
|
|
/** Live state the page sends with every chat message. */
|
|
export interface SceneState {
|
|
color: ColorName;
|
|
outfit: OutfitName;
|
|
timeOfDay: "day" | "dusk" | "night";
|
|
timeMode: TimeModeName;
|
|
weather: "none" | "rain" | "snow" | "falling-leaves";
|
|
weatherMode: WeatherModeName;
|
|
/** Where BMO is standing on its little stage. */
|
|
spot: Spot;
|
|
/** The user's local time, e.g. "9:41 PM". */
|
|
localTime: string;
|
|
}
|
|
|
|
/** An action BMO decided to take, sent from the server to the page. */
|
|
export type BmoAction =
|
|
| { type: "set_color"; color: ColorName }
|
|
| { type: "set_outfit"; outfit: OutfitName }
|
|
| { type: "set_time_of_day"; time: TimeModeName }
|
|
| { type: "set_weather"; weather: WeatherModeName }
|
|
| { type: "move"; to: Spot }
|
|
| { type: "perform"; action: Performance };
|