# ask-user-question

## Назначение

`ask-user-question` дает агенту human-in-the-loop primitive: агент может задать пользователю один или несколько OMP-compatible вопросов через UI и получить structured answer. Extension нужен для случаев, где продолжать без выбора человека нельзя или небезопасно.

## Почему он есть в проекте

Проекту нужна явная граница между автономной работой агента и решениями пользователя. OMP уже реализует правильный contract для такого выбора: `questions[]`, `recommended`, `multi` и автоматический `Other`. Поэтому локальная версия больше не считается самостоятельным product design: она портирует OMP contract в `miloc-pi` и держит старый `askUserQuestion` только как compatibility alias.

## Пользовательская поверхность

- Агент вызывает primary tool `ask`, когда ему нужен ответ от пользователя. Параметр `questions` содержит один или несколько вопросов с `id`, `question`, `options`, optional `multi` и optional `recommended`.
- UI автоматически добавляет `Other (type your own)`, поэтому caller не должен передавать этот вариант сам.
- Legacy tool `askUserQuestion` сохранен для старых callers. Он преобразует старую схему `question`/`kind`/`options` в новый `ask` flow и сохраняет redaction behavior для `sensitivity=secret`.
- Extension не регистрирует slash-команду: default package surface exposes only the tool/API path, чтобы QA-команда не засоряла пользовательский command list.

## Как работает по коду

Entrypoint `extensions/ask-user-question/index.ts` регистрирует TypeBox-backed tool `ask` и compatibility tool `askUserQuestion`. Handler валидирует параметры через `_shared/validation.validateParams`, затем вызывает OMP-compatible flow.

Primary `ask` использует OMP-shaped schema: single question возвращает `selectedOptions` и optional `customInput`, multi-question возвращает `details.results[]` и OMP-style text summary вида `id: value`, `id: [a, b]` или `id: "custom"`. `recommended` добавляет UI suffix ` (Recommended)`, который затем снимается из result. Для `multi=true` adapter показывает checkbox-style select-loop с `[ ]`, `[x]`, `Done selecting` и `Other (type your own)`. `Other (type your own)` открывает editor. Legacy `askUserQuestion` после ответа применяет `_shared/redaction.redactForSensitivity`: для `secret` значение не возвращается в `details.value`, а visible answer редактируется.

Extension пишет только developer event `ask:answered`. Постоянного состояния нет, а manifest запрашивает только UI permissions, нужные для вопроса.

- Entrypoint: `./extensions/ask-user-question/index.ts`
- Manifest: `extensions/ask-user-question/manifest.json`
- Commands: none
- Tools: `ask`, `askUserQuestion`
- Hooks: none
- Permissions: fs.read=none, fs.write=none, subprocess=none, network=none, browser=false, models=false, ui=`select`, `input`, `editor`
- State: постоянное состояние не используется; extension только пишет developer event `ask:answered`.
- Review: status=reviewed, source=copy-after-audit, reviewedBy=miloc-pi, reviewedAt=2026-06-01, risk=medium

## Ограничения и риски

Unit smoke покрывает OMP-compatible single question, checkbox-style multi-select loop, multi-question, `Other` input и legacy redaction; E2E proof покрывает default package загрузку и local tool matrix. UI-поведение еще не является полноценным OMP TUI: local adapter теперь показывает checkbox labels через обычный select, но это еще не настоящий OMP renderer с left/right navigation между вопросами. Этот gap блокирует заявление о полной OMP TUI parity, но не блокирует default tool/API wrapper.

## Решение

Решение: `compat-wrapper`, active by default. Extension использует OMP-compatible `ask` contract, держит `askUserQuestion` только как legacy alias и остается ограниченным adapter-ом без full OMP renderer/navigation parity.
