* fix(docker): add system ripgrep via apt for keyword search fallback * fix(ci): install ripgrep and npm deps for keyword search in CI * fix(memory-search): warn when ripgrep not resolvable instead of silent skip * fix(memory-doctor): check rg status, arch mismatch, and require errors * test(memory): add keyword search and doctor unit tests * test(memory): unskip e2e keyword tests without RUN_LIVE * docs(handoff): add handoff and ADR for keyword search fix * test(memory): remove unused var in keyword search test * docs(handoff): set PR number to 124 * docs(project-map): update after structural changes (PR#124) --------- Co-authored-by: opencode-agent <agent@opencode.local>
76 lines
No EOL
4.6 KiB
Markdown
76 lines
No EOL
4.6 KiB
Markdown
---
|
||
pr: 124
|
||
title: fix(memory): keyword search out-of-box + doctor gaps + tests
|
||
---
|
||
|
||
## Что сделано
|
||
|
||
- **Dockerfile**: добавлен `ripgrep` в `apt-get install` (строки 3-16).
|
||
System rg = fallback; `@vscode/ripgrep` в `npm install -g` (строка 38)
|
||
остаётся primary path.
|
||
- **ci.yml** (job `test`): после `setup-node@v4` добавлены
|
||
`apt-get install -y ripgrep` и `npm ci` (working-directory: .opencode) —
|
||
CI теперь устанавливает ripgrep и npm-deps для keyword search.
|
||
- **memory-search.ts** (~строка 312): при `rgBin===null` пишет warning в
|
||
stderr (`ripgrep not resolvable — keyword search disabled`) вместо
|
||
молчаливого skip. Аналогичный warning в category-fallback блоке.
|
||
- **memory-doctor.ts** — закрыты 4 gap'а:
|
||
- **G9**: `checkRipgrep` возвращает `{ lines, rgWorks }` где
|
||
`rgWorks = rgBin !== null && r.status === 0`; `formatDoctorReport`
|
||
и `allGreen` используют `rgWorks`, а не `rgBin !== null`.
|
||
- **G5**: `resolveRgBinary({ allowSystemFallback: true })` в execute
|
||
(консистентно с memory-search.ts:305).
|
||
- **G3**: при `rgBin===null` (npm-пакет не найден) — строка с подсказкой
|
||
`npm package missing — run npm ci in .opencode/`.
|
||
- **G2**: `detectArchMismatch()` — если rgBin path содержит 'darwin'
|
||
при `process.platform === 'linux'` (и обратные комбинации) + arch
|
||
mismatch (arm64 vs x64) → строка `arch mismatch: binary platform !=
|
||
runtime platform` в отчёт.
|
||
- **tests/test_memory_keyword_search.ts** (новый): 5 TS unit-тестов для
|
||
`resolveRgBinary()` (npm-package, system-fallback, null-nothing,
|
||
null-no-fallback) + memory-search stderr warning при rgBin===null.
|
||
- **tests/test_memory_doctor.ts** (новый): 4 TS unit-теста — allGreen
|
||
false при битом бинарнике (G9), allGreen true при рабочем (regression
|
||
guard), arch-mismatch detection (G2), npm-missing hint в report (G3).
|
||
- **tests/test_memory_tools_e2e.py**: убран глобальный `pytestmark`
|
||
skipif(RUN_LIVE). Keyword-тест `test_zero_config_keyword_only` теперь
|
||
запускается БЕЗ RUN_LIVE. Semantic-тесты (hybrid, fallback, deletion)
|
||
имеют individual `skipif(not RUN_LIVE)`.
|
||
|
||
Проверки: `pytest tests/ -x -q` 427 passed, 6 skipped; `ruff check` OK;
|
||
`ruff format --check` OK.
|
||
|
||
## Почему
|
||
|
||
README заявлял keyword search как "always works", но:
|
||
1. System `rg` не был установлен нигде (Dockerfile/CI/host) — только
|
||
хрупкий volume-mount npm-пакета.
|
||
2. CI не устанавливал ripgrep ни через apt, ни через npm ci для
|
||
`.opencode/package.json`.
|
||
3. `memory-search` молча пропускал keyword search при `rgBin===null` —
|
||
без warning, что затрудняло диагностику.
|
||
4. `memory-doctor` имел 4 расхождения: allGreen проверял `rgBin!==null`
|
||
а не `r.status===0`, `allowSystemFallback` расходился с memory-search,
|
||
нет arch-mismatch detection, require-ошибки не попадали в отчёт.
|
||
5. E2E-тесты скипались без `RUN_LIVE` целиком — даже keyword-тесты,
|
||
которые не требуют embeddings API.
|
||
|
||
## Pending
|
||
|
||
—
|
||
|
||
## Watch out
|
||
|
||
- TS unit-тесты (`test_memory_keyword_search.ts`, `test_memory_doctor.ts`)
|
||
runnable under `bun test` — bun runtime отсутствует на CI host; файлы
|
||
валидны как TS, но не запускаются pytest'ом. Это тот же pattern что
|
||
`test_commit_tool.ts` / `test_merge_pr_tool.ts`.
|
||
- `detectArchMismatch()` использует эвристику по имени path (contains
|
||
'darwin'/'linux'/'win32' + 'arm64'/'x64') — не вызывает `file` command.
|
||
Покрывает основной случай (@vscode/ripgrep platform dir names).
|
||
- `resolveRgBinary({ allowSystemFallback: true })` в memory-doctor теперь
|
||
консистентен с memory-search — но меняет поведение: если npm-пакет
|
||
отсутствует но system rg есть, doctor покажет ✅ вместо ❌. Это
|
||
намеренно (doctor = зеркало реального поведения search).
|
||
- CI: `npm ci` в `.opencode/` требует `package-lock.json` — проверь что
|
||
он есть в репо (иначе CI упадёт). |