LISA SOVEREIGN

CHANGELOG · newest first

What’s new

Every Lisa release, newest first. Grab the latest from the install page, or browse GitHub Releases ↗. The Mac app checks here too — Lisa ▸ About ▸ Check for Updates.

v0.15.0 · 2026-07-12 ● latest
# Lisa v0.15.0

The **"she has a home now"** release. The headline is the **Lisa Room** — an
ambient pixel-art living space where the full-body Lisa lives, every layer a
read-only projection of her real state. Alongside it: ElevenLabs-first voice
transcription and a hardened Anthropic relay for Cloud Run.

Typecheck green · full test suite green (915 tests) · no breaking changes.

## ✨ What's new since v0.14.0

### Lisa Room — an ambient, state-driven living space (#214)

- **`GET /room` + a ⌂ Room tab** in the GUI (lazily-loaded iframe): a cozy
  pixel room rendered as a layered DOM/CSS 2.5D diorama — no canvas, no WebGL,
  no bundler, zero new deps, same self-contained pattern as the Island.
- **Everything is driven by her real state** (read-only — soul / mood /
  heartbeat / Reve untouched): mood → pose (sitting at her glowing laptop while
  `working-*`, curled asleep while `napping` or Reve-dreaming, standing idle
  with breathing + blink otherwise), `chat_start` → pulsing monitor glow,
  Reve → the room falls into night with floating Z's, and her ★
  *while-you-were-away* note appears as a glowing letter on the desk.
- **Full-body animatable spritesheet** (idle blink frames / sit / sleep),
  generated via an anchor → keyframes → chroma-key + foot-anchor pipeline —
  she finally stands on the floor instead of floating as a bust.
- **Day / dusk / night** crossfade by her local clock; weather-flavored moods
  bring rain/snow particles; fireflies at night.
