| tuix Ink Phase 1: cell-level diff — keystroke 2× 降幅、menu 开合 53% 降幅
CC 源码启示(参见 claude-code-src/ink/screen.ts:1156-1256 的 diffEach):
Ink 按 absolute (row, col) 的 cell 做 diff,新 frame vs prev frame 只
emit 真正变化的 cell。我们此前是 row-level diff —— 任何字节变化触发
整行 re-emit,加上 footer 高度变化时 row index 失配整表作废,菜单
开合喂给 Mac Terminal.app 的字节量达 1900 B,是用户感知卡顿的根源。
本 commit 只升级 footer/menu 路径的 diff 粒度。body(scroll region
内的 streaming / tool output)保持 pure-append — streaming 的 43 B/
delta 架构不动。
## 架构变化
**新 render/cell.rs**(~350 行):
- Cell { ch, style: CellStyle { fg, bold, reverse } } — 字符 + SGR
- diff_cells(prev: HashMap<row, Vec<Cell>>, next: ...) -> Vec<Patch>
按绝对屏幕行匹配,cell-by-cell 对比
- serialize_patches(patches) -> Vec<u8> 带 SGR 状态机:
- 相邻同行 cell 跳过 cursor move(cursor auto-advance)
- 相邻同 style cell 跳过 SGR transition
- 默认样式序列不 emit 终结 \x1b[0m
- row_to_bytes(cells) 为 legacy (non-DECSTBM) 路径提供序列化
**ansi.rs**:
- 5 个 build_*_row 从 Vec<u8> 改返回 Vec<Cell>
- last_footer_rows: Vec<Vec<Cell>>
- emit_footer_absolute 用 diff_cells + serialize_patches,去掉
了之前 "total_rows 变化就全量 emit" 的短路逻辑
- emit_footer_diff (legacy) 用 row_to_bytes 维持 row-level 行为
## 字节量数据
新增 menu_toggle_byte_cost 测试:
| 场景 | Pre-Ink | Post-Ink | 降幅 |
|---|---|---|---|
| Menu 打开 (5→9 行) | 1899 B | 899 B | 53% |
| Menu 关闭 (9→5 行) | 1556 B | 895 B | 42% |
| Up/Down 导航 | 1885 B | 210 B | 89% |
| Keystroke 稳态 | 56 B | 26 B | 54% |
| Streaming delta avg | 43 B | 41 B | 持平 |
Up/Down 降 89% 是 cell-diff 的招牌效果:只有两行的 reverse-video
cell 变,其他 cells 全部 skip。
~900 B 的 open/close 是近物理下界:rule 在 5-row 和 9-row footer 里
位于不同绝对行号,cell-diff 无法跨行匹配,每次 footer 高度变就要
emit 一整条新 rule = ~627 B UTF-8 × 1-2 条。要继续压只能改视觉(rule
缩短 / 去掉顶 rule),这是 Phase 2 工作。
## 不动的
- pure-append body 架构(streaming/tool output 继续 append)
- DECSTBM 固定 footer
- 所有 lifecycle hooks(shutdown/suspend/resume/reset)
- streaming 的 43 B/delta 已经是 Ink 级的了
## 测试
170/170 lib test 通过(新增 menu_toggle 测试 + 11 个 cell 模块测试)。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| 1 个月前 |
| retained Phase 0: diff_cell_frames slice 版 + 计划落盘
Retained-mode 重写准备工作:在 render/cell.rs 新增 diff_cell_frames
slice 版,接受两个 &[Vec<Cell>] 作为 prev / next 帧,输出和 HashMap
版相同的 1-indexed Patch 流。保留 HashMap 版 diff_cells 不动 —
Phase 1 的 Screen 用 slice 版(连续 2D buffer),现有 AnsiRenderer
继续用 HashMap 版(footer-only frame),两个并存直到 Phase 6 清理。
新增 3 个测试:
- diff_cell_frames_agrees_with_hashmap_version: 两个 API 语义一致
- diff_cell_frames_produces_one_indexed_coords: 0-indexed 输入 → 1-indexed 输出
- diff_cell_frames_empty_frames: 空帧空 patches
完整 plan 在 docs/superpowers/plans/2026-04-19-tuix-retained-mode-rewrite.md。
186/186 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| 1 个月前 |
| docs(plans): 取消 mutating-bash-approval, 反映 upstream 路径轴已落地
与 upstream 2026-04-22 (ff540aa) effect-based 决策冲突:pattern 识别
sed -i / perl -pi / awk -i 的方向已被 upstream 明确以 post-exec snapshot
diff + 文本 nudge 替代。Ship 顺序里下一刀顺位移到 tool-failure-hints
(原则 2,纯加法,不与 upstream 冲突)。原则 4 路径轴列入"已 ship"行,反映
upstream ff540aa path-aware approval 是 cost awareness 的首刀落地。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| 1 个月前 |
| docs(plans): 归档 cadence-reflection + 新增 agent harness 四原则 roadmap
cadence-reflection 已在 v4.20 ship,plan 文件留档对照。harness-principles
作为顶层设计文档,规定后续 agent 层改动(prompt/guard/discipline/tool trait)
必须映射到四原则之一,避免 scope 再次收窄;文档内列出 ship 顺序,下一刀是
mutating-bash-approval(原则 4 子集)。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| 1 个月前 |
| docs(plans): 归档 merge-current-task-into-cadence
| 1 个月前 |
| docs(plan): vision-preprocessor auto-config from /codingplan
Three-task addendum to the original feature: extend model_name_suggests_vision
to recognize OCR substring (so OCR-on-VLM endpoints auto-qualify), add
auto-set logic to coding_plan::setup::step_models_and_register with explicit
precedence rules (preserve user non-AtomGit values; replace stale AtomGit-*
references; clear when no VL in list), surface the outcome in SetupReport
render output.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| 26 天前 |
| docs(spec,plan): generic VL wrapper text — drop hardcoded model brand
User-facing wrapper for the spliced VL description goes from
"[image content (recognized by Qwen3-VL)]" to the brand-agnostic
"[image content (recognized by VL model)]" so users who configure a
different VL model (Pixtral, GPT-4o-mini, MiniCPM-V) do not see an
inaccurate label. Config-key examples and test-fixture model strings
retained — those are illustrative, not product code.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| 26 天前 |
| docs(plan): TUI unified in-app scroll implementation plan
31 tasks across 9 phases, TDD-driven. Implements the spec at
docs/superpowers/specs/2026-05-25-tuix-unified-in-app-scroll-design.md.
Phases:
- Phase 0: i18n message variants
- Phase 1: extract selection module (BodyLineView trait, OSC 52 emitter)
- Phase 2: body buffer cap + MessageMark on both renderers
- Phase 3: retained view_mode state machine + scroll
- Phase 4: retained mouse capture (?1002h ?1006h + conhost parity)
- Phase 5: retained selection wiring
- Phase 6: scrollbar render + /scrollbar + ui-state.toml
- Phase 7: Alt+arrow / Ctrl+arrow message-jump keys
- Phase 8: /keys docs (zh-cn + en)
- Phase 9: full test suite + manual QA checklist
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| 10 天前 |
| docs(webui): Phase 1.5 TUI⇄webui 实时同步(方案 A 进程内活动会话总线)
- LiveSession 总线放 core:单一 Conversation + broadcast 扇出 + mpsc 输入 + 单写者守卫
- server /live SSE(快照+实时) + /live/message;TUI 同步模式输入走总线、渲染订阅 broadcast
- 默认 webui 独立、开关同步;turn 进行中另端输入禁用;晚加入 replay;审批先到先得
- 计划新增 Milestone 6 / Task 18-23
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| 5 天前 |