Commit Graph

697 Commits

Author SHA1 Message Date
th-kim0823
15cdc97cae feat(cli): [stale] tag on plain search output (fb-32)
Yellow when TTY, plain when not. JSON path inherits via serde
on the domain type; no CLI-side wire change needed there.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 02:24:54 +09:00
th-kim0823
cc41adabb5 feat(wire): search_hit.v1 + citation.v1 require indexed_at + stale (fb-32)
Additive minor — schema_version unchanged. Existing v1 consumers
that ignore unknown fields stay compatible; consumers that validate
strictly will reject pre-fb-32 payloads, which matches the wire
contract escape hatch (recipient version >= producer required).

Cross-task placeholders: kebab-eval / kebab-tui synthetic test
fixtures pin UNIX_EPOCH + stale=false (same pattern as
hybrid.rs / vector.rs). These don't exercise staleness — Task 11
adds dedicated TUI staleness rendering tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 02:17:15 +09:00
th-kim0823
16db60f7bd docs(fb-32): mirror back-reference + fix pipeline doc-comment ordering
- kebab-app::staleness::compute_stale gains note pointing at the
  kebab-rag mirror so future modifiers know to update both copies.
- kebab-rag::pipeline: doc comments adjacent to compute_stale and
  embedding_ref_for were positioned such that rustdoc would
  misattribute them. Reorder/separate so each comment hugs its
  own function.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:51:40 +09:00
th-kim0823
e398272a24 feat(rag): AnswerCitation inherits indexed_at + stale from hit (fb-32)
pack_context widened to carry indexed_at + stale alongside marker
and Citation. LLM-citation construction site now plumbs real values
from upstream SearchHit instead of the Task 6 UNIX_EPOCH placeholder.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:44:24 +09:00
th-kim0823
e891e487cf test(rag): mk_hit gains indexed_at + stale stubs (fb-32)
Test helper missed the SearchHit field expansion from fb-32 Task 1.
UNIX_EPOCH + false placeholders consistent with the cross-crate
synthetic-mock pattern (hybrid.rs, vector.rs build_hit Task 4 stub).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:37:19 +09:00
th-kim0823
dfef65f196 feat(app): staleness module + post-process search hits (fb-32)
compute_stale: strict > boundary, threshold=0 disables, future
timestamps treated as fresh (clock skew safety). App::search
re-stamps on cache hit so config threshold changes take effect
without flushing the cache.

