| 1 | # Cookbook: семантическая навигация через MCP (`get_code_navigation_context`) |
| 2 | |
| 3 | Контекст: [ADR 0039](../adr/0039-workspace-navigation-affordances.md). |
| 4 | |
| 5 | ## Зачем |
| 6 | |
| 7 | Команда `ide_execute_command` с `command_id` = `get_code_navigation_context` возвращает JSON со связанными файлами (`mode`: `related`) или компактным подграфом (`mode`: `subgraph`). Агенту нужны **стабильные имена видов связей** и **эхо фильтра**, чтобы не гадать, что реально применилось после пресета и `include_kinds` / `exclude_kinds`. |
| 8 | |
| 9 | ## Виды связей (канон) |
| 10 | |
| 11 | `partial_peer`, `project_peer`, `xaml_codebehind_pair`, `test_counterpart`, `same_namespace`, `same_directory`. |
| 12 | |
| 13 | ## Базовые пресеты (бандл) и overlay в `settings.toml` |
| 14 | |
| 15 | **Шипнутый файл** `CodeNavigation/presets.toml` рядом с `CascadeIDE.exe` задаёт пресеты по умолчанию (`peers_only`, `no_namespace_noise`, `tests_and_peers`, `structure_only`), по тому же принципу, что `UiModes/` и темы; если файла нет, используется тот же текст из **встроенного ресурса** сборки. |
| 16 | |
| 17 | **Overlay репозитория** — опционально в **`.cascade/workspace.toml`** в корне решения: те же **`[[code_navigation.presets]]`**, merge по **`id`** поверх шипнутого бандла (как [ADR 0021](../adr/0021-pfd-mfd-cockpit-attention-model.md) для метрик UI). |
| 18 | |
| 19 | **Пользовательский overlay** — в `%LocalAppData%\CascadeIDE\settings.toml` (ADR 0028), секция **`[code_navigation]`** и массив таблиц **`[[code_navigation.presets]]`**: у каждой записи поля **`id`**, опционально **`include_kinds`** / **`exclude_kinds`** (массивы строк). Запись с тем же **`id`** **перекрывает** и бандл, и репо; новые **`id`** добавляются. Порядок слоёв: **бандл → `.cascade/workspace.toml` → settings**. |
| 20 | |
| 21 | Пример (как у `[[sources]]` в других конфигах — нативный TOML): |
| 22 | |
| 23 | ```toml |
| 24 | [[code_navigation.presets]] |
| 25 | id = "my_focus" |
| 26 | include_kinds = ["partial_peer", "project_peer"] |
| 27 | exclude_kinds = ["same_namespace"] |
| 28 | ``` |
| 29 | |
| 30 | ## Аргументы MCP |
| 31 | |
| 32 | | Аргумент | Назначение | |
| 33 | |----------|------------| |
| 34 | | `mode` | `related` или `subgraph` | |
| 35 | | `file_path` | Якорный файл; если не задан — текущий открытый в редакторе | |
| 36 | | `preset` | Имя пресета из `presets` (merge с явными списками см. ниже) | |
| 37 | | `include_kinds` | Явный белый список; если передан непустой — **перекрывает** include из пресета | |
| 38 | | `exclude_kinds` | Объединяется с exclude пресета (дедуп по канону), если оба заданы | |
| 39 | |
| 40 | Неизвестное имя пресета или ошибка в данных пресетов → JSON с `error`: `bad_preset`. |
| 41 | |
| 42 | ## Эхо фильтра в ответе |
| 43 | |
| 44 | В режимах `related` и `subgraph` в JSON есть объект **`kind_filter`**: |
| 45 | |
| 46 | - `preset` — какой пресет запрашивали (или `null`) |
| 47 | - `include_kinds_effective` / `exclude_kinds_effective` — **канонические** списки после merge и нормализации (пустой exclude — `[]`) |
| 48 | |
| 49 | Так агент видит эффективный фильтр без повторного парсинга настроек. |
| 50 | |
| 51 | ## Режим `subgraph` |
| 52 | |
| 53 | - У **узла** поле **`kind`** — семантический вид связи с якорем (не общее слово `related`). |
| 54 | - У **ребра** поле **`related_kind`** — вид связи для этой пары. |
| 55 | |
| 56 | Используй это, чтобы отличать, например, `project_peer` от `same_namespace`. |
| 57 | |
| 58 | ## Минимальные примеры вызова |
| 59 | |
| 60 | Только пресет: |
| 61 | |
| 62 | ```json |
| 63 | { "command_id": "get_code_navigation_context", "args": { "mode": "related", "preset": "no_namespace_noise" } } |
| 64 | ``` |
| 65 | |
| 66 | Якорь + явный exclude поверх дефолтного пресета (exclude в запросе объединяется с пресетом, если пресет задаёт exclude): |
| 67 | |
| 68 | ```json |
| 69 | { |
| 70 | "mode": "related", |
| 71 | "file_path": "D:/repo/src/Foo.cs", |
| 72 | "preset": "tests_and_peers", |
| 73 | "exclude_kinds": ["same_directory"] |
| 74 | } |
| 75 | ``` |
| 76 | |
| 77 | Подграф с капами: |
| 78 | |
| 79 | ```json |
| 80 | { "mode": "subgraph", "max_nodes": 16, "max_edges": 32 } |
| 81 | ``` |
| 82 | |