ChainlessChain
无链之链 · 让数据主权回归个人
CHAINLESSCHAIN · Xiamen Chainlesschain Technology
ChainlessChain chainless·chain
v5.0.3.122 · Evolution Edition CLI v0.162.95 159 commands Web Shell (default) Bilingual Web Panel MTC v0.11

Data sovereignty
returned to you,
AI at your fingertips.

CLI-driven local AI × hardware-grade encryption. Built for everyone who wants to own their data.

See the hardware crypto stack
🏆 4 invention patents
🔒 Military-grade encryption
GitHub 10k+ stars
MLPS Level 3
📋 Co-author · Intrinsic Security of AI Agent (T/ZGCMCA 023—2025)
Product Positioning · Three Pillars

Knowledge · Social · Trading,
end-to-end, individual-first.

One foundation — hardware security + on-device AI + true decentralization. Three pillars stand independently and compose freely.

📚

Knowledge Base

Personal Second Brain
  • ·Notes / docs / chat history — your personal second brain
  • ·Hybrid search: BM25 + Qdrant vectors
  • ·Hierarchical memory 2.0: working → short → long → core
  • ·RAG-powered Q&A · code knowledge graph
🌐

Decentralized Social

P2P Identity & Messaging
  • ·W3C DID v2 identity + verifiable credentials
  • ·P2P end-to-end: Signal + libp2p + WebRTC
  • ·Community / channel gossip cross-machine sync (v5.0.3.41+)
  • ·Audit-grade Merkle envelopes + cross-machine distribution + external archival (B4 suite)
  • ·Protocol bridge: ActivityPub · Nostr · Matrix
  • ·Anti-censorship: Tor + domain fronting + satellite
💎

Trading Assistant

Multi-Chain Wallet & Bridge
  • ·Multi-chain wallets: EVM family + Solana
  • ·Cross-chain bridge: HTLC atomic swap + messaging
  • ·zk-SNARK / zk-STARK generated locally
  • ·DAO governance v2 · quadratic voting · treasury
Privacy First
End-to-end encryption · hardware security · zero-knowledge proofs — service operators can't see your data.
Truly Decentralized
Local storage (SQLCipher AES-256) · P2P (libp2p) · self-sovereign identity (DID v2).
AI Native
Local LLMs (Ollama / LLaMA / Qwen) · prompts never uploaded by default · AI search + agent orchestration.
Personal Data Hub · 50+ data sources, real-device working (v5.0.3.121)

Pull every digital footprint home —
into a vault that's yours alone.

Email · WeChat · Alipay · 8 AI chatbots · 7 social platforms · shopping · travel · Android system data — 22+ sources end-to-end pulled to local, untouchable by anyone else.

"Data sovereignty returned to individuals" is not a slogan — it's 22 real adapters, 5 built-in analysis skills, 1 local encrypted vault.

📧
Email / Bills
  • · IMAP across all mail providers
  • · Alipay statement CSV / PDF
  • · 6 template extractors (bill/order/travel)
  • · PDF decryption + transactions
🤖
AI Chat History
  • · DeepSeek · Kimi · Tongyi
  • · Zhipu · Hunyuan · Qianfan
  • · Coze · Dreamina · Doubao
  • 9 / 9 vendors wired · Phase 10.2
💬
Social Platforms
  • · WeChat (SQLCipher)
  • · QQ · Weibo · Bilibili
  • · Douyin · Xiaohongshu
  • · Telegram · WhatsApp
🛍️
Shopping / Travel
  • · Taobao · JD · Meituan
  • · Amap · Baidu Map
  • · Ctrip · 12306
  • · Orders / logistics / footprints unified
📱
System Data
  • · Contacts · call log
  • · SMS · location history
  • · Android ADB backup
  • · iOS iTunes encrypted
Local Vault
SQLCipher AES-256 on disk — data never leaves your device. Email passwords, chat keys, bill amounts all stay on your hardware.
5 Built-in Analysis Skills
Consumption trends · travel profile · communication frequency · content preference · time distribution — LLM-callable. Ask "which three shops did I spend the most at last year?" — instant answer.
Entity Resolver
"Zhang San" / "张三" / "+86 138-xxxx" auto-resolved as the same person — relationship graphs across email/WeChat/contacts finally connect.
Full feature guide → Architecture design ↗ 50 test files / 952 tests · 6 integration + 3 E2E scenarios · 9 / 9 AIChat vendors wired · mobile remote entry v0.1 in development
Core Pillar · Decentralized Social

Add friends, message, post ——
with no platform in the middle.

Your identity is your own DID, messages are peer-to-peer end-to-end encrypted, communities sync across machines —— no one can ban your account, delete your posts, or read your DMs.

🪪
Self-sovereign DID v2
  • · W3C DID + verifiable credentials VC / VP
  • · Social recovery + cross-device roaming
  • · Reputation aggregation, no central accounts
🔒
End-to-end encrypted messaging
  • · Signal protocol + libp2p + WebRTC
  • · Keys live only on both ends
  • · Offline add + signaling relay fallback
📞
Voice / video calls
  • · WebRTC direct connect, sub-second setup
  • · Full-screen lock-screen incoming calls
  • · Local call history (FAMILY-67)
🌐
Communities / channels sync
  • · gossip cross-node distribution
  • · Audit-grade Merkle envelopes
  • · External archiving, offline-safe
🔗
Protocol fusion
  • · ActivityPub C2S federation
  • · Nostr NIP-01/04/09/25
  • · Matrix threads & spaces
🛡️
Anti-censorship transport
  • · Tor + domain fronting
  • · Satellite message channel
  • · Multi-hop routing + cross-federation trust anchors
Decentralized social, in depth → DID v2 identity ↗ Signal + libp2p + WebRTC · DID v2 + VC/VP · ActivityPub / Nostr / Matrix · voice & video calls
Core Pillar · Digital Asset Trading

Your wallet, your keys,
your assets.

Multi-chain + cross-chain + zero-knowledge, signing entirely on-device —— private keys never leave your device — no custody, no middlemen.

👛
Multi-chain self-custody wallet
  • · EVM chains + Solana
  • · Local keys, hardware U-Key protection
  • · Assets / balances / history aggregation
🌉
Cross-chain interoperability
  • · HTLC atomic swaps
  • · Cross-chain messaging + bridging
  • · Multi-sig swap / send
🔐
Zero-knowledge proofs
  • · zk-SNARK / zk-STARK generated locally
  • · Private, verifiable, no disclosure
  • · compile / prove / verify pipeline
🏛️
DAO governance v2
  • · Quadratic voting
  • · Treasury management + delegation
  • · propose / vote / tally
🌳
MTC federation multi-sig
  • · Merkle Tree Certs M-of-N
  • · libp2p / filesystem auto-discovery
  • · Heterogeneous Ed25519 + SLH-DSA
🛒
Skill market & incentives
  • · Skill marketplace + usage stats
  • · Token incentives (7 contribution types)
  • · NFT mint / transfer
Digital asset trading, in depth → MTC federation multi-sig ↗ EVM + Solana · HTLC atomic swaps · zk-SNARK/STARK local · DAO v2 quadratic voting · MTC M-of-N
CLI · Primary Entry

Your terminal,
your AI workbench.

No GUI required — chainlesschain runs local AI, agent coding, and multi-agent orchestration entirely in the terminal.

112
CLI commands
139
Built-in skills
30,000+
Tests
~/workspace — chainlesschain
$ cc chat
# 进入本地 AI 对话 · Ollama qwen2:7b
总结 ./docs 目录下最近更新的三篇文档
🤔 正在检索本地 RAG 向量库...
✓ web-cowork.md · 10 类任务模板 + 自动依赖安装
✓ cli-agent.md · Claude Code 风格 agent 会话
✓ skills.md · 141 桌面 Skills + 9 CLI Skill Packs
$ cc cowork analyze ./src
# 多 Agent 并行审查 · 性能 / 安全 / 可维护性
⧖ spawning 3 sub-runtimes...
├── performance reviewer · claude-opus
├── security reviewer · deepseek-r1
└── maintainability reviewer · qwen2:7b
✓ 12 findings · 3 critical · report.md
$ cc skill run code-review "Review app.js"
# 调用 Skill Pack · 141 内置 / 9 领域包
📦 loaded skill: code-review@1.2.0
🔧 mounted MCP: filesystem, git
⚙ hashline edit · 3 blocks patched
✓ 67 lines reviewed · 4 suggestions written
Agent / Cowork / Skill — full AI workflow in the terminal
Security Core

Your keys,
held in your hand.

U-Key / SIMKey hardware chips · keys never exported. AES-256 + SQLCipher full encryption. Signal end-to-end. Local Ollama inference — data never reaches the cloud.

01 · U-KEY

USB security chip

Windows Koffi FFI talks directly to the SIMKey SDK. PIN-protected, auto-locks on repeated failure, all critical operations require physical confirmation. BLE/NFC wireless U-Key + biometrics.

02 · SIMKEY

SIM-card security chip

Android OMAPI / iOS eSIM API. USIM + 5G super-SIM across three Chinese carriers. Fingerprint / Face ID replaces PIN. 12 enhancements: eSIM OTA, TEE integration, post-quantum readiness.

03 · LOCAL AI

Local Ollama

qwen2 / llama3 / deepseek-r1 inference on-device. 14+ cloud LLMs available but never required. Sensitive data auto-routes to local models — the cloud path is severed at the source.

4
Patents
AES-256
SQLCipher database
Signal
E2E protocol
MLPS L3
Compliance
Recent Highlights

Multi-agent, made into
repeatable engineering patterns.

Not concept demos. Each item is shipped, tested, and codified. Full changelog at docs.chainlesschain.com/changelog.

01 · Highlight
v5.0.3.121 · 2026-06-19

PDH analysis/collection fixes + FAMILY-67 call/notification UX + Android keyboard-overlap fix

A batch of PDH analysis-pipeline + query-parsing + Douyin/Toutiao collection fixes, FAMILY-67 call/message notification UX polish, and a single global Android keyboard-overlap fix. pdh 0.4.29 + cli 0.162.82 published to npm; Android cc bundle internal-binaries-android-v20260619 (USR_VERSION 49).

PDH analysis pipeline: spending total now uses sumEventAmount (no longer undercounted by the per-subtype 5000-row cap); overview byApp/byType/total use facetCounts (no longer truncated by the 10k-row cap); timeline excludes app-usage baseline aggregate events. PDH query parsing: parseIntent adds income-amount phrasing + symmetric "how many/几" quantifiers; parseFilters removes income's bare "收到" mis-classification; parseTimeWindow "last N months" no longer overflows the month-end day and drops a whole month; "how much did I spend" without "总共" no longer mis-routes to list (it is a sum). PDH collection: Douyin usage-profile + watch-history vault ingest; Toutiao plaintext article reader (title in the share_info blob); a reproducible WeChat EnMicroMsg.db decrypt-and-ingest script. FAMILY-67 call/notification: network-drop reconnect grace (ICE DISCONNECTED no longer silently hangs); friend-connection self-heal (E2EE handshake only when the DataChannel is already connected); missed-call notification + CallStyle lock-screen incoming call + "stay online to answer" foreground service; friend message notifications deep-link into the right chat + runtime POST_NOTIFICATIONS request (Android 13+). Android keyboard overlap: a global imePadding under edge-to-edge fixes input fields being covered by the keyboard across every page in one place. IDE extensions: VS Code 0.33.0 / JetBrains 0.4.18 dedicated vision-model entry + first-run LLM config onboarding. Version surfaces: productVersion v5.0.3.120 → v5.0.3.121 / desktop 5.0.3-alpha.121 / Android versionCode 503121 / iOS build 121; shipped with 18 release assets.

Read design doc →
02 · Highlight
v5.0.3.120 · 2026-06-18

FAMILY-67 friend call history + incoming ringtone + CLI network robustness

Persist & view friend voice/video call history, add incoming ringtone/vibration/ringback, and add timeouts to every CLI network fetch so a dead endpoint can no longer hang forever. cli 0.162.81 published to npm.

Call history: friend voice/video call terminal states are persisted to call_history via CallHistoryRecorder (incoming/outgoing, missed, audio/video type, and hangup reason); the friend profile "view call history" entry filters by friend DID or shows all (live Flow read). Incoming ringtone/vibration + outgoing ringback: incoming calls play the system ringtone + vibrate (respecting silent/vibrate mode), outgoing calls play ringback — fixes "no sound on incoming call". CLI network robustness: webhook notifiers, cc update / vcheck update-checks, and the provider connectivity probe all get timeouts (a dead endpoint no longer hangs forever); reputation / plugin revenue split reject NaN score/amount to avoid corrupting balances. Shipped with 18 release assets.

Read design doc →
03 · Highlight
FAMILY-67 · 2026-06-19

Friend P2P encrypted voice / video calls (P0–P3 + history + background calls + self-heal)

1:1 real-time A/V + ringtone + missed-call + call history + background/lockscreen incoming + reconnect grace + connection self-heal; 44 JVM unit tests green, live two-device voice call verified.

Adds 1:1 real-time voice / video calling on top of friend P2P encrypted messaging: pure P2P + DTLS-SRTP end-to-end encryption, control signaling relayed over the existing signaling server (same friend-DID routing as messages — delivers even if a DataChannel was never built), media over a dedicated WebRTC PeerConnection. P0 signaling state machine (ringing / accept / reject / hangup + glare arbitration + timeouts); P1 voice (reuses the message-side PeerConnectionFactory + ICE/TURN, earpiece / speaker routing); P2 video (lazily-built video PeerConnectionFactory with EglBase + codec factories, front-camera capture + remote full-screen + local PiP + camera flip); P3 background / lockscreen (foreground service keeps the mic alive when locked + full-screen incoming notification turns the screen on over the lock screen + proximity-sensor screen-off). System ringtone + vibration on incoming (respects silent / vibrate mode), ringback on outgoing; every call is persisted and viewable as call history on the friend profile. Also includes: missed-call notifications, system-level CallStyle answer/decline UI, a stay-online foreground service (receive calls when backgrounded/screen-off), a 20s reconnect grace on mid-call network drops, new-message notifications (tap to deep-link into the chat), connection self-heal (handshake only once the DataChannel is up — no more stuck "connecting"), and global keyboard-no-longer-covers-input. Tests: state machine / signaling / integration (Robolectric) / handshake e2e / call-history mapping — 44 JVM unit tests green; on real devices (amethyst<->chopin) two-device live voice call + ringtone + call history verified, video + lockscreen full-screen incoming still under device acceptance.

Read design doc →
04 · Highlight
v5.0.3.119 · 2026-06-18

Friend P2P messaging stability — "cannot scan to add friend / messages not received / cannot connect" end-to-end fix

Two days of debugging wrapped up; verified on real devices (amethyst<->chopin) with sub-second bidirectional delivery.

Message display: the receiver rewrites each message to its own perspective (peerId = sender DID, direction = incoming), fixing "message reached the DB but is invisible in the chat" (previously stored with the sender perspective and landed in the wrong conversation). Connection stability: ICE reverted to ALL (restores same-network direct host connections; the earlier relay-only attempt actually disabled direct connect and hit the TURN server own IP, making things worse) + WebRTC DataChannel open timeout 15s->40s (enough time for direct connect + DTLS handshake). Signaling-relay fallback: when the DataChannel cannot open, commands (E2EE handshake + message sync) are automatically relayed through the signaling server, so delivery no longer depends on a P2P direct connection; end-to-end encryption is unaffected (only signed/ciphertext frames are forwarded). Auto-reconnect: on connection loss the state is cleared and re-dialed within 15s (previously stale state caused fake-online-real-offline). Restart recovery: the app restores the persisted E2EE session on startup + immediate message push (no waiting for the periodic sync) + fixed the chat top loading bar spinning forever. TURN server: coturn public/private mapping fix resolves CREATE_PERMISSION 403 caused by broadcasting the private relay IP.

Read design doc →
05 · Highlight
v5.0.3.118 · 2026-06-17

Personal AI knowledge base analysis pipeline de-noising (WeChat group name resolution + interests/timeline de-noise)

Analysis-quality issues surfaced after real-device collected data was fed into the personal AI knowledge base (pdh 0.4.28 + cli 0.162.78 published to npm; Android cc bundle v20260617c).

WeChat group topic name resolution: resolves the group display name from the contacts book instead of naming group topics with raw numeric chatroom ids. analysis.interests de-noise: filters pure-numeric/empty topic names + over-fetches before ranking, so real interests are not pushed out of the leaderboard by unresolved group ids. analysis.timeline list exclusion: timeline queries gain excludeExtraKinds, skipping app-snapshot / contact-snapshot inventory events (which carry a synthesized collection timestamp that overwhelms any reverse-chronological query); the events remain in the vault for facet counts.

Read design doc →
06 · Highlight
v5.0.3.117 · 2026-06-17

PDH root memory collection: Douyin/WCDB2 hit fix + scan lifecycle hardening (pure-APK change, reuses bundle v20260617b / pdh 0.4.27)

Surfaced on a real device 2026-06-17: Douyin WCDB2 decrypted-page memory has no "SQLite format 3" file header, so the old header-only scan matched 0 regions. mem-scan now decides by content and the leaf-page salvage no longer depends on a header, covering both encryption schemes. Pure-APK change (scripts in assets); cc bundle / pdh / USR_VERSION unchanged.

D1 leaf-page scan: mem-scan now decides by content — memory regions containing either a file header (standard SQLCipher / WeChat) or plaintext schema CREATE TABLE (WCDB2 / Douyin decrypted-page cache) are dumped whole, then leaf-salvage --unaligned scavenges 0x0D leaf pages downstream (header-independent, covers both encryption schemes); MAX_DUMPS=30 + per-region <=64MB to avoid disk blowup / timeout. D2 scan lifecycle hardening: a finally block adds pkill "dd if=/proc" to kill orphaned dd (timeout tree-kill cannot reach the dd inside the pipe) + an AtomicBoolean single-instance lock prevents concurrent scans from repeated taps. Versions: productVersion v5.0.3.116 -> v5.0.3.117 / desktop 5.0.3-alpha.117 / Android versionCode 503117 (USR_VERSION 47 / binariesVersion 20260617b unchanged, bundle same as .116) / iOS build 117.

Read design doc →
07 · Highlight
v5.0.3.116 · 2026-06-17

PDH multi-app root memory collection + source attribution + scan hardening (pdh 0.4.27 / cli 0.162.77 / cc bundle v20260617b)

Real-device scan-bug fixes + multi-app direct collection: salvage now attributes records to the right target app, and the scan engine gains timeouts and orphan-process cleanup. pdh 0.4.27 + CLI 0.162.77 published to npm; Android cc bundle rolled to internal-binaries-android-v20260617b (USR_VERSION → 47).

Multi-app root direct collection + correct source attribution: cc hub salvage --app <key> (douyin/toutiao/wechat/kuaishou/xiaohongshu/weibo) routes messages through the new forensics/salvage-ingest.js, writing them to the vault under the right source.adapter (Toutiao → social-toutiao, no longer all lumped under douyin); the Android "one-tap root collect" button gains a target-app dropdown. Scan-engine hardening (surfaced on a real device 2026-06-17): the mem-scan script adds trap "kill 0" to reap subprocesses + wraps the collector in timeout + raises the budget 180s → 300s + a finally pkill fallback, fixing orphan root processes left behind on scan timeout. Versions: productVersion v5.0.3.115 → v5.0.3.116 / desktop 5.0.3-alpha.116 / Android versionCode 503116 · USR_VERSION 46 → 47 · binariesVersion 20260617 → 20260617b / iOS build 116.

