diff --git a/app/config/settings.json b/app/config/settings.json index 22101bba..65e95ada 100644 --- a/app/config/settings.json +++ b/app/config/settings.json @@ -25,7 +25,7 @@ "openai": "", "anthropic": "", "google": "", - "byteplus": "62a75ab1-0f00-4d4e-8873-23551e624375", + "byteplus": "", "openrouter": "" }, "endpoints": { diff --git a/app/ui_layer/browser/frontend/public/mascot-backgrounds/background_1_day.jpg b/app/ui_layer/browser/frontend/public/mascot-backgrounds/background_1_day.jpg new file mode 100644 index 00000000..a8cc2c6b Binary files /dev/null and b/app/ui_layer/browser/frontend/public/mascot-backgrounds/background_1_day.jpg differ diff --git a/app/ui_layer/browser/frontend/public/mascot-backgrounds/background_1_night.jpg b/app/ui_layer/browser/frontend/public/mascot-backgrounds/background_1_night.jpg new file mode 100644 index 00000000..cec60bf2 Binary files /dev/null and b/app/ui_layer/browser/frontend/public/mascot-backgrounds/background_1_night.jpg differ diff --git a/app/ui_layer/browser/frontend/src/pages/Chat/ChatPage.tsx b/app/ui_layer/browser/frontend/src/pages/Chat/ChatPage.tsx index 44db3455..a20cacc8 100644 --- a/app/ui_layer/browser/frontend/src/pages/Chat/ChatPage.tsx +++ b/app/ui_layer/browser/frontend/src/pages/Chat/ChatPage.tsx @@ -3,11 +3,12 @@ import { X, Loader2, Reply } from 'lucide-react' import { useWebSocket } from '../../contexts/WebSocketContext' import { IconButton, StatusIndicator } from '../../components/ui' import { Chat } from '../../components/Chat' +import { MascotDisplay } from '@mascot' import { getActivePlaceholder } from '../../utils/taskPlaceholder' import styles from './ChatPage.module.css' // Panel width limits -const DEFAULT_PANEL_WIDTH = 380 +const DEFAULT_PANEL_WIDTH = 460 const MIN_PANEL_WIDTH = 200 const MAX_PANEL_WIDTH = 800 @@ -93,6 +94,7 @@ export function ChatPage() { {/* Task/Action Panel */}
+

Tasks & Actions

diff --git a/app/ui_layer/browser/frontend/src/pages/LivingUI/CraftBotPet.tsx b/app/ui_layer/browser/frontend/src/pages/LivingUI/CraftBotPet.tsx deleted file mode 100644 index 2f610333..00000000 --- a/app/ui_layer/browser/frontend/src/pages/LivingUI/CraftBotPet.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import { useEffect, useRef, useState } from 'react' -import styles from './LivingUIPage.module.css' - -export type PetState = 'creating' | 'launching' | 'stopped' - -interface Props { - state: PetState - progress?: number - indeterminate?: boolean - completedCount?: number - size?: number -} - -// Eye path d-values lifted from the original logo (paths 3 and 2 in the SVG). -// Keeping them in their own wrappers lets us apply CSS transforms (blink/close) -// without fighting the SVG-attribute transforms on the paths themselves. -const LEFT_EYE_D = - 'M0 0 C2.92937654 1.81310142 5.43647949 3.87295899 7 7 C7.12311126 9.56761586 7.18836415 12.10706019 7.203125 14.67578125 C7.20882507 15.43795456 7.21452515 16.20012787 7.22039795 16.98539734 C7.22985081 18.60019542 7.23638307 20.21501282 7.24023438 21.82983398 C7.24992133 24.29250092 7.28093303 26.75432656 7.3125 29.21679688 C7.3190321 30.78645338 7.32428176 32.35611586 7.328125 33.92578125 C7.3404718 34.65928299 7.3528186 35.39278473 7.36553955 36.14851379 C7.34154924 41.69538739 6.08230904 44.91769096 2.1875 48.8125 C-0.8527265 50.46290867 -2.57949832 50.54728027 -6 50 C-8.9228334 48.16899068 -11.43323854 46.13352292 -13 43 C-13.28424778 37.93535225 -13.31377183 32.86972252 -13.35009766 27.79785156 C-13.36663059 26.1063051 -13.39388581 24.41482773 -13.43212891 22.72363281 C-13.48710365 20.27893001 -13.50880304 17.835864 -13.5234375 15.390625 C-13.54610687 14.64041077 -13.56877625 13.89019653 -13.59213257 13.11724854 C-13.57625216 9.13973933 -13.06467198 6.59267156 -10.59228516 3.53808594 C-6.97219204 -0.00631866 -5.04757551 -0.58241256 0 0 Z' - -const RIGHT_EYE_D = - 'M0 0 C4.33669495 0.36139125 5.72030822 1.28280822 8.75 4.3125 C11.19715759 7.98323639 11.07300278 10.80084797 11.0859375 15.05078125 C11.0925943 15.80916794 11.0992511 16.56755463 11.10610962 17.34892273 C11.11623038 18.95353778 11.12092682 20.55819486 11.12060547 22.1628418 C11.12496613 24.60602159 11.16125324 27.04737571 11.19921875 29.49023438 C11.20508977 31.05207718 11.20905726 32.61392854 11.2109375 34.17578125 C11.22530853 34.90098465 11.23967957 35.62618805 11.25448608 36.37336731 C11.20886626 41.49335244 9.99115623 44.38403683 6.75 48.3125 C3.0126144 50.8040904 1.17668417 50.77043285 -3.25 50.3125 C-6.00329021 48.51687595 -7.77627461 47.25995078 -9.25 44.3125 C-9.53474008 38.94460889 -9.56375869 33.57565738 -9.60009766 28.20092773 C-9.61665091 26.40554842 -9.6439329 24.61023484 -9.68212891 22.81518555 C-9.73696923 20.22409959 -9.75878148 17.63455732 -9.7734375 15.04296875 C-9.79610687 14.24384567 -9.81877625 13.4447226 -9.84213257 12.62138367 C-9.82575533 8.28890941 -9.65327311 6.79951266 -6.77978516 3.3293457 C-5.94495605 2.66378662 -5.11012695 1.99822754 -4.25 1.3125 C-3.25 0.3125 -3.25 0.3125 0 0 Z' - -export function CraftBotPet({ - state, - progress = 0, - indeterminate = false, - completedCount = 0, - size = 140, -}: Props) { - const [wiggling, setWiggling] = useState(false) - const prevCompleted = useRef(completedCount) - - useEffect(() => { - if (completedCount > prevCompleted.current) { - setWiggling(true) - const t = setTimeout(() => setWiggling(false), 600) - prevCompleted.current = completedCount - return () => clearTimeout(t) - } - prevCompleted.current = completedCount - }, [completedCount]) - - const sleeping = state === 'stopped' - const showBlush = state === 'creating' && progress > 60 - const antennaActive = state !== 'stopped' - const breatheClass = sleeping ? styles.petSleepBreathe : styles.petBreathe - const eyeClass = sleeping ? styles.petEyeClosed : styles.petEye - - return ( - - ) -} diff --git a/app/ui_layer/browser/frontend/src/pages/LivingUI/CreationProgress.tsx b/app/ui_layer/browser/frontend/src/pages/LivingUI/CreationProgress.tsx index 33a23342..59ed1124 100644 --- a/app/ui_layer/browser/frontend/src/pages/LivingUI/CreationProgress.tsx +++ b/app/ui_layer/browser/frontend/src/pages/LivingUI/CreationProgress.tsx @@ -2,7 +2,7 @@ import { useMemo } from 'react' import { Lightbulb } from 'lucide-react' import type { LivingUITodo } from '../../types' import { useRotatingHint } from '../../hooks' -import { CraftBotPet } from './CraftBotPet' +import { CraftBotMascot } from '@mascot' import styles from './LivingUIPage.module.css' interface Props { @@ -76,10 +76,9 @@ export function CreationProgress({ projectName, todos }: Props) { return (
-

Creating {projectName}

diff --git a/app/ui_layer/browser/frontend/src/pages/LivingUI/LivingUIPage.module.css b/app/ui_layer/browser/frontend/src/pages/LivingUI/LivingUIPage.module.css index 21924917..26941ffb 100644 --- a/app/ui_layer/browser/frontend/src/pages/LivingUI/LivingUIPage.module.css +++ b/app/ui_layer/browser/frontend/src/pages/LivingUI/LivingUIPage.module.css @@ -156,121 +156,6 @@ color: var(--text-muted); } -/* CraftBot Pet */ -.petWrapper { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: var(--space-2); -} - -.petFloat { - display: inline-flex; - transform-origin: 50% 85%; -} - -.petBreathe { - transform-origin: 50% 60%; -} - -.petSleepBreathe { - transform-origin: 50% 60%; -} - -.petEye { - transform-origin: center; - transform-box: fill-box; - animation: petBlink 4.5s infinite; -} - -.petEyeLeft { - animation-delay: 0ms; -} - -.petEyeRight { - animation-delay: 120ms; -} - -.petEyeClosed { - transform-origin: center; - transform-box: fill-box; - transform: scaleY(0.08); -} - -.petAntennaPulse { - transform-origin: center; - transform-box: fill-box; -} - -.petBlushPulse { -} - -.petWiggle { -} - -/* Body silhouette is near-white — in light mode it blends into the bg, - so stroke a thin outline. Dark mode needs no outline. */ -.petBody { - stroke: none; -} - -[data-theme="light"] .petBody { - stroke: var(--text-muted, var(--border-secondary)); - stroke-width: 3; - paint-order: stroke fill; -} - -.petSleepZ { - transform-origin: center; - transform-box: fill-box; - animation: petSleepZ 2.4s ease-in-out infinite; - opacity: 0; -} - -.petSleepZDelayed { - animation-delay: 1.2s; -} - -@keyframes petFloat { - 0%, 100% { transform: translateY(0); } - 50% { transform: translateY(-6px); } -} - -@keyframes petBreathe { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.015); } -} - -@keyframes petBlink { - 0%, 92%, 100% { transform: scaleY(1); } - 95%, 97% { transform: scaleY(0.05); } -} - -@keyframes petAntennaPulse { - 0%, 100% { opacity: 0.45; transform: scale(1); } - 50% { opacity: 1; transform: scale(1.12); } -} - -@keyframes petBlushPulse { - 0%, 100% { opacity: 0.45; } - 50% { opacity: 0.9; } -} - -@keyframes petWiggle { - 0% { transform: translateY(0) rotate(0deg); } - 20% { transform: translateY(-4px) rotate(-6deg); } - 45% { transform: translateY(-2px) rotate(6deg); } - 70% { transform: translateY(-1px) rotate(-3deg); } - 100% { transform: translateY(0) rotate(0deg); } -} - -@keyframes petSleepZ { - 0% { opacity: 0; transform: translateY(0); } - 30% { opacity: 1; } - 100% { opacity: 0; transform: translateY(-14px); } -} - - /* Creation Progress */ .creationProgress { display: flex; diff --git a/app/ui_layer/browser/frontend/src/pages/LivingUI/LivingUIPage.tsx b/app/ui_layer/browser/frontend/src/pages/LivingUI/LivingUIPage.tsx index 2871a755..4e5eefa8 100644 --- a/app/ui_layer/browser/frontend/src/pages/LivingUI/LivingUIPage.tsx +++ b/app/ui_layer/browser/frontend/src/pages/LivingUI/LivingUIPage.tsx @@ -11,7 +11,7 @@ import { Maximize2, Minimize2, } from 'lucide-react' -import { CraftBotPet } from './CraftBotPet' +import { CraftBotMascot } from '@mascot' import { useWebSocket } from '../../contexts/WebSocketContext' import { useFullscreen } from '../../contexts/FullscreenContext' import { Button } from '../../components/ui/Button' @@ -267,7 +267,7 @@ export function LivingUIPage() { /> ) : project.status === 'launching' ? (
- +

Launching Living UI...

Installing dependencies, running tests, starting servers

@@ -282,7 +282,7 @@ export function LivingUIPage() {
) : (
- +

Living UI is not running