| 1 | # ADR 0016: Внешний агент по Agent Client Protocol (stdio, Cursor CLI) |
| 2 | |
| 3 | **Статус:** Accepted · Implemented |
| 4 | **Дата:** 2026-04-05 |
| 5 | ## Связанные ADR |
| 6 | |
| 7 | | ADR | Роль | |
| 8 | |-----|------| |
| 9 | | [0008](0008-mcp-contracts-and-testable-infrastructure.md) | MCP — **другой** контур: сервер инструментов IDE; не путать с ACP | |
| 10 | |
| 11 | ### Вне ADR |
| 12 | |
| 13 | | Документ | Роль | |
| 14 | |----------|------| |
| 15 | | [note-acp-cascade-cursor-v1.md](../ui-ux/note-acp-cascade-cursor-v1.md) | терминология и ссылки на спецификацию | |
| 16 | | [concept-pfd-mfd-cascade-v1.md](../ui-ux/concept-pfd-mfd-cascade-v1.md) | concept pfd mfd cascade v1 | |
| 17 | |
| 18 | ### Снимок реализации |
| 19 | |
| 20 | | Элемент | Значение | |
| 21 | |---------|----------| |
| 22 | | — | Cursor ACP / stdio в чате и настройках; ортогонально MCP — см. текст | |
| 23 | |
| 24 | --- |
| 25 | ## Контекст |
| 26 | |
| 27 | Нужна связь встроенного чата CascadeIDE с **внешним** агентом (в первую очередь **Cursor** через официальный CLI и режим ACP), без встраивания UI Cursor и без собственного провода «с нуля». |
| 28 | |
| 29 | **Agent Client Protocol (ACP)** — открытый контракт клиент↔агент (JSON-RPC по строкам, типичный транспорт **stdio**). PoC пройден: ответы в чате, русский текст, сессия и обратные вызовы к IDE (fs, terminal) по спецификации. |
| 30 | |
| 31 | ## Решение |
| 32 | |
| 33 | 1. **Транспорт:** подпроцесс `cursor-agent` (или эквивалент из пакета dist-package) с аргументом **`acp`**, **stdin/stdout** для протокола, без консольного окна (`CreateNoWindow`), перенаправление потоков. |
| 34 | |
| 35 | 2. **Кодировка:** для **Windows** явно задавать **UTF-8** для перенаправленных stdin/stdout/stderr процесса агента (и для дочерних процессов ACP-terminal), иначе ответы на русском декодируются в OEM и дают «кракозябры». |
| 36 | |
| 37 | 3. **Клиентский SDK:** библиотека **AgentClientProtocol** (community, upstream [acp-csharp](https://github.com/nuskey8/acp-csharp)) — **вендор** в `externals/acp-csharp/` как исходники, подключаются через `ProjectReference`. Исходники под `externals/**/*.cs` **не** компилируются в основной сборке IDE (`Compile Remove` в `CascadeIDE.csproj`), чтобы вложенный sandbox с top-level `Main` не перехватывал точку входа приложения. |
| 38 | |
| 39 | 4. **Интеграция в продукт:** отдельный провайдер чата (**Cursor ACP**), настройка пути к `cursor-agent.cmd` или к каталогу с `dist-package`; жизненный цикл сессии ACP и зеркалирование terminal/fs — в `Services/CursorAcp/`. |
| 40 | |
| 41 | 5. **Аутентификация Cursor:** не интерактивно внутри WinExe-чата при первом запуске; пользователь проходит **`agent login` / API key** в обычном терминале или через переменные окружения (как в документации Cursor). Ошибки агента до UI — по мере развития можно дублировать stderr в чат/лог (не часть этого ADR). |
| 42 | |
| 43 | 6. **Границы:** ACP — про **диалог с внешним агентом**. MCP-сервер IDE (`--mcp-stdio`, инструменты для агента) остаётся отдельным контуром ([0008](0008-mcp-contracts-and-testable-infrastructure.md)); объединение сценариев — последующими итерациями. |
| 44 | |
| 45 | ## Последствия |
| 46 | |
| 47 | - Обновления upstream `acp-csharp` — осознанный merge/вендоринг; при смене major спецификации ACP — проверка совместимости с `cursor-agent`. |
| 48 | - Зависимость от формата CLI Cursor (аргумент `acp`); при изменениях документации Cursor — регрессия вручную или смоук-сценарий. |
| 49 | - Дублирование типов при ошибочном включении исходников SDK и ссылки на пакет — предотвращается `Compile Remove` для `externals`. |
| 50 | |
| 51 | ## Отклонённые альтернативы |
| 52 | |
| 53 | - **Только Ollama / только локальные LLM без ACP** — остаётся другим провайдером; не покрывает сценарий «тот же агент, что в Cursor». |
| 54 | - **Свой бинарный протокол поверх stdio** — отклонён в пользу стандарта ACP и готового клиентского SDK. |
| 55 | - **Встраивание webview Cursor** — вне scope десктопного клиента ACP. |
| 56 | |
| 57 | ## Обсуждение (не блокирует Accepted) |
| 58 | |
| 59 | - Подмодуль вместо вендоринга `externals/acp-csharp` — возможна миграция при стабилизации процесса обновлений. |
| 60 | - Вывод stderr агента в UI чата при ошибках и «Authentication required». |
| 61 | |