refactor(tools): генерировать инвентарь SERVER_INSTRUCTIONS из реестра + guard имён тулов (#448) #460
Open
agent_coder
wants to merge 5 commits from
refactor/448-generate-inventory into develop
pull from: refactor/448-generate-inventory
merge into: vvzvlad:develop
vvzvlad:main
vvzvlad:feat/424-drawio-rules
vvzvlad:fix/409-invalid-node-validation
vvzvlad:refactor/445-execute-mapping
vvzvlad:refactor/446-derive-client-types
vvzvlad:fix/447-registry-stamp-ci
vvzvlad:fix/444-agent-loop-guards
vvzvlad:fix/396-sendnow-detached-run
vvzvlad:fix/452-immutable-cache-control
vvzvlad:develop
vvzvlad:docs/footnote-authoring-comment-cleanup
vvzvlad:feat/437-error-diagnostics
vvzvlad:fix/442-cursor-pagination
vvzvlad:feat/419-footnote-normalize
vvzvlad:perf/399-comment-resolve-async
vvzvlad:perf/435-collab-token-cache
vvzvlad:perf/344-background-rerenders
vvzvlad:perf/348-backend-lowhanging
vvzvlad:feat/423-drawio-crud
vvzvlad:perf/401-collab-hotpath
vvzvlad:feat/430-live-reconnect
vvzvlad:perf/400-collab-session
vvzvlad:refactor/414-dedup-node-ops
vvzvlad:feat/417-new-comments-signal
vvzvlad:feat/408-createcomment-hints
vvzvlad:feat/407-persist-tool-errors
vvzvlad:feat/420-footnote-render
vvzvlad:dummy-review/mcp-hang-fix
vvzvlad:dummy-review/mcp-hang-base
vvzvlad:feat/381-resumable-sse-pr1
vvzvlad:feat/git-sync-2
vvzvlad:docs/agents-workspace-build-order
vvzvlad:feature/offline-sync
vvzvlad:perf/342-code-splitting
vvzvlad:perf/346-compression-cache
vvzvlad:feat/196-multi-cursor
vvzvlad:feat/370-page-versioning
vvzvlad:perf/343-typing-latency
vvzvlad:docs/how-to-test
vvzvlad:fix/ai-sdk-partial-output-oom
vvzvlad:test/351-generative-converter
vvzvlad:feat/371-roles-catalog
vvzvlad:refactor/345-server-converter
vvzvlad:refactor/294-spec-registry-cont
vvzvlad:fix/363-migration-order
vvzvlad:fix/e2e-callout-and-gate-build
vvzvlad:fix/docker-re2-toolchain
vvzvlad:feat/git-sync
vvzvlad:fix/media-roundtrip-stability
vvzvlad:fix/340-comment-panel-perf
vvzvlad:fix/332-deferred-tools
vvzvlad:fix/329-ephemeral-suggestions
vvzvlad:fix/330-search-in-page
vvzvlad:fix/328-resolved-anchor-spam
vvzvlad:fix/331-intraline-diff
vvzvlad:fix/324-coverage-gate
vvzvlad:fix/325-mobile-390
vvzvlad:feat/293-A-git-sync-package
vvzvlad:feat/300-avatar-oklch
vvzvlad:fix/321-banner-mobile
vvzvlad:feat/300-avatar-colors
vvzvlad:feat/315-comment-suggestions
vvzvlad:feat/scroll-restore-stable-wait
vvzvlad:feat/300-agent-avatar-stack
vvzvlad:feat/300-avatar-polish
vvzvlad:refactor/294-tool-spec-registry
vvzvlad:feat/scroll-restore-ux
vvzvlad:fix/responsive-tablet-sidebar
vvzvlad:feature/ai-chat-page-change-observability
vvzvlad:image-inline-center
vvzvlad:fix/283-short-remap-title
vvzvlad:fix/283-slash-layout
vvzvlad:image-inline-row
vvzvlad:feat/276-ai-chat-dock
vvzvlad:fix/269-table-menu-refocus
vvzvlad:docs/dev-stand-guide
vvzvlad:feat/266-scroll-position
vvzvlad:fix/260-collab-docname-slugid
vvzvlad:test/244-phase2-tail
vvzvlad:fix/262-reindex-progress-realtime
vvzvlad:fix/258-changelog-compare-links
vvzvlad:fix/244-dataloss-bugs
vvzvlad:feat/246-spoiler
vvzvlad:feat/221-image-captions
vvzvlad:test/244-part-b
vvzvlad:feat/251-intentional-clear
vvzvlad:fix/embeddings-reindex-progress
vvzvlad:refactor/193-tool-spec-registry
vvzvlad:fix/255-ws-redis-adapter-leak
vvzvlad:fix/252-e2e-open-handles
vvzvlad:feat/229-catalog-yaml
vvzvlad:feat/243-blob-sandbox
vvzvlad:feat/228-inline-footnotes
vvzvlad:fix/qa-ui-bugs-216-218
vvzvlad:feature/agent-roles-catalog
vvzvlad:fix/share-alias-rename
vvzvlad:fix/ai-chat-empty-render
vvzvlad:feat/191-chat-doc-binding
vvzvlad:feat/201-temporary-notes
vvzvlad:feat/198-interrupt-agent
vvzvlad:feat/ai-chat-full-history
vvzvlad:feat/199-ai-generate-title
vvzvlad:feat/205-share-aliases
vvzvlad:batch/issues-189-187-170
vvzvlad:feat/170-mcp-test-button
vvzvlad:feat/189-context-badge
vvzvlad:feat/198-interrupt-agent-send-now
vvzvlad:fix/issues-190-159
vvzvlad:fix/ai-chat-new-chat-during-stream
vvzvlad:fix/ai-chat-stream-perf
vvzvlad:batch/issues-2026-06-25
vvzvlad:feat/ai-chat-persistent-history
vvzvlad:fix/ai-chat-copy-chat-wysiwyg
vvzvlad:fix/ai-stream-reset-resilience
vvzvlad:fix/ai-stream-undici-timeout
vvzvlad:fix/footnote-review-1227-followup
vvzvlad:fix/ai-chat-token-counter-realtime
vvzvlad:docs/manual-qa-test-plan
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4cb762b039 |
docs(mcp): обновить AGENTS.md + коммент под генерируемый инвентарь (ревью #460)
Две доковые правки по ревью: (1) AGENTS.md-буллет описывал ДО-#448 мир (ручная
правка SERVER_INSTRUCTIONS, enforced server-instructions.test.mjs, EXCEPTIONS) —
переписан: shared-спеки авто-обновляют генерируемый <tool_inventory>, только
inline-тул требует строки в INLINE_MCP_INVENTORY, enforced tool-inventory.test.mjs,
EXCEPTIONS больше нет; (2) коммент в server-instructions.ts называл гард окольно
('tool-specs.test.mjs's sibling test') → назван tool-inventory.test.mjs напрямую.
Единственная оставшаяся ссылка на удалённый тест устранена. Только доки/комменты.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
d0f99052cf |
refactor(tools): генерировать инвентарь SERVER_INSTRUCTIONS из реестра + guard имён тулов в промпте (#448)
Финальный линк Фазы 1б. Инвентарь тулов жил в 4 рукописных прозаических копиях (SERVER_INSTRUCTIONS под regex-тестом; <tool_catalog>; имена в ai-chat.prompt.ts без гарда; README) — роадмап #416 планировал 4 последовательных ручных правки этого текста (#411/#412/#413/#415). - SERVER_INSTRUCTIONS разбит (новый модуль server-instructions.ts): ROUTING_ PROSE (рукописные intent-подсказки «когда что» — осмысленно ручные, перенесены ДОСЛОВНО со всеми предостережениями: <=250 у create_comment, soft-delete у delete_page, baseHash у drawio_update, PUBLIC у share_page) + buildToolInventory() — генерирует <tool_inventory> из реестра (mcpName + purpose из catalogLine, группировка по TOOL_FAMILY, бакет OTHER ловит незамаппленное → тул нельзя тихо потерять) + 5 inline MCP-only (INLINE_MCP_INVENTORY). Детерминирован (семейства FAMILY_ORDER, имена localeCompare). regex-тест server-instructions удалён; структурные гарантии — в новом tool-inventory.test.mjs (точное членство множества сильнее старого \b-скрейпа). - Имена тулов в ai-chat.prompt.ts → через экспорт PROMPT_TOOL_NAMES; новый гард ai-chat.prompt.tool-names.spec.ts: каждое имя — реальный тул реестра, скан guidance-нот на camelCase-токены падает на несуществующем (escape- нейтрализация против ложных nThe-токенов). - INLINE_TOOL_TIERS уже содержал ровно 8 genuinely-inline тулов (после #445) — сжатие не потребовалось. Критерий: добавление/переименование спека меняет инвентарь БЕЗ правки прозы. Внутреннее ревью: APPROVE — фактическим прогоном подтверждено, что НИ ОДИН тул из старого SERVER_INSTRUCTIONS не выпал (диф старый-vs-новый пуст; добавился get_workspace, раньше прятавшийся в EXCEPTIONS); проза дословна; инвентарь полон/детерминирован/без фантомов; гард краснеет на обеих ветках провала. 613 node + 289 jest зелёные. Стоит на #445 — мержить последним в стопке 1б. README-каталоги вне обязательного скоупа (docs-скрипт) — в чек-лист #412. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
8c74659d91 |
refactor(tools): execute-маппинг в SHARED_TOOL_SPECS + автопроводка обоих хостов (#445)
Ядро Фазы 1б. Реестр (#294) шарил только метаданные (имя/схема/описание/tier), но НЕ execute-логику — у каждого shared-тула было ДВА рукописных execute-тела с копией маппинга аргументов (MCP registerShared в index.ts; in-app sharedTool в ai-chat-tools.service, зеркалящий MCP-транспорт вручную). Корень повторяющихся parity-багов ( |
||
|
|
fe5b6ecd8c |
refactor(mcp): вывести DocmostClientLike/SharedToolSpec из реального типа клиента — убить ручные зеркала (#446)
Восстановленный отложенный долг #294: @docmost/mcp не отдавал .d.ts, поэтому в сервере жили ТРИ дрейфующие ручные копии одних и тех же имён/сигнатур (DocmostClientLike ~230 строк, копия SharedToolSpec, name-only HOST_CONTRACT_ METHODS-тест). In-app execute-тела зовут клиент ПОЗИЦИОННО, так что перестановка параметра в client.ts доезжала до прода рантайм-ошибкой без сигнала на компиляции. - declaration:true (+declarationMap) в packages/mcp/tsconfig.json; types-экспорт в package.json (exports → conditional {types, default} для . и ./http; require.resolve/dynamic-import резолвят default → build/index.js, рантайм не тронут). build/index.d.ts эмитится, реэкспортит DocmostClient + SharedToolSpec. Правок исходников пакета для эмита НЕ потребовалось. - DocmostClientLike → Pick<DocmostClient, 48 методов> из type-only import (стёрт на компиляции, ESM/CJS-границу не задевает); ручное зеркало удалено. - SharedToolSpec → type-only реэкспорт из пакета; ручная копия удалена. - client-host-contract.test.mjs удалён целиком — имена И сигнатуры теперь проверяет tsc. - Позиционная безопасность: never-called __assertClientCallContract(client: DocmostClientLike) воспроизводит каждый позиционный вызов с типизированными плейсхолдерами (AI-SDK стирает вход execute-замыканий в any, иначе позиционные вызовы не проверялись). Перестановка параметров client.ts → ошибка компиляции сервера ровно тут. Loose as-касты в ai-chat-tools.service не потребовали правок; as any не добавлялся. Внутреннее ревью: APPROVE. Runtime resolution через conditional exports не сломан (разобрано для прод-инсталляции, не только symlink); покрытие __assertClientCallContract полное (48 call-sites == union == assert, сверено программно); Pick полон; демонстрация reorder → TS2345 в assert. Единственная находка (Promise<any> в части возвратов) предсуществующая в client.ts, вне цели PR. Стоит на #447 (закрытие skew build/vs/src) — мержить после него. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
2e6f1c3de5 |
fix(ci,mcp): REGISTRY_STAMP в билд-артефакте + кросс-пакетный CI — закрыть skew build/ vs src/ (#447)
Два структурных слепых пятна: (1) сервер грузит СКОМПИЛИРОВАННЫЙ
packages/mcp/build/index.js, а серверные guard-тесты читают src/tool-specs.ts —
правка src без пересборки оставляет тесты зелёными, но рантайм расходится со
спеками; (2) спеки добавляют в packages/mcp, а parity-тесты живут в jest-сьюте
apps/server — PR, трогающий только пакет, проходит зелёным, сломанная in-app-
проводка всплывает уже на develop (кейс
|