Skip to content

Repository files navigation

Luna

Luna

A desktop AI companion that lives with you — she remembers, perceives, acts, and speaks.

An LLM brain with layered memory and dreams, proactive agency, action-integrity rails, and a code-agent capability — embodied as a Live2D avatar with lip-synced custom voice.

License: MIT Runtime: Bun TypeScript Desktop: Electron

English · 简体中文

Luna, a Live2D companion, sharing a joke

Luna TV — live capability showcase

This repository is the engineering, published as a reference — not a distributed product.
There are no installers: Luna is one person's companion, and the instance that matters lives on one machine. Read the code, clone it, take the parts you want.


✨ Features

  • 🧠 Three-layer memory + dreams — a rolling working window, salience-scored durable turns, and structured long-lived facts over one SQLite file; an offline dream cycle consolidates the day into facts, diary, and distilled skills. Hybrid recall blends embeddings, keywords, recency, and a relevance floor so a decisively relevant old memory is never buried.
  • 🌱 Proactive agency — she can open a conversation herself: silence-aware timing ladders, weather-shift and reconnect hooks, follow-up thoughts — all behind deterministic, tunable rails (quiet hours, outreach intensity) instead of a "message me every N minutes" loop.
  • Streaming everything — one WebSocket, one Zod-typed event contract shared by server and web. Reply tokens, tool starts/progress, memory updates all stream live; tool turns never block.
  • 🛠 Real capabilities — web search + SSRF-guarded page reading, weather (QWeather / Open-Meteo), time perception, a gated code-agent (repo map, symbol search, edits), and a skills shelf she distills herself.
  • 🎭 Embodied — a Live2D avatar with emotion-driven expressions, gaze follow, idle animation profiles, phoneme lip-sync, and a transparent always-on-top desktop pet mode.
  • 🗣 Her voice — a GPT-SoVITS cloned voice, set up with no terminal anywhere: the wizard downloads & deploys the runtime in one click, you drag a voice pack in, and Luna starts + supervises the voice server herself. Drop a new pack onto the running app to swap voices.
  • 🧙 Guided onboarding — a bilingual (中文/English) wizard that opens by asking which Luna you want: the complete companion (Live2D + voice, seven steps) or just the agent core (chat box only, five steps, nothing to download). Either way you get live key validation against the real vendors, drag-and-drop avatar/voice installs, and escape hatches everywhere (status-bar button, native ⌘, menu, failure dialogs) so a bad config can never strand you.
  • 🔒 Local-first — memory is a local SQLite file, keys live in a local config only, the server binds loopback by default. Nothing about her leaves your machine.

🚀 Run your own

There is no installer to download — you build her from source, which is also the honest way to read what she is.

git clone https://github.com/Alan-Yu-2077/Luna-ts.git
cd Luna-ts
bun run app        # installs deps → builds → packages → puts Luna.app on your Desktop → launches
The bilingual guided setup wizard
First launch opens a bilingual guided setup — no env files, no docs required.

The only required thing is a chat API key (Anthropic, or any compatible gateway) — every other step is optional and re-runnable from Settings.

Prefer the browser, or not on macOS?

bun install
cp .env.example .env   # set ANTHROPIC_API_KEY
bun run dev            # server + web at http://localhost:5173
Voice step: drag a GPT-SoVITS pack in
Voice step — one-click GPT-SoVITS deploy, drag a voice pack in, live health badge
First run: settings panel over the bring-your-own-avatar empty state
First run — she ships with no body; you bring the avatar and the voice

🏗 How it fits together

graph LR
  D[desktop shell<br/><sub>pet mode · wizard · supervision</sub>] -.hosts.-> W
  W[web<br/><sub>Live2D · lip-sync · chat UI</sub>] <-- "one WS, Zod-typed events" --> S[server<br/><sub>turns · tools · proactive rails</sub>]
  S --- M[(SQLite<br/><sub>3-layer memory · dreams · skills</sub>)]
  S -- provider seam --> L[Anthropic / OpenAI-compatible]
Loading

Five Bun workspace packages with a one-way dependency arrow: protocol (the shared wire contract — a wire change that isn't reflected on both sides is a compile error), server (the brain; owns all state and model calls), web (a thin reactive view), music-cli (a vendored macOS Now-Playing observer), and desktop (an optional Electron shell). The deep dive lives in ARCHITECTURE.md.

🎬 Moments

Real conversations — she jokes, she looks things up, she reads her own codebase, she remembers.

A running fries joke Working out an exam-grade problem together
She has a sense of humor. A running fries bit, played straight — mood pill flips to Playful. She actually helps. Does the grade math, and gets the emotional register right ("the cutoff itself, not your nerves").
Saving a skill for her future self, then using it Reading her own codebase to check the skill system
She builds on herself. Saves a skill "for a version of myself I haven't met yet," then uses it minutes later (ran a command → shell exit 0). She can read her own code. Searches the repo (103 of 103 matches) to answer how her own skill system works.

📚 Documentation

Reading this as a reference? Start with ARCHITECTURE.md for the shape, then docs/history/DEVELOPMENT.md — 140+ per-version entries, each split into Fact (what changed) and Inference (why it mattered), including the versions that were wrong and the gaps that were never closed. That log, not this README, is the honest account of how she got built.

Doc What it covers
docs/SETUP.md Bring-your-own model & voice, step by step (the wizard does this for you)
ARCHITECTURE.md The structural map: packages, wire contract, memory, tools, proactive rails
ROADMAP.md Where things are heading, by theme
docs/history/DEVELOPMENT.md The full per-version engineering log (130+ entries)
.env.example Every configuration knob, documented
CONTRIBUTING.md Dev workflow, tests, conventions

🧪 Development

bun test                                  # the whole suite, all packages
bun run --cwd packages/server tsc --noEmit  # per-package typecheck (server/web/desktop/protocol)

Tests live next to the code (*.test.ts), the wire contract is as-free, and every risky feature lands behind a default-off env flag before its default flips. The server binds loopback (127.0.0.1) by default; set LUNA_BIND_HOST=0.0.0.0 only on a trusted network.

🤝 Using this code

This is a personal project published as a reference, not a supported product — no promises about issues, PRs, or platform support. That's the deal, and it's meant generously: the code is MIT, the per-version reasoning is all in docs/history/DEVELOPMENT.md, and CONTRIBUTING.md documents the conventions if you're forking or reading closely. Take what's useful; you don't owe anything back.

📄 License

MIT, with one carve-out: the vendored Live2D Cubism Core runtime (packages/web/public/live2dcubismcore.min.js) is proprietary to Live2D Inc. and governed by its own license. See THIRD_PARTY_LICENSES.

❤️ Acknowledgements

GPT-SoVITS · pixi-live2d-display · Live2D Cubism · Bun · Electron · weather by QWeather & Open-Meteo · search by Tavily

About

A desktop AI companion that remembers, perceives, acts, and speaks — Live2D avatar, custom voice, layered memory. 住在桌面上的 AI 伙伴。

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages