tool-rename-deprecation by microsoft/vscode
npx skills add https://github.com/microsoft/vscode --skill tool-rename-deprecation当工具或工具集引用名称发生更改时,必须始终将旧名称添加到弃用/遗留数组中,以确保现有的提示文件、工具配置和已保存的引用能够继续正确解析。
在对内置工具或工具集注册代码进行任何更改时运行此技能,以捕获回归问题:
toolReferenceNamereferenceNametoolSet/toolName 路径成为遗留名称)确定您是在重命名一个工具还是一个工具集,以及它在何处注册:
| 实体 | 注册位置 | 要重命名的名称字段 | 遗留数组 | 稳定 ID(永不更改) |
|---|---|---|---|---|
| 工具 () |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
IToolData| TypeScript |
toolReferenceName |
legacyToolReferenceFullNames |
id |
| 工具(扩展) | package.json languageModelTools | toolReferenceName | legacyToolReferenceFullNames | name(变为 id) |
工具集 (IToolSet) | TypeScript | referenceName | legacyFullNames | id |
| 工具集(扩展) | package.json languageModelToolSets | name 或 referenceName | legacyFullNames | — |
关键点: 对于扩展贡献的工具,package.json 中的 name 字段会映射到 IToolData 上的 id(参见 languageModelToolsContribution.ts 中的 id: rawTool.name 行)。它也用于激活事件(onLanguageModelTool:<name>)。切勿重命名 name 字段 — 只重命名 toolReferenceName。
验证旧的 toolReferenceName 值出现在 legacyToolReferenceFullNames 中。 不要假设它已经存在 — 检查实际的数组内容。如果旧名称已列出(例如,来自之前的重命名),请确认它没有被移除。如果不存在,则添加它。
对于内部/内置工具(TypeScript IToolData):
// 重命名前
export const MyToolData: IToolData = {
id: 'myExtension.myTool',
toolReferenceName: 'oldName',
// ...
};
// 重命名后 — 保留旧名称
export const MyToolData: IToolData = {
id: 'myExtension.myTool',
toolReferenceName: 'newName',
legacyToolReferenceFullNames: ['oldName'],
// ...
};
如果该工具之前位于某个工具集内,请使用完整的 toolSet/toolName 形式:
legacyToolReferenceFullNames: ['oldToolSet/oldToolName'],
如果多次重命名,累积所有之前的名称 — 切勿移除现有条目:
legacyToolReferenceFullNames: ['firstOldName', 'secondOldName'],
对于工具集,在调用 createToolSet 时将旧名称添加到 legacyFullNames 选项:
toolsService.createToolSet(source, id, 'newSetName', {
legacyFullNames: ['oldSetName'],
});
对于扩展贡献的工具(package.json),只重命名 toolReferenceName 并将旧值添加到 legacyToolReferenceFullNames。不要重命名 name 字段:
// 正确 — 仅更改 toolReferenceName,name 保持稳定
{
"name": "copilot_myTool", // ← 保持此字段不变
"toolReferenceName": "newName", // ← 已重命名
"legacyToolReferenceFullNames": [
"oldName" // ← 保留旧的 toolReferenceName
]
}
遗留名称必须在所有通过引用名称查找工具的地方都得到尊重,而不仅仅是在提示解析中。关键的使用者包括:
getDeprecatedFullReferenceNames() 将旧名称映射到当前名称,用于 .prompt.md 验证和代码操作getToolAliases() / getToolSetAliases() 产生遗留名称,以便工具选择器和启用映射能够解析它们isToolEligibleForAutoApproval() 根据 chat.tools.eligibleForAutoApproval 设置检查 legacyToolReferenceFullNames(包括命名空间遗留名称中 / 之后的部分)LEGACY_TOOL_REFERENCE_FULL_NAMES重命名后,请确认:
.prompt.md 文件中的 #oldName 仍然可以解析(不显示验证错误)"chat.tools.eligibleForAutoApproval": { "oldName": false } 的用户,其限制仍然有效虽然遗留名称确保了向后兼容性,但建议更新第一方引用以使用新名称:
.prompt.md 文件| 文件 | 包含内容 |
|---|---|
src/vs/workbench/contrib/chat/common/tools/languageModelToolsService.ts | 包含遗留名称字段的 IToolData 和 IToolSet 接口 |
src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts | 解析逻辑:getToolAliases, getToolSetAliases, getDeprecatedFullReferenceNames, isToolEligibleForAutoApproval |
src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.ts | 扩展点架构、验证以及关键的 id: rawTool.name 映射(约第 274 行) |
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts | 一个工具示例,它有自己的针对遗留名称的本地自动批准检查 |
runInTerminal 工具:从 runCommands/runInTerminal 重命名 → legacyToolReferenceFullNames: ['runCommands/runInTerminal']todo 工具:从 todos 重命名 → legacyToolReferenceFullNames: ['todos']getTaskOutput 工具:从 runTasks/getTaskOutput 重命名 → legacyToolReferenceFullNames: ['runTasks/getTaskOutput']legacyToolReferenceFullNames 和 legacyFullNames,构建了解析基础设施,并执行了第一批工具重命名。可作为如何正确使用遗留名称进行重命名的模板。eligibleForAutoApproval 设置没有检查遗留名称 — 限制了旧名称的用户失去了该限制。展示了为什么所有工具引用名称的使用者都必须考虑遗留名称。openSimpleBrowser 重命名为 openIntegratedBrowser,但同时也将 name 字段(稳定 ID)从 copilot_openSimpleBrowser 改为 copilot_openIntegratedBrowser。toolReferenceName 的向后兼容性只是巧合地起作用(旧名称碰巧已经因为之前的更改而存在于遗留数组中 — 它并非作为此次重命名的一部分被有意添加的)。在任何触及工具注册(TypeScript IToolData、createToolSet 或 package.json languageModelTools/languageModelToolSets)的 PR 上运行此检查:
toolReferenceName 或 referenceName 值。 对于每个更改,确认之前的值现在出现在 legacyToolReferenceFullNames 或 legacyFullNames 中。不要假设它已经存在 — 阅读实际的数组。name 字段。 name 字段是工具的稳定 id — 它绝不能更改。如果更改了,将其标记为错误。(这会破坏激活事件、通过 id 调用工具以及任何通过其 name 引用工具的代码。)toolSet/toolName 完整路径在遗留数组中。languageModelToolSets 贡献中的 tools 数组)。如果工具的 toolReferenceName 更改了,任何引用旧名称的工具集 tools 数组都应该更新 — 但遗留解析系统会处理这个问题,所以旧名称仍然有效。name 字段 — package.json 中的 name 会变成 IToolData 上的 id(通过 languageModelToolsContribution.ts 中的 id: rawTool.name)。更改它会破坏激活事件(onLanguageModelTool:<name>)、任何通过 id 引用工具的代码以及工具调用。只重命名 toolReferenceName,切勿重命名 name。(参见 vscode-copilot-chat#3810,其中 name 和 toolReferenceName 都被更改了。)id 字段 — 与上述原理相同。id 是一个稳定的内部标识符,绝不能更改。legacyToolReferenceFullNames 内容来验证,而不仅仅是检查该字段是否存在。遗留数组可能列出更早重命名的名称,但不包含当前正在更改的名称。RunInTerminalTool)都需要尊重遗留名称(参见 #278506)。每周安装量
175
代码库
GitHub 星标数
183.0K
首次出现
2026年2月20日
安全审计
安装于
gemini-cli175
github-copilot175
codex175
kimi-cli175
amp175
opencode175
When a tool or tool set reference name is changed, the old name must always be added to the deprecated/legacy array so that existing prompt files, tool configurations, and saved references continue to resolve correctly.
Run this skill on any change to built-in tool or tool set registration code to catch regressions:
toolReferenceNamereferenceNametoolSet/toolName path becomes a legacy name)Determine whether you are renaming a tool or a tool set , and where it is registered:
| Entity | Registration | Name field to rename | Legacy array | Stable ID (NEVER change) |
|---|---|---|---|---|
Tool (IToolData) | TypeScript | toolReferenceName | legacyToolReferenceFullNames | id |
| Tool (extension) | package.json languageModelTools | toolReferenceName | legacyToolReferenceFullNames | name (becomes ) |
Critical: For extension-contributed tools, the name field in package.json is mapped to id on IToolData (see languageModelToolsContribution.ts line id: rawTool.name). It is also used for activation events (onLanguageModelTool:<name>). Never rename thename field — only rename toolReferenceName.
Verify the oldtoolReferenceName value appears in legacyToolReferenceFullNames. Don't assume it's already there — check the actual array contents. If the old name is already listed (e.g., from a previous rename), confirm it wasn't removed. If it's not there, add it.
For internal/built-in tools (TypeScript IToolData):
// Before rename
export const MyToolData: IToolData = {
id: 'myExtension.myTool',
toolReferenceName: 'oldName',
// ...
};
// After rename — old name preserved
export const MyToolData: IToolData = {
id: 'myExtension.myTool',
toolReferenceName: 'newName',
legacyToolReferenceFullNames: ['oldName'],
// ...
};
If the tool previously lived inside a tool set, use the full toolSet/toolName form:
legacyToolReferenceFullNames: ['oldToolSet/oldToolName'],
If renaming multiple times, accumulate all prior names — never remove existing entries:
legacyToolReferenceFullNames: ['firstOldName', 'secondOldName'],
For tool sets , add the old name to the legacyFullNames option when calling createToolSet:
toolsService.createToolSet(source, id, 'newSetName', {
legacyFullNames: ['oldSetName'],
});
For extension-contributed tools (package.json), rename only toolReferenceName and add the old value to legacyToolReferenceFullNames. Do NOT rename thename field:
// CORRECT — only toolReferenceName changes, name stays stable
{
"name": "copilot_myTool", // ← KEEP this unchanged
"toolReferenceName": "newName", // ← renamed
"legacyToolReferenceFullNames": [
"oldName" // ← old toolReferenceName preserved
]
}
Legacy names must be respected everywhere a tool is looked up by reference name, not just in prompt resolution. Key consumers:
getDeprecatedFullReferenceNames() maps old → current names for .prompt.md validation and code actionsgetToolAliases() / getToolSetAliases() yield legacy names so tool picker and enablement maps resolve themisToolEligibleForAutoApproval() checks legacyToolReferenceFullNames (including the segment after / for namespaced legacy names) against chat.tools.eligibleForAutoApproval settingsLEGACY_TOOL_REFERENCE_FULL_NAMESAfter renaming, confirm:
#oldName in a .prompt.md file still resolves (shows no validation error)"chat.tools.eligibleForAutoApproval": { "oldName": false } still has that restriction honoredWhile legacy names ensure backward compatibility, update first-party references to use the new name:
.prompt.md files| File | What it contains |
|---|---|
src/vs/workbench/contrib/chat/common/tools/languageModelToolsService.ts | IToolData and IToolSet interfaces with legacy name fields |
src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts | Resolution logic: getToolAliases, getToolSetAliases, getDeprecatedFullReferenceNames, isToolEligibleForAutoApproval |
runInTerminal tool: renamed from runCommands/runInTerminal → legacyToolReferenceFullNames: ['runCommands/runInTerminal']todo tool: renamed from todos → legacyToolReferenceFullNames: ['todos']getTaskOutput tool: renamed from runTasks/getTaskOutput → legacyToolReferenceFullNames: ['runTasks/getTaskOutput']legacyToolReferenceFullNames and legacyFullNames, built the resolution infrastructure, and performed the first batch of tool renames. Use as a template for how to properly rename with legacy names.eligibleForAutoApproval setting wasn't checking legacy names — users who had restricted the old name lost that restriction. Shows why all consumers of tool reference names must account for legacy names.openSimpleBrowser → openIntegratedBrowser but also changed the name field (stable id) from copilot_openSimpleBrowser → . The backward compat only worked by coincidence (the old name happened to already be in the legacy array from a prior change — it was not intentionally added as part of this rename).Run this check on any PR that touches tool registration (TypeScript IToolData, createToolSet, or package.json languageModelTools/languageModelToolSets):
toolReferenceName or referenceName values. For each change, confirm the previous value now appears in legacyToolReferenceFullNames or legacyFullNames. Don't assume it was already there — read the actual array.name fields on extension-contributed tools. The name field is the tool's stable id — it must never change. If it changed, flag it as a bug. (This breaks activation events, tool invocations by id, and any code referencing the tool by its name.)name field on extension-contributed tools — the name in package.json becomes the id on IToolData (via id: rawTool.name in languageModelToolsContribution.ts). Changing it breaks activation events (onLanguageModelTool:<name>), any code referencing the tool by id, and tool invocations. Only rename toolReferenceName, never name. (See vscode-copilot-chat#3810 where both and were changed.)Weekly Installs
175
Repository
GitHub Stars
183.0K
First Seen
Feb 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli175
github-copilot175
codex175
kimi-cli175
amp175
opencode175
Perl 5.36+ 现代开发模式与最佳实践 | 构建健壮可维护应用程序指南
952 周安装
AI上下文管理器技能 - 动态上下文工程、向量数据库与多智能体工作流编排专家指南
152 周安装
qwen-image:通义千问图像处理API与Git集成工具,支持多平台安装
11 周安装
mcporter - API与Git集成工具,提升开发效率与代码管理自动化
11 周安装
Python类型注解教程:现代类型提示、TypedDict、Protocol与泛型实战指南
11 周安装
Aster 现货 API WebSocket v3 测试网指南:实时市场数据与用户数据流
13 周安装
数据可视化技能 - 使用Matplotlib、Seaborn、Plotly创建专业图表 | CodeKit
12 周安装
idTool set (IToolSet) | TypeScript | referenceName | legacyFullNames | id |
| Tool set (extension) | package.json languageModelToolSets | name or referenceName | legacyFullNames | — |
src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.ts | Extension point schema, validation, and the critical id: rawTool.name mapping (line ~274) |
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts | Example of a tool with its own local auto-approval check against legacy names |
copilot_openIntegratedBrowsertoolReferenceNametoolSet/toolNametools array in languageModelToolSets contributions). If a tool's toolReferenceName changed, any tool set tools array referencing the old name should be updated — but the legacy resolution system handles this, so the old name still works.nametoolReferenceNameid field on TypeScript-registered tools — same principle as above. The id is a stable internal identifier and must never change.legacyToolReferenceFullNames contents, not just checking that the field exists. A legacy array might list names from an even older rename but not the current one being changed.RunInTerminalTool) all need to respect legacy names (see #278506).