`kebab ingest` 가 진행 상황을 사용자에게 보여주는 두 surface 추가:
- **사람 모드 (TTY)**: indicatif `ProgressBar` on stderr — scan 중에는
spinner, ScanCompleted 후 bar 로 전환, 매 asset 마다 message 갱신.
- **사람 모드 (non-TTY, CI/pipe)**: indicatif draw target 을 hidden
으로 두고 stderr 에 한 줄씩 (`ingest: scanning`, `ingest: 1/N path`,
`ingest: complete (...)`).
- **`--json` 모드**: stderr 비우고 stdout 에 line-delimited
`ingest_progress.v1` JSON 을 emit. 마지막 줄은 기존
`ingest_report.v1` 그대로 (외부 wrapper backward-compat).
구현:
- 신규 `crates/kebab-cli/src/progress.rs` — `ProgressMode::{Json,
Human { tty }}`, `ProgressDisplay` (background thread 가 channel
drain + 모드별 render), `now_rfc3339` helper. mode 가 무엇이든 ts
는 wire emit 시점에 stamp.
- `crates/kebab-cli/src/wire.rs` 에 `wire_ingest_progress` 추가.
serde tag (`kind`) 위에 `schema_version` + `ts` 두 필드 더해 spec
§2.4a wire shape 완성.
- `Cmd::Ingest` 핸들러: mpsc channel 만들고 background thread 가
display 돌리는 동안 main 이 `ingest_with_config_progress` 호출.
ingest 반환 시 Sender drop → display thread 정상 종료. join 후
최종 ingest_report 출력.
- 새 dep: `indicatif` 0.17 (TTY 전용 진행 바, non-TTY/--json 에서는
hidden draw target).
Test:
- 3 lib unit (mode resolution + RFC 3339 round-trip).
- 3 integration (--json line-delimited / non-TTY stderr text /
ts+kind 검증). 16 PASS 전체 회귀 0.
Plan 갱신:
- p9-fb-01: status `in_progress` → `completed` (PR #52 머지 후속).
- p9-fb-02: status `planned` → `in_progress`. 머지 후 별도 한 줄
commit 으로 `completed` flip.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
79 lines
2.8 KiB
Markdown
79 lines
2.8 KiB
Markdown
---
|
|
phase: P9
|
|
component: kebab-app + kebab-core
|
|
task_id: p9-fb-01
|
|
title: "Ingest progress callback / event channel"
|
|
status: completed
|
|
depends_on: []
|
|
unblocks: [p9-fb-02, p9-fb-03]
|
|
contract_source: ../../docs/superpowers/specs/2026-04-27-kebab-final-form-design.md
|
|
contract_sections: [§7 ingest, §10 UX]
|
|
source_feedback: p9-dogfooding-feedback.md item 1
|
|
---
|
|
|
|
# p9-fb-01 — Ingest progress callback
|
|
|
|
## Goal
|
|
|
|
`kebab_app::ingest_with_config` 가 진행 상황을 caller 에게 흘려보낼 수 있도록 progress callback (또는 mpsc Sender) 주입 surface 추가. CLI / TUI / desktop 셋 모두 같은 이벤트 stream 소비.
|
|
|
|
## Why now
|
|
|
|
도그푸딩 시 ingest 가 1.8 초 묵음 후 결과만 출력 — hung 인지 빈 워크스페이스인지 구분 불가. progress event 가 모든 UI surface 의 prerequisite.
|
|
|
|
## Allowed dependencies
|
|
|
|
- 기존 kebab-app deps. 신규 X.
|
|
- `std::sync::mpsc` 또는 `crossbeam_channel`.
|
|
|
|
## Public surface
|
|
|
|
```rust
|
|
#[derive(Debug, Clone)]
|
|
pub enum IngestEvent {
|
|
ScanStarted { root: PathBuf },
|
|
ScanCompleted { total: u32 },
|
|
AssetStarted { idx: u32, total: u32, path: String, media: MediaKind },
|
|
AssetFinished { idx: u32, kind: IngestItemKind, chunks: u32 },
|
|
EmbedBatchStarted { n_chunks: u32 },
|
|
EmbedBatchFinished { n_chunks: u32, ms: u64 },
|
|
Aborted { partial_counts: AggregateCounts },
|
|
Completed { counts: AggregateCounts },
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
pub fn ingest_with_config_progress(
|
|
config: kebab_config::Config,
|
|
scope: SourceScope,
|
|
summary_only: bool,
|
|
progress: Option<Sender<IngestEvent>>,
|
|
) -> anyhow::Result<IngestReport>;
|
|
```
|
|
|
|
기존 `ingest_with_config` 는 `progress=None` 으로 forwarding wrapper.
|
|
|
|
## Behavior contract
|
|
|
|
- progress event 발신은 best-effort. receiver drop 되면 이후 send 무시 (panic 금지).
|
|
- 이벤트 ordering: `ScanStarted < ScanCompleted < (AssetStarted < AssetFinished)* < Completed|Aborted`. embed batch 는 asset 사이 임의 위치.
|
|
- `Aborted` 이벤트는 cancellation token (p9-fb-04) trigger 시에만 발신. CLI / TUI 의 cancel 신호 wiring 은 각각 p9-fb-04, p9-fb-03 에서 구현.
|
|
- `--json` CLI 는 line-delimited 형태로 dump (`schema_version=ingest_progress.v1`) — 별도 task (p9-fb-02).
|
|
|
|
## Test plan
|
|
|
|
| kind | description |
|
|
|------|-------------|
|
|
| unit | `Sender<IngestEvent>` 가 ScanStarted → ScanCompleted → Asset* → Completed 순서로 받는다 |
|
|
| integration | tmp workspace 3 md → 받은 이벤트 sequence 가 monotonic idx |
|
|
|
|
## DoD
|
|
|
|
- [ ] `cargo test -p kebab-app` 통과
|
|
- [ ] 기존 `ingest_with_config` 호출자 (CLI 단발 호출) 변경 없음
|
|
- [ ] HOTFIXES 항목 X — 신기능, deviation 아님
|
|
|
|
## Out of scope
|
|
|
|
- progress event JSON 직렬화 (별도 wire schema task)
|
|
- TUI 가 이벤트 소비해서 status bar 그리기 (p9-fb-03)
|