feat(plan): conditionally add enter/exit plan mode tools based on current mode (#24378)

This commit is contained in:
ruomeng
2026-04-01 11:56:10 -04:00
committed by GitHub
parent ca43f8c291
commit eb95e99b3d
4 changed files with 50 additions and 0 deletions
@@ -22,6 +22,8 @@ import { ToolRegistry, DiscoveredTool } from './tool-registry.js';
import {
DISCOVERED_TOOL_PREFIX,
UPDATE_TOPIC_TOOL_NAME,
ENTER_PLAN_MODE_TOOL_NAME,
EXIT_PLAN_MODE_TOOL_NAME,
} from './tool-names.js';
import { DiscoveredMCPTool } from './mcp-tool.js';
import {
@@ -833,6 +835,40 @@ describe('ToolRegistry', () => {
expect(toolRegistry.getAllToolNames()).toContain(UPDATE_TOPIC_TOOL_NAME);
expect(toolRegistry.getTool(UPDATE_TOPIC_TOOL_NAME)).toBe(topicTool);
});
it('should show enter_plan_mode only when NOT in plan mode', () => {
const enterTool = new MockTool({ name: ENTER_PLAN_MODE_TOOL_NAME });
toolRegistry.registerTool(enterTool);
// Not in plan mode
vi.spyOn(config, 'getApprovalMode').mockReturnValue(ApprovalMode.DEFAULT);
expect(toolRegistry.getAllToolNames()).toContain(
ENTER_PLAN_MODE_TOOL_NAME,
);
// In plan mode
vi.spyOn(config, 'getApprovalMode').mockReturnValue(ApprovalMode.PLAN);
expect(toolRegistry.getAllToolNames()).not.toContain(
ENTER_PLAN_MODE_TOOL_NAME,
);
});
it('should show exit_plan_mode only when in plan mode', () => {
const exitTool = new MockTool({ name: EXIT_PLAN_MODE_TOOL_NAME });
toolRegistry.registerTool(exitTool);
// Not in plan mode
vi.spyOn(config, 'getApprovalMode').mockReturnValue(ApprovalMode.DEFAULT);
expect(toolRegistry.getAllToolNames()).not.toContain(
EXIT_PLAN_MODE_TOOL_NAME,
);
// In plan mode
vi.spyOn(config, 'getApprovalMode').mockReturnValue(ApprovalMode.PLAN);
expect(toolRegistry.getAllToolNames()).toContain(
EXIT_PLAN_MODE_TOOL_NAME,
);
});
});
describe('DiscoveredToolInvocation', () => {
+10
View File
@@ -31,6 +31,8 @@ import {
WRITE_FILE_TOOL_NAME,
EDIT_TOOL_NAME,
UPDATE_TOPIC_TOOL_NAME,
ENTER_PLAN_MODE_TOOL_NAME,
EXIT_PLAN_MODE_TOOL_NAME,
} from './tool-names.js';
type ToolParams = Record<string, unknown>;
@@ -583,6 +585,14 @@ export class ToolRegistry {
}
}
const isPlanMode = this.config.getApprovalMode() === ApprovalMode.PLAN;
if (
(tool.name === ENTER_PLAN_MODE_TOOL_NAME && isPlanMode) ||
(tool.name === EXIT_PLAN_MODE_TOOL_NAME && !isPlanMode)
) {
return false;
}
const normalizedClassName = tool.constructor.name.replace(/^_+/, '');
const possibleNames = [tool.name, normalizedClassName];
if (tool instanceof DiscoveredMCPTool) {