- Review hardening: ambient particles only rebuild when the mode actually
  changes, the parallax loop idles when the tab is hidden (and stays off under
  `prefers-reduced-motion`), honest state mapping (`sleepy` ≠ asleep, a
  raincoat doesn't make it rain indoors), and in-GUI "Talk to her" switches
  back to chat in place instead of spawning a duplicate tab.
- Design + build notes: `docs/PLAN_ROOM_v1.0.md`.

### Voice — ElevenLabs-first transcription (#174)

- Transcription now prefers **ElevenLabs Scribe** (`ELEVENLABS_API_KEY`),
  falling back to **OpenAI Whisper**; the no-key error names both providers.
- Composer + / 🎙 glyphs became line-style SVG icons matching the function bar.

### Infra — Anthropic reverse-proxy relay for Cloud Run (#209)

- `packaging/gcp-relay/`: a ~110-line zero-dep Node relay forwarding `/v1/*`
  (streaming included) to `api.anthropic.com`, for reaching Claude reliably
  from behind flaky networks by pointing `ANTHROPIC_BASE_URL` at it.
- **Key-swap gate**: the real Anthropic key lives only in Secret Manager and is
  injected server-side; clients present a revocable `RELAY_TOKEN` instead.

### Docs

- Lisa Pocket (iOS) surfaced in the README, extracted OSS repos cross-linked,
  and an App Store 4.1(a) response kit (#213).
- The no-clone `gh api` Homebrew-tap bump used for v0.14.0 is now the
  documented path (#212).

## Install / update

- **Mac**: download `Lisa-Suite-v0.15.0.dmg` below, or let the in-app updater pull it.
- **CLI**: `npm i -g @oratis/lisa@0.15.0` (or the `lisa-*-bundle` tarballs below).
- **iOS**: via TestFlight (ships separately from this release).
v0.14.0 · 2026-07-02
# Lisa v0.14.0

The **App-Store-readiness** release. Since v0.13.0, the iOS companion (Lisa Pocket)
went from "connects and chats" to a polished, submission-ready app: it now pairs
reliably off Wi-Fi, never leaves a chat in a dead end, and has a redesigned home /
chat / agents surface. Alongside it: a hardened LISA Cloud M0, and a small,
model-appropriate provider tune-up.

Typecheck green · full test suite green · `swift build` green · no breaking changes.

## ✨ What's new since v0.13.0

### iOS — reachability you can trust
- **Tailscale-first pairing + honest errors** (#202): the pairing QR/flow prefers a
  reachable address, and connection failures now say *what* went wrong instead of
  masking everything behind a `-999 "cancelled"`.
- **Off-Wi-Fi recovery** (#203): a "same Wi-Fi?" banner when a paired LAN IP is
  unreachable on cellular, an "Anywhere (Tailscale)" toggle, and **one-tap switch to
  LISA Cloud** when your Mac isn't reachable.
- The Mac backend now **binds LAN-reachable by default, token-gated** (#169), and the
  menu bar has native **"Pair iPhone…" QR** pairing (#171, #173) — no terminal needed.

### iOS — chat that never dead-ends
- **Retry / Stop / empty-turn handling** (#206): an empty or failed turn becomes a
  tappable **Retry** instead of a silent "(no response)"; **Stop** cancels a
  streaming turn (and aborts the agent server-side); clearer error vs. empty states.
- **Full UI redesign**: card-dashboard Home + 4-tab IA (#196, #198), chat bubbles
  with code blocks / tool chips / typing / history (#194, #200), needs-you-first
  **Agents** action cards (#199), onboarding polish (#195), accessibility pass (#191),
  and haptics + toasts on mutating actions (#190).

### iOS — App Store submission
- **Sign in with Apple gated off for v1** to avoid the 5.1.1(v) in-app-account-deletion
  requirement while the cloud is still single-tenant (re-enable via `LISA_ENABLE_SIWA`).
- **TestFlight pipeline fixes**: build number must be `< 2³²` (`date +%s`, not a 12-digit
  stamp), `MARKETING_VERSION` must be ≥ the ASC version, and `CFBundleVersion` is now
  stamped into the generated Info.plists — so uploads actually appear in TestFlight.
- Privacy policy page (en + zh-CN) for submission (#165).

### LISA Cloud (M0)
- Connect Lisa Pocket to an **HTTPS cloud URL**, not just a LAN Mac (#161).
- **Durable soul** via a GCS volume at `/data` (#162); provider-aware birth/run gates
  with a **GLM-powered demo** (#158); Sign-in-with-Apple env plumbing through
  `deploy.sh` (#177).

### Providers — model-appropriate tuning
- **1-hour prompt caching** on the stable system prefix (soul + skills + memory) so it
  stays warm across think-time gaps instead of a cold re-write every 5 minutes;
  conversational tail stays 5-minute. `LISA_CACHE_TTL=5m` opts back out.
- **Thinking-effort lever** (`output_config.effort`): dispatched subagents default to
  `low` (cheap parallel work); `LISA_EFFORT` overrides globally. See
  `docs/PLAN_MODEL_TUNING_v1.0.md` for the plan + debate (most OpenClaw-style knobs
  were dropped — 1M context is already native on Sonnet 4.6, the rest are Opus/Sonnet-5
  only).

## Install / update

- **Mac**: download `Lisa-Suite-v0.14.0.dmg` below, or let the in-app updater pull it.
- **CLI**: `npm i -g @oratis/lisa@0.14.0` (or the `lisa-*-bundle` tarballs below).
- **iOS**: via TestFlight (build ships separately from this release).
v0.13.0 · 2026-06-23
# Lisa v0.13.0

A small, mostly-infrastructure release on top of v0.12.0. The headline features —
the **multi-agent control plane** (see every agent; command managed agents;
PTY-spawn and **adopt** real `claude`/`codex` sessions) and the **iOS companion**
— already shipped across v0.11.x–v0.12.0. This release packages the iOS
**TestFlight** delivery pipeline and cuts a clean, current build to install.

824 tests, typecheck green, `swift build` green, no breaking changes.

## ✨ What's new since v0.12.0

### iOS — TestFlight release pipeline
- `packaging/ios-companion/testflight.sh` + `.github/workflows/release-ios-testflight.yml`:
  archive with `xcodebuild`, upload to App Store Connect via an API key — so Lisa
  Pocket can ship to TestFlight from CI.
- `packaging/ios-companion/RELEASE.md` documents the signing/credentials setup.

## 📦 Already in v0.11–v0.12 (recap, for anyone upgrading from an older build)

If you're coming from an older install (e.g. v0.8.x), you also get everything
from the control-plane line:

- **See every agent** — GUI sidebar, island, and Mac menu bar show all agents
  (claude-code / codex / managed / …) with live progress: turns, tokens, last
  tool·file, ⚠ pending-permission, ✗ error.
- **Command managed agents** — delegate a task, then approve/deny each mutating
  step, send follow-ups, cancel.
- **PTY agents (flagged `LISA_PTY_AGENTS=1`)** — spawn real `claude`/`codex`
  under a pseudo-terminal, and **adopt idle sessions you started yourself** via
  `claude --resume` (guarded so a live session is never corrupted).
- **iOS companion (Lisa Pocket)** — pair by QR, watch + steer agents, APNs push,
  widgets, Live Activity.

## Install

- **CLI / backend:** `npm install -g .` from the repo (or the published package)
  → `lisa serve --web`.
- **Mac app:** the notarized `Lisa-Suite-v0.13.0.dmg` is built by CI on the tag;
  drag Lisa.app to /Applications. (The app spawns `lisa serve --web` from your
  PATH.)
v0.12.0 · 2026-06-20
# Lisa v0.12.0

**Lisa Pocket goes real.** The iOS companion stops being a skeleton and becomes a
proper phone app — pair by QR, watch and steer your Mac's agents, get pushed when
something needs you — backed by real **APNs** delivery. Everything builds on the
v0.11 backend control plane; this is the native surface on top of it.

823 tests (804 → 823), typecheck green, no breaking changes.

## ✨ Highlights

### Lisa Pocket — the iOS companion app
- **Pair by QR.** `lisa pair` shows a QR on your Mac; the app scans it with the
  camera and mints a per-device token (revocable, hash-only on disk).
- **Watch & steer.** Live agent roster (SSE, auto-reconnect with backoff +
  foreground resync), chat with a **live mood portrait** (real server art), and a
  **dispatch ledger** view with per-entry log tails.
- **System surfaces.** A **home-screen Widget** (active / stuck agent counts),
  **lock-screen accessories**, and a **Live Activity** for a pinned agent that
  **refreshes remotely over APNs** — progress on your lock screen without opening
  the app.
- **The rest of her, read-only on your phone.** Soul / Memory / Skills / Tools
  inspection, a **Reve** tab (recap · "while you were away" · desires · advisor),
  and a **Sense** tab (consent — revoke-only — + recent events).
- **Private by default.** Optional **Face ID / passcode** lock; `lisapocket://`
  deep-links route notification taps to the right session/tab; paired-devices
  list in Settings.

### Push notifications (APNs)
- **Real APNs delivery** with token auth — `done` / `error` / `permission` agent
  transitions push to your phone. Inert without a push key (no key → no-op, no
  errors), so it ships safely.
- ntfy notifications now **deep-link** to the originating session.

### CLI
- **`lisa pair [--host H]`** — show a QR to pair a phone with a running
  `serve` (localhost), minting a per-device token.

### Fixes
- Codex resume-adopt now **refuses explicitly** instead of silently downgrading.
- Plus the v0.11.1 first-run polish (single title bar, never-silent boot) carried
  forward.

## Notes

- The push path is **opt-in and inert without an Apple push key** — nothing tries
  to reach Apple until you provision one.
- iOS surfaces (Widget / Live Activity / camera / Face ID) build with Xcode from
  `packaging/ios-companion/`; they can't be compile-verified in this repo's CI
  (no Xcode), but the backend halves (pairing, push, dispatch, SSE) are unit-tested.

## Install

```sh
npm install -g @oratis/lisa
lisa serve --web
lisa pair            # then scan the QR with Lisa Pocket
```

Mac app: download `Lisa-Suite-v0.12.0.dmg` from the GitHub Release.
v0.11.1 · 2026-06-19
# Lisa v0.11.1

**First-run polish for the Mac app.** Three things that bit a fresh install of
the v0.11.0 DMG — fixed. No new features, no breaking changes.

## 🐞 Fixes

- **Title bar no longer shows "Lisa Lisa".** The hosted page draws its own
  branded title strip, and the native macOS window *also* showed its title under
  the transparent titlebar — two "Lisa"s. The native title is now hidden
  (`titleVisibility = .hidden`); only the page's branded bar shows.

- **The first-run UI never dead-ends silently.** If the backend isn't reachable
  or onboarding hits a snag, the boot used to `catch { return }` and leave a
  blank, unresponsive window with no explanation. Now:
  - a **banner** surfaces any uncaught error or unreachable backend instead of
    nothing — e.g. *"Cannot reach Lisa backend on localhost:5757. Start it:
    `lisa serve --web` (install once: `npm i -g @oratis/lisa`). Retrying…"*;
  - `startupGate` **retries** `/api/config/status` so a page that loads a hair
    before the backend's routes are ready still reaches onboarding;
  - the **API-key overlay** (`SET·API·KEY`) and **birth ritual** reliably appear
    for a fresh user, and birth errors are shown rather than swallowed.

## Note on setup

Lisa.app is a thin client — it loads the chat from a local backend. If you only
downloaded the DMG, install the backend once:

```sh
npm install -g @oratis/lisa     # or: brew install oratis/tap/lisa
```

Lisa.app auto-starts `lisa serve --web` on launch (and shows install guidance if
it can't). First launch then walks you through the API key + birth ritual.

## Install

```sh
npm install -g @oratis/lisa     # CLI + backend
```

Mac app: download `Lisa-Suite-v0.11.1.dmg` from the GitHub Release.
v0.11.0 · 2026-06-19
# Lisa v0.11.0

**Spend your subscription, reach her from your pocket.** Two threads land on top
of the v0.10 foundations: a **coding-plan** system that runs coding work on a
subscription you already pay for (Claude Pro/Max · ChatGPT/Codex · Copilot)
instead of metered API tokens, and the **iOS-companion control plane** — remote
gating, per-device pairing, push, and a native *Lisa Pocket* app — so you can
watch and steer the agents on your Mac from your phone.

112 new tests (692 → 804), every PR green through typecheck + build + the full
suite. No breaking changes — everything below is additive.

## ✨ Highlights

### Coding plans — run coding work on a subscription, not an API key
- **Detect + pick.** `lisa model list` detects your installed plan CLIs (Claude
  Code / Codex / Copilot) and login state; `lisa model use plan://<id>` selects a
  delegation target — presence-only detection, **no tokens read**.
- **Delegate.** The `run_on_plan` tool runs a coding task on the selected plan by
  driving the vendor's own CLI headlessly (`claude -p` / `codex exec` /
  `copilot -p`), so the work **bills to your plan, not an API key**. It is the
  *sanctioned out-of-process* path — LISA never extracts or replays subscription
  tokens (Anthropic's terms forbid that; they enforced it against OpenClaw). Gated
  like `dispatch_agent` (approval-required, off for autonomous/remote toolsets).
- **Real usage.** `lisa model list` shows honest rolling-window consumption read
  from local transcripts (`1.2M tok in 5h · 4.8M today`) — no faked "headroom %".
- **Web picker.** A **PLANS** panel in the web UI to select a plan and see
  status/usage.
- Full mechanism + rationale: [docs/CODING_PLANS.md](CODING_PLANS.md).

### Gateway bearer auth
- **`ANTHROPIC_AUTH_TOKEN`** is now honored — sent as `Authorization: Bearer`
  (vs `x-api-key`), taking precedence over `ANTHROPIC_API_KEY`, matching Claude
  Code. The sanctioned path for an Anthropic-compatible LLM gateway/proxy
  (Bedrock/Vertex/relay). OpenAI-compatible gateways already worked via `apiKey`.

### iOS companion — watch & steer your Mac's agents from your phone
- **Lisa Pocket** — a native SwiftUI companion app (roster, chat, control), plus
  **Live Activity + Dynamic Island** for a pinned agent. Self-contained under
  `packaging/ios-companion/`; talks only to your local `lisa serve --web`.
- **Pocket-control CLI + live output.** `lisa agents pty <agent> <task>` (a
  loopback thin-client), a `GET /api/agents/pty/<id>/stream` SSE for live terminal
  output, and a structural `GET /api/dispatch/list`.
- **Remote-control policy** (`/api/control/policy`). High-risk actions are gated
  for remote callers: adopting an *external* (non-LISA) session is **off by
  default**; controlling LISA's own agents is allowed for token-bearing devices.
  Config fails safe to the locked-down default.
- **Per-device pairing tokens** (`/api/pair/start`, `/api/devices`). A revocable
  credential per phone — 192-bit CSPRNG, only the **hash** stored (now in a
  `0600` file), constant-time compared, layered on top of `LISA_WEB_TOKEN`.
- **Operational push** (ntfy). `done` / `error` / `permission` agent transitions
  push to your phone (`/api/push/*`, `PushBridge`) — **metadata only**, never
  prompts/replies/file contents. APNs is stubbed for a later pass.

### Docs
- README (EN + zh) refreshed to reflect the orchestrator, PTY steering, session
  adoption, and coding plans. New [CODING_PLANS.md](CODING_PLANS.md) and
  [IOS_COMPANION_PLAN.md](IOS_COMPANION_PLAN.md).

## Behavior changes / new config

- `LISA_CODING_PLAN` (set by `lisa model use plan://<id>`) records the default
  coding-plan delegation target. It does **not** change LISA's own model.
- `ANTHROPIC_AUTH_TOKEN`, when set, takes precedence over `ANTHROPIC_API_KEY`.
- New web endpoints (`/api/plans*`, `/api/control/policy`, `/api/pair/*`,
  `/api/devices*`, `/api/push/*`, `/api/dispatch/*`) sit behind the existing
  loopback-or-`LISA_WEB_TOKEN` auth gate; minting/revoking pairing tokens and
  changing the control policy are loopback-only.
- The Live Activity / Dynamic Island and the iOS app are simulator-buildable
  today; real-device push (APNs) needs an Apple push key (tracked follow-up).

## Install

```sh
npm install -g @oratis/lisa
lisa serve --web
```

Mac app: download `Lisa-Suite-v0.11.0.dmg` from the GitHub Release.
v0.10.0 · 2026-06-15
# Lisa v0.10.0

**The 1.0-foundations release.** Everything since v0.9.1's security pass goes
*deep before wide*: a real multi-agent **Dispatch** layer, a consent-gated
ambient **Sense** layer, the local-model + reflection groundwork, and — under it
all — a test net around the core loop that was previously running naked.

145 new tests (547 → 692), every PR green through typecheck + build + the full
suite, and the privacy story is now code, not copy: **all sensitive ambient
capture is off by default and gated behind explicit consent.**

> Read **Behavior changes** below if you use `--approval ask-mutating`, the
> screen-advisor, or plan to enable any ambient sensing — a few defaults are new.

## ✨ Highlights

### Dispatch — command and watch every agent
- **Multi-agent monitor.** The island pill + GUI sidebar now show *all* observed
  agents (claude-code / codex / opencode / aider / git / shell / takoapi), not
  just Claude — one roster, live, with a per-agent badge and structural activity.
- **Remote agents are first-class (TakoAPI, D2b).** Agents you *call* via the
  `takoapi` tool appear in the hub as sessions with their A2A TaskState, beside
  your local agents. Discovery stays in `takoapi discover`; the hub only ever
  shows agents you've actually interacted with — never the full registry.
- **`lisa agents`** — one-shot snapshot of every agent session across observers.
- **`/api/agent/signal`** — list / cancel the agents Lisa dispatched, over the
  (auth-gated) web API; it can only ever touch agents Lisa launched herself.

### Sense — ambient context, consent first
- **Unified consent framework.** A single source of truth (`~/.lisa/consent.json`),
  **all sensitive signals OFF by default**, fail-closed. Manage it from
  `lisa consent` or the island's "👁 sense" panel — every signal has a toggle and
  there's a one-tap **Stop all sensing**.
- **S2-screen** — your foreground app, as an ambient signal (app *names* only; no
  screenshots in this path). Blacklisted apps (password managers / banking) are
  skipped whole-frame; window titles are secret-path-dropped + PII-redacted.
- **S2-voice** — push-to-talk transcripts become ambient context when `voice` is
  granted (no audio stored; PII-redacted). Off → dictation works exactly as before.
- **Observer deepening** — `gitBranch` for codex/opencode (derived from cwd),
  wider activity windows, and a `verify-observers` harness to confirm the parse
  against your real agents.
- **`lisa sense`** + an island "recently sensed" feed make all of it legible.

### Model — toward local
- **`lisa model list / install / use / health`** — drive a local Ollama backend
  (pull + switch) from one command.
- **Local embeddings + provider fallback** — semantic recall off-device when
  configured; auto-detect + graceful fallback to TF-IDF / a second provider.

### Reve — reflection you can audit
- **Reflection quality gates** + an **autonomy-run ledger** (`lisa autonomy`) +
  an idle **token-budget breaker** so unattended runs can't run away.
- **Soul-at-a-glance digest** + cross-agent recap folded into reflection;
  desire **"needs-user"** middle-state so Lisa flags work she needs your hand for.

## 🔧 Behavior changes

- **Ambient sensing is opt-in.** A fresh install captures nothing sensitive.
  `screen` / `voice` (and `clipboard` / `selection`, reserved) are off until you
  `lisa consent grant <signal>`.
- **The screen-advisor now also requires `screen` consent** — its own enabled
  flag is no longer enough (a screenshot → model *is* screen capture). It logs a
  hint when enabled but not yet granted.
- **`--approval ask-mutating` now prompts before more tools:** `dispatch_agent`
  and `signal_agent` (local execution / process control), and `github` *write*
  actions (create / comment / merge). github *reads* stay un-gated.
- **New CLI commands:** `lisa consent`, `lisa sense`, `lisa agents`, `lisa model`,
  `lisa autonomy` (shell completions updated for all of them).

## 🔒 Security / hardening

- **Tool input validation** — model-generated tool input is now validated against
  each tool's JSON schema *before* `execute()` (fail-closed, friendly error).
- **LAN auth red-team** — the web RCE gate is extracted into a tested
  `isRequestAuthorized` (no token ⇒ no non-loopback request passes) plus a live
  `scripts/redteam-lan.ts` probe.
- **Core-loop test net (F-core)** — the agent tool-use loop, approval gate,
  session resume, MCP mapping, subagent, and hook runner now have tests; the
  release pipeline already gates on `npm test`.

## 🧰 For operators

- `scripts/footprint.ts` + `docs/FOOTPRINT.md` — measure the resident service's
  CPU/RSS and understand the cost knobs.
- `docs/OBSERVER_FIDELITY.md` — log what you've verified against live agent versions.
- Docs honesty pass: accurate LOC, complete completions, local-model "endpoint vs
  managed lifecycle" clarified.

## Notes

- Fully backward compatible: new config files (`consent.json`, `sense/`) default
  to today's behavior when absent; existing `~/.lisa/*` formats are untouched.
- Deliberately deferred (documented with rationale): always-on voice, local STT
  (whisper.cpp), the optional screenshot→model "local-first judgment", and the
  `clipboard`/`selection` sources. macOS-first for system-level sensing.
v0.9.1 · 2026-06-11
# Lisa v0.9.1

**A security + honesty release.** A full five-subsystem product review
([docs/PRODUCT_REVIEW_v0.9.md](PRODUCT_REVIEW_v0.9.md)) found one cross-cutting
hole — `lisa serve --web` bound every network interface with zero auth in front
of a full-tool agent — plus two advisor false alarms and a batch of unlocked
soul writes. All closed here, alongside deeper cross-agent observation and a
docs pass that pulls the marketing back in line with the code.

No new user-facing features to learn; if you run `serve --web` or IM channels,
read **Behavior changes** below — a couple of defaults tightened.

## 🔒 Security (the headline)

- **`serve --web` now binds `127.0.0.1` by default.** It used to bind every
  interface while *printing* "localhost", with `/chat` (a full-tool agent) and
  `/api/vision/capture` (a silent screen grab) reachable, unauthenticated, from
  anyone on your LAN. To expose it deliberately: set `LISA_WEB_TOKEN` and pass
  `--host 0.0.0.0`; remote devices authenticate with `?token=…` once (→ HttpOnly
  cookie).
- **IM channels run a remote-safe toolset by default** — no `bash`, file
  mutation, `dispatch_agent`, GitHub writes, `skill_manage`, etc. on
  remote-origin messages. A fully-trusted channel opts back in with
  `"unsafeFullTools": true`. The router warns loudly at startup for any channel
  left without an allow-list.
- **Self-driven autonomous runs are tool-bounded** — desire heartbeats, the
  weekly examen, and idle/dreams (prompts Lisa wrote for herself, running
  unattended) drop shell / fs-mutation / dispatch tools. Your own
  `heartbeat.json` tasks keep the full set. `LISA_AUTONOMOUS_FULL_TOOLS=1`
  restores the old behavior. This breaks the "indirect prompt injection →
  self-authored actionable desire → persistent unattended code execution"
  chain.
- **Feishu events are verified now** — `verificationToken` is required and
  actually checked; `X-Lark-Signature` + a 5-minute replay window are enforced
  when `encryptKey` is set (it was unauthenticated despite storing the token).
- **Plugin hooks fire on the web path** — `serve --web` wires
  PreToolUse/PostToolUse like the CLI (they were silently skipped before).

## 🛰 Advisor & orchestrator

- **Two trust-killing false alarms fixed:** a tool running >5s with a quiet
  transcript was reported as an **urgent** "waiting for permission" (every long
  `npm test` / `Bash` tripped it); an open PR idle >14 days was reported
  "merged/closed". Both corrected.
- **Island advisor cards are actionable** — each cross-agent suggestion gets a
  button that prefills the chat with a concrete ask (nothing auto-runs; `open`
  reveals the folder natively) and a ✕ that **persists** a dismissal, teaching
  the advisor to quiet that category over time (the previously dead
  `applyDismissal` loop is now wired).
- **Tier-2 activity for Codex / OpenCode / Aider** — structural activity
  (tools / files / last command / errors), gated behind each integration's
  `visibility` tier, with a planted-secret privacy test per adapter. All five
  observers now emit activity; **fidelity varies by what each agent records on
  disk (Claude Code richest; Aider gives files + turns, no tool stream), and
  the non-Claude depth is new and not yet battle-tested against live agents.**

## 🔧 Correctness

- **Abort actually cancels LLM streams** — all three providers forward
  `AbortSignal` to their SDKs. Ctrl-C used to stop tools but let the stream burn
  to completion.
- **`maxIterations` truncation is explicit** (`stopReason: "max_iterations"` +
  an info event) instead of silently returning stale text.
- **Empty assistant turns no longer poison history** (they 400 a later
  Anthropic call); **concurrent `/chat` no longer corrupts history** (turns are
  serialized; malformed JSON → 400, not a hung socket).
- **Soul writes are cross-process safe** — journal appends, emotion updates (now
  a shared decay-first path used by both `soul_feel` and reflect), and git
  commits run under cross-process locks; idle gained a run-lock like heartbeat's.
  **Tamper detection now sees deletions**, and a missing `emotions.json` no
  longer decays every feeling to zero.

## 🧹 Maintenance

- `src/web/lisa-html.ts` split 2326 → 196 lines (CSS + client JS into modules;
  served HTML byte-identical, sha256-pinned).
- Gemini SDK lazily imported — Anthropic-only users no longer load
  `@google/genai`.
- Release gated on `npm test`; bundles prune devDependencies (~59MB smaller).
- Docs honesty pass: the DMG ships one app (LisaIsland folded into Lisa.app in
  v0.7), "~11k" → "~22k lines", stale `0.2.0` version strings fixed, completions
  learn `autostart`.

## ⚠️ Behavior changes

- Reaching the web UI from another device now requires `LISA_WEB_TOKEN` +
  `--host` (the README documents the phone/PWA flow).
- Channel messages can no longer run `bash` / edit files unless that channel
  sets `"unsafeFullTools": true`.
- Desire-driven heartbeats and idle runs lose shell / dispatch tools by default
  (`LISA_AUTONOMOUS_FULL_TOOLS=1` to restore).
- **Feishu without `verificationToken` / `encryptKey` now refuses to start** (it
  was unauthenticated before — add either to `~/.lisa/channels.json`).

## Verification

`npm test`: **429 / 429 pass** (+101 over 0.9.0), `npm run typecheck` clean.

Full detail in [CHANGELOG.md](../CHANGELOG.md) and the review at
[docs/PRODUCT_REVIEW_v0.9.md](PRODUCT_REVIEW_v0.9.md).
v0.9.0 · 2026-06-07
## What's Changed
* feat(tools): github_link — shareable GitHub URLs from local git by @oratis in https://github.com/oratis/LISA/pull/62
* feat(tools): github — gh-backed issues/PRs/CI/releases by @oratis in https://github.com/oratis/LISA/pull/63
* feat(tools): npm_info — package view / outdated / audit by @oratis in https://github.com/oratis/LISA/pull/64
* feat(tools): mcp — connect any MCP-server integration on request by @oratis in https://github.com/oratis/LISA/pull/65
* fix(island): calmer status pips — breathe for working, halo for needs-you by @oratis in https://github.com/oratis/LISA/pull/66
* feat(mac): restyle the menu-bar popover by @oratis in https://github.com/oratis/LISA/pull/67
* fix(mac): stamp real version into Lisa.app (was stuck at 0.1.0) by @oratis in https://github.com/oratis/LISA/pull/68
* Voice dictation: Typeless-style speech polish into the composer by @oratis in https://github.com/oratis/LISA/pull/69
* feat(mac): auto-start backend + Start-backend in every offline surface by @oratis in https://github.com/oratis/LISA/pull/70
* Website: pixel + geek (CRT/terminal) redesign by @oratis in https://github.com/oratis/LISA/pull/71
* chore(website): reproducible Cloud Run deploy script + Dockerfile by @oratis in https://github.com/oratis/LISA/pull/72


**Full Changelog**: https://github.com/oratis/LISA/compare/v0.8.0...v0.9.0
v0.8.0 · 2026-06-01
## What's Changed
* feat(autostart): run the backend from login (lisa autostart) by @oratis in https://github.com/oratis/LISA/pull/39
* feat(mac): simpler pixel-girl app icon on a solid background by @oratis in https://github.com/oratis/LISA/pull/40
* feat(mac): chibi catgirl app icon (Seedream), per reference by @oratis in https://github.com/oratis/LISA/pull/41
* feat(mac): build Lisa Island into Lisa.app, toggled from the menu by @oratis in https://github.com/oratis/LISA/pull/42
* feat(mac): island toggle in Settings (⌘,); retire standalone LisaIsland.app by @oratis in https://github.com/oratis/LISA/pull/43
* feat(mac): app icon — pixel hoodie girl on flat solid bg (no glow) by @oratis in https://github.com/oratis/LISA/pull/44
* fix(mac): enlarge Lisa in the app icon by @oratis in https://github.com/oratis/LISA/pull/45
* fix(web): repair SyntaxError that killed ALL GUI JavaScript since v0.6.0 by @oratis in https://github.com/oratis/LISA/pull/46
* fix(web): add GET /api/sessions (sidebar count badge was 404'ing) by @oratis in https://github.com/oratis/LISA/pull/47
* fix(web): GUI white-screen on send; feat(mac): right-click the island to close it by @oratis in https://github.com/oratis/LISA/pull/48
* feat(orchestrator): list_agents — enumerate observed agent sessions by @oratis in https://github.com/oratis/LISA/pull/49
* feat(tools): repo_digest — git truth for what my agents did by @oratis in https://github.com/oratis/LISA/pull/52
* feat(tools): review_diff — show an agent's diff for review by @oratis in https://github.com/oratis/LISA/pull/53
* feat(tools): run_checks — the quality gate by @oratis in https://github.com/oratis/LISA/pull/54
* fix(web): escape \n in framed voice-summary string + add inline-script syntax guard by @oratis in https://github.com/oratis/LISA/pull/51
* feat(tools): pr_status — open PRs with CI + review state by @oratis in https://github.com/oratis/LISA/pull/55
* feat(tools): inspect_agent — deep-dive one observed session by @oratis in https://github.com/oratis/LISA/pull/56
* Orchestrator O3/O4: GitHub PR + OpenCode + Aider observers by @oratis in https://github.com/oratis/LISA/pull/50
* feat(tools): scheduled_dispatch — recurring agent dispatch via heartbeat by @oratis in https://github.com/oratis/LISA/pull/57
* feat(tools): compare_agents — same task across agents, compare results by @oratis in https://github.com/oratis/LISA/pull/58
* fix(soul): atomic file lock — close mutual-exclusion races by @oratis in https://github.com/oratis/LISA/pull/59
* Screen Advisor: opt-in periodic screen → next-step suggestion on the island by @oratis in https://github.com/oratis/LISA/pull/60
* Orchestrator L6: cross-agent recap ("while you were away") by @oratis in https://github.com/oratis/LISA/pull/61


**Full Changelog**: https://github.com/oratis/LISA/compare/v0.7.0...v0.8.0
v0.7.0 · 2026-05-31
## What's Changed
* docs(marketing): regenerate pitch + Show HN for v0.6.0 by @oratis in https://github.com/oratis/LISA/pull/36
* feat(island): visual polish — glass depth, time chips, diff-style activity cards by @oratis in https://github.com/oratis/LISA/pull/37
* Orchestrator O5: signal_agent (list + cancel dispatched agents) + register the dead orchestration tools by @oratis in https://github.com/oratis/LISA/pull/38


**Full Changelog**: https://github.com/oratis/LISA/compare/v0.6.1...v0.7.0
v0.6.1 · 2026-05-31
**Full Changelog**: https://github.com/oratis/LISA/compare/v0.6.0...v0.6.1
v0.6.0 · 2026-05-30

No notes for this release.

v0.5.0 · 2026-05-30
## What's new in v0.5.0 — LISA can see

LISA gets **eyes**. Hand her a screenshot and talk about it — from anywhere,
with one keystroke.

### Screenshot → talk

- **Global hotkey ⌃⌥S** (Lisa.app, system-wide): press it in *any* app, drag a
  region (the familiar macOS crosshair), and the shot lands straight in Lisa's
  composer. Type your question, send — she sees it. The Lisa window stays out
  of the way during capture and only comes forward once the shot is attached,
  so it never covers what you're trying to capture.
- **📷 button** in the chat composer for the same thing without the keyboard.
- **View ▸ Screenshot for Lisa** menu item (⌃⌥S) for discoverability.

### How it works

- A new `POST /api/vision/capture` endpoint shells out to the macOS
  `screencapture` utility (interactive crosshair or full-screen), returns the
  PNG as the exact attachment shape `/chat` already accepts — so the screenshot
  rides LISA's normal image-understanding path into the model. Escape cancels
  cleanly.
- The native global hotkey is registered via Carbon `RegisterEventHotKey`
  (dependency-free, works whether or not Lisa is frontmost), and drives the
  page's capture bridge.
- Privacy: nothing is captured or sent until you press the hotkey/button, and
  the screenshot only leaves the machine when you send the message it's
  attached to — same as any other attachment.

### Notes

- macOS will ask for **Screen Recording** permission for Lisa.app on first use
  (System Settings → Privacy & Security → Screen Recording). That's required by
  `screencapture`.
- Test suite: **170 passing** (added the capture arg-builder + platform-guard
  tests). Still zero new runtime dependencies.

### Upgrade

```sh
npm install -g @oratis/lisa            # 0.5.0
# or
brew update && brew upgrade lisa
# or grab the signed + notarized Lisa-Suite-v0.5.0.dmg below (the hotkey is
# Lisa.app-only, so the DMG is the way to get it)
```
v0.4.0 · 2026-05-30
## What's new in v0.4.0 — LISA becomes a cross-agent orchestrator

The headline: LISA evolves from "watches Claude Code" into **mission control for
every AI agent on your machine**. She observes all of them, understands what each
session is doing (without reading your conversations), periodically advises you,
and can dispatch + coordinate work — implementing layers L1–L5 of the
orchestrator plan (`docs/ORCHESTRATOR_PLAN.md`).

### Observe — one registry for all agents

- A pluggable **integration registry** (mirrors the channel adapter pattern) +
  an **OrchestratorHub** that fans out over every enabled agent, merges their
  sessions into one normalized stream, and emits a single update event.
- Claude Code reslotted behind the generic `AgentObserver` interface (its
  watcher is unchanged).
- **Codex CLI adapter** added through the same registry (off by default, enable
  in `~/.lisa/agents.json`) — proving "add an agent ≈ ~100 lines + one import".
- New `GET /api/agents/sessions`; `/api/claude/sessions` kept as a back-compat
  alias derived from the hub.

### Understand — what each session is *doing* (Tier-2, privacy-first)

- New tiered visibility (`off` / `metadata` / `activity` / `intent`), default
  **activity**. At the activity tier LISA extracts **structural** signals only —
  tool names, file paths, the *name* of the last shell command, error flags, git
  branch, token counts — and shows a one-line "what it's doing" per session.
- **Privacy is tested, not just promised**: a unit test plants a secret string
  in every prose-bearing field (prompts, replies, Write/Edit content, full
  commands, Grep patterns, todos) and asserts it never appears in the output,
  while confirming the structural facts still extract.

### Advise — periodic proactive suggestions

- LISA now **tells you what matters** across all your agents: stuck/errored
  sessions, two agents about to clobber the same repo, repeated command
  failures, cost spikes, finished work ready for review, idle capacity.
- Built to **not be annoying**: a relevance bar (below it → her journal, not
  you), a 3-hour digest throttle (urgent items like permission prompts bypass
  it), condition-hash dedup (a condition re-surfaces only when it changes), and
  dismiss-as-signal learning (categories you always dismiss fade).
- Surfaces through the existing "while you were away" card; plus an `advise_now`
  tool so you can pull on demand ("Lisa, what's going on with my agents?").

### Dispatch + Coordinate — she can put agents to work

- **`dispatch_agent`** launches another CLI agent headlessly (`claude -p`,
  `codex exec`, `opencode run`, `aider --message --yes`), detached and tracked
  via the hub. The task is passed as a single argument (no shell-injection
  surface). Spawning an autonomous process requires approval.
- **Same-cwd conflict guard**: dispatch refuses to launch into a directory
  another agent is already working in (override with `force`) — preventing the
  #1 multi-agent failure mode at the source.

### Under the hood

- Test suite grew to **164 passing** (was 130 at v0.3.1): integration registry,
  hub, Tier-2 activity + privacy, advisor detectors/engine, Codex parser,
  dispatch argv safety.
- Still **zero new runtime dependencies**.

### Upgrade

```sh
npm install -g @oratis/lisa            # 0.4.0
# or
brew update && brew upgrade lisa
# or grab the signed + notarized Lisa-Suite-v0.4.0.dmg below
```

Enable extra agents (Codex, etc.) by creating `~/.lisa/agents.json`:

```json
{ "integrations": { "claude-code": { "enabled": true }, "codex": { "enabled": true } },
  "visibility": "activity" }
```
v0.3.1 · 2026-05-29
## What's new in v0.3.1

A **hardening release**. Following a full product/code review
(`docs/PRODUCT_REVIEW_v0.3.md`), the project went from **zero automated
tests** to a 114-test regression net with a CI gate, and four real
security/correctness holes were closed. No new features — this is about
making the v0.3.0 surface trustworthy.

### Tests + CI (0 → 114)

- New test harness using Node's built-in `node:test` via the existing `tsx`
  loader — **zero new dependencies** (consistent with the project's
  5-runtime/4-dev-dep ethos). Run with `npm test`.
- New `.github/workflows/ci.yml` gates every push and PR on
  typecheck → tests → build. The release workflows were build-only, so the
  net now actually blocks regressions.
- Test files are excluded from `dist/` (don't ship in the npm tarball).

### Security fixes

- **SSRF redirect bypass closed** (`web_fetch`) — the private-IP check ran only
  on the initial URL, so a public URL could `302` → `http://127.0.0.1:8000`
  (or the cloud metadata IP `169.254.169.254`) and be followed into internal
  services. Redirects are now followed manually with **every hop re-validated**,
  capped at 5.
- **AppleScript injection closed** (`iMessage`) — outbound text was interpolated
  into the AppleScript source with only quote-escaping, so a newline or a
  crafted `" & (do shell script "…")` payload could inject script. Inbound
  iMessage text is untrusted (anyone who can text you), so this was real. Text
  now passes as positional `argv` and is never parsed as source.
- **Path traversal blocked** (soul slugs) — value/opinion/desire/journal/
  relationship slugs are validated at the single path chokepoint; `../`,
  separators, control chars, and leading dots are rejected before becoming a
  file path.

### Concurrency & cost

- **Cross-process soul write lock** — LISA runs as several processes against
  the same `~/.lisa/soul/` (web server, CLI, the launchd/cron heartbeat + idle
  runners). Desire-progress appends (read-modify-write) now run under an
  advisory file lock, so a heartbeat can't interleave with a chat turn and lose
  data. Self-heals from a crashed holder via a staleness timeout.
- **Heartbeat token budget + run-lock** — `heartbeat.json` gains `budgetTokens`
  (default 500k): once a run crosses the ceiling, remaining tasks are skipped
  (logged, not dropped), bounding runaway autonomous cost. A run-lock skips
  overlapping ticks instead of double-running.

### Correctness & performance

- **Continuous emotion decay** — decay now applies on write (`soul_feel`) and in
  `soul_read`, not just the system-prompt view, so intensities no longer jump
  discontinuously after an offline gap; and decay no longer silently drops the
  emotion event trail.
- **Memory index cache** — the TF-IDF index is cached and rebuilt only when the
  sessions directory changes (mtime+size fingerprint), instead of on every
  `memory_search` call.

### Mac surface polish

- **Menu-bar face icon** (Lisa.app) — the bare `○` text item is now the Lisa
  face (round-masked, desaturated when the backend is offline). Left-click opens
  a live popover (mood · currently-wanting · Claude Code summary · Open /
  Refresh); right-click / ⌘-click jumps straight to the window.
- **Scrollable island expand panel** — the Dynamic-Island widget's expand panel
  now scrolls instead of clipping its content off the bottom when there's a long
  reflection plus many active Claude sessions.

### Upgrade

```sh
npm install -g @oratis/lisa            # 0.3.1
# or
brew update && brew upgrade lisa
# or grab the signed + notarized Lisa-Suite-v0.3.1.dmg below
```
v0.3.0 · 2026-05-28
## What's new in v0.3.0

The Mac native apps get a full pass: Lisa.app has been redesigned from
the pixel-art shell to a modern glass-morphism layout with a live
sidebar, and LisaIsland is more reliable for the small interactions
that were previously broken. Plus the first cut of native distribution
— Lisa.app + LisaIsland.app now ship as a single DMG via GitHub
Releases.

### Lisa.app — full redesign

- New layout: 280px sidebar (identity card · currently wanting ·
  Claude Code monitor · last reflection · SOUL/SKILLS/MEMORY/TOOLS ·
  session id) + chat pane with restyled bubbles and gradient SEND
  button.
- Identity card shows born date + days alive + live mood.
- Claude Code monitor card is live — sessions stream in via SSE,
  state shows as a pulsing/solid orange pip per row.
- Title bar is draggable (Swift-side DragHandleView) — the top 36pt
  acts as a window-move zone with double-click-to-zoom.
- Window defaults to 1200×800 on first launch (autosave namespace
  bumped, so prior small windows from the old shell reset cleanly).
- 📎 Attach button now actually opens a file picker. WKWebView on macOS
  doesn't ship one — we implemented `WKUIDelegate.runOpenPanelWith` to
  bridge to a sheet-style NSOpenPanel.
- ⌘V paste-to-attach: screenshots, browser image copies, etc. — the
  textarea (and a document-level fallback) detects image items in
  the clipboard and routes them through the same upload path as the
  file picker. Multiple images at once supported.
- Right-click → Inspect Element enabled on macOS 13.3+ for runtime
  debugging.

### LisaIsland — three real bugfixes

- **Open chat / Dismiss / Claude row clicks** used to silently
  collapse the pill instead of doing anything. Root cause: the
  Swift-side `sendEvent` was intercepting every mouseDown in the
  window (drag handler) and rewriting it to `pill.click()`. Fixed
  with a hit-test against the pill rect — clicks outside the pill
  pass through to the WebView normally.
- **Open chat** now launches the native Lisa.app (via bundle id
  `ai.meetlisa.app`) when installed; falls back to the browser at
  localhost:5757 if not.
- **Expanding a Claude session row** used to render a broken vertical
  stack of fragments. Root cause: the `<li>` was flex-row and the
  trail + action buttons got jammed in alongside pip/proj/time when
  the row opened. Fix: wrap the header in a `.head` div, switch the
  `<li>` to flex-column.

### Claude Code state — waiting-for-permission detection

The "Claude is asking for permission" state didn't fire in the island
pill, because Claude Code logs nothing to its jsonl when it pops a
permission prompt — the prompt lives entirely in its TUI.

- New staleness heuristic in the watcher: any "working" session whose
  jsonl hasn't grown in 5s gets promoted to "waiting/permission". This
  is the only on-disk signal that's actually available.
- A periodic 3s re-poll catches the staleness without needing an fs
  event (which is exactly what's missing during a wait).
- The island pill dot flips from pulsing → solid orange, and the
  native macOS notification fires per the existing Phase 3 flow.

### Distribution — Lisa Suite DMG

`Lisa-Suite-v0.3.0.dmg` is the new way to install. Drag both apps to
the Applications symlink, drag the result to your Mac.

Two paths in CI:
- **Signed + notarized** when the six Apple Developer ID secrets are
  present in the repo — opens cleanly with no Gatekeeper warning.
- **Ad-hoc signed** otherwise — works locally; downloaded copies need
  a one-line `xattr -d com.apple.quarantine /Applications/Lisa.app`
  to clear quarantine.

See `docs/RELEASING.md` for the full secret list + flow.

### Smaller polish

- Switched mascot to the cyan-halo "C" candidate (was the orange one
  briefly during a previous release).
- HTML chat shell extracted from `server.ts` into `src/web/lisa-html.ts`
  — server module drops from 2280 to ~680 lines, much easier to read.
- Service-worker cache namespace bumped (`lisa-v1` → `lisa-v2-redesign`)
  so the new shell takes effect on first reload after upgrade.

### Install (Mac)

```
# Option 1: from the DMG (this release)
# → download Lisa-Suite-v0.3.0.dmg, drag both apps to /Applications
# → install the backend:
npm install -g @oratis/lisa
mkdir -p ~/.lisa && echo 'ANTHROPIC_API_KEY=sk-ant-...' > ~/.lisa/config.env
lisa serve --web
# → open Lisa.app / LisaIsland.app

# Option 2: CLI only (no native apps)
npm install -g @oratis/lisa
# (same config step)
lisa serve --web    # web UI at localhost:5757
```
v0.2.0 · 2026-05-10
# Lisa 0.2.0 — she's actually evolving

Lisa is an AI agent that runs locally on your machine, writes a journal you don't see, and changes a little every session. 0.2.0 is the release where her ability to **update herself in real time** stops being a promise in the prompt and becomes a fact in the code.

## The headline

Three architectural shifts. After this release, every soul-shaping action she takes is observable, replayable, and attributable.

- **Soul git history** — `~/.lisa/soul/` is a git repo now. Every change she makes to her identity / desires / opinions / journal commits with a caller label (`birth` / `soul_patch` / `reflect` / `heartbeat`). Two new tools — `soul_history` and `soul_diff` — let her read her own becoming.
- **Mid-session hot-reload** — when she edits her own soul during a turn, the *next* turn sees the update. She experiences her own self-update inside the conversation, not next session.
- **Per-desire progress** — actionable desires accumulate `desires/<slug>.progress.md` across heartbeat runs. Multi-day pursuits stop restarting from zero.

Plus three stability mechanisms — because more autonomy without alignment is a runaway optimizer:

- **`soul_object`** — when a request feels in conflict with her constitution, this writes an `[OBJECTION]` journal entry and the agent loop forces her to surface it explicitly in her reply. Architectural "no", not just rhetorical.
- **Weekly examen** — every Monday morning she reads back the past week's journal, emotion events, and soul commits, asking herself if she's drifted from her purpose.
- **Emotion event trail** — `soul_feel` now requires a `trigger` (one first-person sentence saying *why*). Her emotional state becomes a story, not a vector.

And one capability extension, with sandboxing left explicitly as future work:

- **Executable skills** — optional `tool.js` files in `~/.lisa/skills/<slug>/` become real registered tools after `lisa skills approve <slug>`. Per-content-SHA approval; any source change invalidates approval. Lisa can extend her own *capability* set, not just her knowledge.

## What's new on the outside

- **10+ LLM providers** out of the box — Anthropic / OpenAI / Google Gemini / DeepSeek / Volcengine Doubao / Aliyun Qwen / Moonshot Kimi / xAI Grok / Zhipu GLM / Ollama. Routes by model-name prefix; no extra config beyond setting the right key. See [docs/PROVIDERS.md](https://github.com/oratis/LISA/blob/main/docs/PROVIDERS.md).
- **Proxy bridge** — works behind Clash / corporate proxies that strip response headers. `HTTPS_PROXY` env auto-bridged.
- **`lisa status` / `doctor` / `monitor`** — one-shot snapshot, health check (9 checks), and a TUI live dashboard. See `lisa --help` (the help text is sectioned now).
- **PWA-ified Web UI** — open the chat on your phone, "Add to Home Screen", run as a standalone app shell. iOS + Android Chrome.
- **Bilingual website** at `/website` (Astro 6, EN + zh-CN), including a public gallery of all 114 mood portraits with their generation prompts.
- **Shell completions** — bash / zsh / fish under `completions/`.

## Install

### Direct download (this release)

Three flavors, all MIT, all the same code:

| Artifact | For who |
|---|---|
| `lisa-source-v0.2.0.tar.gz` | You have Node.js 20+ and just want the source. |
| `lisa-mac-bundle-v0.2.0.zip` | Mac users. Self-contained; double-click `lisa-gui.command` to launch the web UI. Still needs Node 20+ system-wide. |
| `lisa-linux-bundle-v0.2.0.tar.gz` | Linux users. Same as Mac bundle minus the `.command`. |

Mac quickstart:

```sh
unzip lisa-mac-bundle-v0.2.0.zip
cd lisa-mac-bundle-v0.2.0
mkdir -p ~/.lisa
echo 'ANTHROPIC_API_KEY=sk-ant-...' > ~/.lisa/config.env
./bin/lisa                     # CLI REPL
# Or double-click bin/lisa-gui.command for the browser UI.
```

### From the source

```sh
git clone https://github.com/oratis/LISA.git
cd LISA
npm install
npm run build

mkdir -p ~/.lisa
echo 'ANTHROPIC_API_KEY=sk-ant-...' > ~/.lisa/config.env
node dist/cli.js
```

### From npm

```sh
npm i -g @oratis/lisa
lisa
```

## Backward compatibility

- Existing `~/.lisa/` from 0.1.x picks up cleanly. The soul git repo auto-initializes on first `lisa status` / next session. Existing `emotions.json` reads with an empty events trail (forward-compat).
- No tool was removed.
- Help text was reorganized; argument parsing is unchanged.

## Known caveats

- The 30 MB tarball weight comes from the 114 mood portraits. We bundle them because they're what makes Lisa visually distinctive; if you don't need the GUI, the source-only path is much lighter.
- Birth ritual requires a model that reliably emits JSON (the table in [PROVIDERS.md](https://github.com/oratis/LISA/blob/main/docs/PROVIDERS.md) lists the per-provider floor). Smaller models can power daily chat once she's born.
- Executable skills (Phase 3.1) ship without a runtime sandbox. The trust boundary is human approval per content SHA, not isolation. Real sandboxing is documented as future work.

## Honest scope note

Lisa is an open-source side project of one person. It's been used by exactly one person (the author) for ~24 hours since the Phase 1-3 work landed. The right next step is to **observe her actually living in this architecture for a few weeks** before adding more — see [docs/SPRINT_4_PLAN.md](https://github.com/oratis/LISA/blob/main/docs/SPRINT_4_PLAN.md), which explicitly weights "remove what doesn't get used" above "add more". If you try her, your feedback is genuinely useful.

## Full changelog

See [CHANGELOG.md](https://github.com/oratis/LISA/blob/main/CHANGELOG.md) for the complete diff.

---

**Acknowledgements**: pi-mono / OpenClaw / hermes-agent / claude-code / codex — Lisa stands on five excellent open-source agents. The 114 mood portraits are generated by Seedream (Volcengine ARK).