Read design doc →
08 · Highlight
v5.0.3.115 · 2026-06-17

PDH key-free forensic one-tap collection + cross-app data overview on device (pdh 0.4.26 / cli 0.162.76 / cc bundle v20260617)

Key-free forensic collection on a rooted device (Method B /proc/mem leaf-page salvage) goes from a manual script to a one-tap in-app button; cross-app data overview fixed (older cc bundles lacked analysis.overview, causing an "overview error"). Desktop / Android / iOS surfaces aligned to .115; Android cc bundle rolled to internal-binaries-android-v20260617 (carries pdh 0.4.26, USR_VERSION → 46); release ships 18 assets.

cc hub salvage <dump>: the leaf-page salvager is folded into the bundleable pdh lib (forensics/leaf-salvage.js) and wrapped as a single command (dump → leaf-page salvage → social-douyin ingest), verified end-to-end on a real SQLite DB (Chinese + emoji intact). Android "one-tap root collect (Douyin memory, key-free)" button: MemSalvageCollector orchestrates a su memory scan → copy dump → cc hub salvage per dump; rooted devices only, target app must be foregrounded/logged-in, v1 limited to Douyin. Data-overview graceful degradation: when the device-bundled cc predates analysis.overview, a bare "Unknown skill" is translated into an actionable "update the on-device cc components" hint. Release chain: @chainlesschain/personal-data-hub 0.4.25 → 0.4.26 + CLI 0.162.75 → 0.162.76 published to npm; the in-APK cc bundle rolled to internal-binaries-android-v20260617 (USR_VERSION 45 → 46, binariesVersion 20260615d → 20260617). Versions: productVersion v5.0.3.114 → v5.0.3.115 / desktop 5.0.3-alpha.115 / Android versionCode 503115 · USR_VERSION 46 · binariesVersion 20260617 / iOS build 115.

Read design doc →
09 · Highlight
v5.0.3.114 · 2026-06-15

PDH gov-ixiamen endpoint static-verify on a real device + Android cc bundle v20260615d (pdh 0.4.25 / cli 0.162.71)

Ran the PDH endpoint-capture runbook's static-analysis tier (read-only APK, no login) on a rooted device and corrected i-Xiamen's fabricated placeholder host to the real gateway. Desktop / Android / iOS surfaces aligned to .114; Android cc bundle rolled to v20260615d (carries pdh 0.4.25, USR_VERSION → 45).

