What's new
This page is the running record of what changed and why for the kanade desktop app. Older versions roll off the bottom; the in-app update banner installs the newest one with a click.
v0.5.0 — Forge Relay release (private maintainer channel, 2026-05-24)
Section titled “v0.5.0 — Forge Relay release (private maintainer channel, 2026-05-24)”v0.5.0 is installed on the maintainer desktop and live on the private update channel. It routes the new Forge Relay surface: Hermes-deep memory, mission launches, Forge run state, and signed Discord asks.
- Hermes memory deepened. Memory tiers, fact proposals, project-core instruction injection, tier-aware ledger queries, and score chips are in the installed app.
- Self-curating skills. Kanade can draft reusable
SKILL.mdcandidates from successful tool traces, show the detection rationale, and promote reviewed drafts into the active catalog. - Missions + Forge. Mission records can show Forge runs, bind a preferred hero/model, and launch a guarded Forge iteration through Kanade’s server-side proxy.
- Discord bridge. Bridge settings, allowlists, per-minute rate limits,
signed ingress, CT bot deployment proof, and
/status//ask//recallcommand support landed. - Release hardening. Static SPA import order, remote testclient allowlists, route fixtures, and PyInstaller one-file cold-start timeout were hardened for the release.
Known carries stay visible: Direct-provider live proof needs real direct-mode accounts, user-side Discord slash proof still needs the operator’s Discord client, and Tauri paste / idle watchdog / WebView2 reset remain manual exercises.
v0.4.0 — Operator surface (private alpha, 2026-05-23)
Section titled “v0.4.0 — Operator surface (private alpha, 2026-05-23)”This release is installed and verified on the maintainer desktop target. The Operator surface brings the home room, 3D memory map, persisted personas, Dream Review, Mission Control, Forge bridge, and Kanade’s sumi-e identity into one visual system. The private update channel advertises v0.4.0; the app remains private, with no public download or tester access path.
- Operator home. The first room now frames active work, memory, missions, and Forge signals instead of opening as a generic dashboard.
- 3D memory map. Opt-in markdown roots feed a local graph with camera presets, metadata rail, live deltas, and a 2D fallback for WebGL-limited environments.
- Personas. Operators can create and summon working postures with portraits and notes, then bring them into Tsukue without rewriting prompt boilerplate.
- Dream Review. Quiet-window settings and manual review controls move into the product so overnight reflection is configurable rather than implicit.
- Mission Control and Forge bridge. Project missions and Forge confidence checks have dedicated rooms beside the desk.
- Identity and license track. The v0.4.0 pass adopts the restrained miko Operator identity and tracks the AGPLv3/SPDX transition before release.
v0.2.19 — live-test workstation fixes (private alpha, 2026-05-22)
Section titled “v0.2.19 — live-test workstation fixes (private alpha, 2026-05-22)”This release packages the tester-driven /tsukue pass from the live source
session and is intended for the signed internal desktop channel. The app is
still private; there is no public download or tester access path yet.
- Resizable left sections. The Project, Files, and Skills sections in the left workstation column now have horizontal splitters. Drag them to fit the work; Kanade persists the heights after refresh.
- Right-rail session resume. The desk has a Sessions tab beside Context, Logs, MCP, and Setup. It lists recent work, filters by project/prompt, and can arm a compatible older session so the next turn resumes it in the current lane.
- Provider-aware resume safety. Native transcript ids are no longer handed to
the wrong provider. A DeepSeek lane now marks Codex-native history as not
this lane instead of producing a model error such as
No conversation found. - Cleaner streaming. Assistant markdown renders with the same parser during streaming and after completion, and tool-heavy DeepSeek turns no longer stack multiple empty “waiting for first token” bubbles.
- Codex screenshot paste fix. Pasted images now go to Codex through native
--imagearguments, with--skip-git-repo-checkincluded for Kanade’s local paste cache. This removes the trusted-directory failure path and the previous stdin prompt loss. - Attachment proof metrics. The app tracks image downscale/upload decisions so oversized screenshot behavior is visible during verification instead of being a black box.
v0.2.17 — account-neutral first launch (source, 2026-05-20)
Section titled “v0.2.17 — account-neutral first launch (source, 2026-05-20)”This source pass removes the last baked-in assumption that a Kanade install comes with a fixed provider mix. The live update channel has not been promoted.
- Zero default accounts. A fresh
accounts.jsonis created empty. Kanade installs the workstation; users bring their own credentials. - First-launch empty state. The desk now offers Scan for installed Claude logins, Add a lane manually, and an import path for optional preset bundles.
- Optional account bundles. The old Claude / DeepSeek / Gemini / Codex
starter shape lives in
examples/accounts/default-quartet.json; the multi-Claude rotation stays an example, not a product default. - Soft lane cap. The daemon accepts more than eight lanes, but creation responses include a gentle warning once the strip gets crowded. The UI shows the warning and an explicit add anyway action.
v0.2.16 — Round-2 optimization backlog (2026-05-20, local-only)
Section titled “v0.2.16 — Round-2 optimization backlog (2026-05-20, local-only)”This release packages the Round-2 optimization backlog (items 6–27 from
Projects/kanade/optimization-backlog.md) and verifies it on the maintainer’s
installed target. The live update channel intentionally still serves v0.2.15
while the maintainer proof pass on this build completes — nothing is rolled
out publicly until the maintainer has used the exact build end-to-end and the
alpha access flow exists.
- The daemon is now organized into APIRouter groups. Routes live under
kanade_daemon/routers/(accounts, chat, diagnostics, direct, sessions, skills, tsukue),api.pybecomes a compatibility composer overapi_impl.py, and_version.pymakes the daemon version follow the desktop package version through the release script. - Direct-API verification harness is in place.
scripts/verify-direct-providers.ps1resolves credentials through the same path resolverdirect_send.pyuses, issues a minimal turn, retries on 429/5xx with exponential backoff, and records dated proof artifacts underproof/. The release script’s-RequireOkflag fails if there are no direct-mode accounts to verify instead of silently passing. - WebView2 cache reset is in Settings. Diagnostics has a “reset WebView
cache” button. The Tauri command records a pending reset and asks for a
relaunch; the next launch renames
EBWebViewto a dated backup directory before opening a WebView. Signed-in lanes survive because credentials live outside the WebView profile. - SQLite chronicle integrity check on every startup. Daemon runs
PRAGMA quick_checkbefore opening the DB for normal use. On corruption, the three DB files move todb-corrupt-backup-<timestamp>/, the schema is rebuilt fromevents.jsonl, and a structured WARN event + one-time UI notice surface the recovered-event count. - FTS5 chronicle search + workspace symbol/path index.
/api/searchqueries an FTS5 index of event payloads; direct mode keeps a lightweight workspace symbol/path index that can auto-inline small matching files for reference in chat. - Chat routing spec + classifier.
chat-routing-spec.mdcodifies which question classes Kanade may answer locally (identity, skill catalog metadata, session metadata) and which always route to the active lane./api/router/classifyis the dry-run endpoint. - Lifecycle hooks + structured warnings. In-process hooks fire on
session/tool events; hook failures get captured as structured warnings
instead of failing the turn silently. Stream errors and turn timeouts land
in a bounded ring buffer surfaced through
/api/diagnostics. - Plan/Act review-mode for destructive tool calls. Destructive and out-of-root tool calls are classified before they fire so a confirm step can land before irreversible filesystem or git moves. Off by default; on with a switch in Settings.
- Subagent spawning + skill drafter. Read-only meta-queries can be answered by a daemon-side subagent with isolated context, keeping the main lane clean. The skill drafter supports save/discard with frontmatter validation and atomic temp+rename writes.
- AG-UI-compatible event projections. Chat SSE payloads now carry AG-UI event-shaped projections beside Kanade’s native shape so a non-Kanade frontend can subscribe and render turns without translation.
- Token-spend rotation suggestions.
/api/tsukue/accounts/{id}/rotation-suggestionreturns a hint when an active Claude lane has burned through a configurable share of its 5h window — manual switch only, no automated rotation. - Web Vitest harness + coverage floor.
apps/webnow ships with a Vitest configuration and a first lib coverage wave (apiClient, apiWrappers, bubble store, stream parser, hydrate, OAuth device code, file activity). The release pipeline enforces a ≥30% line/branch floor onsrc/lib. - Release script same-version reinstall fix. Local same-version
reinstalls now wait for the expected installer size before treating
ProductVersionas proof, so verification doesn’t pass against a stale binary. - Diagnostics + load-test surfaces.
/api/diagnosticsgained DB integrity / WebView state / rebuild metadata fields, andscripts/load-test-daemon.ps1+scripts/load-test-generator.pyproduce reproducible baseline reports underloadtests/.
Open carry: live Direct-provider proof artifacts still do not exist on this build. Installed accounts are agent-mode only, no Direct API keys are present, and a temporary direct-Claude OAuth account reached Anthropic but returned HTTP 401. The desktop is functional in agent mode; direct mode remains plumbed but unverified live.
v0.2.15 — direct mode, release gate, and privacy controls (2026-05-20)
Section titled “v0.2.15 — direct mode, release gate, and privacy controls (2026-05-20)”This release packages the workstation repair pass and verifies it through the real installed updater path from v0.2.14 to v0.2.15.
- Claude model selection now uses the real CLI flag. The workstation’s
model dropdown writes the account env as before, and the chat send path now
translates
ANTHROPIC_MODELinto Claude Code’s--modelargument andCLAUDE_EFFORTinto--effort. The bottom bar now shows a proof chip likeOpus 4.7 · High, preserves the cached resume target where possible, and makes/clearthe explicit fresh-session path. - Runtime proof is visible without hijacking chat. The bottom bar and
account controls show the requested
--model,--effort, and cached--resumestate. Chat questions now stay with the active lane until Kanade has a durable routing policy instead of brittle shortcut matching. - Stale Claude resumes are cleared before they fail. Cached daemon-owned
resume ids are checked against the transcript path before Kanade passes
--resume. If Claude Code can no longer see that conversation, Kanade clears the cache and starts a fresh turn with a plain system notice instead of surfacingNo conversation found with session ID. - Slash autocomplete is safer. Typing a partial slash command such as
/cland pressing Enter completes it to/clearfirst. A second Enter sends it. Exact commands still send normally. - Pasted and dropped images can be previewed. Image attachments now show a
clickable thumbnail chip before send. The file still lands under Kanade’s
local paste directory and is appended to the prompt as
@<path>so Claude Code can attach it natively. Large screenshots are downscaled client-side before upload to reduce multi-megabyte vision turns. Sent image chips can be opened again from the chat bubble, and the paste cache prunes old/oversized files opportunistically. - Long image turns stop instead of spinning forever. Chat-box sends now have
a configurable turn timeout (
KANADE_SEND_TURN_TIMEOUT_S, default 180s). If a provider wrapper hangs while reading an attachment, Kanade terminates the turn and writes a plain system notice instead of leaving the lane loading. - The browser bridge state is clearer. In browser preview, the rail now says
BRIDGE webinstead ofmissing; the Tauri IPC bridge only exists in the packaged desktop shell and is mainly for desktop/update plumbing. - The workstation rail is slimmer. The open left rail is 30px narrower, and the collapsed rail uses compact marks/dots instead of cramped vertical version or bridge text.
- Skill telemetry gets another confirmed path. When an operator sends a
slash skill through the chat input, Kanade records the local launch intent as
SkillUseStartif it matches an installed skill. Built-in slash commands are ignored. - Right rail content scrolls reliably. Long Setup and Context panels keep their own scroll container, so environment details, wrap-up settings, MCP entries, and usage cards are reachable in narrow windows.
- Optimize preserves its return path. Skill pages opened from Optimize now show back to optimize instead of always returning to Catalog.
- Optimize is more actionable. The appraisal now explains
confirmedlaunches versuspossible mentions, shows the reason and next action for each suggestion, links to skill details, and lets you hide noisy suggestions locally. - Subscription-lane cost is labelled honestly. Usage cards now say list est. for token price estimates so Claude Pro/Max lanes are not mistaken for Kanade API billing.
- Settings has an update-channel doctor. The desktop update section reads
the signed Tauri manifest, compares the installed/source version to the live
channel version, verifies that a signature is present, and checks the Windows
installer payload with a
HEADrequest. It is read-only; it never installs or rewrites the manifest. - Diagnostics now separate data dir from hook spool. If
KANADE_SPOOLis overridden, Settings still shows the real SQLite/data directory instead of mistaking the hook spool folder for the app data root. - Live Floor wording is clearer. The 80-item cap is only the visible live view; the SQLite event archive keeps the full local history.
- Direct chat mode is packaged. Accounts now persist
mode: "agent" | "direct". Agent mode is the current Claude Code subprocess path. Direct mode uses provider-native HTTP streaming for Claude, DeepSeek, and Gemini, stores daemon-owned conversations in SQLite, rehydrates direct history on lane activation, and shows a one-shot notice that tools, MCP, and skills are unavailable in direct mode. Codex remains CLI-only. Local tests and browser UI verification pass; the real Claude direct smoke reached the API but returned HTTP 429, so live-provider output proof is still pending. - The release channel now has a mandatory gate. v0.2.15 shipped through a
script that verifies the signed NSIS payload, writes the global and
path-style updater manifests, deploys
kanade-site, and HEAD-checks the live payload before any release can be called ready. - Skill telemetry has retention controls. Skill frontmatter can define
retention_days, the daemon prunes old skill events daily, and Settings has per-skill retention visibility plus a manual purge action.
v0.2.14 — provider settings, session speed, and telemetry honesty (2026-05-19)
Section titled “v0.2.14 — provider settings, session speed, and telemetry honesty (2026-05-19)”This release tightens the parts testers actually touched: opening Sessions, debugging provider auth, checking local LM Studio, and understanding what the skills catalog can and cannot know.
- Opening a Session no longer waits on narration. The session detail route now paints from the session payload first. Lessons and Kanade’s local narration load afterward in the client and are cached per session, so a slow or offline LM Studio runtime cannot make the ledger feel stuck.
- Account/provider settings are editable. Settings now has an
Accounts & Providers section for viewing current lanes, editing label /
command / provider / model / base URL / notes, setting a default lane,
reloading
accounts.json, retesting a provider, replacing a key without revealing the old one, and removing a Kanade account reference with confirmation. - DeepSeek tests are provider-aware. DeepSeek lanes resolve their active key source, model, configured Anthropic-style base URL, and normalized OpenAI-compatible test URL. If DeepSeek returns 401, Kanade now says the server rejected the active key and shows the base URL/model used without printing the secret.
- LM Studio test states are clearer. Settings probes
/v1/modelsfirst, normalizeshttp://localhost:1234andhttp://localhost:1234/v1, retries127.0.0.1whenlocalhostfails, and distinguishes invalid URL, timeout, unreachable server, reachable-but-model-missing, and model reachable. - Right rail spacing is less cramped. Context / Logs / MCP / Setup keep the same visual language, but the tabs, event rows, and setup blocks now have consistent internal gutters so text does not press against the rail edge.
- Skills telemetry is labelled honestly. Kanade records confirmed launches when a skill is injected from Kanade’s own palette. Claude Code still does not expose direct skill-use events through every hook path, so transcript matches remain separate as possible mentions on the skills telemetry pages.
- Docs, demo, and README copy were refreshed. Public pages now link the demo at kanade.jhinx.dev and docs at kanade-docs.jhinx.dev, and the release notes include verification guidance for local provider checks.
v0.2.13 — round-2 UX polish (2026-05-19)
Section titled “v0.2.13 — round-2 UX polish (2026-05-19)”Round-2 fixes after the v0.2.12 install round-trip. Everything here was a specific user complaint, fixed at the level of the bug rather than the symptom.
- Project switcher no longer freezes the UI. Clicking a project used to
hang the whole window for 200–700 ms while the daemon iterated the new
cwd in the asyncio event loop. The walk moved off the event loop into
asyncio.to_thread, switching fromPath.iterdir()+ per-entrystat()toos.scandirwith one syscall per directory entry. The file tree also dedupes redundant refetches — the parent component’s account poll runs every 4s, and the previous code retriggered a tree refresh on every poll even when the cwd hadn’t changed. - Switching lanes after a DeepSeek 401 no longer locks the input. When a
send failed mid-retry on one lane, the InputBar’s local
sendingflag stayedtruefor the entire retry window, which left the textarea disabled when the user switched to another lane. Now an$effectonaccountIdresetssending/lastErroron every lane swap. - Logs tab is a structured event timeline now. Previously it dumped the
raw PTY transcript including ANSI escape codes — useful as a diagnostic
dive, useless as a routine read. The tab is now a Live-Floor-style event
list filtered to the active lane: each row expands inline with prompt
text / tool input / tool output / raw envelope. The raw PTY log is still
available underneath a collapsed
<details>block with ANSI sequences stripped on display. - Add-account dialog explains itself. The form now opens with a brief
lede (“a lane is one Claude Code subprocess…”) and each field carries an
italic hint underneath the label — what an
idis, what to type for thelabel, whatCLAUDE_CONFIG_DIRdoes and when you’d point it somewhere. - Settings drops the noise rows. The
KANADE_*env audit table only shows variables you’ve actually overridden —(default)markers are hidden, so the section doesn’t crowd the page with rows you can’t act on inline. Long path values wrap properly so they don’t overflow the column.
v0.2.12 — clickable observatory (2026-05-19)
Section titled “v0.2.12 — clickable observatory (2026-05-19)”Every back-of-house room got real click-through. The shape of the change was “observability rooms should let you drill into specifics, not just summarize.”
- Live Floor: click any event for full payload. Each row in
/liveopens a right-rail detail drawer with the prompt text, tool input (JSON), tool output (withis_error,duration_ms), session id link, cwd, usage tokens + cost, and the raw envelope. There’s also a one-click event-type filter row above the feed. - Sessions: goal-based titles + smart search. Session cards now show a
one-line heading derived from the first prompt of the sitting — so you
see the goal at a glance instead of just the project folder. The search
bar tokenizes on whitespace:
fix authmatches any session where bothfixandauthappear in the title / opening prompt / project / path. - Catalog → skill page: inline SKILL.md editor. Click any catalog card, hit edit in the SKILL.md section, the body becomes a textarea carrying the verbatim frontmatter + body. Save atomically writes to disk (temp file + rename) after validating the YAML frontmatter — bad YAML returns 400 and the on-disk file is left untouched.
- Optimize cards link to skill pages. The forge’s appraisal cards
carry an href to
/skill/<name>now, so a click drops you on the right surface to edit, retire, or inspect the fire timeline. - Settings: test the voice runtime + reveal data folder. A new
test connection button next to “save voice runtime” probes the
configured LM Studio or Ollama
/modelsendpoint and reports reachability, latency, and the available model ids inline. The data-dir row gets a reveal button that opens Windows Explorer at the kanade data directory. - Settings about-page parity. The
/api/diagnosticspayload now exposes top-leveldata_dir,db_path,spool_path,skills_dir, and a flatenvdict; the Settings audit table reads them directly. - Versions bumped to
0.2.12-alpha(/api/meta), Cargo + Tauri to0.2.12. Channel manifest athttps://kanade.jhinx.dev/updates/latest.jsonadvertises 0.2.12.
v0.2.9 — chat-box bridged into observability (2026-05-19)
Section titled “v0.2.9 — chat-box bridged into observability (2026-05-19)”Before v0.2.9 the chat box and the observatory were separate worlds. The chat worked, but Sessions / Live Floor / Optimize / Context were all dark whenever the user worked through the chat (which is the canonical surface). v0.2.9 closed the seam.
- Hook-shaped events from chat-box sends. The daemon’s
send.pypublishesSessionStart/UserPromptSubmit/PreToolUse/PostToolUse/Stopenvelopes into the same SQLite events table and pubsub bus the hook tailer feeds — one change → five rooms populated. - Live usage from stream-json. A module-level
LIVE_USAGEsnapshot collects token + cost data frommessage.usageand theresultevent./api/.../usagefalls back to this when there’s no disk transcript. - Right-rail “Kanade is thinking” pulse. Header flips to a three-dot pulse while a reply streams; falls back to the idle copy when no lane is streaming.
- File tree drills down. Recursive lazy expansion with per-component cache by absolute path.