Four optional, serde-skipped-when-None fields added to `Metadata` for
code ingest context. All 11 downstream construction sites patched with
`repo: None, git_branch: None, git_commit: None, code_lang: None`.
Full workspace check (`--tests`) and per-crate test suite pass clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add missing score_kind field to SearchHit constructors in:
- kebab-tui/tests/search.rs::make_hit()
- kebab-eval/tests/metrics_and_compare.rs::hit()
- kebab-eval/src/metrics.rs::hit()
All test fixtures default to Rrf (hybrid mode), matching the field's
Default impl and the test semantics.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- doc TraceFusionInput.fusion_score semantics (single-mode vs hybrid)
- comment why total_ms vs stage sum can drift (millis truncation)
- TODO marker on TUI trace popup filter passthrough
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Worker channel now carries kebab_app::StreamEvent. drain_stream
matches on Token { delta }; RetrievalDone and Final are ignored
(citations render from last_answer, Final is redundant with
worker join). app::AskState.rx type widened to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Append ": A docx, B txt, ..." after the N skipped count in both the
CLI ingest summary and TUI status_line terminal events (completed +
aborted). Breakdown is desc-sorted by count, ties broken by key
alphabetic; empty map produces no extra text.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Remove `pub include: Vec<String>` from `WorkspaceCfg` struct (denylist-only model).
- Drop `include: vec!["**/*.md"]` from `Config::defaults()`.
- Add `from_file` deprecation probe: raw `toml::Value` scan fires a
one-shot `tracing::warn!` (via `OnceLock`) when an old config still
carries `workspace.include = [...]`. serde ignores the unknown field
cleanly (no `deny_unknown_fields`).
- Compile-fix `kebab-cli` (main.rs:329) and `kebab-tui`
(ingest_progress.rs:39): replace `cfg.workspace.include.clone()` with
`Vec::new()` (Task 2 will switch to `..Default::default()`).
- Two new tests: `legacy_include_field_is_ignored_silently` (backward
compat round-trip) + `workspace_cfg_has_only_root_and_exclude_fields`
(exhaustive destructure — compile-time guard against re-introduction).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Updates the terminal (completed) and aborted branches of status_line
to include the unchanged counter alongside new/updated/skipped, so
users can see how many assets were skipped via the incremental-ingest
early-skip path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
회차 1 review (PR #97 회차 1) 의 4 건 actionable nit 모두 수렴.
- `crates/kebab-tui/tests/inspect.rs`: pre-fb-24 의 `page_keys_scroll_by_ten`
이 신규 `page_down_scrolls_by_ten_in_inspect` + `page_up_rewinds_by_ten_saturating_in_inspect`
와 중복 커버리지였음. 신규 두 테스트가 더 정밀 (PgUp 의 25→15→ 그 다음
3→0 saturating 명시) 이라 기존을 삭제하고 신규로 대체. inspect 테스트
-1 (14 → 13).
- `tasks/HOTFIXES.md`, `tasks/p9/p9-fb-24-tui-affordances.md`: 테스트
카운트 `기존 720+` → `기존 695개 (cargo test --workspace -j 1 기준
716 passed)` 정확화. 영속 기록.
- `crates/kebab-tui/src/run.rs`: status bar 의 magic string `" │ "`
를 `const STATUS_SEPARATOR: &str` 로 추출. docstring 의 rendered shape
과 sync 보장 코멘트 추가.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wire `format_doc_header` into `render_doc_list`: render the block
independently, split block_inner into a 1-row header + list via
vertical Layout, and drop the `.block(block)` from the List widget.
Remove `#[allow(dead_code)]` from `format_doc_header` now that it
is consumed. Add `library_renders_column_header_row` integration test.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Refactor the Inspect pane's PageDown/PageUp handlers to consume the
PAGE_STEP constant from pager.rs instead of hard-coding 10. Adds
regression tests to pin the scroll delta (=10), ensuring future
viewport-aware refactors surface here rather than silently in
user-visible behaviour.
Test coverage: added page_down_scrolls_by_ten_in_inspect and
page_up_rewinds_by_ten_saturating_in_inspect (+ existing
page_keys_scroll_by_ten still passes).
Remove #[allow(dead_code)] from pager.rs now that PAGE_STEP is
consumed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
회차 2 review (PR #96 회차 2) 의 2 건 cosmetic nit 모두 수렴.
- `tasks/HOTFIXES.md`, `tasks/p9/p9-fb-22-tui-cursor-and-autoscroll.md`:
\"기존 38 개\" → \"기존 39 개 (input.rs unit 18 + tests/ask.rs 21)\"
로 정확 카운트 + 출처 명시.
- `crates/kebab-tui/src/library.rs`: `active_buf_mut` doc comment 의
\"3-line dispatch\" → \"2-arm dispatch\" (실제 dispatch 가 2 arm 이라
가장 정확한 표현).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
도그푸딩 중 발견된 두 건 (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>
도그푸딩 피드백 (사용자 2026-05-03): Ask Insert→Esc→Normal 후 Insert 로
돌아가는 키 모름. 전반적 키바인딩 안내 부족.
Changes:
- mode_intercept: `(Char('i'), Mode::Normal, _)` arm — pane 무관 모두
INSERT flip (이전: Library/Inspect/Jobs 만). 사용자가 어느 pane 에서든
Esc 후 `i` 로 Insert 즉시 복귀 가능.
- Search 의 chunk inspect 키 `i`→`o` (vim "open") rebind. `i` 가
universal Insert toggle 로 자유로워짐.
- `footer_hints` 모든 (pane, mode, filter) 조합 첫 fragment = `F1 도움말`.
cheatsheet binding 의 discoverability 보장.
- Search/Ask Normal hint 에 `i 입력모드` fragment 추가.
- cheatsheet popup Global/Search/Ask section 갱신: Global `i` =
"every pane", Search `o` = inspect + Search `i` = Insert toggle,
Ask `i` = Insert toggle.
- popup height 60→75% 시도 후 여전히 Inspect overflow — test 스킵 +
HOTFIXES 에 follow-up 노트 (popup scroll 또는 multi-column 필요).
Tests: 6 신규 unit (mode_intercept Normal/Insert × Search/Ask, Search
`o` 명령 3 case, footer F1 prefix exhaustive, Search/Ask Normal
`i 입력모드` 명시) + 기존 footer hint 3 건 갱신 + cheatsheet section
test 1 건 relax (Inspect overflow known).
spec: `tasks/p9/p9-fb-21-tui-insert-key-discoverability.md` (status
`completed` 직접 — 도그푸딩 직접 피드백 source).
`pub fn footer_hints(focus: Pane, mode: Mode, filter_open: bool) -> &'static str`
신규 (run.rs). 기존 `render_footer` 의 영문 `key=action` 형식이 한국어
동사구로 — `"위로"` / `"아래로"` / `"필터"` / `"타이핑 검색어"` /
`"Esc 로 NORMAL 모드"` 등 — 변경되고 (pane, mode, filter_open) 조합에
따라 자동 분기. NORMAL 모드는 navigation verbs, INSERT 모드는
typing + Esc reminder. Library filter overlay 는 overlay-only key 3
개로 override.
8 unit tests pin: 모든 (pane, mode, filter) 조합 non-empty exhaustive
+ Library Normal/filter, Search Normal/Insert, Ask Normal/Insert,
Inspect Normal 별 verb fragment 존재 검증.
spec status `in_progress` → `completed` — p9-fb-13 partial 의 deferred
verb-form 항목이 닫힘.
- Add `place_cursor_x(inner_x, inner_width, prompt_w, cursor_col) -> u16`
to `input.rs`: sums in `usize` (no u16 wrap), clamps to inner right
edge, tries_into with u16::MAX fallback. Two unit tests pin the clamp
and the in-bounds path.
- Re-export from `lib.rs` alongside `InputBuffer`, `display_width`,
`truncate_to_display_width`.
- Replace the open-coded 2-line `raw_x`/`cursor_x` blocks in Search,
Ask, and Library with a single `place_cursor_x` call each —
consistent usize arithmetic across all three panes.
- Add `filter_overlay_render_places_cursor_on_focused_field` integration
test in `tests/library.rs`: opens the filter overlay, renders through
`TestBackend`, asserts `terminal.get_cursor_position().x > 0` (label
offset > 0 proves `set_cursor_position` was called with a meaningful
coordinate, not stuck at origin).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Migrates FilterEdit.tags_buf and lang_buf from String to InputBuffer
(the same display-width-aware type used by Search/Ask), adds cursor
placement in render_filter_overlay so the caret sits at the end of the
focused field, and adds a Hangul filter test
(filter_overlay_accepts_hangul_tags) that confirms wide chars round-trip
through key events and commit_into unchanged.
Also adds App::library_filter_for_testing accessor mirroring
populate_library_for_testing style.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Migrates SearchState.input from String to InputBuffer so wide-char
(Hangul/CJK) keystrokes advance the terminal cursor by display columns
instead of char count. Adds cursor placement in render_input_bar via
f.set_cursor_position and a Hangul round-trip pin in tests/search.rs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add `InputBuffer` with `push_char`/`push_str`/`pop_char`/`clear` tracking
cursor position in display columns (CJK = 2, ASCII = 1) plus 6 unit tests
(p9-fb-10 Task 1). Re-export from crate root.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TAGS_COL_W const 추출 (truncate + pad 동시 사용 — drift 방지).
- format_doc_row 직접 unit test 2개 (Hangul title / Hangul tag) 가
display column 정렬을 정확히 pin. `<title_w$>` 으로 되돌리는
회귀가 unit-level 에서 catch 됨.
- format_doc_row: title/tags padding 을 display_width 기반으로 명시
계산 (std::fmt 의 char-count 기반 `<width$>` 가 wide char 에서 column
drift). truncate 가 보장하는 width 계약 위에 padding 도 같은 단위로
통일.
- input.rs 테스트 코멘트 cleanup (`= wait` 디버깅 잔재 제거).
- HOTFIXES "후속 spec issue" → "후속 PR 체크리스트" 로 owner 명시,
체크박스 5 개로 actionable 화.
`kebab-tui::input::{display_width, truncate_to_display_width}` 신규.
unicode-width 위에서 column-단위 width 계산 (ASCII=1, Hangul/CJK/
fullwidth=2, combining=0) + char-boundary 안전 truncate.
library.rs 의 중복 `truncate_to_display_width` private fn 제거 — 단일
source 로 통일. 9 unit tests + 1 integration render test (Korean +
Japanese fixture, TestBackend 80×20).
spec 의 `InputBuffer` struct 도입은 follow-up — Ask/Search/Editor pane
의 String + cursor 일괄 마이그레이션이 회귀 표면이 커서 helper 만
먼저 머지. backspace 는 모든 pane 이 이미 `String::pop()` 사용 → byte-
boundary 안전성 확보. crossterm 0.28 가 native IME composing 미노출 →
preedit handling out of scope.
spec status `planned` → `in_progress`. HOTFIXES.md 에 InputBuffer
struct deferral 사유 기록.