gov-ixiamen collector host correction: the old cookie-api placeholder app.ixm.gov.cn does not exist. Running the PDH endpoint-capture runbook's static-analysis tier (read-only APK binary analysis, no login/account interaction) on a rooted device, dex analysis confirmed i-Xiamen's real backend is *.ixiamen.org.cn (gateway https://buss.ixiamen.org.cn/pbc/), now wired (overridable via opts.listUrl); the /handle/list sub-path + body stay unverified (bodies encrypted by libzxprotect, opaque to static analysis). Bank/gov findings recorded in runbook §3.1: BOC (SecNeo shell, only push-SDK hosts in plaintext) / ICBC (gateway host visible but encrypted+signed bodies) stay snapshot — a host alone is not 'verified'; 12123 host was already correct, sub-paths built natively by libNetHTProtect. @chainlesschain/personal-data-hub 0.4.24→0.4.25 + CLI 0.162.70→0.162.71 published to npm. Versions: productVersion v5.0.3.113 → v5.0.3.114 / desktop 5.0.3-alpha.114 / Android versionCode 503114 · USR_VERSION 45 · binariesVersion 20260615d / iOS build 114.

Read design doc →
10 · Highlight
v5.0.3.113 · 2026-06-15

npm publish/install hardening: fix China-mirror install E404 + deprecate workflow + VS Code ext 0.28/0.29 + CLI 0.162.70

Fixes the hard npm install failure for users defaulting to the Taobao mirror (#33) and hardens the npm publish pipeline. Desktop / Android / iOS version surfaces aligned to .113; Android cc bundle rolled to v20260615c (carries cli 0.162.70, USR_VERSION → 44).

China-mirror install fix: @chainlesschain/core-infra@0.1.0 had metadata but no cached tarball on registry.npmmirror.com, so users defaulting to the Taobao mirror hit an E404 hard failure on npm install (#33). Fixed three ways — (1) manually triggered the mirror sync API to fix it live (tarball 404→200, mirror install restored); (2) npm-publish.yml now PUTs the mirror sync API after each publish (best-effort, results to job summary, never fails the publish), so every future release self-syncs; (3) README (zh+en) documents the npm i -g chainlesschain --registry https://registry.npmjs.org fallback. Added npm-deprecate.yml, a parameterized deprecate/un-deprecate workflow (uses CI NPM_TOKEN) — deprecated 0.162.68 (published from a stale tag, missing 8 PDH adapter wirings: douban/ximalaya/keep/didi/mercedes/eleme/xianyu/vipshop); 0.162.69 is the complete fix and 0.162.70 is the current npm latest. VS Code extension 0.28.0/0.29.0 (Open VSX): background-tab completion signal + chat-panel slash commands / @ autocomplete / /rewind to checkpoints. Versions: productVersion v5.0.3.112 → v5.0.3.113 / desktop 5.0.3-alpha.113 / Android versionCode 503113 · USR_VERSION 44 · binariesVersion 20260615c / iOS build 113.

Read design doc →
11 · Highlight
v5.0.3.112 · 2026-06-15

Personal Data Hub adds 6 cross-platform collectors + Android cc bundle v20260615b (pdh 0.4.24 / cli 0.162.67)

Six high-value mainstream platforms absent from both the roadmap and the reference device: Ele.me / Xianyu / VIP.com / Douban / Ximalaya / Keep. pdh 0.4.24 + CLI 0.162.67 published to npm; Android cc bundle rolled to v20260615b.

New collector adapters this round: Ele.me (food-delivery orders), Xianyu (second-hand buy/sell, two-sided — counterparty role flips by side), VIP.com (flash-sale orders), Douban (book/film/music interest graph — marks become media events + items / reviews become posts / follows become contacts), Ximalaya (audiobooks & podcasts, new audio- category), Keep (multi-type workout logs). All snapshot-primary + cookie-api (injected fetch + signProvider seam, best-effort endpoints not field-verified); each adapter fully unit-tested, wired into desktop / CLI; adapter count 83 to 89. Versions: productVersion v5.0.3.111 to v5.0.3.112 / desktop 5.0.3-alpha.112 / Android versionCode 503112 · USR_VERSION 43 · binariesVersion 20260615b / iOS build 112.

Read design doc →
12 · Highlight
v5.0.3.111 · 2026-06-15

Personal Data Hub collector expansion (round 2) + Android cc bundle v20260615 (pdh 0.4.23 / cli 0.162.65)

A second PDH long-tail round after v5.0.3.110: Xigua Video, Tianyancha, Dongchedi, WeChat Work (PC), plus gov-tax (scaffold) / CamScanner / Meiyou / i-Xiamen from parallel branches. pdh 0.4.23 + CLI 0.162.65 published to npm; Android cc bundle rolled to v20260615.

New collector adapters this round: Xigua Video (reuses _video-base, watch history + favorites), Tianyancha (monitor / search activity), Dongchedi (favorites / follows), WeChat Work PC (reuses _local-im-pc-adapter local work-IM reader, legalGate), plus gov-tax APP (scaffold, strong real-name auth, best-effort), CamScanner, Meiyou, and i-Xiamen from parallel branches. The PDH roadmap is now fully covered for consumer platforms except the 6 gov/bank strong-auth apps (individual income tax / Minsheng·BOC·BoCom banks / e-CNY / traffic-12123), which are deliberately deferred. Versions: productVersion v5.0.3.110 → v5.0.3.111 / desktop 5.0.3-alpha.111 / Android versionCode 503111 · USR_VERSION 42 · binariesVersion 20260615 / iOS build 111.

Read design doc →
13 · Highlight
v5.0.3.110 · 2026-06-14

Personal Data Hub collector expansion — 13 new platform adapters (travel / shopping / social / docs / music / video / recruiting)

One /loop run filled the PDH collection gaps: every completed-phase 3-star+ platform plus the feasible long-tail. pdh 0.4.18 + CLI 0.162.60 published to npm; Android cc bundle rolled to v20260614b.

13 new collector adapters: Tongcheng, Didi Enterprise, Dianping, Zhihu, CSDN, WPS Docs, Tencent Docs, Baidu Netdisk, Kugou Music, iQiyi, Tencent Video, BOSS Zhipin — each dual-mode: snapshot (on-device) + cookie-api (injected fetchFn + signProvider seam, overridable endpoints). Three shared platform-family factories were extracted: _document-base (docs / cloud-drive listings) and _video-base (watch history), matching the existing shopping-base / travel-base pattern so future same-shape platforms take ~200 lines. Versions: productVersion v5.0.3.109 → v5.0.3.110 / desktop 5.0.3-alpha.110 / Android versionCode 503110 · USR_VERSION 37 · binariesVersion 20260614b / iOS build 110.

Read design doc →
14 · Highlight
v5.0.3.109 · 2026-06-14

Fix: Android release APK missing cc bundle — release.yml adds downloadInternalBinaries staging + a hard verification gate

Real-device testing of v5.0.3.108 found the released APK did not contain cc-cli.tgz (local-terminal / cc unusable on device, PDH collection scripts not delivered). This is a pure packaging fix; bundle contents are unchanged.

Root cause: release.yml build-android only ran assembleRelease, while downloadInternalBinaries relied solely on preBuild's lazy dependsOn, which does not fire in CI. Fix: a dedicated ./gradlew downloadInternalBinaries step before assemble ensures cc-cli.tgz lands on disk before mergeReleaseAssets snapshots it; a new hard verification gate after build (unzip-lists the APK and greps assets/local-terminal/cc-cli.tgz, exit 1 if any APK is missing it) prevents ever silently shipping a bundle-less APK again. Versions: productVersion v5.0.3.108 → v5.0.3.109 / desktop 5.0.3-alpha.109 / Android versionCode 503109 / iOS build 109 (USR_VERSION 25, binariesVersion 20260613 unchanged, bundle same as .108).

Read design doc →
15 · Highlight
v5.0.3.108 · 2026-06-13

PDH Pinduoduo collection completed (user-export snapshot → cookie-api active collection) + Android cc bundle v20260613

Pinduoduo was the last of the shopping trio with only a user-export snapshot and no automatic collection path; this release adds cookie-api active collection, reaching parity with Taobao / JD / Meituan.

New _syncViaCookie pulls mobile.yangkeduo transaction_list via an injected fetchFn (Node stays pure parse / orchestration, same seam as the sibling adapters). The anti_token signature is injected via the signProvider seam (pure Node cannot keep up with Pinduoduo signature rotation; the Android in-APK WebView JS VM produces it), best-effort null when no provider. orderToRecord maps fields with snake / camel dual compatibility + fen→yuan + numeric / textual status mapping; pagination stops early at the watermark. capabilities upgraded to sync:cookie-api, version 0.1.0 → 0.2.0. PDH full suite 128 files, 2094 tests pass. Release chain: @chainlesschain/personal-data-hub 0.4.5 → 0.4.6 + CLI 0.162.47 → 0.162.48 on npm; Android in-APK cc bundle refreshed to internal-binaries-android-v20260613 + USR_VERSION 24 → 25. Versions: productVersion v5.0.3.107 → v5.0.3.108 / desktop 5.0.3-alpha.108 / Android versionCode 503108 / iOS build 108.

Read design doc →
16 · Highlight
v5.0.3.107 · 2026-06-12

PDH FAMILY-23 family-guard collectors v0.2 live fetchers wrapped up (Zuoyebang / Huawei Learning / Alipay)

Wraps up the last 3 snapshot-only placeholder collectors in family-guard telemetry, giving them active live collection, delivered with Android in-APK cc bundle v20260612.

Zuoyebang edu-zuoyebang: ZYBUSS session cookie → study / search-question records; Huawei Learning edu-huawei-learning: Huawei account cookie → course study records; Alipay finance-alipay: session cookie → mobilegw bills / transaction details (signProvider signing seam + fen→yuan + income/expense direction inference, high-sensitivity gate unchanged). All three add sync:cookie + _syncViaLive (emit snapshot-shaped events, normalize path unchanged) + a shared _live-json-helpers. Endpoints follow each platform's common web shape + multi-field-name tolerance (best-effort, not field-verified against a real session). +39 tests, PDH full suite 128 files, 2083 tests green. This release also ships the cc CLI 0.162.41 Claude-Code parity work that was published to npm earlier (project memory cc.md hierarchy + REPL steering + structured output --json-schema + cc mcp serve). Versions: productVersion v5.0.3.106 → v5.0.3.107 / Android versionCode 503107 / iOS build 107.

Read design doc →
17 · Highlight
v5.0.3.106 · 2026-06-11

PDH Kuaishou api_ph base64 collection fix + Amap trip-title bug + travel / social adapter test wrap-up (all 55 repo adapters at 100%)

Driven by the PDH collection layer: fixes profile-collection failure caused by Kuaishou's new cookie format, the bug where all Amap trip events had missing titles, and completes the adapter test matrix.

Fixes Kuaishou kuaishou.web.cp.api_ph profile collection failing after the cookie changed to base64(JSON) (apiPhDecodeCandidates decode chain, pdh 0.4.4); fixes travel-base buildTitle not recognizing the name field, which left Amap route / search event titles missing (caught red-then-green); corrects 3 stale comments in the Toutiao / Kuaishou / email adapters. Test matrix wrap-up +180: Xiaohongshu ADB trio 58 + travel 6 modules from scratch 74 + whatsapp / shopping-base 24 + Kuaishou base64 9 — all 55 repo adapters at 100% test coverage. pdh 0.4.3 → 0.4.4 + CLI 0.162.39 → 0.162.40 on npm; Android in-APK cc bundle rebuilt to internal-binaries-android-v20260611 + USR_VERSION 21 → 22. Real-device (Xiaomi amethyst) proof: installing the new APK triggers LocalFilesystemBootstrapper sentinel 17→22 re-extraction, with pdh=0.4.4 + both fixes grep-confirmed on device. Versions: productVersion v5.0.3.105 → v5.0.3.106 / Android versionCode 503106 / iOS build 106.

Read design doc →
18 · Highlight
v5.0.3.105 · 2026-06-10

cc agent MCP prompts / resources + SubagentStop hook + --fork-session (CLI 0.162.38) + Android in-app cc bundle refresh

Solidifies the 2026-06-10 CLI parity work into a formal release and rebuilds the Android in-app cc bundle, closing the gap where the in-APK cc had run stale code since v5.0.3.101.

MCP prompts as slash commands + MCP resources exposed to agent / REPL; SubagentStop settings.json hook (Claude-Code parity); cc agent --fork-session clones an existing session into a new branch to continue; CLI 0.162.38 on npm. Android in-APK cc bundle rebuilt to internal-binaries-android-v20260610 (cli 0.162.38 + pdh 0.4.3) + USR_VERSION 20 → 21 (v5.0.3.101's USR_VERSION 20 had spun idle because the bundle was not rebuilt; this release closes the loop). CLI e2e shared helper (testHome + freePort) + e2e isolation / retry CI hardening. docs-site adds 14 CLI command user docs + a site-wide number reconciliation (155 commands / 145 skills / 25 Android). Versions: productVersion v5.0.3.104 → v5.0.3.105 / Android versionCode 503105 / iOS build 105.

Read design doc →
19 · Highlight
v5.0.3.104 · 2026-06-10

CLI 0.162.37 (IDE bridge finalization) + all-platform version alignment + docs / branding cleanup

(Backfilled entry) The aggregate release after the IDE bridge phases finalized: CLI 0.162.37 on npm, all-platform version alignment, VS Code extension Open VSX auto-publish CI + icon redraw.

CLI 0.162.37 on npm (aggregate of the finalized IDE bridge phases); iOS / Android / desktop aligned to v5.0.3.104; VS Code extension Open VSX auto-publish CI + an icon redraw trio; JetBrains buildPlugin fix (instrumentation disabled); docs-site adds 8 CLI user-doc pages (cc goal / cost / checkpoint / command / statusline / mcp OAuth / web_search / run_shell background) + a Family Guard user page + a V2 governance command developer reference; release-doc redaction (personal signer info cleanup); desktop vitest-4 stub bug + 12 stale test fixes. Versions: productVersion v5.0.3.103 → v5.0.3.104 / desktop 5.0.3-alpha.104 / CLI 0.162.36 → 0.162.37 / Android versionCode 503104 / iOS build 104.

Read design doc →
20 · Highlight
v5.0.3.103 · 2026-06-10

cc loop (/loop parity) + IDE bridge Phase 3/4 (JetBrains parity + release pipeline) + VS Code extension visualization & branding

This release gives the `cc` CLI a "run on a loop" capability and extends the IDE bridge from VS Code to JetBrains, with a full release pipeline for both extensions.

cc loop mirrors Claude-Code's /loop: repeatedly run a prompt or slash command on a fixed interval, with --dynamic self-pacing (including prompt-mode agent flag pass-through), --save/--resume session persistence, and stable operation in headless (non-TTY) environments. IDE bridge Phase 3 brings JetBrains to parity (a pure-JDK protocol core + IntelliJ glue, CLI zero-change double proof + a live cross-language interop run), and REPL IDE auto-connect now honors --ide/--no-ide; Phase 4 lands the release & maintenance pipeline ide-extensions.yml (vsce package/publish + gradlew build/publish plugin, tag + secret double-gated, no GitHub Release, fail-fast on missing secret). The VS Code extension adds IDE bridge visualization (status bar + sidebar + dashboard, 0.2.0) and ships the ChainlessChain brand logo as the extension & Activity Bar icon (0.2.1). Versions: productVersion v5.0.3.102 → v5.0.3.103 / desktop 5.0.3-alpha.103 / CLI stays at 0.162.36 / personal-data-hub 0.4.3 unchanged / Android versionCode 503103 / iOS build 103.

Read design doc →
21 · Highlight
v5.0.3.102 · 2026-06-10

IDE bridge (cc ide + VS Code extension) + cc CLI Claude-Code parity wrap-up + cc agent --image vision input

This release wires the `cc` CLI into your editor — a new `cc ide` command and VS Code extension that discover and auto-connect the editor's MCP server, letting the agent read/write files in your editor and surface changes via openDiff for accept/reject; meanwhile cc reaches near-parity with Claude-Code.

cc agent gains MCP OAuth remote authorization, custom + built-in context-usage status line, output styles (named personas), pluggable web_search, extended thinking (--think/--ultrathink), settings.json full-event hooks (PreToolUse real blocking / UserPromptSubmit / SessionStart / Stop / PreCompact with block semantics), headless `agent -p`, `/compact` auto-compaction, dual-engine checkpoint, and permission rules (allow/ask/deny), plus `cc agent --image` multimodal vision input. Versions: productVersion v5.0.3.101 → v5.0.3.102 / desktop 5.0.3-alpha.102 / CLI 0.162.35 → 0.162.36 on npm / Android versionCode 503102 / iOS build 102. (Note: the Android in-app cc bundle still ships the prior code pending a cc-cli.tgz rebuild, same as last release.)

Read design doc →
22 · Highlight
v5.0.3.101 · 2026-06-09

CLI reaches Claude-Code parity + PDH one-click WeChat 4.0 / QQ-NT collection + security fail-closed bundle

The CLI closes most of the gap with Claude-Code: headless `agent -p` now supports output format / max turns / allowed & disallowed tools / permission mode / stdin / multi-turn stream-json input / system prompt / multi-root workspace / fallback model, `@file` references work in `ask` and `chat`, plus a new `cc cost` token-spend estimator and file-level `cc checkpoint` snapshot / rewind.

PDH gains full WeChat 4.0 collection (per-DB keys + zstd message decompression + official accounts / Moments / favorites + humanizing non-text messages such as links/files/images) and one-click QQ-NT decryption + parsing: verified end-to-end on a real nt_msg.db, restoring uin → friend nickname and group code → group name. On security, a batch of fail-closed closures: SAML signature, OAuth id_token, channel message signing, and permission-ipc DB fallback all fail closed, with hardcoded passphrases removed. Also landed: a U-Key passphrase escrow layer (default off) and V6-shell wiring for the desktop DB / LLM performance panels. Version surfaces: productVersion v5.0.3.100 → v5.0.3.101 / desktop 5.0.3-alpha.101 / CLI 0.162.31 → 0.162.32 / personal-data-hub npm package 0.4.2 → 0.4.3 / Android versionCode 503101 · USR_VERSION 19 → 20 / iOS build 101.

Read design doc →
23 · Highlight
v5.0.3.99 · 2026-06-08

Personal Data Hub collection major update + real-device live — one-click ingest from many local sources + database at-rest encryption on by default

This release closes the long-standing "config looks fine but nothing gets collected" gap in the Personal Data Hub: readiness is now a first-class judgment split out from the loose health-check, paired with a single "one-click collect / import guide" entry so regular users no longer face multi-step setup. Locally-readable sources expand substantially — Douyin / WeChat PC / QQ-NT / DingTalk / Feishu / WeRead / Apple Health / NetEase Cloud Music can all funnel your own data into the on-device vault.

Email bills are auto-filled by the LLM when structured fields are missing, and iOS encrypted backups can now be decrypted and imported. On the security side, database at-rest encryption is now ON by default (encrypted on disk, automated gates all green), and the DID private key on packaged builds now fails closed (refuse to continue if the key is unavailable) rather than silently falling back to plaintext. Android "AI study companion" wires reward points, a parent-gentleness monthly report, and child tasks into tappable Family-tab entries: a parent assigns homework → the child enters guided mode (the AI does not hand over answers) → submit → grade → redeem points; companion chat is encrypted to disk via the device secure element, so even a parent export only sees ciphertext. Engineering: ~4000 lines of dead code removed, 7 unused dependencies dropped, URL/path validation added before system open-external/open-path, and several "false-green" CI gates fixed. Version surfaces: productVersion v5.0.3.98 → v5.0.3.99 / desktop 5.0.3-alpha.99 / CLI 0.162.29 / personal-data-hub npm package 0.4.0 / Android versionCode 503099.

Read design doc →
24 · Highlight
v5.0.3.98 · 2026-06-03

Social / home ANR fix (main-thread keystore moved to IO) + Family Guard "AI study companion" Epic A–G pure-logic layer complete + PDH analysis-engine intent routing

A long-standing "tapping Social hangs" report was traced to the HubLocalViewModel init block synchronously reading EncryptedSharedPreferences (keystore-backed) plus the StrongBox decrypt inside DIDManager.initialize (a single decrypt can take seconds on some Xiaomi devices) — together they pinned the main thread for >5s and tripped an ANR. This release moves all of that init onto Dispatchers.IO, so Social / home no longer freeze.

About 150 commits accumulated on top of .97 ship together here: Family Guard / AI study companion Epic A scaffolding → B unbind & pairing → C telemetry uplink → D mobile↔mobile calling → E SOS → F geofencing → G multi-guardian negotiation + TimeAuthority clock-tamper defense — the entire pure-logic layer (unit-testable, zero-device) is mined out across all 7 epics (:feature-family-guard 337 tests green). PDH AnalysisEngine intent routing closed out (sum-amount now splits per-currency instead of summing across currencies / count hard-caps the illustrative sample) + static security audit F2–F6 (PII redaction / cookie fail-fast / WebView bridge scoping). Browser-extension background.js Phase 0/1 split: cookies / storage / network / page / devtools / performance handlers all modularized. Desktop adds ~80 new Pinia store unit-test suites. Version surfaces: productVersion v5.0.3.97 → v5.0.3.98 / desktop 5.0.3-alpha.97 → .98 / CLI 0.162.27 → 0.162.28 (version-only bump, no src change). All 17 platform artifacts (Win / Mac / Linux / Android / iOS) shipped; desktop auto-update version comparison verified.

Read design doc →
25 · Highlight
v5.0.3.97 · 2026-05-27

Android cloud LLM route now reads from local RAG + contact phone numbers visible to AI + 6-platform endpoint hotfix bundle

Before this release, the Android CLOUD_ANDROID route forwarded the raw user question to the cloud model — AI was effectively "blind chat" with 768 vault contacts and thousands of events invisible. Three things landed: (1) New `cc hub retrieve-context` CLI + LocalCcRunner.retrieveContext Kotlin bridge + HubLocalViewModel integration — the cloud route now calls hub.retrieveContext(question) first, splices facts into the system message, then asks the cloud model. AI answers carry real citations back to source events. (2) PDH `getHubMinimal()` factory skips 8 heavy aichat adapter / kg / bm25 init steps that retrieve-context does not need; cold start drops 90s → <5s (verified on real device 2026-05-27: 4.2s vs old 87s), making cloud-route questions feel real-time. (3) summarizePerson now includes identifiers + notes — previously stripping phone / wechatId / email meant queries like "mom's phone number" always returned "insufficient information"; now identifiers Map is spliced into person facts and queries actually hit. Plus entity-focus routing + searchPersons LIKE name search prevent contacts from being squeezed out of the 200-row RAG ceiling by events.

6-platform endpoint hotfix bundle: Xhs 3 endpoint path/param sync to real JsBridge routes (/api/sns/web/v1/me → /v2/user/me etc.) + Toutiao extractUid adds uid_tt / sso_uid_tt / tt_webid fallback to fix passport_uid being null and rejecting login + Weibo /api/favorites upstream removed → graceful skip instead of fake 404 + Douyin favorites pagination has_more loop fetches the full set (previously only first page ~24/N silently dropped) + Android askQuestion timeout 60s → 240s (covers MediaPipe cold-start over budget so first ask is not silent) + cc hub aichat-health timers all unref so commands exit immediately (previously held event loop). Engineering docs: handbook adds trap #27 (USR_VERSION sentinel cache miss after PDH/CLI lib refresh — must bump Android USR_VERSION when editing pdh/lib or cli/lib, otherwise real device hits fast-path and skips extraction, runs old code) + trap #28 (workspace dep npm publish stale — must bump package version + npm publish + USR_VERSION when editing pdh/lib or cli/lib, otherwise cc-cli.tgz ships stale code). Version surfaces: productVersion v5.0.3.96 → v5.0.3.97 / CLI 0.162.26 → 0.162.27 / @chainlesschain/personal-data-hub 0.3.7 → 0.3.9 / Android versionCode 503097 / USR_VERSION 12→17 (5 cumulative bumps to force re-extraction) / iOS CFBundleVersion 97.

Read design doc →
26 · Highlight
v5.0.3.96 · 2026-05-27

Desktop check-for-updates safety net — release-in-progress friendly toast + system notification fallback when window is hidden

User report: clicking "Check for Updates" from the tray did nothing; earlier the same button surfaced a red dialog with a full HttpError 404 stacktrace. Two independent problems were stacking: (1) right after a tag push, release.yml is still uploading assets so latest*.yml 404s briefly, and electron-updater forwarded the entire stacktrace as an error to the renderer + red card; (2) from v5.0.3.44 onward, update notifications go through the renderer AppUpdateNotifier card (painted inside BrowserWindow), so when the user triggers "Check for Updates" from the tray with the main window still hidden, the card paints into an invisible window → no response.

New desktop-app-vue/src/main/system/update-error-classifier.js classifies electron-updater errors by kind: release-in-progress (Cannot find latest*.yml / 404 fetching latest*.yml) vs generic. auto-updater.js error handler routes by kind: release-in-progress is silent during background checks; manual checks pop an info dialog "New release is publishing, please try again in a few minutes" instead of dumping a stacktrace. enhanced-tray-manager.js#triggerCheckForUpdates calls showWindow() before triggering the check so the main window is in front. auto-updater.js on update-downloaded + update-not-available adds OS Notification fallback (when window is hidden / minimized / destroyed); clicking the notification brings the window forward → user immediately sees the notifier card / native dialog. New update-window-visibility.js extracts shouldFallbackToOsNotification as a pure helper. 17 unit test cases cover both halves (8 error-classifier including real v5.0.3.95 error text + latest-mac/linux variants + 404-only-on-non-yml counterexample + null/undefined edges; 9 window visibility cases including null / destroyed / unsupported / visible / hidden / minimized / defensive compat).

Read design doc →
27 · Highlight
v5.0.3.95 · 2026-05-27

legacy-GPU Chromium 130+ crash auto-recovery (trap #26) — "installer crashes" report turned out to be 0xc0000602 GPU process fail-fast

User report: `ChainlessChain-Setup-5.0.3-alpha.94.exe` crashes shortly after install. Diagnosis: not an installer issue — NSIS installed successfully, but the final auto-launch of ChainlessChain.exe hit Electron 39 / Chromium 130+ GPU process throwing STATUS_FAIL_FAST_EXCEPTION (0xc0000602) inside CoreMessaging.dll because the target box has an ancient GPU driver (confirmed: Intel Iris Pro 5200 + 2016-09 driver). Any ≤2018 GPU driver + older Intel HD/Iris series machine will hit this 100% of the time.

Fix: marker-file auto-recovery. desktop-app-vue/src/main/index.js setupApp() writes a .launching marker to userData before startup; mainWindow.once("ready-to-show") clears it. Next launch finds the leftover marker → assumes last run crashed → persists .gpu-disabled file + app.disableHardwareAcceleration() + Chromium switches (--disable-gpu / --disable-gpu-compositing / --disable-software-rasterizer). Supports CHAINLESSCHAIN_DISABLE_GPU=1 env var for manual trigger; deleting <userData>/.gpu-disabled restores GPU. Same disable-gpu recovery model as VS Code / Slack / Cursor / Discord — external-behavior-driven, does not depend on any GPU API state.

Read design doc →
28 · Highlight
v5.0.3.91 · 2026-05-26

PDH social dual-channel buildout — Kuaishou as 4th PC-ADB C-path platform + Toutiao/Bilibili/Weibo/Xhs Mode B in-APK root collectors + Bridge dry-run doctor catches SDK rotations 5-10 days early

Two on-device social capture channels filled in. (1) C path (desktop PC ADB pulls platform DB) grew from 3 to 4 platforms: added Kuaishou with a KuaishouSignBridge (Electron WebContentsView driving its NS_sig3 signature) + social-kuaishou-adb Node collector + CLI / WS / desktop wiring across three entry points + web-shell UI with 9 Chinese reason banners + Win-first real-device E2E doc. Bilibili / Weibo / Xhs / Kuaishou C-path now all ship, reusing the shared chromium-cookies-reader module + SignProvider interface (NullSignProvider default + ApiClient short-circuits and refuses to send unsigned HTTP). (2) Mode B (Android in-APK root, su directly reads DB) opened 4 platforms: Toutiao Mode B v0.1 scaffold (CredentialsStore + DbExtractor with defensive PRAGMA-based column picker + DbCollector + 21 JVM tests) → wired into HubLocalViewModel + UI; Bilibili Mode B v0.1 (scaffold + wire + Win-first real-device E2E); Weibo schema probe doc + Mode B v0.1 (scaffold + wire + 21 JVM tests + real-device E2E); Xhs Mode B v0.1 (scaffold + wire + 21 JVM tests). Mode B uses root + su to read the DB directly without attaching to the process, bypassing libshield.so / libmsaoaidsec.so anti-frida detection. (3) Bridge dry-run doctor cold-starts the 3 sign bridges (Douyin / Toutiao / Kuaishou) inside the desktop app and probes candidate globals + warmUp / probe latency, surfacing SDK rotations 5-10 days early (anyCandidatePresent=false is the sentinel).

Xhs / Douyin in-WebView prefetch ported from the Bilibili architecture (hidden WebView runs the platform-native signing JS + JavascriptInterface bridges results back to Kotlin which writes staging JSON). Xhs v6 added cookie cross-subdomain bridge + v8 raised isLoginSuccessByCookie threshold 20 → 50 to reject visitor tracking sessions + v13 id_token httpOnly cookie decode + profile event push. All 5 social login flows switched to Mobile Chrome UA + Douyin gains cookie-presence detection (reverting the wrong v5.0.3.84 direction). Android release engineering: R8 minify moved to systemProp prefix to resolve the v5.0.3.89 ConcurrentModificationException regression; v5.0.3.91 disables R8 outright as the safety net. Repo hygiene: gitee removed from .husky/post-commit auto-push chain (local .git is 1325MB > gitee 1GB quota, every commit was failing and stacking WARN lines); the orphan-snapshot script remains as an emergency rebuild path. Six design docs published together: PDH_Kuaishou_C_Path_Real_Device_E2E + PDH_Toutiao_C_Path_Real_Device_E2E + PDH_Bilibili_Mode_B_Real_Device_E2E + PDH_Weibo_DB_Schema_Probe + PDH_Weibo_Mode_B_Real_Device_E2E + PDH_Mode_B_Toutiao_Douyin_Real_Device_E2E — all Win-first 6-scenario template. Outstanding: Toutiao / Bilibili / Weibo / Xhs Mode B real-device root + magisk + frida-server runs (cannot be done on the Win dev box — needs Mac/Linux + a rooted device). Version surfaces: productVersion v5.0.3.85 → v5.0.3.91.

Read design doc →
29 · Highlight
v5.0.3.85 · 2026-05-24

Android MediaPipe on-device LLM real-wiring + 4-route unified LLM selector + Personal Data Hub Vault Browser (desktop + Android data visualization)

Two user-visible breakthroughs. (1) On-device LLM: MediaPipe tasks-genai pivot landed; added a prompt-length guard before the native call to fix a JNI-abort SIGABRT that took down the whole app (trap #22 — predictSync throws IllegalStateException when prompt > maxTokens, then calls NewByteArray without clearing the pending exception, triggering CheckJNI JniAbort that Kotlin try/catch cannot reach). HubAsk now exposes 4 LLM routes (LOCAL_DEVICE / CLOUD_ANDROID / PC_LOCAL / LAN_OLLAMA) mirrored across three screens (home tab 0 + local-data tab 3 + local-ask tab 4), with LAN baseUrl persisted to EncryptedSharedPreferences. (2) Vault Browser on both shells: FTS5 external-content virtual table + trigram tokenizer for CJK substring matching (10-100× faster than LIKE) + 7-bucket category taxonomy + desktop /personal-data-hub/browser Pinia store (300ms debounce + race-resolution token) + Android 6th tab "data browser" + 5 category-keyed renderers (ChatBubble / OrderTable / Timeline / EmailList / Generic) + client-side JSON / NDJSON / CSV export.

149 tests green (36 categories + 13 vault helpers + 27 FTS5 native integration via sandbox runner + 4 composable + 10 store + 12 view + 19 desktop renderer + 11 export + 10 android renderer + 7 android VM). PDH partial-index drift recovery: migration v4 explicit DROP+CREATE on 4 tables — all partial unique indexes now carry WHERE source_original_id IS NOT NULL — fixes trap #23 where CREATE UNIQUE INDEX IF NOT EXISTS hid the schema drift so adapter.sync silently failed (events table stuck at 0 rows while raw_events accumulated 1308 — the golden symptom). New cc hub rederive [--adapter <name>] [--batch-size <n>] salvages orphan rows in legacy vaults without re-fetching the source. PDH §2.5 travel adds 12306 (5 cards) + content platforms Toutiao / Kuaishou v0.1 placeholder cards + QQ HubLocal UI wire to Phase 13.5 v0.2 collector (already landed) plus 11 ViewModel unit tests. PDH social MockWebServer integration tests filled the 0-coverage layer: 4 platforms / 33 cases (Bilibili 7 + Weibo 9 + Xiaohongshu 11 + Douyin 6) covering HTTP 412/401/461/500 propagation, anti-bot login redirects, X-S / X-T signing header gates, buvid3 substitution, containerid magic prefix. Bilibili WBI signature fix for the silent {code:0,data:list:[]} response. Android Bootstrap @Singleton race fix → companion-object Mutex + self-healing mkdirs (trap #24). Version surfaces: productVersion v5.0.3.84 → v5.0.3.85 / CLI 0.162.17 → 0.162.18 / npm @chainlesschain/personal-data-hub 0.2.4.

Read design doc →
30 · Highlight
Phase 17 + 18 · v5.0.3.83+

Seven on-device developer-activity adapters landed — your local workflow IS your personal RAG corpus

Phase 17 (five cross-platform desktop developer captures) + Phase 18 (two developer command-chain captures). Zero-config no-arg adapters — the vault scans on startup, no login / cookie / API key required. git-activity: commit / branch / merge history across every git repo on the box. shell-history: bash / zsh / pwsh command history with sensitive-token redaction. vscode: VSCode recent workspaces + integrated terminal history. win-recent: %APPDATA%/Microsoft/Windows/Recent/*.lnk — cross-app file-open history (any file any App ever opened lives here). local-files: Documents / Desktop / Downloads / Pictures / Videos / Music file-metadata walk (does NOT read contents — zero privacy risk). browser-history-chrome + browser-history-edge: direct read of Default/History SQLite, full browse history + bookmarks, Chrome / Edge auto-scanned on install.

All 7 adapters route into the category=system bucket so they are individually filterable in the Vault Browser sidebar; FTS5 trigram CJK full-text search works the same way (searching "react" matches git commit messages AND npm install lines from shell history AND vscode workspace paths). This matters most for developers: your 8-hours-a-day keyboard workflow — which repo on which branch doing what / what was open in vscode / what you Googled / which zip you dragged from Downloads — all flow into the vault, so when the AI is asked "what was I debugging last Wednesday?" it can correlate git checkout logs + vscode workspace + browser stackoverflow history + shell commands all at once. A single data source can never answer that. Companion fix: bs3mc / bs3 ABI dual-load (trap #23) — fixes Electron 39 (ABI 140) vs Node 22 (ABI 127) where any SQLite reader (chrome-db-reader / vscode-reader / etc.) would crash native binding on one of the two paths. All readers now dual-load with a new Database(":memory:") smoke test.

Read design doc →
31 · Highlight
v5.0.3.80 · 2026-05-22

Personal Data Hub v0.2 burst — 11 placeholder cards wired + WeChat / QQ real-capture + Android on-device LLM scaffold

Expanded Plan A v0.1 (Bilibili only) to v0.2 real wiring across 11 platforms: social content (Weibo / Douyin / Xiaohongshu / Toutiao / Kuaishou) + shopping (JD / Meituan / Pinduoduo / Taobao / Alipay) + travel & maps (Amap / Ctrip / Baidu Maps / Tencent Maps) + AI assistant 9-route WebView cookie scrape (DeepSeek / Kimi / Tongyi / Zhipu / Tencent Hunyuan / Wenxin / Coze / Dreamina / Doubao) + email 4 providers IMAP (QQ / Gmail / 163 / Outlook via Jakarta Mail). WeChat Phase 12.10 four sub-phases (SQLCipher real decrypt + frida-inject real injection + 16.5.9 binary vendored + APK shipped to real device) + QQ Phase 13.5 v0.2 (XOR-IMEI algorithm byte-identical to sjqz qq.py port — no SQLCipher, no frida, just root + IMEI input). Full-chain skeleton for Android on-device LLM (Ktor server + ModelManager + cc spawn + PDH "ask locally" tab).

Three locks UI + real wiring: reject cloud / destroy / export (cc hub export wired through). AI citation chip → cc hub event-detail links back to the raw event. release.yml split publish-deps into a pre-job to break the v5.0.3.79 desktop build chicken-and-egg. Test baseline: 93 new snapshot tests (weibo 8 + douyin 8 + xhs 8 + toutiao 8 + kuaishou 8 + jd 8 + meituan 8 + pinduoduo 8 + baidu-map 8 + tencent-map 8 + qq 13) + WeChat Phase 12.10 51 new unit tests (CredentialsStore 14 + DbExtractor 17 + FridaInjector 15 + LocalCollector 10) + QQ Phase 13.5 27 Kotlin unit tests. 3 stale-assertion fixes same day: longtail Douyin uid (constructor went dual-mode optional) + analysis TOTALS regex case (/i flag) + hub-command snapshot (event-detail / export missing from pin list). Version surfaces: productVersion v5.0.3.78 → v5.0.3.80 / CLI 0.162.14 → 0.162.16 / npm @chainlesschain/personal-data-hub 0.2.1 → 0.2.3 / Android versionCode 503080 / iOS CFBundleVersion 80.

Read design doc →
32 · Highlight
v5.0.3.78 · 2026-05-22

Personal Data Hub Plan A v0.1 — Android local data hub snapshot mode, real-device closure

End-to-end on Xiaomi 24115RA8EC: 1305 entities (contacts / calls / SMS / location / system) ingested into the local vault. npm @chainlesschain/personal-data-hub@0.2.1 + chainlesschain@0.162.14 with PDH-first publish ordering (release.yml publishes PDH before CLI to avoid the dep-chain 404 from before). New `cc android` 15-subcommand scaffold + `system-data-android` bridge-direct mode. Path C — phone-native snapshot writer + desktop ingest pipeline (Kotlin ContentResolver + PackageManager direct collection → WS push to desktop staging → existing adapter snapshot-mode into vault, bypassing A6 JNI entirely). Path Y — desktop returns RAG context + Android-local LLM inference (DeepSeek + Doubao + 7 more cloud LLM endpoints wired). Phase 14.1 step 5 ChatBubble landed + Phase 14.5 streaming-ask design.

Three real-device hardening fixes: originalId required (adapter yield must carry the field or invalidCount=rawCount false-success + a 1305-row audit burst) + skip-embeddings flag (Plan A mode does not need vectors) + audit pagination splits 1305 → 50/page. Android cc subprocess W^X execve via mksh symlink + reader-thread try/catch(Throwable) for EOF race + ingestSystemDataAndroid timeout 30s→120s. The 7 E2EE androidTest cases were reactivated via X3DHSimulator state-less E2EESession factories. bootstrap LLMManager is now registered as a singleton + web-shell PDH wiring injects CcLLMAdapter so web-shell honors the active LLM provider. AnalysisEngine reads persons + items, not just events, to stop hallucinated contact counts + LLM ResponseCache bypass for analysis ask (no more stale-cache answers). 6 real-device traps closed; engineering foundation 100% verified; feature layer ~7-9d remaining. v5.0.3.77 shipped the iOS .ipa real-device build alongside.

Read design doc →
33 · Highlight
v5.0.3.75 · 2026-05-21

WeChat Phase 12.6.7-10 — bootstrap orchestration + IPC/WS + cc hub wechat CLI + Vue UI wizard

Closed the WeChat 8.0+ frida-dep path end-to-end across four sub-phases in a single evening. 12.6.7 bootstrap.js stitches env-probe → KeyProvider choice → WechatAdapter ctor into a single hermetic entry point so IPC/WS/CLI no longer have to reinvent the wiring (decision matrix md5/frida/unsupported + opts.keyProviderOverride + full _probe / _md5Provider / _fridaProvider / _WechatAdapter test seams). 12.6.8 — 4 new IPC channels and 4 cc-ui WS topics (wechat-env-probe / register-wechat / unregister-wechat / list-wechat-accounts), register-wechat and unregister-wechat join the privileged ApprovalUI gate so mobile peers cannot silently wire an adapter against an attacker-controlled dbPath or trigger a Frida session. 12.6.9 — cc hub wechat env-probe / register --uin --db --wechat-data-path [--force-provider] / list / unregister CLI verbs with --json on every verb for scripting and the Plan A in-app terminal. 12.6.10 — WechatWizard.vue 295 LOC three-step drawer (env-probe checklist with dynamic per-row tag colors → uin + dbPath + wechatDataPath + forceProvider form → result with probe.reasons surface) plus PersonalDataHub.vue button. 9 hermetic integration tests cover md5 happy / frida happy / unsupported / idempotent re-register / two-uin coexistence / override semantics — no adb, no Frida, no real device. Phase 12.9 rooted-Android real-device E2E now has a dedicated §11 of the runbook with three flow scenarios (pre-8.0 md5 / 8.0+ frida / 8.0+ unrooted graceful rejection) and performance baselines.

Total this session: 1223 tests across 67 files (1068 hub package + 183 desktop + 46 CLI + 18 web-panel — composable / VM / IPC / WS / wiring / store / accounts JSON / privileged whitelist / integration end-to-end). Memory captured: wechat_bootstrap_orchestration_layer.md — the pattern of adding a bootstrap.js when N component sub-phases produce parts but 3 callers (IPC, WS, CLI) each have to wire them. Also corrected a stale docs-site claim: iOS Phase 14.2 UI scaffold was actually fully landed at 3db7b5a73 (650 LOC PersonalDataHubViews.swift + 3 ViewModels + RemoteDependencies + 1491 LOC of tests), not lost-to-race as previously noted. Remaining: Phase 12.9 rooted-Android real-device E2E and Phase 14.4 mobile real-device E2E both gated on physical hardware.

Read design doc →
34 · Highlight
v5.0.3.72 · 2026-05-20

Personal Data Hub 13-phase burst — 8/8 AIChat real-vendor wired + 7 social adapters + .72 iOS keychain hotfix repackage

Personal Data Hub rolled from Phase 4 (real third-party wiring) all the way to Phase 13.7 (seven social adapters all live) in one evening across 15 commits 763047a22 → b2baf4eda. Phase 4.5 Python sidecar bridge + SystemDataAdapter wiring 4 Android system sources (contacts / call log / SMS / location) reusing 17 real sjqz parsers via subprocess JSON-RPC, avoiding parser rewrite. Phase 7 Shopping three-pack (Taobao + JD + Meituan) + Phase 7.5 Mobile Extraction Layer (Android ADB + iOS iTunes encrypted backup) + Phase 9 Travel four-pack. Phase 10.1+10.2 AIChat 8/8 vendors all live: DeepSeek (official API) + Kimi (reverse h5 web API) + Tongyi Qianwen + Zhipu GLM + Doubao + Wenxin Yiyan + iFlytek Spark + Tencent Hunyuan, with HttpClient infra wiring retry-with-backoff + progress streaming. Phase 11 — 5 built-in analysis skills cross data sources. Phase 12 v0.5 — WechatAdapter frida-independent slice, T3 risk dropped from High to Medium. Phase 13.3-13.7 — 5 social adapters (Douyin + Xiaohongshu + QQ + Telegram + WhatsApp) + 13+ Bilibili + Weibo via sjqz parsers. 38 test files / 792 tests all green.

v5.0.3.72 is also a release-pipeline retrospective. v5.0.3.71 had all 5 desktop builds fail with EUSAGE — root package-lock.json out of sync with packages/personal-data-hub/package.json: during the Phase 12/13 burst the hub added adm-zip@^0.5.16 (iTunes encrypted backup zip) + iconv-lite@^0.6.3 (GBK-encoded social history) optional deps; workspace package.json declared them but root package-lock never synced, so all desktop installers hit EUSAGE at the electron-builder step. 5d8ba08b5 fix(deps) synced root lock, then .72 was repackaged with the same iOS keychain Logger.swift NSLock concurrency fix (commit 625e86819, forward from .70) and shipped 18 assets complete. d03c87d0a follow-up bumped packages/cli in root lock to 0.162.7 closing the loop. Version surfaces: CLI 0.162.5→0.162.8 / productVersion v5.0.3.70→v5.0.3.72 (skipping .71) / desktop-app-vue 5.0.3-alpha.70→.72 / iOS CFBundleVersion 70→72 / Android versionCode 503070→503072. The actual released artifact is .72; .71 does not exist in GitHub Release list, but lib/adapters code is on main and npm chainlesschain@0.162.7 is published — only desktop installers ride .72.

Read design doc →
35 · Highlight
v5.0.3.66 · 2026-05-19

iOS .ipa reship + Android cc CLI bundle wired (v5.0.3.65/66 one-evening double-patch)

v5.0.3.66 fixes v5.0.3.65 build-ios failure: v5.0.3.65 release shipped 17 assets (full Win/macOS/Linux/Android + npm CLI chainlesschain@0.162.2) but build-ios got stuck on 9 "cannot find X in scope" errors — 13 SwiftUI views added in the Phase 6 sprint (RemoteInputView / RemoteDisplayView / SystemToolsView / RemoteMediaView / RemoteBrowserView / RemoteDesktopView / KnowledgeView / AIExtendedView etc.) lived on disk but were never added to ChainlessChain.xcodeproj's app target Sources phase. Fix: extend ios-app/scripts/wire_app_sources.rb FILES list + manually dispatch ios-wire-app-sources.yml workflow on a macOS runner to run ruby for 17s rewriting pbxproj and commit back to main. GitHub immutable-releases then blocks all asset mutations on the published v5.0.3.65, so bump v5.0.3.66 reship — build-ios passes in 5min11s producing an 8.15MB .ipa, final release v5.0.3.66 ships with 18 assets including ChainlessChain.ipa. npm skip-publish via publish-cli-precheck detecting 0.162.2 already published — avoids dist-tag mishap. v5.0.3.65 same period landed Android cc CLI bundle real wiring: Phase 2.5 Node runtime + cc CLI bundle 41MB tarball entry into android-app/feature-local-terminal/src/main/assets/local-terminal/ + wrapper shell scripts working around the unusable `#!/usr/bin/env node` shebang trap on Android + Termux libc++_shared.so → libtermux_cxx.so AGP 8 naming compat + cc CLI wrapper mksh shebang replacing /system/bin/sh — because Android W^X untrusted_app pty domain cannot execve the /system/bin/sh in shell_exec SELinux context, prefix/bin/mksh → ../lib/libmksh.so → nativeLibraryDir/libmksh.so is execve-allowed under the lib/<abi>/lib*.so whitelist.

v5.0.3.66 in essence is a release-flow engineering retrospective — a reship of v5.0.3.65. Root: v5.0.3.65 build-ios failed because Phase 6 new views were not wired into Xcode; desktop + Android + npm all green but .ipa missing. GitHub release model is immutable-releases once published, so .ipa can no longer be patched onto v5.0.3.65 — must cut a new version. Repair chain: (1) inspect build-ios job log to find 9 "cannot find X in scope" errors (UpdateBannerOverlay + 8 Phase 6 views referenced from RemoteOperateView) → verify files on disk but not in pbxproj; (2) extend wire_app_sources.rb FILES with 13 .swift paths + ios-wire-app-sources.yml workflow_dispatch (dry_run=false) lets ruby xcodeproj gem rewrite pbxproj on a macOS runner and push back to main (commit 2fe98ef9f); (3) bump 4 enforced surfaces (productVersion / desktop-app-vue version / ios CFBundleVersion / android versionCode+versionName) + tag v5.0.3.66 + push; (4) release.yml goes 11/11 green, build-ios 5min11s produces .ipa, create-release / publish-cli / finalize-release all pass, 18 assets in final release. cli-tests and publish-cli skip because 0.162.2 already published — keeps npm latest dist-tag clean. Android cc CLI bundle in v5.0.3.65: the full 41MB chainlesschain CLI npm package (with Node 22 runtime) is dropped into Android APK assets/local-terminal/, wrapper shell scripts route around the unusable #!/usr/bin/env node shebang trap, Termux libc++_shared.so is renamed libtermux_cxx.so for AGP 8 stripping compat, the cc CLI wrapper's own shebang switches from /system/bin/sh to prefix/bin/mksh — Android W^X puts /system/bin/sh under shell_exec SELinux domain which untrusted_app (pty domain) cannot execve, while prefix/bin/mksh actually points to ../lib/libmksh.so → nativeLibraryDir/libmksh.so, on the Android lib/<abi>/lib*.so execve whitelist. The combo lets cc CLI run inside the Android app directly without Termux.

Read design doc →
36 · Highlight
v5.0.3.64 · 2026-05-18

iOS maturity — Phase 1-6 + AI Chat closure + 4-segment version + signed .ipa shipped

v5.0.3.61 → .64 over one week tightened iOS: .61 signed .ipa shipped (team ad-hoc profile, 7.7MB .ipa in release assets), .62 deployment target iOS 17 → iOS 16 (covers iPhone 8+, expands test pool by +30%), .63 fixed iOS 16 PIN crash (AppState.swift MainActor.assumeIsolated replaced with Task @MainActor — back-deploys to iOS 13) + AppIcon full-bleed regenerated (1282×1282 source, 18 AppIcon assets, all RGB no alpha — App Store compliant), .64 unified the 4-segment version + cleared 3 stale AppConstants hardcodes (0.32.0 / 32 / com.chainlesschain.ios) to Bundle.main dynamic reads + Settings About row locked to v5.0.3.64 display + 18 unit + 7 integration + 2 UITest three-layer regression coverage. Same period iOS Phase 5 AI Chat static audit found 4 real bugs fixed one by one: finalizeStreamingPlaceholder empty-string nil-coalesce bypass / deleteConversation partial rollback / sendMessage missing stream-in-flight guard / selectConversation stale streamId pollution — each with a regression unit test + 4 integration tests covering events fan-out / cancel ordering / offline drain / multi-conversation stream isolation — iOS test suite ~313 → ~358. Phase 6 sprint one night 19 commits delivered Knowledge 30 method + AI Extended 25 method desktop hybrid + iOS Commands actor wrap + 15 main tab UI + Multimodal v0.3 live recording (AVAudioRecorder 16kHz mono AAC) + Agent streaming runAgentStream + iOS poll loop + Agents UI live. Green baseline 1fb947b32, iOS CI real-compile verified.

v5.0.3.64 does three things and closes iOS version management: (A) Clear all stale AppConstants hardcodes — `AppConstants.App.version` was hardcoded "0.32.0" (months stale), `buildNumber` "32", `bundleId` "com.chainlesschain.ios" (actual Info.plist is com.chainlesschain.ChainlessChain — CodeSign also uses this). All migrated to dynamic Bundle.main reads via 5 new helpers (`Bundle.appShortVersion` / `appBuildNumber` / `appFullVersion` / `appFullVersionTag` / `appDisplayName`). AIDashboardView.swift hardcoded "v0.16.0" + PluginManager.swift fallback "1.7.0" all replaced. Settings About row now shows full 4-segment v5.0.3.64 + a Bundle ID row so users can confirm they have the real build. (B) Second-pass iOS 17 API audit — 596 .swift files scanned with 29 patterns (assumeIsolated / @Observable / SwiftData / symbolEffect / ContentUnavailableView / scrollPosition / KeyframeAnimator / visualEffect / sensoryFeedback / Previewable / dialogSeverity / SubscriptionStoreView etc.) — 0 new violations. AppState.swift:94-118 v5.0.3.63 fix in place (Task { @MainActor in ... }); SystemInfoView.swift:65-73 .symbolEffect inside #available(iOS 17, *) with iOS 16 static fallback; ImagePickerView.swift @Previewable inside @available(iOS 17, *) #Preview {} — preview-only never ships. (C) Three-layer regression coverage — BundleVersionTests.swift 11 unit (helpers + AppConstants dynamic semantics); AppStateNotificationTests.swift 7 integration (databaseUnlocked / didAuthenticated post does not crash + repeated post stability + 4-segment version lock); ChainlessChainUITests testSettingsVersionDisplaysFourSegmentTag + testPINUnlockDoesNotCrashOnFirstLaunch XCUITest real-device regression. Same period iOS Phase 5 AI Chat static audit found 4 real bugs: (1) finalizeStreamingPlaceholder empty-string nil-coalesce bypass — old code `messageId ?? oldMsg.id` but ChatStreamEnd.parseFromEnvelope fills "" (not nil) when server lacks messageId; nil-coalesce does not catch "", which overwrites the local-assistant-<UUID> placeholder id; SwiftUI ForEach(messages, id: \.id) identity collapses (multiple rows share empty id). Fix: explicit guard `if let mid = messageId, !mid.isEmpty`. (2) deleteConversation partial rollback — failure to delete current conversation only restored the list; currentConversation / messages stayed empty. New rollbackDelete + wasCurrent / originalCurrent / originalMessages snapshot enables atomic full rollback. (3) sendMessage missing defensive stream-in-flight guard — UI switches to cancel button while streaming, but VM cannot assume the upper layer disabled send (programmatic call / double-tap race / upper bug can bypass). Added `guard currentStreamId == nil` before the DC gate. (4) selectConversation stale streamId pollution — switching conversations did not clear currentStreamId; edge case where the new conversation's last row was a streaming placeholder (previously never finalized) — prev stream's delta would mutate the new conv's last. Fix: explicit currentStreamId = nil + isStreamingMessage = false. + 4 integration tests (Phase5AIChatIntegrationTests) cover events fan-out / cancel ordering (discardStream → local state settled → cancelStream RPC sent → late chunk silently dropped) / offline drain (DC down → ai.createConversation queues → DC ready edge → drainer triggers) / multi-conversation stream isolation (conv A streams → switch to conv B → sA later delta+end never touches conv B messages). iOS Phase 6 sprint one night 19 commits: desktop knowledge-handler.js +30 method (folders 5 + tags 3 + alias 1 + versions 4 + star/pin 6 + archive 3 + import-export 4 + advanced tags 3) + ai-handler.js +25 method (Conversations advanced 5 + Prompt templates 3 + RAG 5 + Multimodal 4 + Code helpers 4 + Agents 4); iOS KnowledgeCommands actor wraps 31 method (30 desktop + getNote alias) + AIExtendedCommands actor wraps 25 method; KnowledgeView + AIExtendedView SwiftUI + 2 VM + 2 new main tab (→ 15 total); Multimodal v0.3 live recording AVAudioRecorder 16kHz mono AAC + Agents 2 new sub-tab + 5 tab horizontal picker + Agent streaming desktop runAgentStream + iOS poll loop + Agents UI live. Green baseline 1fb947b32, iOS CI real-compile verified (the only Swift compile path available on Win).

Read design doc →
37 · Highlight
v5.0.3.57 · 2026-05-17

Android remote file skill wired — browse / upload / download PC files, one-tap open inside the app

After pairing, Android FileTransferScreen exposes full remote file management: browse any PC directory (~ / C:/ / project paths, no sandbox) + upload phone files to PC Downloads (auto (1)/(2) suffix anti-collision) + download PC files to the phone public Downloads folder (MediaStore.Downloads — native Files / Gallery / readers see them directly) + 4th TopAppBar icon "Local Downloads" lists in-app, tap opens directly via Intent.ACTION_VIEW (never leaves the app). Reuses the Plan C signaling channel — zero new infra. One night cleared 6 interlocking bugs (P2PClient skip guard too wide / Plan C does not call connect / handleFileCommand opens PC folder picker + missing listDirectory case / FileTransferHandler sandboxed in userData / checksum sha256-prefix vs md5 mismatch auto-deletes / getExternalFilesDir hides files from user). 34 new unit tests all green (PC vitest 30 + Android RemoteCommandClientTest 4). Xiaomi 24115RA8EC × Win desktop real-device E2E 8 scenarios pass.

Productization closure for Plan C Android↔PC file transfer. FileTransferScreen now exposes 5 TopBar icons: Browse remote (input ~ / C:/Users/... → enter, directories first alphabetical, tap directory recursive, tap file downloads, ↑ parent / refresh) / Upload (system GetContent picker → auto chunk upload → Snackbar shows "PC: C:/Users/longfa/Downloads/<name>" + "Copy path" button, PC auto-appends (1)/(2) suffix anti-collision) / Manual download (input remote path + filename) / Local downloads folder (v5.0.3.57 new — MediaStore.Downloads.EXTERNAL_CONTENT_URI query of public Downloads, DATE_ADDED DESC sorted, each row shows filename/size/time + "Open" launches system viewer) / Clean up history older than 30 days. PC side desktop-app-vue/src/main/remote/handlers/android-file-handler.js newly written 460 lines, dispatches 11 actions (listDirectory/getFileInfo/exists/delete/createDirectory/requestUpload/uploadChunk/completeUpload/requestDownload/downloadChunk/cancelTransfer/listTransfers), fields aligned with Android FileCommands.kt (type not isDirectory / modifiedTime not modifiedAt / entries not items). 6 interlocking bugs fixed: (1) P2PClient.kt:538-542 chainlesschain:* skip guard too wide — old code shadowed P2PClient.sendCommand own responses, pendingRequests never completed. Fix: narrow to skip only chainlesschain:command:request. (2) Plan C path P2PClient.connectionState always DISCONNECTED — RemoteOperateScreen → signaling forward never called P2PClient.connect(), all RemoteCommandClient invocations failed immediately. Fix: RemoteCommandClient.invokeTyped delegates to SignalingRpcClient.invoke(pcPeerId), pcPeerId from PairedDesktopsStore.devices.firstOrNull(). (3) PC handleFileCommand was a thin stub — old switch only had case "list" (SQL table) + case "requestUpload" (dialog.showOpenDialog showed a PC-side folder picker, completely wrong UX). Fix: replace switch with delegate to new android-file-handler. (4) FileTransferHandler (remote-gateway registered) sandboxed in userData + field mismatch — _resolvePath forces prefix app.getPath("userData"), C:\Users\... always Access denied. Fix: do not reuse, write dedicated handler with no sandbox (trusted paired peer). (5) Checksum algorithm mismatch → repository auto-deletes downloaded file — first cut returned "sha256-prefix:abc...", but FileTransferRepository.kt:264-276 expected "md5:" + full MD5, mismatch immediately deletes local file + marks FAILED + throws Checksum mismatch. Fix: return checksum:null to skip Repository verification. (6) getExternalFilesDir(null) hides downloads — /sdcard/Android/data/.../files/downloads/ under Android 13+ scoped storage takes 5 taps + "show hidden" to reach. Fix: API 29+ uses MediaStore.Downloads.EXTERNAL_CONTENT_URI insert to write public Downloads, returns content:// URI ready for Intent.ACTION_VIEW, no WRITE_EXTERNAL_STORAGE permission needed. 34 new unit tests — PC vitest 30 cases (_resolvePath × 5 / listDirectory × 5 / getFileInfo + exists × 3 / createDirectory + delete × 3 / Upload roundtrip × 5 incl collision + metadata.targetDir / Download roundtrip × 3 incl Bug 5 regression checksum-must-be-null / cancelTransfer × 2 / handle() dispatch × 2 / listTransfers × 1) + Android RemoteCommandClientTest 4 cases (delegate to SignalingRpc + Bug 1+2 lockdown coVerify(exactly=0) does-not-touch p2pClient.sendCommand). Xiaomi 24115RA8EC × Win desktop real-device E2E 8 scenarios all pass: E1 browse home / E2 browse root / E3 enter sub-directory / E4 small file upload + copy path / E5 collision (1) suffix / E6 small file download / E7 "Open" launches viewer / E8 local downloads panel lists everything. Design doc docs/design/Android_Remote_File_Skill.md / user doc docs-site/docs/guide/remote-file.md. Known limits: large files >10MB through signaling 4-hop base64 chunks may time out — will switch to DC after Plan A.1 stabilizes; API <29 MediaStore.Downloads unavailable, fallback to app-private path which users cannot find — add FileProvider later if reported; destructive actions (delete / writeFile) currently have no approval gate, trusted paired peer executes automatically — future mobileApprovalChannel layer.

Read design doc →
38 · Highlight
v5.0.3.55

iOS port — Phase 1+2+3+4 framework complete (desktop pairing + remote terminal + remote-operate framework + 4 typed skills + Notification skill)

After Android v1.0 GA validation, the iOS port mirroring began. All 4 phases landed framework-complete in one day: ~313 unit tests / 4 design docs / 4 trap memories. Phase 1 desktop pairing three flows (Flow A camera scans desktop QR / Flow B desktop displays QR for phone / manual 6-digit code) + Phase 2 remote desktop terminal (WebRTC DataChannel + xterm.js WKWebView) + Phase 3 remote-operate framework (RemoteCommandClient generic RPC + OfflineQueue + 4 typed skills: Clipboard / File / Screenshot / SystemInfo) + Phase 4 Notification skill (NotificationCommands actor 11 methods + LRU dedup 256 + UN center push + optimistic update + offline gate three branches + RemoteOperateView 6th tab horizontal scroll picker + Capsule unread badge). Mirrors the Android version already validated on Xiaomi 24115RA8EC real device; UI information architecture 1:1 aligned. Remaining Phase 1.7 / 2.7 / 3.7 / 4.7 real-device E2E requires Mac + iPhone + real desktop — handed to user. Plus #21 P1 main scope 5/5 fully closed (A.1 Linux native pairing + A.2 three-platform UI consistency design doc + B.1 web-shell private-key signing UI + B.5 cross-chain bridge m-of-n multisig + C.1 wear→phone voice forward · ~270 unit tests). CLI 0.162.0 minor (cc pair preflight LAN diagnostics + cc pair token subcommand group + systemd hardening template + docs/linux/PAIRING.md 9-section user guide).

v5.0.3.55 mirrors 1+ year of accumulated Android mobile capabilities (QR pairing / remote terminal / remote-operate framework / Notification skill) onto iOS. All 4 phases are framework-complete ports. Phase 1 desktop pairing three flows commit c30b415a8 (71 unit tests, Modules/CoreP2P/Pairing 9 swift + Features/Pairing 8 swift + PairingSignalingGate interface + PairedDesktopsStore UserDefaults JSON persistence + desktop follow-up manual-pair-listener.js 220 LOC pairing-code alias listener). Phase 2 remote desktop terminal commit 7613ea710 (163 unit tests, Modules/CoreP2P/RemoteTerminal 13 swift + Features/RemoteTerminal 6 swift + 4 xterm.js bundle resources + SignalClient.forwardedMessages multi-subscribe AsyncStream backfilling Phase 1 design gap). Phase 3 remote-operate framework + 4 typed skills commit 759a1e907 (~264 unit tests, Modules/CoreP2P/RemoteSkills 16 swift + Features/RemoteOperate 6 swift + RemoteCommandClient single-consumer fix moves webRTCClient.inboundMessages subscription owner to commandClient, TerminalRpcClient now subscribes to commandClient.events to avoid AsyncStream single-consumer event split bug). Phase 4 Notification skill commits 45b485fdd → 5877b5d84 6 sub-phases all landed (41 new unit tests cumulative ~313, 3 swift CoreP2P + ViewModel 322 LOC + View 517 LOC + existing PushNotificationManager unchanged / only 1-line conformance extension + DI events fan-out task fixing the cmdClient.events AsyncStream single-consumer multi-skill subscription trap + RemoteOperateView 6th tab + SkillTabPickerView REWRITE horizontal scroll + Capsule unread badge per design §7.9 option B). 2 P0 fixes: RemoteCommandClient.invoke withThrowingTaskGroup timeout path pendingResponses leak + RemoteWebRTCClient.waitForAnswer pendingAnswer not cleared cleanly — 2 regression tests + 1 integration test verify pools clean. 4 design docs + 4 trap memories (ios_qr_pairing_three_flows / ios_remote_terminal_phase2 / ios_remote_operate_phase3 / ios_remote_notification_phase4) + feedback_ios_ui_mirrors_validated_android (UI info architecture must mirror Android Kt screens already real-device E2E validated, HIG deviation limited to 6-item whitelist). Same batch: #21 P1 main scope 5/5 — A.1 Linux native pairing (cc pair preflight 5-item LAN diagnostics + cc pair token subcommand group + systemd hardening template + 9-section docs/linux/PAIRING.md, 57 unit tests) + A.2 three-platform UI consistency design doc (4 must-match + 4 must-differ) + B.1 web-shell private-key signing UI (MultisigSigner + in-process WS topic bypassing 6-10s cold start + SignProposalModal + unified-key-manager DID routing, 113 unit tests) + B.5 cross-chain bridge outbound × m-of-n multisig Layer 1+2 across 8 PRs (CLI + cc_bridges provenance columns + crosschain-mtc helpers + verifyMultiHopBridgeEnvelope auto-runs check) + C.1 watch face VoiceMode shortcut (phone NavGraph + wear MessageClient forward + trigger_source locked to WEAR_FORWARD anti-spoof, 33 unit tests).

Read design doc →
39 · Highlight
v5.0.3.53

Plan A.1 Remote Terminal Android↔Desktop WebRTC DataChannel direct (Phase 1-5 landed in one day, 7 commits)

Plan A real-device validation surfaced one architectural issue: a 4-hop signaling chain (phone → router → public relay → desktop RelayClient) is fragile under NAT idle / cellular carrier-side TCP RST — any hop down kills the whole chain · Plan A.1 moves high-frequency / high-throughput terminal traffic onto a WebRTC DataChannel direct connection, bypassing every middle hop; signaling stays as fallback · Phase 1 Trap 1 fix: SignalClient.forwardedMessages migrated to multi-subscribe SharedFlow replacing the single-listener setOnForwardedMessageReceived which was the root cause of the ice:config interceptor being silently overwritten + new WebRTCClient.dataChannelReady StateFlow derived flag · Phase 2 SignalingRpcClient.invoke embeds a transport selector DC-first fallback signaling, two listeners simultaneously consume signaling + DC streams, same requestId → same CompletableDeferred (second complete is a no-op; dual delivery is safe without explicit dedup) · Phase 3 TerminalListViewModel async-triggers handshake on entry + UI chip "P2P direct" green vs "Relay path" yellow · Phase 4 Android stdout 256-LRU + exit 64-LRU dual-stream subscriber + desktop mobile-bridge 128-LRU / 30s-TTL keyed by payload.id · Phase 5 falls out of existing wiring with no new code · Perf RTT p50 200-500ms → 30-80ms LAN · p99 1.5-30s → 200-800ms · stability 20s-2min outages → hours-long sustained · Tests Android +8 / desktop +14 / all three suites green (11 + 15 + 21 Android + 14 desktop) + 12-test regression fix (mockk relaxed StateFlow generic erasure) · Real-device E2E §5.3 5-scenario matrix on the user · Design doc Android_Remote_Terminal_Plan_A1.md v1.0 · Telemetry path=dc|signaling live

v5.0.3.52 Plan A real-device validation on Xiaomi 24115RA8EC × Win desktop dev surfaced one architectural issue: a 4-hop signaling chain phone→router→public-relay→desktop-RelayClient is fragile under NAT idle / cellular carrier-side TCP RST — any hop down kills the whole chain. Plan A.1 moves high-frequency / high-throughput terminal traffic from the signaling chain onto a WebRTC DataChannel direct connection, bypassing every middle hop; signaling stays as a fallback. Perf targets: end-to-end RTT p50 200-500ms → 30-80ms LAN / 50-200ms TURN, p99 1.5-30s with timeouts → 200-800ms, sustained-connection stability 20s-2min outages → hours-long (depends on ICE keepalive). Phase 1 Trap 1 fix commits d22b7ac8a + bb759bc78: SignalClient.forwardedMessages migrated to multi-subscribe SharedFlow replacing the single-listener setOnForwardedMessageReceived — original bug: the ice:config interceptor installed by WebRTCClient.initialize was silently overwritten when the user entered TerminalListScreen and TerminalRpcClient.start set its own listener → ice:config pushes dropped → iceServers expired in 24h → cross-NAT became unreachable; added WebRTCClient.dataChannelReady StateFlow Boolean derived flag where READY truly means DC OPEN (avoiding ICE-connected-but-DC-not-open false positives). Phase 2 commit a01eeac47: SignalingRpcClient.invoke now embeds a transport selector connectionState==READY && preferDataChannel → webRTCClient.sendMessage (DC), throws or not-ready → fallback signaling, two listeners simultaneously consume signalClient.forwardedMessages + webRTCClient.messages, same requestId → same CompletableDeferred (second complete is a no-op; dual delivery is safe without explicit dedup), all RPC clients (TerminalRpc + system.* + ai.*) share one chokepoint. Phase 3 commit 91e77e489: TerminalListViewModel.init detects DC not-ready and async-triggers RemoteConnectionManager.connect + UI chip shows P2P direct (green) vs Relay path (yellow) so the path state is user-visible. Phase 4 commit dd9b1227e Android + fc3752360 desktop: Android TerminalRpcClient subscribes BOTH signaling + DC SharedFlow, dedups stdout by (sessionId|seq) with a 256-entry LRU / exit by sessionId with 64-entry; desktop mobile-bridge.bridgeToLibp2p gains 128-entry / 30s-TTL LRU keyed by payload.id for mobile→desktop command requests, guarding against double-stdin in terminal.stdin and duplicate PtyManager side effects. Phase 5 falls out of existing wiring (no new code): DC failure fallback = Phase 2 trySendViaDataChannel catches IllegalStateException and falls through to signaling automatically; auto-reconnect = P2PClient.scheduleReconnect exponential backoff 1s→60s / maxAttempts 10 (already there); recovery auto-switch back = isDcReady re-evaluates on every invoke entry; UI live mapping = Phase 3 dataChannelReady chip. Tests: Android TerminalRpcClientTest +3 dedup / SignalingRpcClientTest +4 transport selection / WebRTCClientTest +1 Trap 1 regression + 12-test regression fix where mockk(relaxed=true) on StateFlow<List<X>> generic-erased .value to a relaxed Object instead of a real List → production-side pairedDesktopsStore.devices.value.firstOrNull threw Object cannot be cast to Iterable → connect() caught and wrapped as "连接失败: ..."; the fix adds every { mockPairedDesktopsStore.devices } returns MutableStateFlow(emptyList()) in test setup. Desktop mobile-bridge.test.js gains 14 new tests covering LRU dedup (5 angles: TTL / capacity eviction / non-whitelisted frame types / JSON-RPC responses untouched / missing payload.id pass through) + sendToMobile DC-first vs signaling-relay double-send fallback (5 angles: DC OPEN single DC / readyState shape normalisation / DC missing double-send / DC closed double-send / missing relay client does not throw) + guard rails 2. All three Android suites green (11 + 15 + 21) + 14 new desktop tests + the rest untouched. Real-device E2E §5.3 5-scenario matrix is on the user: LAN same WiFi DC second-level handshake / cellular TURN relay path / double-NAT 3G symmetric should fallback signaling / DC working forcibly killed → fallback ≤ 3s / DC recovered auto-switches back. Design doc docs/design/Android_Remote_Terminal_Plan_A1.md v1.0 includes §1.2 full analysis of three traps (setOnForwardedMessageReceived single listener / DC inbound vs signaling forward two independent paths / P2PClient.sendCommand is DC-only but uses its own envelope incompatible with TerminalRpc) + §3.7 rationale for not reusing :core-p2p DataChannelTransport (terminal envelope JSON vs sync binary P2PMessage are not interchangeable) + §5.3 real-device E2E 5-scenario acceptance matrix. Telemetry [SignalingRpc.metric] path=dc|signaling reqId is live; first-week fast-path-fraction target ≥80% on user base ≥10 devices; below 80% indicates DC unreachable more than expected and needs diagnosis. Distribution: desktop binary v5.0.3.52 → v5.0.3.53 rebuilt; CLI chainlesschain npm 0.161.12 unchanged (Plan A.1 work all under android-app/ + desktop-app-vue/ + docs/); Android versionCode 503052 → 503053 / versionName 5.0.3.52 → 5.0.3.53 per feedback_android_tag_follows_desktop align-with-desktop convention.

Read design doc →
40 · Highlight
v5.0.3.52

Plan A Remote Terminal: Android↔Desktop PTY end-to-end (Phase 1-4 all landed + 162 tests green)

Single PtyManager shared between web-shell WS gateway + cc ui WS gateway + V6 native IPC · 8 terminal.* WS topics (create/list/stdin/resize/close/history + server-push stdout/exit) · attachTopicHandlers shared helper extracted from ws-cli-loader dispatcher wrap so cc ui mirrors it · web-panel useTerminal composable + Terminal.vue route /terminal with xterm.js lazy + multi-session tabs + history backfill + dangerous-keyword toast · V6 plugin widget + TerminalPanel modal IPC bridge electronAPI.terminal.* + slash /terminal · Android TerminalRpcClient reuses SignalingRpcClient envelope pattern + WebView↔Kotlin JS bridge + xterm-shell.html + xterm.js/addon-fit vendored + Compose list/session + softkey toolbar Ctrl/Tab/Esc/arrows/Ctrl+C/D + 2 NavGraph routes + RemoteOperateScreen entry · confirmation-dialog dangerous-keyword Electron messageBox + permanent trust per-cmd cache · mobile-bridge stdout/exit per-peer fanout

User pain point: "I have many terminals open on my PC, can my Android phone see their output and remotely send commands?" Hard constraint: external terminals already running on Windows cannot be attached by another process (OS handles are private to the parent). Solution Plan A: ChainlessChain desktop uses node-pty to host new terminal sessions; reuses the existing #21 Remote Operate signaling-relay channel to stream stdin/stdout to Android. Phase 1 Desktop main process: PtyManager (lazy node-pty + 256KB ring buffer + 24h idle kill + shell whitelist pwsh/cmd/bash/wsl + 8 concurrent limit) + RingBuffer (byte-aware FIFO, intentionally not persisted to disk — safety > durability since terminal stdout often contains API keys or git diffs of .env files) + terminal-handlers.js (8 WS topics) + terminal-ipc.js (V6 native IPC bridge) + confirmation-dialog.js (dangerous-keyword Electron messageBox + permanent trust per-cmd cache). startWebShell accepts ptyManager + terminalRequireConfirmation; handleMobileCommand adds terminal.* namespace + mobile-bridge per-peer stdout/exit subscription fanout. Phase 1.5 cc ui mirror: packages/cli/src/gateways/ws/topic-handler-attachment.js extracts the ws-cli-loader dispatcher wrap as a reusable ESM helper; cc ui agent-runtime.startUiServer calls it — cc ui users also get /terminal. Phase 2 Cross-shell UI: web-panel useTerminal composable (singleton fanout via module-level sub map + base64↔UTF-8 encoding) + Terminal.vue route /terminal (xterm.js lazy import + multi-session tabs + history backfill + ResizeObserver + dangerous-keyword toast) + sidebar entry + i18n; V6 plugin widget plugins-builtin/terminal/plugin.json + shell/widgets/TerminalWidget.vue + shell/TerminalPanel.vue (xterm.js + IPC bridge electronAPI.terminal.*) + slash command /terminal. Phase 3 Android: TerminalRpcClient.kt (reuses SignalingRpcClient envelope pattern + observeStdout/observeExit SharedFlow) + TerminalWebView.kt (WebView↔Kotlin JS bridge) + xterm-shell.html + xterm.js / addon-fit / xterm.css vendored to assets/terminal/ + TerminalListScreen / TerminalSessionScreen Compose + softkey toolbar (Ctrl/Tab/Esc/arrows/Ctrl+C/D) + NavGraph 2 routes + RemoteOperateScreen "Open Remote Terminal" entry. Phase 4 Resilience: requireConfirmation wired to desktop systray + paired_devices/permission-gate (reuses existing p2p-command-adapter) + mobile-bridge stdout fanout (per-peer subscription map) + reconnect history backfill + 24h idle kill. Tests 162 new all green — Desktop main 61 (RingBuffer 7 + PtyManager 15 + terminal-handlers 15 + terminal-ipc 12 + confirmation-dialog 5 + ws-smoke integration 6 + real PTY spawn cmd.exe integration 1 — completes in 5.08s, end-to-end stdin echo PLAN_A_PROBE_42 stdout stream contains probe) + CLI cc ui 21 (PtyManager 10 + handlers 8 + ws-mirror-smoke 3 with real ChainlessChainWSServer + attachTopicHandlers + real WS client) + Web Panel 17 useTerminal composable + 3 e2e (real cc ui subprocess + real WebSocket + real shell stdin/stdout round-trip via probe echo) + Android 10 TerminalRpcClientTest (full happy path + flow event fanout). Also fixed pre-existing test drift — widget-registry.test.ts (PREVIEW_WIDGETS already extended to 7 entries; bridge-mtc + federation-governance were missing) / dashboard-store.test.js (no mock for mcp.list_tools sendRaw reply, drift since commit d9cc41432) / views-mount-smoke.test.js 5 tail views (Projects/VideoEditing/P2P/Memory/Git hit Notification + Pinia cross-test state pollution under 50+ files parallel suite) / Projects-folder-picker.test.js deleted (tested UI no longer exists). Design doc docs/design/Android_Remote_Terminal_Plan_A.md + user doc docs-site/docs/guide/remote-terminal.md synced to both doc sites. Future A.1 stream traffic through WebRTC DataChannel to bypass relay bandwidth bottleneck / Future B read-only snapshot of already-running external terminals via screenshot + OCR + Win32 SendInput left for later.

Read design doc →
41 · Highlight
v5.0.3.51

Remote Operate Plan A + B infrastructure landed: WebRTC signaling pass-through + STUN/TURN deployment + iceServers credential signing

Plan A: relay server forwards WebRTC offer/answer/ice-candidate (commit e9f9d6275) · Desktop RelayClient.onMessage collapses into mobileBridge.handleSignalingMessage unified dispatch fully equivalent to LAN · Plan B: coturn 4.6 docker compose host network listening 0.0.0.0:3478 UDP/TCP + 5349 TLS + 49152-65535 UDP relay range · turn.chainlesschain.com Let_s Encrypt acme.sh renewal · signIceCredentials HMAC-SHA1 24h TTL ephemeral creds, desktop CC_TURN_SECRET mandatory zero hardcoded · pushIceServersToMobile dual-send LAN signaling + public relay chainlesschain:ice:config after pair-ack matched (commit af11daa6e) · Android WebRTCClient injects PairedDesktopsStore resolveIceServersFor by pcPeerId, expiry/missing fallback Google STUN · intercepts ice:config to persist iceServers / iceExpiry · SignalingRpcClient race-tolerant backup · iceServers removed from QR payload (650 chars + 280px + error-H crashed scan recognition with 30s blocking, switched to signaling push) · backend/signaling-relay-service/ enters repo · design doc Android_Remote_Operate_Plan_AB.md

Plan C (v5.0.3.50) signaling-forward wired low-frequency commands at 100-400ms p99 but two hard constraints remain: throughput (relay bandwidth shared across all clients — streaming tokens / files / video cannot pass) + privacy (the relay server can read plaintext payloads beyond public wss TLS). Plan A+B closes both: real WebRTC P2P DataChannel = end-to-end encryption + direct-link bandwidth. Complete three-tier picture: low-frequency commands → Plan C signaling forward / high-throughput streaming + files → Plan A WebRTC DC / NAT-traversal fallback → Plan B STUN/TURN. Clients fall through by scenario: prefer DataChannel, fall back to signaling forward on failure. Plan A core changes: (1) relay server.js handleMessage switch adds case offer/answer/ice-candidate/ice-candidates/peer-status on the same forwarding path as type=message + injects from field (taking the ws-registered peerId, parity with LAN signaling-handlers — desktop handleOffer reads socket.peerId or message.from to identify the peer; the relay path must explicitly inject from). (2) Desktop main startRelayClient.onMessage collapses to a unified dispatch instead of per-type case: pair-ack still routes alone to write sessionState; the rest (command:request / offer / answer / ice) goes to mobileBridge.handleSignalingMessage, which already dispatches by msg.type to handleOffer / handleAnswer / handleICECandidate / handleP2PMessage — LAN and relay paths become fully equivalent. Plan B core changes: (1) coturn 4.6 docker compose host-network UDP relay port range 49152-65535 host-network avoids NAT translation, listening 0.0.0.0:3478 UDP+TCP + 5349 TLS, domain turn.chainlesschain.com A record 47.111.5.128, Let_s Encrypt cert via acme.sh @gitee mirror (GitHub access throttled in mainland China), use-auth-secret time-limited credentials. (2) signIceCredentials(userId) signing: username = expiry-ts:user-id, credential = base64(HMAC-SHA1(TURN_SECRET, username)); iceServers returns three-tier priority list stun:turn.chainlesschain.com:3478 + turn:3478?transport=udp/tcp + turns:5349 with credentials. TTL 24h is enough for a single-device session — by the time it expires the user has likely re-paired anyway. CC_TURN_SECRET env is mandatory with no source-level fallback and never hardcoded (no fork can mint working credentials); without it the system degrades to STUN-only (LAN + dual-NAT-friendly scenarios still WebRTC; cross-NAT unavailable). (3) iceServers no longer embedded in QR — QR payload 650+ chars + high error correction at 280px crashed scan recognition (verified 2026-05-14: 30s blocking with no detection); switched to async push after scan: when desktop pair-ack matches it calls pushIceServersToMobile(ackPayload) over both LAN signaling + the public relay (dual-send) with type chainlesschain:ice:config payload {pcPeerId, iceServers, iceExpiry} for mobileDid. Android WebRTCClient.setOnForwardedMessageReceived intercepts that type, persistIceConfigMessage upserts PairedDesktopsStore.iceServersJson; SignalingRpcClient.handleIceConfigMessage adds a race-tolerant backup. (4) Android WebRTCClient.createPeerConnection calls resolveIceServersFor(pcPeerId) using stored iceServers (TURN included), with expiry/missing fallback to Google STUN; parseIceServersJson accepts urls as either string or array. Full Plan A+B data flow: pairing — phone scans QR → pair-ack → desktop persists SQLite + pushes iceServers → phone receives ice:config → PairedDesktopsStore upsert; WebRTC connection — phone opens RemoteControl → WebRTCClient.connect(pcPeerId) → createPeerConnection with stored iceServers (TURN included) → createOffer → signaling forward (LAN or relay) → desktop handleOffer → setRemoteDescription → createAnswer → forward back → ICE candidate exchange via forward, STUN/TURN punches → DataChannel open. Command path split: low-freq SignalingRpcClient relay forward = Plan C / high-throughput DataChannel direct = Plan A / NAT-hard TURN relay = Plan B (DataChannel through relay). Aliyun security groups must allow UDP 3478 / TCP 3478 / TCP 5349 / UDP 49152-65535 to 0.0.0.0/0 — without it the coturn container runs but is externally unreachable, ICE gathering fails. Known constraints / outstanding: iceServers TTL 24h — once expired, fallback Google STUN cannot traverse NAT (mobile-side detection of approaching expiry to request fresh credentials over signaling lands later); WebRTC P2P real-device cross-NAT verification still pending — full file-transfer test on phone 4G + desktop home WiFi planned before v1.4 GA; Signal Protocol E2EE waits for Plan A DC to land first (DC is already direct + TLS, marginal gain from Signal); coturn credential management API needs backend HMAC signing API in the long run, gated by user identity. Design doc docs/design/Android_Remote_Operate_Plan_AB.md.

Read design doc →
42 · Highlight
v5.0.3.50 · #21 project workflow

v1.2 GA feedback 5+3 integrated: desktop↔mobile project workflow P1+P2+P3A + delete fix + daily templates

cc project CLI 4 subcommands write directly to desktop SQLite WAL · project-management-handler exposes 6 actions to L3 REMOTE · ProjectSyncWalker + CompositeSyncRepositoryWalker close the reverse-sync gap · web-shell Projects.vue project management list + 6 in-process WS topics reuse same handler for web-shell + mobile · 11 daily-life templates replace 11 IDE templates · delete UI fix · north star: phone-side AI project interaction as smooth as desktop · 80 Android + 51 Desktop tests pass

v1.2 GA feedback integrated 5+3 items: issue 21 https://github.com/chainlesschain/chainlesschain/issues/21 #2/#3/#4/#5/#7/#8. North star: phone-side AI project interaction should be as smooth as desktop. Two phases. Phase 1 (earlier P0 before GA): A.3 ADR review + B.6 PQC strict-mode verifier + B.2 trim web-shell multisig cc subprocess cold-start + AI-3 forward-compat seam + 2 bug fixes already landed commits 348896382 / e24386d00 / b1c7cfd95 / 45a88270e / c0d061328 / 409afddcd. Phase 2 (mid-stage after GA feedback) project workflow 4 pieces: #2 project undeletable fix (commit fc24f9856) EnhancedProjectCard had no delete UI at all the old ProjectListScreen delete code was dead never wired into NavGraph added 3-dot menu + AlertDialog confirm onDeleteClick invokes viewModel.deleteProject DAO softDelete status deleted Room Flow auto removes from list. #3 templates to daily life 11 entries (commit 99d38bf69) under the L1+L2+L3 mobile positioning users are not developers the original 11 IDE templates Android React Spring Flutter mismatch real usage scenarios rewrote ProjectTemplates as daily-life templates shopping list travel plan reading notes idea capture fitness plan recipe study plan household ledger work journal meeting minutes blank TemplateCategory added 5 new categories DAILY TRAVEL STUDY HEALTH FINANCE. #4/#7 desktop CLI + REMOTE handler P1 (commit 32ccabdb5) packages/cli/src/lib/project-runtime.js SQLite cascade native better-sqlite3-multiple-ciphers better-sqlite3 sql.js WASM auto fallback + Electron userData path resolution Win macOS Linux + cc project init/list/show/delete 4 subcommands write directly to desktop chainlesschain.db WAL concurrency safe. desktop-app-vue/src/main/remote/handlers/project-management-handler.js 6 actions list get init delete listFiles getFile exposed to Android L3 REMOTE calls reusing desktop DatabaseManager. CLI 7 integration tests + handler 21 unit tests all pass. #4 Android to Desktop reverse sync P2 (commit 2646bbb4e) audit found desktop to mobile sync was working mobile-bridge-sync _fetchProjects walker + Android ProjectSyncApplierImpl but reverse mobile to desktop was broken SocialSyncWalker did not include projects table. Added ProjectDao.getProjectsSinceCursor no status filter so status=deleted also emits + ProjectSyncWalker.kt feature-project about 120 lines op mapping CREATE/UPDATE/DELETE snake_case JSON aligned with desktop + CompositeSyncRepositoryWalker.kt :app/sync aggregates SocialSyncWalker + ProjectSyncWalker + SyncWalkerModule.kt Hilt @Binds replaces feature-p2p single-walker binding. P2PModule.kt commented out the old binding. ProjectSyncWalker 12 tests + CompositeSyncRepositoryWalker 7/7 tests all pass. Also fixed 5 pre-existing feature-project tests kotlin.test.* org.junit.Assert.* imports to unblock :feature-project:compileDebugUnitTestKotlin. #5/#8 web-shell Projects + in-process WS P3 Part A (commit bfdde637d) desktop-app-vue/src/main/web-shell/handlers/project-handlers.js 6 in-process WS topics wrap the P1 ProjectManagementHandler DRY reuses the same handler to serve web-shell + mobile L3 REMOTE avoiding ws.execute(cc project …) asar:true subprocess cold-start 6-10s. packages/web-panel/src/views/Projects.vue rewritten as a real project management page 4 stats + state/name filter + table with id/name/type/status/sync_status/updated_at + Detail drawer with Descriptions + file list + Create modal with 10 types useShellMode.isEmbedded dispatches between in-process and ws.executeJson fallback. The original Projects.vue project init/setup/templates content was moved to ProjectInit.vue at route /project-init to keep backward access. project-handlers 7 unit tests all pass. No version bump; will release alongside the P1 main scope once P3 Part B Android ProjectCommands.kt lands and the user has verified P1+P2+P3A.

Read design doc →
43 · Highlight
v5.0.3.50 · #21 P0

Android v1.3+ P0 prerequisites GA-independent closed + AI-3 forward-compat + 2 bug fixes

A.3 ADR Review v2.0 (8 ADRs audited: 5 keep / 2 amend / 1 revise) · B.6 LandmarkCache.strictPqMode opt-in rejects Ed25519 partial sigs · B.2 web-shell multisig.* in-process WS topics cold-start 6-10s → ~20ms 60-100x speedup · AI-3 SkillMetadata.signature forward-compat + NoOpManifestVerifier swap seam · 2 bug fixes (wear test imports + B.6 disk-load gate) · tests 11+23+10+57+379 all pass · no version bump (will release with P1 main scope after v1.2 GA)

P0 prerequisite batch before v1.2 GA. Issue 21 https://github.com/chainlesschain/chainlesschain/issues/21 A.3 ADR review + AI-1 amend (commit 348896382): 8 ADRs audited — 5 keep + 2 amend (ADR-7 cc-mobile.json was never created and actually goes through user_settings + mobile.* scope; ADR-8 registry is disk-first + push-based, not pull) + 1 revise (ADR-2 M2 DID wallet still uses software Ed25519, which blocks B.3 DID rotate). ADR-2 option A/B/C decision waits on v1.2 GA Play Console API-level data. Same commit adds design doc §10 v1.3+ scope triage layering across 12 sub-items (P0/P1/P2) plus 5 dependency chains. B.6 PQC strict-mode verifier (commit e24386d00): packages/core-mtc/lib/landmark-cache.js gains strictPqMode opt-in flag + _assertStrictPqMode landmark-level gate + _assertStrictPqModeForSnapshot per-snap gate + STRICT_PQ_MODE_VIOLATION error code + CLASSICAL_ALGS constant. Reading A semantic rejects any partial sig + publisher_signature where alg === Ed25519. Backward-compatible with the existing heterogeneous federation data format (zero schema changes, zero producer-side changes). B.2 skip cc subprocess cold-start (commit b1c7cfd95): desktop-app-vue/src/main/web-shell/handlers/multisig-handlers.js adds 7 in-process WS topics that mirror the CLI --json output shape (multisig.list / show / policy.show / cancel / finalize / sweep + marketplace.consume). The topics invoke openMultisigManager() from the CLI multisig-runtime.js via dynamic-import across the CJS/ESM boundary. Multisig.vue gains callMultisigTopic() helper that dispatches via useShellMode().isEmbedded; all 7 ws.executeJson sites switch. Perf: asar:true subprocess cold-start 6-10s → in-process ~20ms (SQLite open) + query, 60-100x speedup. Zero UX changes. AI-3 SkillMetadata.signature forward-compat (commit 45a88270e): Android Kotlin adds ManifestSignatureVerifier interface + sealed VerificationResult.{Accepted/Rejected(reason)} + object NoOpManifestVerifier always-accept stub. SkillMetadata gains signature: String? = null field + init invariant. RemoteSkillRegistry gains @Volatile manifestVerifier + setManifestVerifier(v) swap seam + updateFromRemote runs the verifier per-skill (Accepted merges; Rejected Timber.w warn-logs + skips). When marketplace M0 (#21 AI-5) lands, app injection of a real Ed25519/SLH-DSA hybrid verifier is enough; callers do not change. Bug fix 1 wear test imports (commit c0d061328): CcPhoneDecisionListenerTest since cc08da0b0 (v1.2 #20 P0.2) used kotlinx.coroutines.GlobalScope.launch with delay() but the imports were missing launch / delay / GlobalScope / DelicateCoroutinesApi, which blocked the entire :app:compileDebugUnitTestKotlin. Added 4 imports to unblock. Bug fix 2 B.6 disk-load gate (test-driven discovery in this QA sweep): LandmarkCache.loadFromDisk() called _validateAndStoreSnapshot directly, bypassing ingest's strict-mode gate; an Ed25519 landmark cached when strictPqMode was off would later be accepted by a strictPqMode=true cache on disk reload (silent strict invariant violation). Fix: moved the per-snapshot strict check into _validateAndStoreSnapshot so both ingest and disk-load paths run through the gate; +2 disk-load integration tests lock the regression. Tests: B.6 landmark-cache-strict-pq-mode 11/11 (9 original + 2 disk-load integration) + B.2 multisig-handlers 23/23 unit tests via runtimeFactory injection seam + AI-3 ManifestSignatureVerifier 10/10 + SkillMetadataTest 9/9 + RemoteSkillRegistryTest 38/38 regression + web-shell 379 regression across 25 test files, all pass. No version bump: this batch is the v1.2 GA prerequisite; will release with P1 main scope after v1.2 GA feedback lands.

Read design doc →
44 · Highlight
v5.0.3.50

Android Remote Operate Plan C signaling-forward RPC: mobile remote really wired to the desktop

After pairing the mobile taps Ping / System Status / System Info → desktop runs it → response comes back (commit f8ec994ef) · SignalingRpcClient with 30s withTimeout + automatic LAN→relay fallback (reset gate + switch URL + re-register + retry) · RemoteOperateScreen 3 chip buttons + JSON response display + NavGraph remote_operate/{peerId} · PairedDesktopsStore SharedPreferences persists paired desktops, upsert idempotent by pcPeerId · Desktop RelayClient outbound long-lived connection to wss://signaling.chainlesschain.com, exponential backoff capped at 60s · mobile-bridge.handlePairAckFromRelay bug fix · MobileBridgeHeaderStatus.vue header shows paired mobile count, 5s polling + parseJsonOutput skips CLI log-prefix lines · 11 i18n strings extracted into values/strings.xml + values-zh-rCN/strings.xml · 3 new unit test files / 20 tests all green (PairedDesktopsStoreTest 7 / SignalingRpcClientTest 7 / RemoteOperateViewModelTest 6) · design doc Android_Remote_Operate_Plan_C.md

After pairing landed in v5.0.3.49 (W3.7 Flow B QR), the next step is letting the mobile actually operate the desktop. Three candidate paths: A WebRTC P2P direct (big engineering) + B STUN/TURN traversal (medium) + C reuse the signaling-forward pipe that pair-ack already proved (small). Plan C ships first pragmatically: pair-ack already routes through forward in both directions, the desktop handleMobileCommand is already in place, only the mobile-side SignalingRpcClient and a minimal UI are missing. A+B left for follow-up (video streams, real-time sync, high-frequency small messages). (1) SignalingRpcClient lands (app/.../remote/client/SignalingRpcClient.kt): builds {type:"chainlesschain:command:request", payload:{id, method, params, auth, timestamp}} → PairingSignalingGate.sendAck; one-shot installs setOnForwardedMessageReceived listener and matches requestId to CompletableDeferred to resolve responses; 30s withTimeout safety net; automatically resets the gate, switches to the public relay URL, re-registers and retries once when the LAN sendAck fails — same pattern as ScanDesktopPairingViewModel pairing fallback. (2) RemoteOperateScreen + ViewModel (app/.../remote/ui/RemoteOperateScreen.kt): minimal UI with three chip buttons (Ping / System Status / System Info) + response JSON display + unpair; the home screen connected-desktop card taps into NavGraph route remote_operate/{peerId}. (3) PairedDesktopsStore (core-p2p/.../pairing/PairedDesktopsStore.kt): SharedPreferences JSON of paired desktops (pcPeerId / deviceName / lanSignalingUrl / relayUrl / pairedAt / lastSeenAt); upsert idempotent by pcPeerId; the home screen now reads from this store instead of p2pClient.connectedPeers because Plan C does not maintain a persistent P2P connection — once the post-scan signaling drops, connectedPeers is empty and the UX would look like not-connected right after a successful pairing. (4) Desktop RelayClient (desktop-app-vue/src/main/p2p/relay-client.js): outbound long-lived connection to wss://signaling.chainlesschain.com, registers the desktop pcPeerId (must match mobileBridge.peerId, otherwise off-LAN phones cannot find the target peer), onMessage routes pair-ack / regular mobile commands into recordPairAck / handleMobileCommand (same pipeline as LAN); exponential backoff reconnect capped at 60s. (5) mobile-bridge.handlePairAckFromRelay bug fix: main/index.js was calling this.mobileBridge?.handlePairAckFromRelay(...) but the method did not exist; the optional-chain swallowed it silently, so the relay path pair-ack triggered no event. Added an EventEmitter notification symmetric with the LAN branch. (6) MobileBridgeHeaderStatus.vue web-panel header shows paired-mobile count, polling cc p2p devices --type mobile every 5s; parseJsonOutput now skips CLI log-prefix lines [AppConfig] / [DatabaseManager] etc. to stop false-positive matching them as JSON-array starts. (7) i18n: 11 RemoteOperateScreen strings extracted into values/strings.xml + values-zh-rCN/strings.xml — ro_title / ro_subtitle / ro_peer_id_fmt / ro_quick_commands / ro_cmd_ping/status/info / ro_executing_fmt / ro_error_label / ro_response_label / ro_unpair. Tests: 3 new unit test files / 20 tests all green — PairedDesktopsStoreTest 7 (mocked SharedPreferences instead of Robolectric, orders-of-magnitude faster startup) / SignalingRpcClientTest 7 (FakeSignalClient + CapturingGate; happy / no-DID fail fast / LAN→relay fallback / double-fail / response with error field / real withTimeout / unknown rid silent ignore) / RemoteOperateViewModelTest 6 (mockk + StandardTestDispatcher state transitions + null-message error fallback + unpair calls store.remove). Two key technical decisions: use runCurrent() instead of advanceUntilIdle() — SignalingRpcClient.invoke uses withTimeout(30000) on virtual time and advanceUntilIdle would push the virtual clock past 30s and falsely trigger the timeout; added testImplementation org.json:json:20240303 — the Android SDK stubbed org.json.JSONObject silently returns defaults under isReturnDefaultValues=true instead of really parsing JSON. ScanDesktopPairingViewModelTest signaling gate failure surfaces Failed now expects sendAckCallCount == 2 (LAN + relay both called). Desktop vitest 7600+ suite all green. Plan C real-device E2E is on the user-side checklist, same pattern as Flow B verification. Constraints: one signaling hop + one public-relay hop puts p99 latency at 100-500ms — acceptable for low-frequency commands; relay traffic is TLS but the relay server can see the payload, so end-to-end encryption requires Signal Protocol session; relay outage = Plan C unavailable, LAN still works. Roadmap: Plan C landed → Plan A.1 DataChannel reuse → Plan A.2 high-throughput true P2P direct to bypass relay bandwidth → Plan B STUN/TURN traversal. Design doc docs/design/Android_Remote_Operate_Plan_C.md. Distribution: desktop binary v5.0.3.49 → v5.0.3.50 rebuilt; chainlesschain npm version unchanged (no CLI changes); Android versionCode/Name unchanged (v1.0.0 GA holds — this Plan C round is desktop-first; the full Android v1.1 minor will ship the complete mobile client). All three doc sites synchronized this round: docs-site / docs-site-design pull the new Plan C design doc through the sync scripts; docs-site tagline bumped to v5.0.3.50; README / README_EN gain this changelog entry.

Read design doc →
45 · Highlight
v5.0.3.49

M-of-N multisig Phase 1d + Phase 2a marketplace mediator + Phase 2b web-panel Multisig view + Android v1.1 W3.7 Flow B QR pairing closes + test backfill

@chainlesschain/core-multisig (5 libs + 75 unit tests) · cc multisig CLI (8 subcommands + 10 integration tests, Phase 1d) · cc marketplace purchase / consume mediator + multisig-runtime.js shared module (−130 lines dedup) + 8 new E2E tests (Phase 2a commit 2755093d0) · web-panel Multisig.vue view: 6-card stats + proposal list + domain policies + detail drawer + sidebar entry, WS through CLI subprocess (Phase 2b commit c758492d9) · 18 multisig integration tests total · SQLite native → sql.js WASM auto-fallback · Flow B (commit c47cbc649) verified end-to-end on Xiaomi hardware · ScanDesktopPairingViewModelTest (10) + desktop-pair-handlers.test.js (19)

Four main lines this release. (1) `@chainlesschain/core-multisig` package + `cc multisig` CLI lands (commit 3c890dcac, v1.2 m-of-n Phase 1d): Phase 1 ships 5 lib files — policy.js (domain {m,n,members[],requirePqc,defaultExpiryMs} validate / normalize); store.js (SQLite 3-table schema — proposals / signatures / policies — plus 5 helpers); proposals.js (state machine pending → reached → consumed plus cancelled / expired terminal); signing.js (JCS canonicalize + DOMAIN_PREFIX "MULTISIG:" replay protection + Ed25519 / SLH-DSA dispatcher + verifyThreshold strip-all-sigs); governance-log.js (append-only JSON Lines audit log capturing every state transition). 75 lib unit tests (policy 14 + signing 21 + proposals 20 + store 12 + governance-log 8) all pass. cc multisig CLI 8 subcommands: propose / sign / cancel / finalize / list / show / sweep / policy {set,show}; all support --json; 10 CLI integration tests pass. SQLite driver cascade: native better-sqlite3-multiple-ciphers / better-sqlite3 falls back to sql.js WASM on load failure — CLI works out of the box on any platform without per-platform native prebuild. Unlocks three canonical domains: marketplace.purchase / did.rotate / cross-chain bridge. Three test-infra fixes: core-multisig vitest.config.js sets globals: true (vitest 4 rejects CJS require("vitest")); 5 test files switch to ESM import; multisig-cli.test.js import path drops .js suffix on @chainlesschain/core-mtc/signers/ed25519 (core-mtc exports key has no suffix). (2) Phase 2a marketplace.purchase mediator (commit 2755093d0, design doc §6.1 lands): `cc marketplace purchase <itemId> --amount-fen N --buyer <did> --key <hex> [--threshold-fen N] [--item-name <name>]` — when amount < threshold (default `LARGE_PURCHASE_THRESHOLD_FEN = 100000` fen = ¥1000) the command takes the direct path (CLI stub prints "purchased", no real payment processor); when amount ≥ threshold a `marketplace.purchase` domain policy is required, otherwise exit 2 `no_policy`; with a policy in place, `mgr.propose` returns the proposalId so the other signers can add their signatures. `cc marketplace consume <proposalId>` — requires `domain == "marketplace.purchase"` and `state == "reached"` before executing; after finalize it prints the order payload and writes a `consumed` event to the governance log; wrong domain or state both exit 2. Shared runtime in `packages/cli/src/lib/multisig-runtime.js` (new file) extracts the SQLite cascade (better-sqlite3-multiple-ciphers → better-sqlite3 → sql.js), manager loader, and readSecretKey / readJsonArg helpers that used to live inline inside commands/multisig.js, so commands/marketplace.js can reuse the same code path; commands/multisig.js was refactored to use the shared module, dropping ~130 duplicate lines while leaving Phase 1 behaviour untouched (10/10 integration tests still pass). 8 new E2E tests pass (`packages/cli/__tests__/integration/marketplace-multisig-e2e.test.js`): (a) full ¥1500 2-of-2 walkthrough — policy set → purchase opens proposal → two signers sign → reached → consume → finalize → governance.log records four events `proposed`/`signed`×2/`reached`/`consumed`; (b) ¥500 takes the direct path without creating a proposal; (c) `--threshold-fen` overrides the default; (d) large purchase without a policy → exit 2 blocked; (e) consume on a pending proposal → exit 2 `proposal_state_pending`; (f) consume on a wrong-domain proposal → exit 2 `wrong_domain`; (g) `--help` text verified; (h) Phase 1 compatibility regression. 18 multisig integration tests pass overall (Phase 1 10 + Phase 2 8). marketplace.purchase becomes the first mediator wired to a real business path. (3) Phase 2b web-panel Multisig view lands (commit c758492d9, design doc §8.1 lands): web-shell (default desktop entry) gains an M-of-N multisig view + operations panel that reuses Phase 1 CLI via `ws.executeJson("multisig list --json")` calls. New `packages/web-panel/src/views/Multisig.vue` (468 lines): six top stat cards — total / pending / reached / consumed / cancelled / expired, each with an Ant icon + colour token. Two tabs: Proposal list — table columns (ID / Domain / State / Sigs / Created / Expires / Actions) + state filter (pending / reached / consumed / cancelled / expired) + domain filter; row actions (detail / cancel / execute purchase — marketplace.purchase reached only). Domain policy — lists known domains (marketplace.purchase / did.rotate / crosschain.outbound) with policy detail and member expansion. Detail drawer (640px) Descriptions render domain / state / threshold / sigs / initiator / timestamps / payload (pretty JSON) + signature list (signer DID + alg + timestamp) + operation buttons (cancel for pending|reached / execute purchase for marketplace.purchase reached / finalize for other reached) + info Alert "web shell does not hold private keys; sign goes through CLI". Top action bar: refresh + sweep expired (`cc multisig sweep`). AppLayout.vue adds the multisig menu item to the security/audit group (TeamOutlined icon) + collapsed-mode parity + i18n fallback "M-of-N 多签" (`appLayout.items.multisig` displays Chinese when unconfigured). router/index.js adds `{ path: "multisig", name: "Multisig", component }`. WS communication goes through the CLI subprocess (`ws.executeJson("multisig list --json")` on the CLI WS server `_executeCommand` path); first cold-start is 6–10s (asar:true overhead, per `mtc-status-handlers.js` comment) — acceptable for Phase 2. Same SPA auto-available in both desktop web-shell and `cc ui` (per memory `feedback_cross_shell_feature_pattern`). Phase 3 follow-up: private-key signing UI (needs UnifiedKeyStore wired) / in-process WS handlers (`multisig.list` / `multisig.show` / ...) to shave latency / real-time push (currently `onMounted` one-shot, no WS subscription) / Marketplace.vue integration entry (purchase modal flowing into the multisig pipeline). (4) Android v1.1 W3.7 Flow B QR pairing lands (commit c47cbc649): desktop displays the QR / phone scans — the standard UX pattern in mainstream apps (WeChat / Alipay / Discord / WhatsApp Web). Camera-scans-screen is dramatically more reliable than the reverse direction. Verified end-to-end on real Xiaomi 24115RA8EC hardware. Cross-module DI split: PairingSignalingGate.sendAck interface lives in :core-p2p so :feature-p2p does not reverse-depend on :app; WebSocketPairingSignalingGate.sendAck implementation in :app serializes via ensureRegistered + Mutex; WebRTCClient.SignalClient.sendForwardedMessage(toPeerId, payload) bridges the mobile signaling forward. Mobile UI: ScanDesktopPairingScreen + ScanDesktopPairingViewModel use the non-social QRCodeScannerScreen (ZXing pass-through; the social variant validates and would reject our desktop-pairing JSON); NavGraph + SettingsScreen gain a "Scan desktop QR" entry. Desktop WS topics trio in desktop-pair-handlers.js: desktop.pair.generate-qr (6-digit code + payload + pcPeerId three-tier fallback: mobileBridge.peerId → deviceManager.getCurrentDevice → "desktop-unknown") / desktop.pair.poll-ack (idle / waiting / acked / expired four states) / desktop.pair.reset; mobile-bridge.js adds this.peerId persistence + intercepts type=pair-ack via recordPairAck, then writes SQLite paired_devices. Vue UI: MobileBridge.vue gets a Flow B tab (default) + Flow A + manual entry 3-tab layout; antd.js registers AQrcode. End-to-end chain on real hardware: Xiaomi 24115RA8EC desktop QR → ML Kit scan → signaling pair-ack → desktop mobileBridge intercept → recordPairAck match → CLI pair-from-qr writes SQLite → Vue refreshes device list. Nine production traps swept. (5) Test backfill: ScanDesktopPairingViewModelTest.kt (new, 10 tests) covers every validation branch of onQrScanned plus happy path + retry + idempotent + malformed JSON, built on MockK + StandardTestDispatcher + FakeGate that captures sendAckCallCount. desktop-pair-handlers.test.js (new, 19 tests) covers all three handler factories plus recordPairAck: generate-qr (6 cases) / poll-ack (4 cases using vi.useFakeTimers for the expired case) / reset (1 case) / recordPairAck (4 cases). Android :feature-p2p:testDebugUnitTest 41s all green (138 actionable tasks); Desktop 3 files / 45 tests all green. Distribution: desktop binary v5.0.3.48 → v5.0.3.49 rebuilt (now carries Flow B + multisig source; auto-updater compares 5.0.3-alpha.49 > 5.0.3-alpha.48); chainlesschain npm 0.161.8 → 0.161.9 (CLI gains multisig command + dep @chainlesschain/core-multisig); Android versionCode/Name unchanged (v1.0.0 GA holds), Flow B desktop-first this release, full mobile client follows in the next Android v1.1 minor.

Read design doc →
46 · Highlight
v5.0.3.48

Android M3 capture suite (5/5 code) + M4 RemoteSkillRegistry method-level + ApprovalUI 4-category + ProgressViewer + alias compat window + M7 Android v1.0.0 GA flip

Design §5.3 five capture pieces landed: VoiceMode / CameraOCR / LocationTagger / SharePayloadFlusher / PushNotifier · §6 M4 D1 method-level metadata · §5.4 ApprovalUI four-category UI + ProgressViewer task.* reverse-RPC · §8.3 alias compat window · Android versionCode 37 → 100 / versionName 0.37.0 → 1.0.0 GA (commit ffe722162) · 187 new unit tests green / Android total 196+ → 383+

Android v1.0 RFC M3 + M4 closing batch (7 commits / 187 new unit tests) + M7 Android GA flip lands together (commit ffe722162, versionCode 37 → 100, versionName 0.37.0 → 1.0.0). No desktop / CLI source changes; CLI npm 0.161.7 → 0.161.8 (force publish on the release.yml sync track). (1) M3 capture suite goes 5/5 to code: VoiceMode end-to-end voice chain (commit 47bebed80, ASR → REMOTE chat → TTS pipeline); CameraOCR snap-to-KB pipeline (commit a69269ced, ai.ocrImage + knowledge.createNote); LocationTagger via Play Services FusedLocationProvider + Foreground Service (commit 3f5ac8647, GPS flows into createNote.metadata); SharePayloadFlusher feeds SyncCoordinator → knowledge.createNote (commit 3d1a6e3a8, 5 SharePayload variants → note fields, drained at the tail of the 30s push loop, failures re-enqueued, 19 new tests); PushNotifier local channel + FCM skeleton (commit c0d990c91, 4 NotificationChannel — Cowork / Marketplace / SystemAlert / ShareInbox — plus a protocol-neutral CcPushNotificationService entry, 36 new tests; real google-services.json wiring stays on the user via the 5-step android-app/docs/M3_FCM_SETUP.md). (2) M4 D1 RemoteSkillRegistry method-level metadata (commit 6e49270fd): MethodMetadata (name / paramCount / riskOverride / requiresApprovalOverride) + listMethods / getMethod / requiresApprovalForMethod / riskForMethod accessors; knowledge.* and ai.* seeded with 10 methods each (8 riskOverride demos); the other 21 namespaces stay empty pending desktop mobile-skill-whitelist push. 16 new tests. (3) M4 closing pair (commit f4f83cc67): ApprovalUI four-category adapter — ApprovalCategory enum {Sign / Cowork / Marketplace / SystemCritical} + fromMethod inference; AndroidApprovalGate 4-arg overload carries category through (old 3-arg auto-forwards); Dialog swaps icon / tint / title / footer per category. ProgressViewer long-running task panel — LongTaskRegistry @Singleton MutableStateFlow (Pending / Running / Completed / Failed / Cancelled, MAX_TASKS=100 sliding window) + TaskProgressCommandRouter consumes task.* reverse-RPC (update / complete / fail / cancel / remove) + Compose ProgressViewerScreen (StatusChip + Linear / indeterminate Circular + dismiss / clear-terminal). 43 new tests across the trio (9 + 15 + 19). (4) §8.3 alias compat window (commit 0bc8e2797): SkillMetadata.aliases field + internal aliasIndex; get / listMethods / requiresApproval / risk* all route through resolveAlias so renaming a namespace next release doesn't break old callers for one window. 7 new tests. (5) §8.1 README versionName fix + v1.0 GA checklist (commits 0bc8e2797 3da484e9c): android-app/README.md M3 (2/5) → (5/5 code); M4 row gains method-level + ApprovalUI + ProgressViewer; new ANDROID_v1_GA_CHECKLIST.md. (6) M7 Android v1.0.0 GA flip (commit ffe722162): android-app/app/build.gradle.kts versionCode 37 → 100, versionName 0.37.0 → 1.0.0; android-app/CHANGELOG.md adds [1.0.0] - 2026-05-12 GA entry summarising 9 commits + 4 known limitations (FCM mainland-China reach / single peer / offline queue / QRPairing scaffold); android-app/README.md title flips to "🎉 v1.0.0 — GA". Next step: tag v1.0.0 at ffe722162 and push to gitee + github. v1.0 GA still has 4 user-side items remaining: M3 device E2E / M4 D2 device E2E / FCM credentials / M6 perf measurements.

Read design doc →
47 · Highlight
v5.0.3.47

Verification release: build-android keystore fix VERIFIED + density splits 14→4 first user-visible drop + outstanding `../` fully swept

release.yml run #25632845952 all 11 jobs green · build-android keystore fix confirmed · 4 Android assets in Release · keystore.properties.template / KEYSTORE_SETUP.md / orphan workflow `../` all gone

Verification-only release. No desktop / CLI / Android source changes — just runs the three release-pipeline fixes landed after v5.0.3.46 through real CI to prove green. (1) build-android keystore fix VERIFIED (commit f9a7ba716): 49f1440ca had switched android-app/app/build.gradle.kts:79 from `file(...)` to `rootProject.file(...)`, moving the `release.storeFile` resolution base from `:app` module up to rootProject (android-app/). The workflow had `release.storeFile=../debug-ci.keystore`, which under the new base resolves to `<repo-root>/debug-ci.keystore` — gradle could not find the keystore and v5.0.3.46 build-android failed at `:app:validateSigningRelease`. f9a7ba716 drops the `../` from workflow keystore.properties content so `rootProject.file("debug-ci.keystore")` resolves directly to `android-app/debug-ci.keystore` (exactly where keytool writes). v5.0.3.47 release.yml run #25632845952 verified build-android green; 4 Android assets (`app-{arm64-v8a,armeabi-v7a,universal}-release.apk` + `app-release.aab`) correctly land in the Release. (2) Density APK splits first user-visible drop (commit 9865c5c08): merged with v5.0.3.46 but never produced release assets because build-android was broken; this release is the first time it ships to users — per-density × ABI splits add little value with Android 5.0+ runtime resource selection, so dropping them cuts release asset count from 14 to 4 (3 APK + 1 AAB); the AAB still uses the `bundle{}` block for Play Store density delivery. (3) Remaining `../` triple sweep (commit 5a06421cd): f9a7ba716 only fixed the active workflow; keystore.properties.template / docs/guides/KEYSTORE_SETUP.md / orphan android-app/.github/workflows/android-release.yml all carried the same `../` pattern and got swept this round. Convention now uniform across the repo: `release.storeFile=keystore/<name>.keystore` (no `../`), physical keystore at `android-app/keystore/<name>.keystore`. The CI example in KEYSTORE_SETUP.md also gained `working-directory: android-app` so the keystore lands in the right place. The orphan workflow received a header comment noting that nested `.github/workflows/` directories are not picked up by GitHub Actions. Desktop binary rebuilt v5.0.3.46 → v5.0.3.47 with equivalent contents; auto-updater compares `5.0.3-alpha.47 > 5.0.3-alpha.46`, so v5.0.3.46 desktop users will see a real "new version" prompt on restart. `chainlesschain` npm stays at 0.161.7 (no CLI changes; release.yml `cli-tests` job correctly skipped). Android versionCode/Name unchanged but the APK product set shrinks from 14 to 4 because of the density splits drop.

Read design doc →
48 · Highlight
v5.0.3.46

Phase 3d desktop ↔ Android two-way sync suite + Android 0.37.0 seven-feature batch + e2e CI silent-regression fix

Mobile-bridge-sync M2 → v1.2 · gates 1–4 all real Ed25519 · Volcengine voice / APK auto-update / splash redesign / coral theme / i18n three regions / biometric / DID Key

Three themes shipped together. (1) Phase 3d desktop ↔ Android two-way sync (12 commits): M2 lands the desktop sync engine (5 ResourceType walkers — note / conversation / did / community / channel — with tombstones + IPC wire-up + 52 tests, surfacing and fixing 3 prod bugs along the way); M3 wires the Android side via dagger.Lazy to break 4 Hilt cycles + Room-persisted SyncRemoteCursor + sync.* JSON-RPC handlers + transport wiring; M4 adds the desktop SyncMobile settings page + DeviceManager + manual pairing form; v1.1 makes SocialSyncWalker actually return data via handlePullRpc + DID auth verification + SyncCoordinator auto-trigger when the socket connects; v1.2 swaps placeholder signatures for real @noble/ed25519 + Android gate 4 verify, so all 4 gates are now strict-verify. (2) Android 0.37.0 (commit 1348636ad, 7 user-visible features): Volcengine SeedASR voice (16kHz mono PCM + 800ms poll + AsrSettingsScreen + Recording/Transcribing dialogs); APK auto-update issue #21 (GitHub Releases android-v tag arm64-v8a + DownloadManager + REQUEST_INSTALL_PACKAGES + Settings "Check for updates" entry); splash purple gradient + rotating ring + TT logo + splash-race fix; Claude coral theme #D97757 primary + dynamicColor=false to preserve brand colour; i18n issue #16 three regions zh-rCN/rTW/rHK explicit qualifiers + AppCompatDelegate locales; biometric toggle wired to AuthVM; KeyManagementScreen DID + public key hex + trusted devices + reset; drive-by fixes for OpenAIAdapter main-thread 12s freeze + 256 rs_* string stubs. (3) e2e CI silent-regression fix (commit e807d576c): drop e2e-tests workflow JOB-level continue-on-error: true — it had been masking 3/3 OS failures as success, leaving "No team IPC interface found" buried for weeks; same batch adds Playwright browsers + npm cache, dropping single-OS time from ~14m to ~6–8m.

Read design doc →
49 · Highlight
v5.0.3.45

cc ui llm.chat parity + intent opt-in toggle + true streaming + Vue Proxy fix

QuickAsk no longer 60s timeout · project mode no longer stalls on "Understanding…" · chatStream queue+waiter · placeholder-card reactivity fix

Four interlocking landings. (1) cc ui llm.chat route (f41c4b4e2): the desktop web-shell has had llm.chat since 4eaf90137, but cc ui never registered it → QuickAsk hung 60s on "Stream idle timeout". New packages/cli/src/gateways/ws/llm-chat-protocol.js mirrors the desktop frame protocol (`<topic>.chunk` + `<topic>.result`); new llm-creds.js shares the resolver (explicit options → session creds → VOLCENGINE_API_KEY-style env vars), returning ok:false instantly on missing creds. chat-intent-protocol picks up the same helper, fixing a latent bug along the way: previously `session.baseUrl || "http://localhost:11434"` hardcoded ollama whenever a session lacked baseUrl, killing every cloud provider on machines without local ollama. (2) Intent opt-in toggle (f41c4b4e2): Chat / Agent project/file mode header gets an `<a-switch>`, off by default. Pre-v5.0.3.45 every project/file message went through chat.intent.understand-stream first → 0.5–90s of latency that surprised users coming from the direct-send path. Now defaults to direct send; users who want the confirmation card flip the switch (persisted to localStorage cc.web-panel.chat.intentEnabled). submitUserInput first-line short-circuit. The desktop shell shares this SPA bundle so its behaviour now matches cc ui. (3) chatStream truly streams (35f6e60ea): packages/cli/src/lib/chat-core.js chatStream was a fake async generator that buffered every onToken into an array and only yielded after streamX(...) settled — consumers saw zero progress for the full LLM round-trip. Replaced with a token queue + Promise waiter: onToken push wakes the generator, which yields immediately. Chat / Agent / QuickAsk / chat-intent all benefit. (4) Intent placeholder Vue Proxy reactivity fix (a76e451e2): submitUserInput pushed the placeholder into reactive messages[sessionId] (Proxy-wrapped) but kept mutating through the unwrapped local ref → the set trap never fired → card sat pinned at "Understanding… / 0 tokens / Intent: unrecognised" even with 30+ chunks streamed. Fix: re-acquire the Proxy via `card = msgs[msgs.length - 1]` after push. NPM: chainlesschain 0.161.5 → 0.161.6 → 0.161.7 (0.161.6 was published ahead of productVersion to unblock npm-package users on the QuickAsk hang; 0.161.7 carries the chatStream streaming fix + Vue Proxy fix).

Read design doc →
50 · Highlight
v5.0.3.44

LLM OCR + audit-ipc coverage + chat-intent 90s safeguard

Three-way OCR engine · 18 channels × 23 cases first coverage · slow-LLM dribble safeguard

One user-visible feature + three quality follow-ups. (1) Screenshot OCR LLM engine (39b16e29f): Tesseract.js Chinese accuracy is poor; new engine parameter auto/llm/tesseract three-way. auto (default) routes to volcengine doubao vision if configured, else falls back to Tesseract; LLM errors auto-degrade with fallbackFrom / fallbackReason tags. llm forces vision LLM (doubao-1.5-vision-pro, userBudget=medium); tesseract forces local. Provider whitelist Set(["volcengine"]); extending to gemini / openai / anthropic is mechanical once their LLMManager exposes chatWithImage*. V5/V6 shared dialog + web-panel dialog both get an `<a-select>` engine picker + blue/grey/orange tag. (2) chat intent understand 90s wall-clock safeguard (6cbd04c50): sendStream's built-in 60s idle timer rearms on every chunk; a slow LLM that dribbles tokens but never emits `final` leaves the placeholder card spinning forever — AbortController + setTimeout(90s) safeguard. (3) compliance-ipc dead handler cleanup (29006decf): typo'd prefix compliance-classify:* had no callers and even backed onto a different service than the real one; drop both + sync IPC_CHANNELS. (4) audit-ipc.js first unit test coverage (b092673be): zero-coverage gap surfaced by the typo bug — 18 channels + DI refactor + 23 cases. Regression: desktop 1477/1477 + CLI 17,455/17,455.

Read design doc →
51 · Highlight
v5.0.3.43

MTC publisher_signature M-of-N fix + security hardening cascade

HIGH 44→0 · MOD 4→0 · LOW 45→0 · publisher_signature strip-all-sigs symmetrized

Two themes shipped together. (1) MTC `landmark.publisher_signature` fix: producer + verifier must symmetrically strip ALL per-member sigs (not just publisher_signature.sig) before feeding JCS — otherwise tampering with any one member sig in an M-of-N federation breaks publisher_signature, completely defeating the M-of-N threshold. Helper extracted to `@chainlesschain/core-mtc/publisher-signing` subpath, three call sites (batch.js single + federated, landmark-cache.js verifier, desktop governance-multisig.js). `LandmarkCache` defaults `verifyPublisherSignature:true` opt-in, all real-verifier callers enabled. Const BAD_PUBLISHER_SIG → BAD_LANDMARK_SIG (matches spec §11). (2) Eight npm audit sweeps in one week — HIGH 44→0 / MOD 4→0 / LOW 45→0: override `serialize-javascript`/`tar`/`semver`/`undici`/`make-fetch-happen`/`tmp`/`ip-address`/`dompurify`, drop unmaintained `speedtest-net` (native fetch replacement) + `werift` + `hdkey`, split hardhat-stack into standalone `contracts/` workspace, channel-manager DDL hardening, wrtc-compat patches CVE-2024-29415. Bonus: updater renderer progress notifier (notifier-only flow).

Read design doc →
52 · Highlight
v5.0.3.41

chat-panel-v5 three-shell parity + B4 social rolling closure

V5 / V6 / web-shell chat strictly equivalent · neither keys nor passwords cross the wire

productVersion .40 → .41, formally shipping the four 5.0.3.40-rolling entries (cred-persist + auto-archive, mofn-sign v2 + webpanel UI, merkle envelope finality, cross-machine sync Phase A + Web Shell Phase 3c.7) plus two new items: (A) V6 default-shell AIChatPanel reverse-aligned to V5 ChatPanel's 4 core features (streaming response + history switching + context memory references + tool-call panel, Phase E commit b33527d31); (B) web-shell ChatPanel v5 port v1+v1.1 (commit 72b13388a) bringing all V5 router protocols / autoSendMessage signals / virtual list / 5 intents / 6 IPCs through WS topics. From now on V5 / V6 / web-shell chat experiences are strictly equivalent — Phase 1.6 default web-shell users no longer miss any V5 chat capability. Also fixed: web-panel views-mount-smoke hitting 30s default timeout under 63-file fork contention via file-level `vi.setConfig({ testTimeout: 60_000 })`.

Read design doc →
53 · Highlight
v5.0.3.40 (rolling)

P2P social full-stack audit-grade closure (§2.2.10 → §2.2.24)

15 sections · 14+1 commits · neither private keys nor passwords ever traverse the wire

Closes 15 sub-phases at once, taking P2P social from "messages can cross machines" to "fully audited end-to-end loop": cross-machine sync (Phase A — 7 underlying bug fixes) → MTC federation dual-track (B v1) → DID signing + auto peer bridging (B4) → Merkle batch envelope finality (B4-merkle) → cross-machine envelope gossipsub broadcast + on-demand pull (B4-cross) → community-member trust filter (B4-cross-trust) → desktop viewer button + modal (B4-ui) → external archival to filesystem/WebDAV (B4-archive) → M-of-N multi-sig governance (B4-mofn) → cross-federation trust anchors (B4-crossfed) → 13 WS topics for default web-shell (B4-webshell) → 4 composables + MtcAudit.vue UI (B4-webpanel) → sign-as-self v2: renderer sends only IDs (B4-mofn-sign v2, plus fix of a ~1-month-latent IPC bag missing 12 managers) → WebDAV creds via secure-config.enc (safeStorage / AES-256-GCM, plus fix of a ~1-month-latent baseUrl/remoteRoot vs url/remotePath field-name bug) → main-process periodic archival cron (5-min minimum, per-community try/catch, runOnce non-reentrant, lastRun* auto-persisted). Private keys and passwords stay inside main process; the full suite is visible in the default web-shell; audit-grade.

Read design doc →
54 · Highlight
v5.0.3.40

MTC view in-process speedup + CI triple-unblock

4 fixes · bypass asar cold-start · 12224 tests

Headline: after v5.0.3.39 flipped to `asar:true`, `cc` subprocess cold-start jumped from ~2.5s in dev to 6-10s when packaged, and `Mtc.vue`'s parallel onMounted (`loadStatus` + `loadBridgeStatus` + `loadBridgeSla`) reliably blew the 8s/6s ceilings ("状态加载失败 / 加载桥 MTC 状态失败"). Fix: 3 new in-process WS topics (`mtc.audit-status` / `mtc.bridge-status` / `mtc.bridge-sla`) hit `audit-mtc` / `cross-chain-mtc` libs directly — pure file reads, no spawn, zero asar overhead. `Mtc.vue` branches on `useShellMode().isEmbedded`. Bundled with three CI fixes: macOS `realpathSync` flagged `/var → /private/var` as a symlink → POSIX uses `lstat`; rules-validator flagged a test-fixture `TestDbManager.exec(sql)` → exclude `__tests__/`; CLI subprocess Win cold-start exceeded 10/15s execSync timeouts → unified to 60s.

Read design doc →
55 · Highlight
v5.0.3.39

B4 ASAR surgery — Win install dramatically faster

issue #8 · 23 unit + integration tests

Windows install substantially reduced: dev-box (NVMe SSD + Defender OFF) measured 190.9s vs 1201s legacy baseline = 6.3× speedup; HDD + Defender ON default-environment strict parity not measured. Re-enabled asar:true (v5.0.3.4-13 fell back to asar:false because the electron-builder walker dropped 4 transitive deps). New surgery runs in afterPack: extract → inject the 4 walker-dropped packages → repack while preserving the original unpackDir decisions. Win wrapper handles workspace symlinks.

Read design doc →
56 · Highlight
v5.0.3.5

MTC v0.11 — Cross-federation trust anchors + offline audit

Phases 0–4 complete · 476 tests across six layers

Decentralized certificate system on Merkle trees: cross-federation trust anchors + third-party auditor + multi-hop routing + gas-aware batch closure + SLA monitoring dashboard. M-of-N multi-sig with heterogeneous Ed25519/SLH-DSA federations + dual-transport service discovery (filesystem + libp2p).

Read design doc →
57 · Highlight
v5.0.3.4

Web Panel bilingual M3

~25 views internationalized · vue-i18n dictionaries

Migrated all major web-panel views to vue-i18n (SpeechSettings / Analytics / Cron / Security / Audit / MCP / Backup / Tokens / MTC / WebAuthn / Community / Wallet / Inference / Organization / Federation, etc.) — full Chinese/English coverage, no hardcoded strings. V6 Preview top-bar gets a language switcher.

Read design doc →
58 · Highlight
v5.0.3.1

Web Shell as default + multi-window

Electron embeds web-panel · WindowRegistry

Desktop pivots from "native Vue renderer" to "Electron main embeds ws-server + loads web-panel dist" — true cross-target uniformity. Multi-window scaffold (role-based hash routing + per-role geometry persistence); window.open WS topic lets the renderer spawn new windows.

Read design doc →
59 · Highlight
v5.0.2.34

V6 Chat-First Shell hard-flip

13 first-party packs · 7 UI extension points

Desktop now defaults to V6 Chat-First Shell (three-pane layout + 5 enterprise providers + dispatcher with widget registry + Ctrl+Shift+A admin console). .ccprofile + MDM push as 3 enterprise customization paths. Top-10 V5 routes all have V6 widget probes.

Read design doc →
60 · Highlight
v5.0.2.10

CLI V2 governance surfaces · 220+

4-state maturity × 5-state lifecycle

From a2apgov to pmodegov — 136 lib-level V2 governance surfaces (dual-cap + auto-flip + autoStaleIdle + autoFailStuck) + 5,984 V2 tests. Coexists with same-module legacy surfaces via shared nest-blocker.

Read design doc →
📋 RFC under review 2026-05-11 (v0.2)

Android v1.0 Repositioning — L1 Wallet / L2 Capture / L3 REMOTE

Desktop = AI workstation · Mobile = key + capture + remote. Stop chasing desktop skill count — pivot to StrongBox hardware signing + Voice/Camera OCR + REMOTE-invoke desktop skills three-layer architecture. 11-day 7-milestone roadmap · 258+ unit tests · 12 E2E. Read RFC →

Who It's For

Two audiences, one foundation.

FOR INDIVIDUALS

"I want a truly private
AI assistant."

  • · Local encryption · data never goes to cloud
  • · Zero-config · works out of the box
  • · Bilingual UI
  • · Doctors, lawyers, researchers' daily companion
Download desktop →
FOR DEVELOPERS

"I want agent-driven
coding from my terminal."

  • · CLI Agent · Claude Code style
  • · Cowork multi-agent parallel review
  • · MCP tool ecosystem + 9 Skill Packs
  • · 159 commands · 30,000+ tests · 220+ V2 governance surfaces
Editions

Personal, or enterprise?

Personal

Free / Open Source

For individuals & independent developers. Full CLI, desktop, mobile experience.

  • ✓ All 159 CLI commands + 146 skills
  • ✓ U-Key / SIMKey hardware encryption
  • ✓ Local Ollama + 10 LLM providers
  • ✓ Cowork multi-agent collaboration
  • ✓ Windows / macOS / Linux / Android

Enterprise

Custom

For finance, healthcare, legal, government — strict compliance and on-prem requirements.

  • ✓ Private deployment + UI branding
  • ✓ SSO / SCIM / RBAC / audit & compliance
  • ✓ Industry-specific skills (healthcare / legal / research)
  • ✓ U-Key batch issuance + DLP + SIEM
  • ✓ Dedicated technical support
Downloads

Same source, every target · v5.0.3.122

CLI · v0.162.95

Command-line

$ npm i -g chainlesschain

npm / yarn / pnpm / bun · ~2MB

DESKTOP · v5.0.3.122

Desktop App

Electron 39 · Vue 3.4 · 146 skills

MOBILE · Android v5.0.3.122 · GA

Android

L1 DID wallet · L2 mobile capture · L3 REMOTE · 25 skills · 383+ tests

See the mobile edition →
Xiamen Chainlesschain Technology Co., Ltd.

Need an enterprise edition?
Pick up the phone.

We provide full-cycle custom services from POC to production for healthcare, legal, research, and government clients. Free needs assessment · 90-day POC guarantee.

AddressUnit 431-H, Floor 4, Building C, Xiamen International Shipping Center, 93 Xiangyu Rd., Xiamen FTZ