Commit Graph

9 Commits

Author SHA1 Message Date
b6e0ab352f feat(kebab-tui): P9-4 Inspect pane — doc/chunk detail with collapsible sections
Library Enter / Search 'i' 가 Inspect 진입. Doc 또는 Chunk 단일 view 로
metadata / provenance / blocks (doc) 또는 spans / text / embeddings (chunk)
6 section 을 collapsible 로 표시. Esc/q 로 originating pane 으로 복귀.

핵심:
- InspectTarget enum (`Doc(DocumentId) | Chunk(ChunkId)`).
- InspectState 본체 (`app.rs`) — target / doc / chunk / collapsed
  HashSet / scroll / return_to / needs_fetch / loading.
- `src/inspect.rs`:
  - `render_inspect` — target 종류별 render_doc / render_chunk 분기,
    section header 가 collapse marker (▾/▸) 표시. metadata.user JSON
    pretty-printed.
  - `handle_key_inspect`: j/k / Down/Up scroll. PageDown/PageUp 10 row.
    c = toggle all sections (v1 simplification). Esc/q = SwitchPane(return_to).
  - `enter_inspect(state, target, return_to)` helper — Library 와 Search
    공통 entry point.
  - run-loop hook `refresh_inspect` — needs_fetch 면 lazy
    inspect_doc_with_config / inspect_chunk_with_config.
- run.rs: Pane::Inspect arm 이 handle_key_inspect + render_inspect.
  Idle tick 마다 refresh_inspect. SwitchPane(Inspect) lazy init.
