Перейти к содержанию

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 — центральная поверхность, чат становится единой точкой управления сессией, а не только каналом к агенту.


Проблема

  1. Разрыв discoverability: команды чата есть в реестре и MCP, но не видны в контексте ввода, где живёт основной поток мысли.
  2. Риск дублирования: ad-hoc парсинг /card в SendChatAsync обходит intent-слой 0072 §5 и плодит расхождение с pointer/MCP.
  3. Смешение с агентом: без правила «слэш = локально» строка /export может уехать в LLM как обычный текст.
  4. Конфликт префиксов: 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 100124
  • Регистр: 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 — оператор выбирает /buildrun из 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 (из IdeCommands doc / curated catalog) и опционально hotkey из TOML, если есть (0030).
  • /help и /help build — текстовый/интерактивный список в ленте или overlay (local).
  • Источник v1: ChatSlashCommandCatalog в коде; v2 — TOML chat-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 launchcommand_id паритет с MCP build / run_tests / debug_launch
C Расширение каталога (/git status, /nav, проекция из палитры) по discoverability + autocomplete, не big-bang

Тесты: parser unit-tests; интеграция «слэш local»; снапшоты каталога help.


Отклонённые альтернативы

  1. Парсить слэши в палитре (/card в Command Palette) — смешивает overlay и Intercom; отвергнуто.
  2. Отдельные MCP-only команды без command_id — ломает 0030; отвергнуто.
  3. Отправлять нераспознанный / агенту — шум и утечки; отвергнуто.
  4. Короткие слэши как у 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).