도그푸딩 중 발견된 두 건 (Gitea #94, #95) 동시 수정. #94 — `InputBuffer` 가 append-only 라 Ask/Search/Filter overlay 에서 타이핑한 텍스트의 중간을 편집할 수 없었음. cursor 모델을 byte-position 기반으로 재구성 (cursor_col 은 prefix slice 의 unicode-width 합으로 derive). 신규 메서드: `move_left / move_right / move_home / move_end / delete_after`. 기존 `push_char` / `pop_char` 는 cursor 위치에서 동작 (cursor 가 끝일 때 backwards-compatible). Ask / Search / Library filter overlay 세 곳에 `← / → / Home / End / Delete` key handler 추가. Search 는 cursor 이동만으로는 input_dirty_at 을 reset 하지 않음 (커서 이동 ≠ 쿼리 변경 → debounce 타이머 유지). #95 — Ask 트랜스크립트의 `Paragraph::scroll((s.scroll, 0))` 가 위에서 부터 카운트라, 새 답변 도착 시 `s.scroll = 0` 으로 리셋하면 viewport 가 위쪽 고정 → 트랜스크립트가 길어지면 새 응답이 시야 밖으로 밀림. `AskState` 에 `follow_tail: bool` (default true) 추가. `render_answer` 가 follow_tail 동안 매 프레임 `Paragraph::line_count(width)` 로 wrapped row 수 계산해 스크롤을 `line_count - inner_height` 에 pin. `j` / `k` 가 follow_tail 끄고 `Shift-G` 가 다시 켬. 새 submission, `Ctrl-L` 도 follow-tail 재활성화. `kebab-tui` 의 ratatui dep 에 `unstable-rendered-line-info` feature 활성화 — `Paragraph::line_count` 가 ratatui 0.28 에서 unstable. 0.28 에 pin 되어있는 동안 안정. 향후 ratatui bump 시 본 feature 의 stable 여부 재확인 필요. cheatsheet popup Search/Ask section 에 화살표 + Home/End + Delete row 추가, Ask 에 `Shift-G` row 추가. README + HANDOFF + HOTFIXES + INDEX 동기. Tests: 12 신규 InputBuffer unit + 6 신규 Ask integration. 기존 699 워크 스페이스 테스트 모두 통과 (cursor 가 끝일 때 backwards-compat). Spec: `tasks/p9/p9-fb-22-tui-cursor-and-autoscroll.md` (status `completed`). Live deviation 기록: `tasks/HOTFIXES.md` `2026-05-04 — p9-fb-22`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
38 lines
1.6 KiB
TOML
38 lines
1.6 KiB
TOML
[package]
|
|
name = "kebab-tui"
|
|
version = { workspace = true }
|
|
edition = { workspace = true }
|
|
rust-version = { workspace = true }
|
|
license = { workspace = true }
|
|
repository = { workspace = true }
|
|
description = "Ratatui shell + Library pane for kebab — UI consumes kebab-app facade only (P9-1)"
|
|
|
|
[dependencies]
|
|
kebab-core = { path = "../kebab-core" }
|
|
kebab-config = { path = "../kebab-config" }
|
|
# UI facade rule (design §8): UI crates may only touch `kebab-app`. The
|
|
# search / store / embed / llm / rag layers stay invisible behind it.
|
|
kebab-app = { path = "../kebab-app" }
|
|
# p9-fb-22: `unstable-rendered-line-info` exposes
|
|
# `Paragraph::line_count(width)` for the Ask follow-tail scroll
|
|
# math. Pinned ratatui 0.28.x means the unstable surface is fixed
|
|
# until we deliberately bump the dep.
|
|
ratatui = { version = "0.28", features = ["unstable-rendered-line-info"] }
|
|
crossterm = "0.28"
|
|
anyhow = { workspace = true }
|
|
tracing = { workspace = true }
|
|
thiserror = { workspace = true }
|
|
time = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
# Korean / wide-char column width — Ratatui's `Span` truncates by chars,
|
|
# not display width, so a list cell with `한` (width 2) followed by `a`
|
|
# (width 1) overflows by one column without explicit width accounting.
|
|
unicode-width = "0.2"
|
|
# p9-fb-11: parse markdown answer bodies into styled `Span`/`Line`s.
|
|
# Same parser the ingest pipeline uses (kebab-parse-md) — keeps the
|
|
# tokenizer behavior aligned with what the corpus is normalized as.
|
|
pulldown-cmark = { version = "0.13", default-features = false }
|
|
|
|
[dev-dependencies]
|
|
tempfile = { workspace = true }
|