Files
memo/docs/orders/05-cli.md
T

80 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Проект: /root/WORK/memo (Kotlin/JVM). Заказ по CLI — руками проверяемые команды.
Правки:
- memo-cli/build.gradle.kts: добавить application-плагин и зависимость на :memo-core
- новый файл memo-cli/src/main/kotlin/memo/cli/Main.kt
- новый файл memo-cli/src/test/kotlin/memo/cli/CliArgsTest.kt
## Настройка модуля memo-cli
build.gradle.kts модуля:
plugins { kotlin("jvm"); application }
application { mainClass.set("memo.cli.MainKt") }
dependencies { implementation(project(":memo-core")) }
## Main.kt — контракт команд
fun main(args: Array<String>)
Разбор аргументов вынести в чистую функцию (тестируемую без процесса):
sealed interface Cmd
data class IndexCmd(val path: String) : Cmd
data class SearchCmd(val path: String, val query: String, val k: Int, val mode: SearchMode, val json: Boolean) : Cmd
data class StatusCmd(val path: String) : Cmd
data class McpProbeCmd(val tool: String, val argsJson: String) : Cmd
object HelpCmd : Cmd
fun parseArgs(args: Array<String>): Cmd // при ошибке — HelpCmd
Правила разбора:
- `index <path>` → IndexCmd
- `search <path> <query> [--k N] [--mode hybrid|lex|vec] [--json]` → SearchCmd
(по умолчанию k = 8, mode = HYBRID); неизвестный флаг или нечисловой --k → HelpCmd
- `status <path>` → StatusCmd
- `mcp-probe --tool <name> [--args <json>]` → McpProbeCmd (args по умолчанию "{}")
- нет аргументов, `--help`, `-h`, неизвестная команда → HelpCmd
Поведение команд:
1. `index <path>`: определить корень так — если path оканчивается на "/.memo" или содержит его, взять родителя;
каталог `X` считается коллекцией, если в нём есть файлы *.md (искать на глубине до 2 от path).
Для каждой найденной коллекции: создать каталог `<коллекция>/.memo`, базу `<коллекция>/.memo/index.db`,
Db(...).init(), затем Indexer(db, embedder).indexTree(коллекция).
Путь к модели: переменная окружения MEMO_MODEL_DIR, иначе /root/WORK/memo/models/siglip2.
Печатать по строке на коллекцию: `индексировано: <N> обновлено, <файлов всего>` и в конце
`итого: <сумма> обновлено в <число коллекций> коллекциях`.
2. `search <path> <query>`: path — ЛИБО коллекция, ЛИБО файл *.md (тогда коллекция = его каталог),
ЛИБО корень, содержащий коллекции (тогда искать по всем коллекциям внутри, объединив результаты
по убыванию score и обрезав до k).
Модель/эмбеддер обязателен: без него базы не откроются — это нормально.
Refresh-хук передавать обязательно: он делает Indexer(db, embedder).indexTree(root) перед поиском.
Без `--json` печатать человекочитаемо:
`<score с 3 знаками> <path>:<line> <heading>`
далее текст чанка с отступом 4 пробела, обрезанный до 300 символов.
С `--json` печатать ОДИН JSON-массив, без пояснений и без лишних строк:
[{"path":"...","line":12,"heading":"...","score":0.51,"text":"..."}]
Если ничего не найдено — пустой JSON-массив `[]` (в режиме --json) и код возврата 0.
3. `status <path>`: по каждой коллекции печатать `<<коллекция>>: файлов <N>, чанков <M>, индекс <дата ISO>`
(дата — максимальный indexed_at из files).
4. `mcp-probe --tool <name> --args <json>`: выполнить то же, что делает MCP-инструмент, и напечатать
результат в формате MCP-ответа:
{"content":[{"type":"text","text":"<результат>"}],"isError":false}
Поддерживаемые инструменты на этом шаге: memo_search (аргументы path, query, k, mode) и memo_status (path).
memo_reindex — вернуть isError: true с текстом "not implemented yet".
## CliArgsTest.kt — ровно 5 тестов, имена ровно такие
1. `indexCommandParsed` — ["index", "/tmp/x"] → IndexCmd с path "/tmp/x".
2. `searchDefaultsAreK8HybridNoJson` — ["search", "/tmp/x", "вопрос"] → SearchCmd(k = 8, mode = HYBRID, json = false).
3. `searchFlagsParsed` — ["search", "/tmp/x", "вопрос", "--k", "3", "--mode", "lex", "--json"] → k = 3, mode = LEX, json = true.
4. `badKValueFallsBackToHelp` — ["search", "/tmp/x", "вопрос", "--k", "abc"] → HelpCmd.
5. `unknownCommandFallsBackToHelp` — ["сломать"] → HelpCmd.
После: ./gradlew :memo-cli:test --rerun-tasks и ./gradlew :memo-cli:installDist — обе команды зелёные.
Проверь руками, что бинарь появился: ls memo-cli/build/install/memo-cli/bin/memo
Коммит: git add -A && git commit -m "cli: index/search/status/mcp-probe"
СТРОГИЕ ЗАПРЕТЫ:
- Не выводить план текстом; сразу правь файлы.
- Не трогать memo-core (ни src/main, ни src/test), кроме использования его публичного API.
- Не добавлять зависимости, кроме :memo-core.
- Не создавать другие файлы.