- Library: Enter 가 enter_inspect(Doc(selected)) 호출 후 SwitchPane.
- Search: 'i' (plain modifier) 가 enter_inspect(Chunk(selected_hit))
  호출 후 SwitchPane. typing 'i' (\"instance\") 와 충돌 가드.

테스트 12개 (`tests/inspect.rs`, TestBackend) — Esc 가 return_to 사용
/ q 도 동작 / j/k scroll bounds / PgUp PgDn ±10 / c 일괄 toggle / no
target hint / loading / doc view header+metadata+provenance+blocks /
collapse hides body / chunk view text+block_ids / no slot →
SwitchPane(Library) / enter_inspect helper sets fields.

Spec deviation (HOTFIXES `2026-05-02 P9-4`):
- `render_inspect<B: Backend>` generic 제거 (P9-1/2/3 와 동일).
- Search `i` 키 추가 (P9-2 spec 에 없었음, P9-4 retroactive 추가).
- `c` 일괄 collapse — spec 의 \"focus 기반 selective collapse\" 는 P+.

Docs (sync rule):
- README: TUI 행 \"4 패널\" + Quick start 코멘트.
- HANDOFF: 한 줄 요약 + Phase status (P9 3/5 → 4/5) + deviation 한 줄.
- HOTFIXES: P9-4 entry.
- tasks/p9/p9-4 status: completed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:41:11 +00:00
f08fefec1d feat(kebab-tui): P9-3 Ask pane — streaming answer + citation panel + explain toggle
P9-1 Library 의 ? 키 활성화. App.ask slot 채움 (parallel-safety contract
그대로). Worker thread 가 kebab-app::ask_with_config 호출하면서
AskOpts.stream_sink 로 token 을 mpsc 채널 에 보냄, 메인 스레드 (TUI) 는
매 render frame 마다 drain 으로 문자열 누적 → 답변 영역 이 token-by-token
업데이트.

핵심:
- AskState 본체 (`app.rs`) — input / explain / streaming / partial /
  answer / thread JoinHandle / rx Receiver / scroll / last_error.
- `src/ask.rs`:
  - `render_ask` — input bar / 답변 영역 (streaming 시 ▍ cursor) /
    bottom split (status: grounded/model/prompt/k/refusal · citations
    or explain panel).
  - `handle_key_ask`: typing → input. Enter → spawn_ask_worker (input
    있음 + not streaming). e (input empty 시) → toggle explain.
    j/k (input empty 시) → scroll. Esc → SwitchPane(Library) +
    streaming/rx/thread 클리어 (best-effort cancel).
  - `spawn_ask_worker` — mpsc::channel + thread::spawn(|| ask_with_config).
  - run-loop hooks: `drain_stream` (try_iter → partial), `poll_worker`
    (handle.is_finished → take + join → answer 채움 또는 ErrorOverlay).
- run.rs: Pane::Ask arm 이 handle_key_ask + render_ask. Idle tick 마다
  drain_stream + poll_worker. SwitchPane(Ask) 시 lazy init.

테스트 13개 (`tests/ask.rs`) — Esc/typing/backspace/e toggle (input
empty)/e typed (input nonempty)/Enter empty/Enter while streaming
no-op/render pre-submission hint/streaming partial+cursor/grounded
answer + citation [1]/refusal score_gate 패널 panic 없음/explain panel
title flip/no slot.

Spec deviation (HOTFIXES `2026-05-02 P9-3`):
- `render_ask<B: Backend>` generic 제거 — ratatui 0.28 Frame
  backend-agnostic (P9-1/P9-2 와 동일).
- e/j/k 가 input 빈 상태 일 때만 command 키, 입력 있으면 typing —
  vim "command vs insert" 변형. spec literal 의 단순 \"e=toggle\" 은
  \"explain\" / \"javascript\" 같은 단어 입력 깨뜨림.

Docs (sync rule):
- README: TUI 행 \"Library + Search + Ask 패널\" + Quick start 코멘트.
- HANDOFF: 한 줄 요약 + Phase status (P9 2/5 → 3/5) + deviation 한 줄.
- HOTFIXES: P9-3 entry.
- tasks/p9/p9-3 status: completed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:24:26 +00:00
0490b6a126 feat(kebab-tui): P9-2 Search pane — input + dense hits + preview + editor jump
Library 의 / 키가 활성화. App.search slot 이 lazy 채워지고 (run loop 가 SwitchPane(Search) 받을 때),
debounce 200 ms 후 kebab-app::search 호출, 선택된 hit 의 chunk 를 preview pane 에 표시.
g 키로 $EDITOR (vim/nvim/code/cursor 자동 감지) 에서 citation 위치 열림.

핵심:
- SearchState 본체 (`app.rs` 의 forward decl 채움) — input / mode / hits /
  selected_hit / input_dirty_at / last_query / searching / preview.
- `src/search.rs` (신규):
  - `render_search(f, area, state)` — 3-pane layout (input bar / 결과 리스트 / preview).
    각 hit 는 §1.5 dense 4-line format (rank.score URI / heading / snippet).
  - `handle_key_search`: typing → input + dirty mark. Tab → mode 순환. Enter →
    immediate refresh. j/k → 선택 이동 + preview invalidate. g → editor jump
    (RAII raw-mode suspend). Esc → Library 복귀.
  - `build_jump_command(citation, editor_env, workspace_root)` 가 vim 류
    `+<line> path` / VS Code `code -g path:line` / cursor `cursor -g`
    자동 분기. unit test 로 잠금.
  - `jump_to_citation` 가 raw-mode + AltScreen 을 RAII 로 suspend/restore
    (panic 안전).
  - run-loop hook 4 함수: `debounce_due` / `fire_search` /
    `refresh_preview` (private to crate).
- run.rs:
  - Pane::Search arm 이 `handle_key_search` 로 dispatch + `render_search`.
  - SwitchPane(Search) 시 `app.search = Some(SearchState::default())` lazy init.
  - Idle tick 마다 debounce_due → fire_search, preview None → refresh_preview.
- 테스트 13개 (`tests/search.rs`) — Esc/typing/backspace/Tab cycle/Enter
  refresh/j-k 이동/jump cmd vim+code+args/render w/hits/empty render/no slot.

Spec deviation (HOTFIXES `2026-05-02 P9-2`):
- `render_search<B: Backend>` generic 제거 (P9-1 와 동일 사유 — ratatui 0.28
  Frame backend-agnostic).
- `jump_to_citation` 가 `workspace_root: &Path` 인자 추가. Citation.path 가
  workspace 상대 라 editor 호출 시 절대 경로 필요. spec literal 의 시그니처
  는 unimplementable.

Docs (sync rule):
- README: TUI 행 \"Library + Search 패널, ask/inspect 진행 중\" + Quick start
  의 `kebab tui` 코멘트 갱신.
- HANDOFF: 한 줄 요약 + Phase status (P9 1/5 → 2/5) + deviation 한 줄 추가.
- HOTFIXES: P9-2 entry 추가.
- tasks/p9/p9-2 status: completed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 14:38:17 +00:00
ec0bbc2a40 docs(README): install 가이드 + 사전 요구 + 사용 흐름
사용자 요청: \"이 바이너리를 설치해서 사용하도록 readme에 가이드\".

추가 / 변경:
- **사전 요구** 절 신설 — Rust toolchain ≥ 1.85 (rustup), Ollama 설치 +
  `ollama pull` 모델 안내, target/ 디스크 6–10 GB, fastembed 모델 자동
  다운로드 ~470 MB 명시.
- **설치** 절 신설 — `cargo install --path crates/kebab-cli --locked` 가
  표준 경로. 또는 `cargo install --git <gitea url> --bin kebab --locked`
  로 clone 없이. PATH 확인 + `which kebab` / `kebab --version` 검증.
  업데이트 (`--force`) + 제거 (`cargo uninstall kebab-cli` + 데이터 정리)
  명시.
- **Quick start** 갱신 — `./target/release/kebab` 흐름 → 설치된
  `kebab` 흐름 (PATH 에서 직접 호출). `kebab doctor` 한 줄 추가.
- 마지막 한 줄 — dev 흐름 (`cargo run --release -p kebab-cli` 또는
  `cargo build --release && ./target/release/kebab`) 보존, 설치 없이
  돌려볼 때 사용.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 13:56:56 +00:00
6bfa9795c6 docs: split user-facing docs by audience — README narrow + HANDOFF 진척도 + ARCHITECTURE 내부
사용자 결정 (2026-05-02): \"README.md는 사용자가 가장 빠르게 이 앱을
사용할 수 있도록 하는 내용만 포함하자. mermaid 다이어그램으로 논리적인
아키텍처 다이어그램 하나 정도만 들어가면 충분할 것 같아\".

세 문서로 분리, audience 겹치지 않음:

1. **README.md (narrow)** — 사용자 first stop. Quick start / 명령 표 /
   Mermaid 1개 (논리 아키텍처) / Configuration pointer / 비-목표 / 라이선스.
   진척도 / crate 그래프 / 디렉토리 트리 / 핵심 결정 표 모두 빠짐.

2. **HANDOFF.md (신규)** — phase-level 진척 dashboard. Phase status table,
   component count (33), \"다음 task 후보\" (P9-2/3/4/5, P8 보류), 머지 후
   발견된 deviation 짧은 요약 (P3-5/P4-3 --config, P6-2 OCR, P6-3 caption,
   P7-2 chunk_id, P7-3 storage UNIQUE, P9-1 ratatui generic). 본문 detail
   은 tasks/HOTFIXES.md.

3. **docs/ARCHITECTURE.md (신규)** — crate 의존성 그래프, 디렉토리 트리,
   핵심 기술 결정 표, 외부 AI 통합 절. README 의 Mermaid 가 여기로 링크.

CLAUDE.md 의 \"User-facing docs\" 절 갱신:
- 세 문서 audience 분리 명시.
- implementation PR 이 셋 다 sync 의무, spec PR 은 안 건드림.
- 갱신 trigger 별 (CLI / TUI / Configuration / phase epic / crate 추가 /
  load-bearing deviation) 어느 문서를 손대는지 매핑.
- Out of scope (HOTFIXES detail / version cascade / per-task spec
  rationale) 어디에도 안 적힘 명시.

CLAUDE.md `## Project` 절도 새 문서 layout 반영. 18 crates → ~20 crates.

Memory feedback 갱신 (`feedback_readme_sync_rule.md`) — 미래 conversation
에서 자동 적용.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 13:51:51 +00:00
24e9f739dd docs: CLAUDE.md README sync rule + README 현행화 (P5 / P6 / P7 / P9-1 반영)
CLAUDE.md 에 새 절 \"User-facing docs (README)\" 추가:
- Implementation PR 이 README 를 갱신, spec PR 은 안 건드림.
- 3 surface (CLI / TUI / Configuration) 마다 README 의 어느 행을 손대야
  하는지 명시.
- Phase status table 갱신 의무 ().
- HOTFIXES detail / version cascade / per-task spec rationale 는 README
  out of scope.

같은 PR 에서 README 의 stale 부분 한꺼번에 정리:
- 상태 line: P0–P5 + P6 + P7 + P9-1 완료 + post-merge hotfix 다수 반영.
- 명령 표: kebab tui 추가, ingest/search 가 markdown/image/PDF 모두
  처리한다고 갱신, eval 상태 .
- 핵심 결정: OCR Tesseract → Ollama-vision (HOTFIXES P6-2),
  Image caption 추가, PDF parser lopdf + chunker_version
  per-medium 명시 (HOTFIXES P7-3), TUI/Desktop 진행 상태.
- Phase 로드맵: P5/P6/P7  완료, P8 ⏸ 보류, P9 🟡 진행 (1/5).
- 디렉토리 구조: kebab-eval / kebab-parse-image / kebab-parse-pdf /
  kebab-tui crate 추가, p6/p7 task 카운트 갱신.
- 빌드 + 실행: kebab tui 사용법 + 두 example 바이너리 (gen_smoke_pdf
  / gen_smoke_png) 안내 추가.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 13:43:24 +00:00
f9714aa5cb docs(rename): kb → kebab — README, tasks/, docs/, design doc, report
마지막 commit. 모든 .md 안의 `kb` 단어 일괄 갱신.

- 19 개 crate 이름 (`kb-core`, `kb-app`, …) → `kebab-*` (Rust 모듈
  path 표기 `kb_*` → `kebab_*` 포함).
- 미래 component (`kb-tui`, `kb-desktop`, `kb-asr-whisper`, `kb-ocr`,
  `kb-mcp`, `kb-vlm`, `kb-rerank`, `kb-vision-ocr`, `kb-index`,
  `kb-smoke`, `kb-architecture`) → `kebab-*` (P6+ 가 시작될 때
  같은 prefix 사용).
- CLI 명령 예제: `kb ingest` / `kb search` / `kb ask` / `kb init` /
  `kb doctor` / `kb inspect` / `kb list` / `kb eval` →
  `kebab <verb>`. fenced code block + 인라인 backtick 모두.
- XDG paths + env vars + binary 경로 (`target/release/kb` →
  `target/release/kebab`) 동기화.
- design doc / 최초 보고서 / SMOKE / HOTFIXES / phase epic / task
  spec 모든 reference 통일.
- task-decomposition.md 의 `git -c user.name=kb` 는 과거 git history
  기록용 author 정보라 그대로 유지 (실제 git history 의 author 는
  변경 불가).
- `tasks/phase-5-evaluation.md` 의 `status: planned` →
  `completed` 도 같이 (P5-1 + P5-2 PR 머지 후 미반영분).

## 검증

- `grep -rEn "\bkb-[a-z]|\bkb_[a-z]|\.config/kb\b|kb\.sqlite|\bKB_[A-Z]"
   --include="*.md"` 0 hits (task-decomposition.md 의 git author
  제외).
- 모든 file path reference 살아있음 (renamed file 들 모두 새 path
  로 update).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 04:01:55 +00:00
d1b99b2994 docs: mark P0–P4 done, add SMOKE recipe, refresh README
State drift after P0–P4 completion + 3 post-merge hotfixes (PR #20
--config across subcommands, PR #24 --config in kb ask, PR #25 RRF
fusion_score normalization). README still framed the project as
"spec frozen, code 0 lines"; phase docs and task specs all carried
status: planned. Sweep:

- README.md: top banner now "P0–P4 done (17/31 tasks) + 3 hotfixes
  applied"; command table marks each subcommand's owning phase and
  current status (kb ask =  via P4-3, kb eval =  P5);
  phase roadmap table grew a Status column (P0–P4 completed, P5
  next, P6–P9 pending); component count bumped 30 → 31 to reflect
  P3-5 (app-wiring, post-spec); core decisions table notes the
  RRF [0,1] normalization invariant; build+실행 section drops the
  "P0 미시작" caveat; new pointers to HOTFIXES.md and SMOKE.md.
- docs/SMOKE.md (new): ~80-line recipe for running the full
  pipeline against an isolated /tmp/kb-smoke/ workspace via
  --config, without polluting ~/.config/kb/ or
  ~/.local/share/kb/. Covers fixture seeding, sample config.toml
  with the post-merge defaults, doctor → ingest → list →
  search × 3 modes → inspect → ask sequence, verification
  checklist, and known-behaviour notes (fastembed model
  download, RAG response time, --config hard-fail on missing
  path).
- tasks/phase-{0..4}-*.md: status frontmatter flipped planned →
  completed.
- tasks/p0/, tasks/p1/, tasks/p2/, tasks/p3/, tasks/p4/: same
  status flip across all 17 component task specs (1+6+2+5+3).
  P5–P9 stay planned.

cargo test --workspace: 319 passed; clippy clean (no source
changes in this commit, just docs + frontmatter).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 16:32:28 +00:00
kb
bf2179b9c4 docs: add Korean README
- Status (spec frozen, P0 not started)
- Command summary (init/ingest/search/ask/inspect/doctor/eval)
- Locked decisions table (Rust 2024, SQLite+FTS5, LanceDB, fastembed, Ollama, whisper, Tauri)
- Dependency graph + module-boundary references
- Phase roadmap (P0..P9) with crates per phase
- Directory layout (current + post-P0)
- Build/run snippet (post-P0)
- Non-goals
- External AI integration paths (skill / MCP / HTTP)
- Contribution workflow + license note
- Cross-links to frozen design / plan / INDEX
2026-04-27 23:50:39 +00:00