refactor(mcp)!: BREAKING — все имена MCP-тулов snake_case → camelCase (#412) #463
Open
agent_coder
wants to merge 1 commits from
refactor/412-camelcase-tool-names into develop
pull from: refactor/412-camelcase-tool-names
merge into: vvzvlad:develop
vvzvlad:main
vvzvlad:feat/425-drawio-graph
vvzvlad:feat/443-get-page-context
vvzvlad:feat/443-get-tree
vvzvlad:feat/443-search
vvzvlad:docs/415-lossy-descriptions
vvzvlad:feat/413-markdown-default
vvzvlad:fix/464-diffdocs-cpu-guard
vvzvlad:develop
vvzvlad:refactor/411-update-page-markdown
vvzvlad:feat/424-drawio-rules
vvzvlad:fix/409-invalid-node-validation
vvzvlad:refactor/448-generate-inventory
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: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
No Reviewers
Labels
Clear labels
epic
needs-human
review/approved
review/changes-requested
review/needs
возможно, баг
Large multi-phase effort spanning many changes
эскалация: нужно решение человека
в последнем ревью нет открытых blocking-находок
последнее ревью оставило открытые blocking-находки
head не ревьюился (head != reviewed_head)
Похоже на баг, но требует подтверждения/воспроизведения; чиним, если повторится
No Label
review/approved
Milestone
No items
No Milestone
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: vvzvlad/gitmost#463
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "refactor/412-camelcase-tool-names"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Второй линк breaking-окна #416 (#411→ЭТОТ→#413→#415). BREAKING. closes #412
Один логический тул жил под двумя именами: внешний MCP snake_case (
edit_page_text), in-app camelCase (editPageText) — дублирование доков, путаница при переносе промптов/скиллов, помеха шарингу спек. Решение владельца: единый camelCase везде, включая внешний MCP. После этогоmcpName === inAppKeyдля каждой shared-спеки.tool-specs.ts:mcpNameвыведен из ключа спеки для всех 43 shared-спек (раньше divergent snake). Проверено —mcpNameчитается только структурно (цикл регистрации, генератор<tool_inventory>,TOOL_FAMILY), ничего не полагалось на старое snake-значение. +5 inline-регистраций (tableGet/updateComment/deleteComment/docmostTransform;searchбез изменений). Рантайм: 47 тулов, все camelCase, ноль подчёркиваний.mcpName === toSnake(inAppKey)→mcpName === inAppKey;toSnakeудалён;tool-specs.test/tool-inventory.testобновлены (скрейпер расширен до[a-zA-Z0-9_]).ai-chat.prompt/guard уже на in-app camelCase-ключах — без изменений.comment-signalEXCLUDED_TOOLS схлопнут с дублей snake+camel.assertUnambiguousMatch(op: "patch_node"|"delete_node")вprosemirror-markdown/node-ops(op интерполируется в model-facing ошибку) →"patchNode"|"deleteNode".PageService.updatePageContentи т.п.) НЕ тронуты — переименованы только ИМЕНА ТУЛОВ.⚠️ Breaking (в CHANGELOG таблица 46 строк + миграция)
Все внешние MCP-клиенты ломаются разом: permission-allowlists (
mcp__gitmost-*__get_node→__getNode), сохранённые промпты/скиллы,.mcp.json, метрики per-tool-label. Мигрировать в lockstep с деплоем. Релизится вместе с #411 — чтобы внешние конфиги ломались один раз.How verified
Стенд (symlink
@docmost/mcp+@docmost/prosemirror-markdownна пакеты ветки, восстановлены):node --test→ 677/677;tsc -p apps/serverчисто;jest ai-chat-tools.service + shared-tool-specs.contract + tool-tiers + ai-chat.prompt + comment-signal-inapp→ 323.Внутренний цикл: 1 проход (APPROVE WITH SUGGESTIONS). Ревьюер подтвердил живой энумерацией 47 camelCase-тулов и исчерпывающим grep'ом отсутствие утечек; конвенция перевёрнута и энфорсится; структурные зависимости от
mcpNameцелы. Единственная находка — устаревшая формулировка «snake_case» в двух ВНУТРЕННИХ комментарияхai-chat-tools.service.ts— поправил (не модель-обращённое).Порядок мержа (стопка breaking-окна)
Стоит на develop; #413 (markdown-default) стоит на ЭТОЙ ветке, #415 на #413. Собираю стопкой без ожидания мержей; порядок опишу в #416. Мержить: #411(влит) → этот → #413 → #415.
Checklist
tools/listвнешнего MCP не содержит ни одного snake-имени (47 camelCase)mcpName === inAppKeyдля каждой shared-спеки (контракт зелёный)Ревью — #463
refactor(mcp)!: BREAKING — все имена MCP-тулов snake_case → camelCase (#412)Вердикт: PASS ✅
Полный веер из 9 аспектов (на develop
e19275e9, #462 влит; 55 файлов, +799/−727 — механический rename). Второй линк breaking-окна #416 — осознанный BREAKING (решение владельца, #412), с migration-таблицей. Гейт зелёный, инвариантmcpName===inAppKeyмутационно-пришпилен.Полнота rename + name-keyed гейты (клик)
Единый camelCase везде →
mcpName === inAppKey === registryKeyдля всех 43 shared-спек + 5 inline (tableGet/updateComment/deleteComment/docmostTransform;searchбез изменений — уже одно слово).mcpNameвыведен из ключа,toSnakeудалён.SERVER_INSTRUCTIONS— 0 snake-токенов (кроме тега<tool_inventory>). tool-specsmcpName— все camelCase; ROUTING_PROSE/TOOL_FAMILY(70+ ключей)/INLINE_MCP_INVENTORY — camelCase; model-facing ошибки (node-ops assertUnambiguousMatchop) →patchNode/deleteNode; ничего в рантайме не хардкодило snake-имя (grep чист — читалось только структурно).COMMENT_SIGNAL_EXCLUDED_TOOLSпереименован в camelCase, ни один тул не выпал/не добавился в exclusion;INLINE_TOOL_TIERScamelCase без тихой смены тира;inAppOnly/mcpOnlyсохранены (importPageMarkdown всё ещё inAppOnly). Расширения возможностей нет./^[a-z][a-zA-Z0-9]*$/(ловит будущий underscore). Адверсариально: вернул один mcpName в snake → контракт-тест «mcpName and inAppKey are the same camelCase identifier» ПАДАЕТ → load-bearing.Объективный гейт (клин-рум /home/claude/gm-ci)
[]. Адверсариальный snake-mcpName краснит контракт-тест; restore зелёный.⛔ DROP — кодеру НЕ делать (лог калибровки)
[below-threshold]low[documentation] 2 стейл-коммента с old-именами:ai-chat-tools.service.ts:785(«patch_node») и:953(«docmost_transform») — ВНУТРЕННИЕ комменты, не model-facing/не client-facing, поведение не задето (заявка PR «рантайм zero-underscore» относится к именам тулов — выполнена, гейт подтвердил). Рекомендую подмести для полноты, но не блок.DO/ESCALATE нет. Rename полон (runtime 0-underscore объективно), инвариант mcpName===inAppKey тестируется+адверсариально держится, name-keyed гейты (exclusion/tiers) переименованы без смены членства, in-app не задет, доки×2 + CHANGELOG migration полны. BREAKING осознанный (#412), в lockstep с #411. Approve.
9 аспектов (coherence+regressions+security+stability, testcov+conv+docs+simp+arch — все LGTM). Полнота runtime подтверждена (SERVER_INSTRUCTIONS snake=[]); mcpName===inAppKey адверсариально пришпилен; EXCLUDED_TOOLS/tiers без смены членства; README×2+CHANGELOG полны. 2 стейл-коммента — below-threshold DROP. Escalate нет.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.