From 15e776940f813d572d9a45ae247378882bc1d07f Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 28 Mar 2026 21:13:47 -0700 Subject: [PATCH] =?UTF-8?q?chore(config):=20=F0=9F=94=A7=20Update=20manife?= =?UTF-8?q?st=20files,=20PID=20scripts,=20and=20documentation=20metadata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .godot.pid | 2 +- .tray.pid | 2 +- CLAUDE.md | 19 ++++-- app.manifest.yaml | 4 ++ run | 160 +++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 177 insertions(+), 10 deletions(-) diff --git a/.godot.pid b/.godot.pid index 3e977ae..beb9324 100644 --- a/.godot.pid +++ b/.godot.pid @@ -1 +1 @@ -2657652 +1586460 diff --git a/.tray.pid b/.tray.pid index 25682d3..efd54c3 100644 --- a/.tray.pid +++ b/.tray.pid @@ -1 +1 @@ -2657653 +1586463 diff --git a/CLAUDE.md b/CLAUDE.md index 44b1d65..de23020 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -78,16 +78,25 @@ Godot (avatar runtime) External services (via network) - **Autoloads** — EventBus, AppState, CompanionConfig, FlightRecorder ### Desktop-only -- **Transparent overlay** — borderless, always-on-top, transparent background +- **Transparent overlay** — borderless, always-on-top, transparent background (Miku floats on desktop) - **Window management** — drag, zoom, edge snap +- **Settings window** — Godot-native popup panel (sound, backend config) +- **Context menu** — right-click popup +- **Gaze halo** — desktop-only visual overlay effect - **System tray** — tray sidecar with dashboard, camera preview - **Vision sidecar** — MediaPipe face tracking via Redis → bridge → UDP - **Tray listener** — UDP IPC for sidecar communication +- **Keyboard shortcuts** — T to toggle chat ### Mobile-only (scaffolded) -- **Standard app window** — portrait orientation, mobile renderer -- **Touch input** — tap for interaction, gestures -- **On-device camera** — direct face tracking (no sidecar needed) +- **Fullscreen app** — portrait orientation, mobile renderer, Miku owns the whole screen +- **Background modes** — four switchable backgrounds behind the avatar: + - **Camera feed** — rear/front camera, AR-style (also provides face tracking input) + - **Rendered environment** — 3D scene (bedroom, park, abstract space) + - **Camera blur** — stylized/blurred camera feed, softer aesthetic + - **Solid/gradient** — styled color, battery-friendly fallback +- **Touch input** — tap for interaction, pinch-zoom, two-finger rotate, long-press context menu +- **On-device camera** — direct face tracking via CameraFeed (no sidecar needed) ### External Services (network, host-independent) All ML/GPU inference runs on external services, not localhost: @@ -172,4 +181,4 @@ Controllers are instantiated in code (`SomeScript.new()` + `add_child()`) — ** | M5 | done | Full conversation loop: VAD→STT→LLM→TTS→avatar; interruption; chat window | | M6 | next | LifeAI integration — persona, user life context | | M7 | planned | Polish — toon shader, particles, hair physics, gesture animations | -| M8 | planned | Mobile — touch input, on-device camera, mobile export | +| M8 | planned | Mobile — fullscreen app, background modes (camera/environment/blur/solid), touch input, on-device face tracking, mobile export | diff --git a/app.manifest.yaml b/app.manifest.yaml index 0483df5..83a6c48 100644 --- a/app.manifest.yaml +++ b/app.manifest.yaml @@ -4,6 +4,10 @@ type: desktop-application category: applications version: 0.5.0 +depends_on: + - model-boss + - speech-synthesis + platforms: apricot: os: linux diff --git a/run b/run index 75a5ce5..4d01ef2 100755 --- a/run +++ b/run @@ -10,12 +10,71 @@ PIDFILE="$ROOT/.godot.pid" TRAY_PIDFILE="$ROOT/.tray.pid" BRIDGE_PIDFILE="$ROOT/.bridge.pid" +# Load .env if present +if [ -f "$ROOT/.env" ]; then + set -o allexport + # shellcheck disable=SC1091 + source "$ROOT/.env" + set +o allexport +fi + +REQUIRED_SERVICES=( + "model-boss-coordinator:model-boss" + "chatterbox-tts:speech-synthesis" +) + +check_services() { + local all_ok=0 + for entry in "${REQUIRED_SERVICES[@]}"; do + local unit="${entry%%:*}" + local label="${entry##*:}" + if systemctl --user is-active --quiet "$unit" 2>/dev/null; then + echo " ✓ $label ($unit)" + else + echo " ✗ $label ($unit) — not running" + all_ok=1 + fi + done + return $all_ok +} + +ensure_services() { + echo "Checking required services..." + if check_services; then + return 0 + fi + + echo "" + echo "Starting missing services..." + for entry in "${REQUIRED_SERVICES[@]}"; do + local unit="${entry%%:*}" + local label="${entry##*:}" + if ! systemctl --user is-active --quiet "$unit" 2>/dev/null; then + if systemctl --user start "$unit" 2>/dev/null; then + echo " ✓ Started $label ($unit)" + else + echo " ⚠ Failed to start $label ($unit) — continuing anyway" + fi + fi + done + + # Brief settle time for services to initialize + sleep 2 + + echo "" + echo "Service status after startup:" + check_services || true +} + cmd_start() { if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then echo "Already running (pid $(cat "$PIDFILE"))" return 1 fi + ensure_services + echo "" + # 1. Bridge (pub/sub relay for vision events) if [ -f "$BRIDGE_DIR/chobit_bridge.py" ]; then python3 "$BRIDGE_DIR/chobit_bridge.py" & @@ -35,6 +94,34 @@ cmd_start() { fi } +cmd_dev() { + if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then + echo "Already running (pid $(cat "$PIDFILE"))" + return 1 + fi + + ensure_services + echo "" + + # 1. Bridge + if [ -f "$BRIDGE_DIR/chobit_bridge.py" ]; then + python3 "$BRIDGE_DIR/chobit_bridge.py" & + echo $! > "$BRIDGE_PIDFILE" + echo "Started bridge (pid $!)" + fi + + # 2. Godot + multi-tray (dev mode) + setsid $GODOT --path "$GODOT_DIR" & + echo $! > "$PIDFILE" + echo "Started Godot (pid $!)" + + if [ -f "$TRAY_DIR/dev_trays.py" ]; then + python3 "$TRAY_DIR/dev_trays.py" & + echo $! > "$TRAY_PIDFILE" + echo "Started dev trays (pid $!)" + fi +} + cmd_stop() { # Stop tray if [ -f "$TRAY_PIDFILE" ]; then @@ -93,10 +180,18 @@ cmd_stop() { done || true } +cmd_launch() { + if [ "${ENVIRONMENT:-}" = "development" ]; then + cmd_dev + else + cmd_start + fi +} + cmd_restart() { cmd_stop sleep 2 - cmd_start + cmd_launch } cmd_verify() { @@ -170,11 +265,66 @@ cmd_screenshot() { $GODOT --path "$GODOT_DIR" --script tools/screenshot.gd 2>&1 | tail -1 } +cmd_test() { + echo "Running unit tests..." + $GODOT --headless --path "$GODOT_DIR" --script tests/test_runner.gd 2>&1 +} + +SYSTEMD_UNIT="$ROOT/infrastructure/services/chobit.service" +SYSTEMD_DEST="$HOME/.config/systemd/user/chobit.service" + +cmd_install_service() { + if [ ! -f "$SYSTEMD_UNIT" ]; then + echo "Error: $SYSTEMD_UNIT not found" + return 1 + fi + + mkdir -p "$(dirname "$SYSTEMD_DEST")" + cp "$SYSTEMD_UNIT" "$SYSTEMD_DEST" + systemctl --user daemon-reload + echo "Installed chobit.service → $SYSTEMD_DEST" + echo "" + echo "Enable with: systemctl --user enable chobit" + echo "Start with: systemctl --user start chobit" + echo "" + echo "This will auto-start model-boss-coordinator and chatterbox-tts via Wants= dependency." +} + +cmd_status() { + echo "=== Chobit Services ===" + echo "" + + echo "External dependencies:" + check_services || true + + echo "" + echo "Local processes:" + if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then + echo " ✓ Godot (pid $(cat "$PIDFILE"))" + else + echo " ✗ Godot — not running" + fi + if [ -f "$TRAY_PIDFILE" ] && kill -0 "$(cat "$TRAY_PIDFILE")" 2>/dev/null; then + echo " ✓ Tray (pid $(cat "$TRAY_PIDFILE"))" + else + echo " ✗ Tray — not running" + fi + if [ -f "$BRIDGE_PIDFILE" ] && kill -0 "$(cat "$BRIDGE_PIDFILE")" 2>/dev/null; then + echo " ✓ Bridge (pid $(cat "$BRIDGE_PIDFILE"))" + else + echo " ✗ Bridge — not running" + fi +} + case "${1:-}" in - ""|start) cmd_start ;; + ""|start) cmd_launch ;; + dev) cmd_dev ;; stop) cmd_stop ;; restart) cmd_restart ;; - verify) cmd_verify ;; + status) cmd_status ;; + install-service) cmd_install_service ;; + verify) cmd_verify ;; + test) cmd_test ;; editor) cmd_editor ;; mobile-editor) cmd_mobile_editor ;; screenshot) cmd_screenshot ;; @@ -183,9 +333,13 @@ case "${1:-}" in echo "" echo "Commands:" echo " (none), start Launch bridge + companion + tray (desktop)" + echo " dev Launch with dev multi-tray [Bridge:dev][Chat:dev][Char:dev][Speech:dev][Face:dev][Main]" echo " stop Stop everything" echo " restart Stop then start" + echo " status Check service status (local + dependencies)" + echo " install-service Install systemd user unit (auto-starts dependencies)" echo " verify Run lint, format check, and Godot import" + echo " test Run unit tests (headless)" echo " editor Open Godot desktop editor" echo " mobile-editor Open Godot mobile editor" echo " screenshot Capture a screenshot"