diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..545a628
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,18 @@
+# Rtty 项目指引(Codex 会话自动加载)
+
+Rtty 是一个仿 dinotty 的分布式虚拟终端系统,**只保留终端同步能力**:Rust 服务端
+(Axum + portable-pty + alacritty_terminal 真相源)通过 WebSocket 同步到
+Flutter 桌面端(原始 ANSI 渲染)与移动端(语义快照)。
+
+**对接前必读**:
+- [KNOWLEDGE_GRAPH.md](./KNOWLEDGE_GRAPH.md) —— 知识图谱:架构、协议、数据流、不变量、踩坑记录
+- [PROJECT_SUMMARY.md](./PROJECT_SUMMARY.md) —— 项目总览与目录导航
+
+**关键约束**:
+- 服务端 alacritty 引擎是唯一真相源;Raw/快照/重绘帧都在引擎锁内广播(严格有序)
+- 协议见 KNOWLEDGE_GRAPH.md §5;移动端颜色分段 `segments` 是扩展字段
+- 会话空闲 60s 回收;`RTTY_TOKEN` 可选鉴权;桌面端输入走二进制帧
+- 本机 flutter/git 命令需要提权(沙盒外)执行;`PUB_CACHE=C:\Users\NianJiu\AppData\Local\Pub\Cache`
+
+**⚠️ 最重要的一条**:服务端不能在文件写入受限的环境(沙盒)里运行,否则子进程
+(如 claude)无法写入用户状态文件,表现为 TUI 应用确认后卡死/退出。
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..1fbb45c
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,20 @@
+# Rtty 项目指引(Claude Code 会话自动加载)
+
+Rtty 是一个仿 dinotty 的分布式虚拟终端系统,**只保留终端同步能力**:Rust 服务端
+(Axum + portable-pty + alacritty_terminal 真相源)通过 WebSocket 同步到
+Flutter 桌面端(原始 ANSI 渲染)与移动端(语义快照)。
+
+**对接前必读**:
+- [KNOWLEDGE_GRAPH.md](./KNOWLEDGE_GRAPH.md) —— 知识图谱:架构、协议、数据流、不变量、踩坑记录
+- [PROJECT_SUMMARY.md](./PROJECT_SUMMARY.md) —— 项目总览与目录导航
+
+**关键约束**:
+- 服务端 alacritty 引擎是唯一真相源;Raw/快照/重绘帧都在引擎锁内广播(严格有序)
+- 协议见 KNOWLEDGE_GRAPH.md §5;移动端颜色分段 `segments` 是扩展字段
+- 会话空闲 60s 回收;`RTTY_TOKEN` 可选鉴权;桌面端输入走二进制帧
+
+**运行**:`cargo run`(监听 ws://0.0.0.0:8080);桌面端 `cd desktop && flutter run -d windows`;
+移动端 `cd mobile && flutter build apk --debug`。
+
+**⚠️ 最重要的一条**:服务端不能在文件写入受限的环境(沙盒)里运行,否则子进程
+(如 claude)无法写入用户状态文件,表现为 TUI 应用确认后卡死/退出。
diff --git a/KNOWLEDGE_GRAPH.md b/KNOWLEDGE_GRAPH.md
new file mode 100644
index 0000000..3016009
--- /dev/null
+++ b/KNOWLEDGE_GRAPH.md
@@ -0,0 +1,218 @@
+# Rtty 知识图谱(Knowledge Graph)
+
+> 面向新会话的快速对接文档。本文件记录项目的**实体、关系、流程、协议与约束**;
+> 项目总览与目录导航见 [PROJECT_SUMMARY.md](./PROJECT_SUMMARY.md)。
+> 新会话请先读本文件 + PROJECT_SUMMARY.md,即可直接对接代码库。
+
+---
+
+## 1. 项目身份
+
+| 项 | 值 |
+|---|---|
+| 名称 | Rtty(rtty-server) |
+| 定位 | 仿 [dinotty](https://github.com/xichan96/dinotty) 的分布式虚拟终端系统,**只保留「终端同步」核心能力** |
+| 技术栈 | 后端 Rust(Axum + portable-pty + alacritty_terminal);前端 Flutter(桌面 Windows + 移动 Android) |
+| 仓库 | `https://gitea.ngmao.com/CNWei/Rtty.git`,默认分支 `developer` |
+| 会话 ID | 形如 `session-0`;也接受客户端自定义 ID(按 ID 原子绑定) |
+
+## 2. 架构总览
+
+```mermaid
+flowchart LR
+ subgraph Server["rtty-server (Rust)"]
+ PTY["portable-pty
Shell 子进程"]
+ ENGINE["alacritty_terminal Term
真相源:网格/历史/ANSI 解析"]
+ WS["Axum WebSocket
会话表 + 广播"]
+ PTY -->|原始字节流| ENGINE -->|快照/重绘| WS
+ end
+ subgraph Desktop["desktop (Flutter Windows)"]
+ DB["RttyPtyBackend
WebSocket 桥接"]
+ DA["flutter_alacritty 引擎
渲染原始 ANSI"]
+ end
+ subgraph Mobile["mobile (Flutter Android)"]
+ MC["RttyMobileClient
语义快照消费"]
+ MU["快照列表渲染
颜色/光标/Keybar"]
+ end
+ WS -->|"二进制原始 ANSI
client=desktop"| DB --> DA
+ WS -->|"JSON 语义快照
client=mobile"| MC --> MU
+```
+
+## 3. 核心实体与关系
+
+### 3.1 服务端(`src/`)
+
+| 实体 | 文件 | 职责 |
+|---|---|---|
+| `AppState` | `main.rs` | 全局状态:`sessions: DashMap>` + 配置 |
+| `ServerConfig` | `config.rs` | 环境变量配置:`RTTY_HOST/PORT/TOKEN/SHELL/COLS/ROWS/MAX_SCROLLBACK/MAX_CLIENTS/IDLE_TIMEOUT` |
+| `PtySession` | `terminal/pty.rs` | portable-pty 封装:reader 独占交出、writer 多客户端共享(`Arc>>`)、resize/kill/try_wait |
+| `TerminalEngine` | `terminal/engine.rs` | alacritty `Term` 真相源;`feed()` 逐字节喂解析器;`snapshot()` 生成移动端快照;`redraw_ansi()` 生成全屏 ANSI 重绘;`SessionListener` 把 `Event::PtyWrite`(终端应答)写回 PTY |
+| `Session` | `ws/handler.rs` | 一个会话 = PTY + 引擎 + broadcast 输出通道 + 控制权 + 客户端计数(`clients`/`mobile_clients`) |
+| `ClientKind` | `ws/handler.rs` | 按 `?client=` 参数区分:`desktop`(原始 ANSI 二进制) / `mobile`(JSON 快照),默认 desktop |
+
+### 3.2 桌面端(`desktop/lib/`)
+
+| 实体 | 文件 | 职责 |
+|---|---|---|
+| `RttyPtyBackend` | `src/rtty_pty_backend.dart` | 实现 flutter_alacritty 的 `PtyBackend`:二进制输入、指数退避自动重连、30s 心跳、token、`onReady(id, cols, rows, resumed)` |
+| `TerminalScreen` | `src/terminal_screen.dart` | TerminalEngine + TerminalView 双向接线、resize 防抖(80ms) |
+| `ConnectionBar` | `src/connection_bar.dart` | HOST/PORT/TOKEN/SESSION 输入 + 状态灯 + `SID · RESUMED/NEW` 徽章 |
+| `RttyTerminalConfig` | `src/terminal_config.dart` | 配色/字体映射到 `TerminalConfig` |
+
+### 3.3 移动端(`mobile/lib/`)
+
+| 实体 | 文件 | 职责 |
+|---|---|---|
+| `RttyMobileClient` | `src/rtty_mobile_client.dart` | `?client=mobile` 连接、快照/分段解析、自动重连、心跳、`sendInput/sendResize/claimControl` |
+| `TerminalPage` | `main.dart` | 连接面板 + 快照列表渲染(颜色/光标块/光标可见滚动)+ 输入框 + Keybar(ESC/TAB/CTRL+C/CTRL+L/方向键/ENTER) |
+
+## 4. 数据流
+
+### 4.1 输出路径(PTY → 客户端)
+
+```
+Shell 输出
+ → PtySession.reader(spawn_blocking 独占)
+ → TerminalEngine.feed()(引擎锁内)
+ → 引擎锁内 broadcast:
+ Raw(chunk) → desktop 客户端收二进制
+ Snapshot(快照) → 仅当 mobile_clients>0 时生成 → mobile 客户端收 JSON
+ → desktop 订阅时/每次 resize:redraw_ansi() 注入 broadcast(全屏重绘)
+```
+
+**顺序不变量**:Raw / Snapshot / 重绘帧全部在**引擎锁内**发出,保证与实时输出严格有序(桌面重连恢复依赖此不变量)。
+
+### 4.2 输入路径(客户端 → PTY)
+
+```
+desktop: 引擎输出字节 → backend.write() → WebSocket 二进制帧 → 服务端 Message::Binary → pty.write()
+mobile: 输入框/Keybar → sendInput() → JSON {type:"input",data} → 服务端 → pty.write()
+```
+
+### 4.3 会话生命周期
+
+```
+连接(?session=X)
+ → 鉴权(RTTY_TOKEN 时校验 ?token=)
+ → get_or_create_session:按 ID 原子「查-建-插」;已存在 → resumed=true,否则新建 resumed=false
+ → Ready{id,cols,rows,resumed} →(mobile 发初始快照)→ 订阅广播 →(desktop 注入全屏重绘)
+ → 持续双向收发
+断开/退出
+ → clients-- ;为 0 时启动 idle_timeout(默认 60s)清理
+ → 兜底:退出监控(100ms 轮询 try_wait,上限 5 分钟)+ 读 EOF(Unix)→ cleanup_session(幂等)
+```
+
+## 5. WebSocket 协议
+
+端点:`ws://host:port/ws?client=desktop|mobile&session=&token=`
+
+### 5.1 客户端 → 服务端(JSON 文本帧)
+
+```jsonc
+{"type":"input","data":"ls\r"} // 输入,写入 PTY
+{"type":"resize","cols":120,"rows":32}
+{"type":"claim_control"} // 声明控制权(无控制者时授予)
+{"type":"ping"} // 心跳 → 服务端回 Pong
+```
+
+桌面端也可用**二进制帧**直接发原始输入字节(无损)。
+
+### 5.2 服务端 → 客户端
+
+| type | 说明 |
+|---|---|
+| `ready` | `{id, cols, rows, resumed}`;resumed=true 表示恢复既有会话 |
+| `mobile_snapshot` | `{data: MobileSnapshot}`,仅发给 mobile |
+| `control_response` | `{granted, holder}` |
+| `pong` | 心跳应答 |
+| `error` | `{message}`;鉴权失败等(客户端据此停止自动重连) |
+| `session_closed` | 会话结束(客户端停止自动重连) |
+
+### 5.3 MobileSnapshot 结构
+
+```jsonc
+{
+ "cursor_x": 0, "cursor_y": 0,
+ "cols": 120, "rows": 32,
+ "display_offset": 0, "scrollback_lines": 0,
+ "lines": ["..."], // 纯文本行(去尾空白)
+ "segments": [[{ // 着色分段,与 lines 一一对应
+ "text": "...", "fg": null, "bg": null,
+ "bold": false, "italic": false, "underline": false
+ }]]
+}
+```
+
+颜色编码:`null` = 默认色;`"n:k"` = 命名色 0-15;`"r,g,b"` = 具体 RGB(服务端已把 256 色索引按标准色表转成 RGB)。
+
+## 6. 关键设计决策与不变量
+
+1. **服务端 alacritty 引擎是唯一真相源**:断线重连恢复、移动端快照、桌面端重绘全部源于引擎网格。
+2. **桌面端重连恢复**:订阅时注入 `redraw_ansi()`(`ESC[2J ESC[H` + 逐行 SGR + 光标归位);重连后画面完整,无需客户端重拉。
+3. **惰性快照**:仅当存在 mobile 订阅者(`mobile_clients>0`)才生成快照,纯桌面场景零额外开销。
+4. **二进制输入**:桌面端输入走二进制帧,避免 UTF-8 有损转换。
+5. **控制权强制**:有控制者时非控制者输入被拒;`claim_control` 仅无控制者时授予。
+6. **会话 ID 绑定**:请求的 ID 不存在时按该 ID 新建(原子 entry),存在则复用(resumed=true),杜绝并发重复创建。
+7. **最小鉴权**:`RTTY_TOKEN` 全局令牌(可选);未设置时仅适合内网。
+8. **快照为文本+颜色语义**,不是像素级画面:适合查看与轻量交互,不适合全屏 TUI 深度操作(vim/claude 建议用桌面端)。
+
+## 7. 构建 / 运行 / 测试
+
+```bash
+# 服务端(仓库根)
+cargo run # 监听 ws://0.0.0.0:8080
+$env:RTTY_TOKEN="xxx" # 可选:启用鉴权
+
+# 桌面端
+cd desktop && flutter run -d windows
+flutter build windows --release
+
+# 移动端
+cd mobile && flutter build apk --debug
+adb install -r build/app/outputs/flutter-apk/app-debug.apk
+
+# 测试
+cargo test # 服务端单测
+flutter test # 桌面端(服务端离线时集成测试自动跳过)
+flutter test # 移动端 widget 测试
+```
+
+## 8. 环境与操作要点(重要,踩坑记录)
+
+1. **⚠️ 服务端必须在无文件写入限制的环境运行**:若在沙盒/受限环境启动服务端,其子进程(claude 等 TUI 程序)将无法写用户状态文件(如 `~/.claude.json`),表现为:claude 信任确认页勾选后卡死/退出、后续画面消失。**修复:在沙盒外启动服务端**(本机当前正确运行方式:提权执行后启动 `target/debug/rtty-server.exe`)。
+2. **本机 Flutter 环境**:Flutter 3.44.4(`D:\flutter`),`PUB_CACHE=C:\Users\NianJiu\AppData\Local\Pub\Cache`;flutter/git 命令需要提权(沙盒外)执行,因为要写 `D:\flutter\bin\cache` 与 `.git`。
+3. **adb**:手机 `3060945816001X7`;`adb install -r` 可能触发手机安装确认弹窗,重试一次即可。
+4. **手机连接地址**:用 PC 局域网 IP(如 `192.168.31.249:8080`),不要用 127.0.0.1。
+5. **Android 明文 WebSocket**:Manifest 已开 `usesCleartextTraffic` + `INTERNET` 权限。
+6. **会话空闲清理**:默认 60s 无客户端即回收会话(PTY 被杀);测试/抓快照要保证有客户端在线。
+
+## 9. 当前状态与路线图
+
+### 已实现
+- 服务端 VTE 真相源(alacritty_terminal)、会话持久化 + `resumed` 语义、多端解耦广播
+- 桌面端全屏重绘恢复 + 自动重连 + 二进制输入 + token + 心跳
+- 移动端最小验证 App:快照渲染(颜色/光标)、自动重连、Keybar(含 ENTER)、token
+- 最小鉴权(`RTTY_TOKEN`)、Ping/Pong、并发会话创建竞态修复
+- **claude 端到端可用**(claude 在服务端 PTY 运行,手机可看可发消息;前提:服务端非沙盒)
+
+### 已知限制
+- 移动端是"语义快照视图":文本+颜色,无完整终端渲染器;全屏 TUI(vim/claude 深度操作)体验有限
+- 移动端无文本换行(Word Wrap)、无 Keybar 自定义、无粘贴支持
+- 鉴权仅全局令牌,无细粒度权限/会话绑定
+
+### 规划
+- 移动端 TUI 透传模式(全屏快照渲染 + 虚拟键盘)
+- 智能换行 / 卡片化命令交互 / Keybar 自定义
+- 分布式横向扩展、服务端细粒度鉴权
+
+## 10. 常见问题速查
+
+| 现象 | 原因/解法 |
+|---|---|
+| 手机连不上 | 用 LAN IP;确认服务端在跑(`Test-NetConnection ip -Port 8080`) |
+| 手机显示空白 | 会话被空闲回收(60s)→ 重新连接;或确认 `?client=mobile` 已带上 |
+| claude 勾选确认后画面消失 | **服务端运行在受限环境** → 改为沙盒外启动 |
+| 桌面端重连后画面空白 | 检查服务端为最新构建(含 `redraw_ansi`);旧二进制无重绘功能 |
+| `flutter` 命令卡住 | 本机 flutter 需提权运行;设置 `PUB_CACHE` 指向 NianJiu 的 Pub 缓存 |
+| 输入乱码/被吞 | 桌面端应走二进制帧;`\r` 进 JSON 必须转义(用 `ConvertTo-Json` 而非手拼) |