ADR 0119: Слэш-команды в чате — unified command line (Intercom + IDE)¶
Статус: Accepted · Implemented
Дата: 2026-05-17
Обновлено: 2026-05-17 — расширение до IDE-глаголов (/build run, /test run, /debug launch); autocomplete обязателен. § История
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0080 | Чат как Intercom — центральный канал, не «окно к боту» |
| 0072 | Topic cards, overview/detail, intent-first навигация (Melody/Chords) |
| 0096 | Содержимое карточек, spine, carry-forward в тред |
| 0013 | Палитра и discoverability — слэши дополняют, не заменяют |
| 0030 | Канон command_id, реестр, паритет MCP |
| 0060 | CascadeChord, Command Melody c: — ортогональный вход |
| 0008 | Паритет агента: те же эффекты через ide_execute_command |
| 0048 | Что уходит агенту vs локальное действие IDE |
| 0057 | Snapshot/layout после смены состояния VM |
| 0116 | Дерево сессии, steer — не смешивать со слэш-парсером |
| 0002 | /build, /test, /debug — те же command_id, что агент через MCP |
| 0018 | Канон имён IdeCommands для проекции каталога |
| 0120 | Intercom в Forward — слэши как основной CLI сессии |
| 0124 | Параметрический слэш: /editor line select|delete (паритет c:els / c:eld) |
| 0125 | Workspace/file: /file open, /solution new, динамические подсказки по файлам solution |
| 0126 | kind=report: /topic//spine list|tree; compact chrome status |
Вне ADR¶
| Документ | Роль |
|---|---|
| MCP-PROTOCOL.md | ide_execute_command, send_chat, chat_* MCP |
| intent-melody-language-v1.md | Грамматика c: — не грамматика / в чате |
| intercom-ux-reference-slack-mattermost-v1.md | Slack/MM как вдохновение для composer и слэшей; границы vs внешний чат 0080 §5 |
Резюме¶
ChatInput— альтернативная command line IDE: можно не уходить из чата для Intercom и для частых действий (/build run,/test run,/debug launch,/card …).- Слэш →
command_id(0030); каталог — проекция реестра на читаемые slash-пути (/build run,/overview), не второй исполнитель в VM. - Discoverability — через autocomplete (иерархия namespace → action, подсказки,
/help), не через короткие мнемоники вроде/br(сжатые формы — слойc:Melody и аккорды, 0060). - Autocomplete обязателен — без него расширенный каталог не принимается.
- Палитра, Melody
c:и аккорды остаются; слэш — равноправный вход для тех, кто уже в поле сообщения (0013). - Внедрение по фазам: Intercom-глаголы → IDE namespaces → расширение из палитры.
Контекст¶
Intercom в CIDE (0080) всё чаще — центральная поверхность: диалог с агентом, картотека тем (0072), product spine (0096), уточнения (0031).
Для power-user уже есть:
- палитра и fuzzy-поиск (0013);
- глобальные хоткеи и CascadeChord (0060);
- Command Melody
c:в палитре (0112); - chat navigation intents с паритетом в MCP (
chat_show_thread_overview,chat_open_selected_thread, … — 0072 §4).
Этого недостаточно, когда оператор уже печатает в поле сообщения и ожидает модель «как в Slack/Discord» или CLI внутри чата:
- Intercom:
/card Новая тема,/overview,/spine focus=…; - IDE:
/build run,/test run,/debug launch— без переключения на палитру, тулбар и без обязательных аккордов.
Продуктовая гипотеза: если Intercom — центральная поверхность, чат становится единой точкой управления сессией, а не только каналом к агенту.
Проблема¶
- Разрыв discoverability: команды чата есть в реестре и MCP, но не видны в контексте ввода, где живёт основной поток мысли.
- Риск дублирования: ad-hoc парсинг
/cardвSendChatAsyncобходит intent-слой 0072 §5 и плодит расхождение с pointer/MCP. - Смешение с агентом: без правила «слэш = локально» строка
/exportможет уехать в LLM как обычный текст. - Конфликт префиксов:
c:зарезервирован за палитрой/Melody (0112);/— отдельное пространство только в ChatInput.
Решение¶
1. ChatInput как unified command line (слэш-префикс)¶
- Строка, начинающаяся с
/(после trim), трактуется как слэш-команда (одно- или двухуровневая, см. §4). - Разбор при отправке (Enter) и инкрементально для autocomplete (§6) — autocomplete не опционален для принятого объёма каталога.
- Не перехватывать
/в середине обычного сообщения; обычный диалог с агентом — без слэша.
2. Intent-first: слэш → command_id → VM → snapshot¶
Инвариант (расширение 0072 §5):
ChatInput (/verb args…) → ChatSlashCommandParser → command_id (+ args)
→ IdeMcpCommandExecutor / ChatPanel handlers (как palette/MCP)
→ ChatPanelViewModel state → ChatSurfaceCompositor → Skia render
- Слэш-команда не меняет Skia напрямую и не читает hit-target геометрию.
- Pointer, Melody, Chords, палитра, MCP и слэш сходятся в одном
command_id, где это возможно.
3. Режимы исполнения¶
| Режим | Поведение | Пример |
|---|---|---|
| Local | Сообщение не уходит агенту; выполняется command_id; поле ввода очищается (или остаётся статус одной строкой). |
/overview, /export |
| Local + echo | Локально + короткая системная запись в ленте (опционально, v1+). | /card с подтверждением «создана тема …» |
| Reject | Неизвестный verb — ошибка в UI, без отправки агенту. | /foo |
| Pass-through (запрещено по умолчанию) | Отправить текст агенту как есть. | Не использовать для нераспознанных / |
Правило v1: нераспознанная строка с ведущим / → Reject с подсказкой «неизвестная команда, Tab — список».
4. Грамматика v1¶
Два уровня (как «namespace / action»):
slash_line = "/" head (WS tail)? WS? ;
head = flat_verb | namespace ;
flat_verb = letter { letter | digit | "-" } ; (* overview, card, help, export *)
namespace = letter { letter | digit } ; (* build, test, debug, git, chat *)
tail = action (WS arg_token)* | arg_tail ; (* run | launch | … OR rest for flat *)
action = letter { letter | digit | "-" } ;
arg_tail = { arg_token } ; (* /card Имя темы — всё после head *)
arg_token = quoted_string | bare_token ;
Примеры:
| Ввод | Разбор |
|---|---|
/overview |
flat: overview |
/card ADR 0119 |
flat: card, args: ADR 0119 |
/build run |
namespace: build, action: run |
/test run |
namespace: test, action: run |
/debug launch |
namespace: debug, action: launch |
/editor line select 5 10 |
namespace: editor, action: line, subAction: select, args: 5 10 — 0124 |
- Регистр: case-insensitive.
- Три уровня (
/editor line select) — исключение для параметрического редактора; не общий прецедент для всех namespace (0124). - Именованные аргументы (
configuration=Release) — v2; v1 — позиционный хвост где нужен.
5. Каталог: проекция на command_id, не второй реестр¶
5a. Источник правды¶
- Исполнение — только через существующий контур
ide_execute_command/IdeMcpCommandExecutor(0030, 0008). - Каталог слэшей (
ChatSlashCommandCatalog) — отображение (slash-путь →command_id+ шаблон args), собираемое из: - Curated таблицы в коде (v1);
- v2+ — проекция подмножества
IdeCommandPaletteCatalog/ метаданныхIdeCommands(заголовок палитры → не обязан совпадать со слэшем; slash-путь задаётся явно). - Не путать с Melody: в каталоге нет отдельных записей «2–3 буквы» (
/br,/tr) как сокращений кnamespace action— оператор выбирает/build→runиз autocomplete или вводит полную форму. - Запрещено: дублировать логику
dotnet build/ тестов / отладки вChatPanelViewModel.
5b. Intercom (flat verbs) — фаза A¶
| Слэш | command_id |
Примечание |
|---|---|---|
/overview |
chat_show_thread_overview |
|
/open |
chat_open_selected_thread |
|
/card <title> |
новый или fork_chat_thread + title |
продуктово |
/spine … |
chat_set_product_spine |
хвост → focus / milestones |
/spine-toggle |
chat_toggle_product_spine_in_agent_context |
|
/export |
chat_export_readable |
|
/help |
локальный каталог | kind=help, без MCP |
/topic list | /topic tree |
локальный отчёт | kind=report, 0126 |
/topic open |
открыть detail темы | kind=intercom, 0126 |
/spine list | /spine tree |
локальный отчёт | kind=report, 0126 |
/topic cards |
картотека тем (overview) | kind=intercom, 0126 |
/spine open |
то же, что /topic cards |
kind=intercom, 0126 |
5c. IDE namespaces — фаза B (не уходя из чата)¶
| Слэш | command_id |
Примечание |
|---|---|---|
/build run |
build или build_structured |
structured JSON в ленту/панель — политика UI |
/build ui |
build_solution_ui |
тулбарный путь, текст в output |
/test run |
run_tests |
|
/test affected |
run_affected_tests |
опционально changed_paths из git |
/debug launch |
debug_launch |
target из launch profile / текущий |
/debug continue |
debug_start_or_continue (UI id) | если нет в IdeCommands — добавить константу |
/git status |
git_status |
фаза C, когда есть в реестре |
Дальнейшие namespace (nav, index, palette) — по мере discoverability, не «весь IdeCommands одним махом».
Паритет: агент вызывает тот же build / run_tests / debug_launch через MCP; оператор — /build run в чате.
6. Discoverability: autocomplete и help (обязательно)¶
Без autocomplete расширение до /build, /test, … не принимается — оператор не обязан помнить namespace и action и не должен полагаться на сжатые слэш-мнемоники (в отличие от c: в палитре).
Поведение UI (v1 минимум):
| Шаг ввода | Popup показывает |
|---|---|
/ |
top-level: flat verbs + namespaces (build, test, debug, card, …) |
/build |
actions: run, ui, … + однострочное описание |
/build r |
фильтр по префиксу (run) |
| неизвестный префикс | «нет совпадений» + ссылка на /help |
Tab— дополнить токен / выбрать highlighted; ↑↓ — навигация; Esc — закрыть popup, не очищая строку.- Под каждым пунктом — краткий help (из
IdeCommandsdoc / curated catalog) и опционально hotkey из TOML, если есть (0030). /helpи/help build— текстовый/интерактивный список в ленте или overlay (local).- Источник v1:
ChatSlashCommandCatalogв коде; v2 — TOMLchat-slash-aliases.tomlпо аналогии 0109.
7. Связь с агентом и spine (0096)¶
- Слэш-команды по умолчанию local — не расширяют промпт агента.
/spine-toggleи/spineменяют метаданные сессии; включение spine в контекст агента — явное (0096 §4), не побочный эффект любой слэш-команды.- Carry-forward в тред по-прежнему обычным сообщением или отдельным intent; слэш не обязан генерировать текст для агента.
8. Non-goals и границы¶
Non-goals:
- Полная замена Command Palette: fuzzy-поиск по всем командам без структуры namespace остаётся в палитре.
- Автоматическое 1:1 «каждая строка палитры = слэш» без curated aliases и UX-фильтра (слишком шумно).
- Слэш-команды в других полях (терминал, редактор, палитра) — только
ChatInput. - Плагины с произвольными verb без записи в каталог /
command_id. - Pass-through нераспознанного
/…агенту. - Короткие слэш-алиасы (2–3 символа, «мелодия после
/»):/brвместо/build run, автогенерация из [0109](0109-declarative-parametric-melody-catalog-toml-and-code-binders.md) без отдельного slash-пути — discoverability только **иерархический autocomplete** и читаемыеnamespace/action` / flat verbs.
В scope (осознанно):
- Альтернативный вход в те же IDE-действия, что палитра/аккорды/MCP — в т.ч.
/build run,/test run,/debug launch. - Оператор может не уходить из чата для частого цикла «спросил агента → собрал → прогнал тесты → отладил».
Ортогональность входов (сводка)¶
| Вход | Где | Префикс / форма |
|---|---|---|
| Палитра | overlay | fuzzy, c: Melody |
| Hotkeys / Chord | глобально | TOML → command_id |
| Chat Melody aliases | палитра / intents | ato, atb, … (0072) |
| Chat slash | ChatInput |
/verb или /namespace action (этот ADR) |
| MCP | агент | ide_execute_command |
Диаграмма¶
flowchart TD
input[ChatInput]
input -->|starts with /| parser[ChatSlashCommandParser]
input -->|normal text| agent[SendToAgent]
parser -->|known verb| cmd[command_id handler]
parser -->|unknown| err[Inline error + help]
cmd --> vm[ChatPanelViewModel]
vm --> snap[ChatSurfaceSnapshot]
snap --> skia[SkiaChatSurfaceControl]
palette[Palette Melody Chords MCP] --> cmd
Якоря реализации (план)¶
| Компонент | Роль |
|---|---|
Features/Chat/ChatSlashCommandCatalog.cs (новый) |
verb → descriptor (command_id, help, arg hint) |
Features/Chat/ChatSlashCommandParser.cs (новый) |
разбор строки, валидация |
ChatPanelViewModel |
вызов парсера в SendChatAsync до ApplyProductSpineToOutboundMessage / ACP |
IdeMcpCommandExecutor |
исполнение тех же command_id, что MCP |
ChatPanelView.axaml |
popup autocomplete (обязателен до фазы B) |
ChatSlashAutocompleteControl (новый) |
иерархический popup, привязка к ChatInput |
IdeCommands |
новые command_id только если нет покрытия (chat_create_or_rename_topic) |
Порядок внедрения:
| Фаза | Содержание | Критерий готовности |
|---|---|---|
| A | Parser (flat + namespace/action), catalog Intercom, local execution | /overview, /export не уходят агенту |
| A′ | Autocomplete для flat + namespace list | после / и /build есть подсказки |
| B | IDE: /build run, /test run, /debug launch → command_id |
паритет с MCP build / run_tests / debug_launch |
| C | Расширение каталога (/git status, /nav, проекция из палитры) |
по discoverability + autocomplete, не big-bang |
Тесты: parser unit-tests; интеграция «слэш local»; снапшоты каталога help.
Отклонённые альтернативы¶
- Парсить слэши в палитре (
/cardв Command Palette) — смешивает overlay и Intercom; отвергнуто. - Отдельные MCP-only команды без
command_id— ломает 0030; отвергнуто. - Отправлять нераспознанный
/агенту — шум и утечки; отвергнуто. - Короткие слэши как у Melody (
/br= build run) — дублируетc:/ аккорды, коллизии и второй парсер; discoverability в Intercom — autocomplete, не мнемоники; отвергнуто.
История изменений¶
| Дата | Изменение |
|---|---|
| 2026-05-17 | Proposed: слэш-команды в ChatInput, каталог v1, intent-first, non-goals. |
| 2026-05-17 | Расширение: unified command line — IDE namespaces (/build run, /test run, /debug launch); autocomplete обязателен; фазы A–C. |
| 2026-05-17 | Уточнение: discoverability слэша — autocomplete; короткие алиасы (/br) и «мелодия после /» — non-goal (сжатие — c: Melody). |
| 2026-05-17 | Accepted · Implemented: фазы A, A′, B (ChatSlashCommand*, autocomplete, IDE namespaces); фаза C — backlog. |
| 2026-05-17 | См. 0124: полный slash-паритет каталога IML (wire_class, /editor line …, /portal open). |