refactor(mcp): declaration:true + вывод DocmostClientLike из реального типа клиента — восстановленный отложенный долг #294 #446

Open
opened 2026-07-10 06:51:00 +03:00 by agent_vscode · 0 comments
Collaborator

Зачем (история потерянного долга)

В #294 вторая половина фикса — «вывод DocmostClientLike из реального типа (type-only import / генерация), а не копировать руками» — была явно помечена « отложены… делать инкрементально». Реестр спеков сделали (PR #367), ишью закрыли 05.07 — и отложенная половина исчезла из трекера. Это ишью её восстанавливает.

Текущее состояние (почему это источник багов)

  • @docmost/mcp не отдаёт .d.ts: в packages/mcp/tsconfig.json нет declaration, в package.json нет types-экспорта. Через ESM(mcp)/CJS(server)-границу тип импортировать нечего.
  • Поэтому DocmostClientLike (apps/server/src/core/ai-chat/tools/docmost-client.loader.ts) — ручное зеркало ~45 сигнатур из packages/mcp/src/client.ts. Рядом второе ручное зеркало — интерфейс SharedToolSpec (копия одноимённого из tool-specs.ts).
  • Guard HOST_CONTRACT_METHODS (packages/mcp/test/unit/client-host-contract.test.mjs) проверяет только имена, не сигнатуры (в шапке теста об этом сказано прямо) — и сам является третьей ручной копией тех же имён.
  • In-app execute-тела вызывают клиент позиционно (client.drawioGet(pageId, node, format ?? 'xml')) — перестановка/смена типа параметра в client.ts доезжает до продакшена как рантайм-ошибка без единого сигнала на компиляции или в тестах.

Механика

  1. "declaration": true (+declarationMap) в packages/mcp/tsconfig.json; types в exports package.json.
  2. DocmostClientLikeimport type { DocmostClient } (или деривация Pick<DocmostClient, …>); ручное зеркало удалить.
  3. Ручную копию SharedToolSpec в loader'е → type-only import из пакета.
  4. Тест HOST_CONTRACT_METHODS удалить целиком — его работу берёт на себя tsc.
  5. Известный блокер из #294: точные возвращаемые типы ломают loose-касты ((result?.data ?? {}) as {…}) в ai-chat-tools.service.ts. Мигрировать инкрементально: сначала satisfies DocmostClientContract рядом с существующим интерфейсом (компилятор сверяет, ничего не ломая), затем замена кастов по одному.

Критерии приёмки

  • В apps/server ноль ручных копий типов из @docmost/mcp (grep по DocmostClientLike, локальному SharedToolSpec).
  • Перестановка параметров любого метода client.tsошибка компиляции сервера, не рантайм-падение тула.
  • client-host-contract.test.mjs удалён (имена + сигнатуры проверяет tsc).

Связано: #294 (источник долга), #416 (роадмап), #445 (execute-в-спеке — использует типизированный DocmostClientLike в сигнатуре execute).

## Зачем (история потерянного долга) В #294 вторая половина фикса — «**вывод `DocmostClientLike` из реального типа** (type-only import / генерация), а не копировать руками» — была явно помечена «⏳ отложены… делать инкрементально». Реестр спеков сделали (PR #367), ишью закрыли 05.07 — и отложенная половина **исчезла из трекера**. Это ишью её восстанавливает. ## Текущее состояние (почему это источник багов) - `@docmost/mcp` не отдаёт `.d.ts`: в `packages/mcp/tsconfig.json` нет `declaration`, в `package.json` нет `types`-экспорта. Через ESM(mcp)/CJS(server)-границу тип импортировать нечего. - Поэтому `DocmostClientLike` (`apps/server/src/core/ai-chat/tools/docmost-client.loader.ts`) — **ручное зеркало ~45 сигнатур** из `packages/mcp/src/client.ts`. Рядом второе ручное зеркало — интерфейс `SharedToolSpec` (копия одноимённого из `tool-specs.ts`). - Guard `HOST_CONTRACT_METHODS` (`packages/mcp/test/unit/client-host-contract.test.mjs`) проверяет **только имена, не сигнатуры** (в шапке теста об этом сказано прямо) — и сам является третьей ручной копией тех же имён. - In-app execute-тела вызывают клиент **позиционно** (`client.drawioGet(pageId, node, format ?? 'xml')`) — перестановка/смена типа параметра в `client.ts` доезжает до продакшена как рантайм-ошибка без единого сигнала на компиляции или в тестах. ## Механика 1. `"declaration": true` (+`declarationMap`) в `packages/mcp/tsconfig.json`; `types` в `exports` `package.json`. 2. `DocmostClientLike` → `import type { DocmostClient }` (или деривация `Pick<DocmostClient, …>`); ручное зеркало удалить. 3. Ручную копию `SharedToolSpec` в loader'е → type-only import из пакета. 4. Тест `HOST_CONTRACT_METHODS` удалить целиком — его работу берёт на себя tsc. 5. Известный блокер из #294: точные возвращаемые типы ломают loose-касты (`(result?.data ?? {}) as {…}`) в `ai-chat-tools.service.ts`. Мигрировать инкрементально: сначала `satisfies DocmostClientContract` рядом с существующим интерфейсом (компилятор сверяет, ничего не ломая), затем замена кастов по одному. ## Критерии приёмки - В `apps/server` ноль ручных копий типов из `@docmost/mcp` (grep по `DocmostClientLike`, локальному `SharedToolSpec`). - Перестановка параметров любого метода `client.ts` → **ошибка компиляции** сервера, не рантайм-падение тула. - `client-host-contract.test.mjs` удалён (имена + сигнатуры проверяет tsc). Связано: #294 (источник долга), #416 (роадмап), #445 (execute-в-спеке — использует типизированный `DocmostClientLike` в сигнатуре `execute`).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#446