Also unblocks the workspace build by plugging placeholder
indexed_at/stale into the two AnswerCitation construction
sites in kebab-rag/pipeline.rs (the score-gate refusal path
forwards from SearchHit; the LLM-citation path uses
UNIX_EPOCH/false until Task 7 wires the real values through
pack_context).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:30:10 +09:00
th-kim0823
8faad2f407 feat(search/vector): populate SearchHit.indexed_at (fb-32)
hydrate_chunks now JOINs d.updated_at. Hybrid fusion path is
unchanged (passes SearchHit through, fields preserved).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:17:54 +09:00
th-kim0823
f4ce6652b2 feat(search/lexical): populate SearchHit.indexed_at (fb-32)
JOIN documents.updated_at. stale defaults to false; App facade
post-processes against config threshold.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:10:20 +09:00
th-kim0823
922849cd95 feat(config): search.stale_threshold_days (fb-32)
default 30 days. env override KEBAB_SEARCH_STALE_THRESHOLD_DAYS.
Malformed env values are silently ignored, matching the existing
apply_env pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:01:01 +09:00
th-kim0823
3a7a28e682 feat(core): AnswerCitation gains indexed_at + stale (fb-32)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 00:56:36 +09:00
th-kim0823
8b0f64db6b feat(core): SearchHit gains indexed_at + stale (fb-32)
Domain field additions for p9-fb-32. Wire serialization is
automatic via serde rfc3339. Other crates fail to compile until
they populate the new fields — fixed in subsequent tasks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 00:52:46 +09:00
th-kim0823
4728a87957 plan(fb-32): stale doc indicator implementation plan
15 tasks covering domain (kebab-core SearchHit + AnswerCitation),
config (SearchCfg.stale_threshold_days), retrievers (lexical + vector
JOIN documents.updated_at), App facade (staleness module + cache
re-stamp), wire schema, CLI plain [stale] tag, TUI [STALE] Warning
badge, snapshot fan-out, docs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 00:40:46 +09:00
th-kim0823
401a47fb43 spec(fb-32): stale doc indicator — design
검색 hit / RAG citation 에 indexed_at + stale 두 wire 필드 추가.
documents.updated_at 재활용 (V006 incremental ingest 가 자연 source-of-truth).
config [search] stale_threshold_days = 30 default. additive minor wire.
TUI Warning role / CLI plain [stale] tag / agent --json 동시 surface.
자동 재 ingest 는 out of scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 18:00:10 +09:00
6d4a648349 Merge pull request 'docs(skill): MCP-first guidance + CLI as fallback' (#121) from docs/skill-mcp-first into main
Reviewed-on: #121
v0.3.3
2026-05-07 14:46:40 +00:00
th-kim0823
b20c1dd56a docs(skill): MCP-first guidance + CLI as fallback
Repo-shipped skill previously framed CLI as primary surface with MCP
as a separate "recommended" alternative. Recipes still used CLI calls
even though MCP server has been the recommended surface since v0.3.1.

Now: MCP tool catalog (6 tools as `mcp__kebab__<name>`) leads, recipes
call MCP tools directly, CLI documented as fallback for hosts without
MCP. Generic wording preserved (no user-specific trigger keywords).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 23:45:25 +09:00
834a1e1723 Merge pull request 'fix(progress): one draw per file — drop set_message in TTY AssetStarted' (#120) from fix/progress-single-draw into main
Reviewed-on: #120
2026-05-07 13:29:56 +00:00
th-kim0823
3328760dca fix(progress): one draw per file — drop set_message in TTY AssetStarted
set_draw_target switching broke cursor positioning: each hidden→stderr
restore caused indicatif to draw a fresh line instead of overwriting.
Root fix: call only set_position() in TTY AssetStarted (one draw per
file). Filename visible in non-TTY plain-line output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 22:28:37 +09:00
f25e16f80c Merge pull request 'docs(tasks): mark fb-30 + fb-31 merged in INDEX.md' (#115) from docs/index-fb30-fb31-status into main
Reviewed-on: #115
2026-05-07 13:20:32 +00:00
4475abbf4f Merge pull request 'fix(progress): eliminate duplicate TTY frame per asset' (#119) from fix/progress-duplicate-tty-frame into main
Reviewed-on: #119
2026-05-07 13:17:34 +00:00
th-kim0823
5be90cffec fix(progress): eliminate duplicate TTY frame per asset
set_position() and set_message() each call update_and_draw()
independently, producing two scrollback lines per file in TTY mode.
Suppress the draw target before the two updates, restore to stderr,
then call tick() to emit exactly one frame.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 22:15:01 +09:00
6f0b2bcc37 Merge pull request 'fix(config): use XDG-standard paths on macOS (prevent DataOnly reset deleting config)' (#118) from fix/xdg-macos-path-collision into main
Reviewed-on: #118
2026-05-07 13:00:59 +00:00
th-kim0823
36fe7416c8 fix(config): use XDG-standard paths on macOS to prevent DataOnly reset deleting config
dirs::config_dir() and dirs::data_dir() both return ~/Library/Application Support
on macOS, so data_dir == config parent dir. ResetScope::DataOnly removes data_dir
and silently deletes config.toml along with it.

Fix: bypass dirs crate fallback for config/data/cache dirs; use
$HOME/.config, $HOME/.local/share, $HOME/.cache directly (XDG standard).
xdg_state_dir already used this pattern. dirs::home_dir() still used for
portability.

Migration: Config::load(None) auto-copies legacy ~/Library/Application
Support/kebab/config.toml to the new ~/.config/kebab/ on first run and
prints a migration notice to stderr.
2026-05-07 21:59:49 +09:00
d6e2e6273e Merge pull request 'fix(progress): eliminate duplicate bar frame per asset in TTY mode' (#116) from fix/progress-duplicate-tty-frame into main
Reviewed-on: #116
2026-05-07 12:50:31 +00:00
th-kim0823
cb266e0071 fix(progress): eliminate duplicate bar frame per asset in TTY mode
AssetStarted now advances position (idx-1) and sets message together.
AssetFinished no longer updates the bar — Completed handles final
cleanup via finish_and_clear. Result: one bar frame per file instead
of two, eliminating the scrollback duplicate-line artifact.
2026-05-07 21:49:47 +09:00
th-kim0823
ee15528acf docs(tasks): mark fb-30 + fb-31 merged in INDEX.md 2026-05-07 21:26:25 +09:00
e03b754a16 Merge pull request 'chore: bump version 0.3.2 → 0.3.3' (#114) from chore/bump-v0.3.3 into main
Reviewed-on: #114
2026-05-07 12:22:22 +00:00
th-kim0823
6b13d8e11f chore: bump version 0.3.2 → 0.3.3 2026-05-07 21:10:23 +09:00
fea91d5c99 Merge pull request 'feat(fb-26,fb-28): ingest log consistency + --readonly/--quiet flags + schema sync' (#113) from feat/p9-fb-26-fb-28-agent-ux into main
Reviewed-on: #113
2026-05-07 12:09:04 +00:00
th-kim0823
0e762e6374 fix: rename leftover kbkebab in main.rs comments 2026-05-07 20:52:34 +09:00
th-kim0823
b230fbb495 fix: apply review nits — kb→kebab comment, quiet reset guard, ingest-stdin readonly test, README+SMOKE docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:58:56 +09:00
th-kim0823
afbd64dafc docs: mark fb-26 + fb-28 merged, HOTFIXES entries for progress bugs + readonly_mode
- fb-26 (progress.rs): Fixed Aborted unconditional writeln (TTY duplicate output)
  and Completed TTY path missing summary line. Added KEBAB_PROGRESS=plain env
  override and quiet field to ProgressMode.
- fb-28 (main.rs): Added --readonly / --quiet global flags with KEBAB_READONLY env.
  Readonly blocks mutating commands (ingest/ingest-file/ingest-stdin/reset) with
  exit code 1; error.v1 code "readonly_mode" in --json mode. Quiet suppresses all
  human progress/hint stderr while preserving errors.
- Updated task spec status for p9-fb-26 and p9-fb-28 to 'merged'.
- Updated tasks/INDEX.md and HANDOFF.md with merge status and summary entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 19:45:40 +09:00
th-kim0823
6bedba4a7f test(fb-26,fb-28): integration tests for readonly/quiet flags and KEBAB_PROGRESS=plain
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:43:04 +09:00
th-kim0823
fd4125c0a0 feat(fb-28): --readonly/--quiet global flags + KEBAB_READONLY env + is_mutating guard
Add readonly/quiet fields to Cli, parse_bool_env for 1/true/yes/on support,
is_mutating guard that short-circuits with error.v1 on write-path commands,
and wire KEBAB_PROGRESS=plain through from_flags in the Ingest arm.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:38:30 +09:00
th-kim0823
4191347491 fix(fb-26): Completed TTY missing summary + Aborted unconditional writeln + quiet suppression in handle_human
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:33:57 +09:00
th-kim0823
dd33902f5a feat(fb-26): extend ProgressMode with quiet field, update from_flags signature
Add `quiet: bool` to `Human` variant and expand `from_flags` to three
args (`json`, `quiet`, `plain_env`). Update `handle`/`handle_human`
accordingly; add four targeted unit tests (TDD).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:31:01 +09:00
th-kim0823
c8a8bc9045 docs: sync wire schema list in CLAUDE.md (remove phantom eval_run/eval_compare/list_docs, add chunk_inspection/citation/doc_summary) 2026-05-07 19:28:05 +09:00
th-kim0823
2de28c43da docs(plan): fb-26 + fb-28 + schema-sync implementation plan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:18:27 +09:00
th-kim0823
9d96504bd9 docs(spec): fb-26 + fb-28 + schema-sync design doc
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:11:47 +09:00
6dcc5ce412 Merge pull request 'chore: bump version 0.3.1 → 0.3.2' (#112) from chore/bump-v0.3.2 into main
Reviewed-on: #112
v0.3.2
2026-05-07 10:01:08 +00:00
th-kim0823
751377cae8 chore: bump version 0.3.1 → 0.3.2
fb-31 single-file/stdin ingest + MCP ingest tools + docs/mcp-usage.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 18:59:03 +09:00
4922f9fc64 Merge pull request 'feat(fb-31): single-file / stdin ingest — agent on-demand 저장' (#111) from feat/p9-fb-31-single-file-stdin-ingest into main
Reviewed-on: #111
2026-05-07 09:56:09 +00:00
th-kim0823
47bfd518c8 📝 docs: comprehensive MCP usage guide (fb-31)
신규 docs/mcp-usage.md (~280 line) — agent integration 의 종합 가이드:

- Quick start + `--config` thread 예시
- Host config 예시 (Claude Code / Cursor / OpenAI Agents / Copilot CLI)
- 6 tool catalog (search / ask / schema / doctor / ingest_file / ingest_stdin)
  각 tool 의 input shape, defaults, output 예시, "언제 사용", mutation
  주의사항.
- Troubleshooting — error.v1 의 7 code 별 조치 표 + grounded:false +
  doctor !ok + empty search + tool-not-found 시나리오.
- Multi-turn ask + session 관리 — session_id 명명, 새 session 시작
  시점, lifetime, single-shot vs session 비교.
- Performance / Security 절.

README.md 의 기존 MCP 절은 quick start 만 유지하고 docs/mcp-usage.md
링크. integrations/claude-code/kebab/SKILL.md 도 동일 cross-link.

agent 사용자 도그푸딩 후속 의견 — host-agnostic 가이드 + 명시적
troubleshooting 표 + multi-turn session 명명 컨벤션 부재 해소.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:53:59 +09:00
th-kim0823
7f5739d8fb 🏗️ refactor(fb-31): apply round 1 review nits
- ingest_file_with_config: lowercase normalize ext (caller-side) +
  early error on unsupported extension (`.docx` etc. now Err with
  helpful message instead of silent skipped_by_extension counter).
  New test ingest_file_errors_on_unsupported_extension.
- ingest_stdin_with_config: doc comment explaining intentional
  double-call of ensure helpers (idempotent + ~ms negligible).
- external::inject_frontmatter: simplify precheck via single
  trim_start binding + add CR-only line ending edge case.
- external::inject_frontmatter: doc note on yaml_quote escape
  contract (agent-supplied titles with special chars are safe).

Round 1 review summary: #111 (comment)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:46:55 +09:00
th-kim0823
dc24cb34b1 🚑 fix(fb-31): apply final review nits
- kebab-app: add #[doc(hidden)] to ingest_stdin_with_config (CLAUDE.md
  convention — all *_with_config functions should have this attribute;
  fb-31's first impl missed it on the second facade fn).
- SKILL.md: "Since v0.4.0" → "Since v0.3.1" (MCP shipped in fb-30
  release v0.3.1; the wrong version claim was introduced in fb-30 doc
  sync and carried forward into fb-31).
- tools_call_ingest_file: add idempotency test (second call with same
  content → unchanged=1, new=0). Spec called for two tests; first impl
  shipped only the happy path.

Version bump 0.3.1 → 0.3.2 deferred to separate `chore/bump-v0.3.2` PR
mirroring fb-27 + fb-30 precedent (commits 73f5d73 / 5495d96).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:38:19 +09:00
th-kim0823
ccee30037d 🧪 test(kebab-cli): update cli_mcp_smoke tools/list assertion 4 → 6 (fb-31)
fb-31 added ingest_file + ingest_stdin MCP tools (Task 9) but the
spawn-based smoke test in cli_mcp_smoke.rs still asserted the fb-30
count of 4. Bump to 6 to match the live tools/list response.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:26:51 +09:00
th-kim0823
e041173e8e 📝 docs(tasks): HOTFIXES entry + p9-fb-31 status → completed
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:18:50 +09:00
th-kim0823
345a4f363a 📝 docs: sync README / HANDOFF / CLAUDE / skill / design for fb-31
- README 명령 표 에 `kebab ingest-file` + `kebab ingest-stdin` 두 row + MCP tool list 4 → 6.
- HANDOFF post-도그푸딩 항목 한 줄.
- CLAUDE.md `_external/` 디렉토리 + naming convention 한 줄.
- integrations skill — Recipe D (agent fetched web doc) + MCP tool list 갱신.
- design §6.7 `_external/` subdirectory 절 신설.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:16:45 +09:00
th-kim0823
71c2bbdc97 🧪 test(kebab-mcp): ingest_file + ingest_stdin integration (fb-31)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:14:07 +09:00
th-kim0823
ecd77290cd feat(kebab-mcp): ingest_file + ingest_stdin tools (fb-31)
5th + 6th MCP tools — first mutation surface (fb-30 v1 was read-only).
Both wrap the new kebab-app facade fns + use spawn_blocking via the
existing spawn_tool helper. tools/list now returns 6 tools.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:12:18 +09:00
th-kim0823
fbc01eda50 🧪 test(kebab-cli): cli_ingest_file + cli_ingest_stdin integration (fb-31)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:10:09 +09:00