mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-23 00:35:51 +00:00
feat: 工具层及 mcp 大重构 (#252)
* feat: 第一版大重构 * fix: 修复类型问题 * chore: 更新版本到 1.3.2 * Add brave as alternative WebSearchTool * fix: 修正顺序 * fix: 修复对穷鬼模式的 auto dream 和 session memory 越过 * feat: 穷鬼模式去除 session-summary * feat: 创建 builtin-tools 包,搬运所有工具实现 将 src/tools/ 下的全部 60 个工具目录迁移至 packages/builtin-tools/src/tools/, 内部导入路径已更新为 src/ alias 模式。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: 更新 src/ 中所有工具引用至 builtin-tools 包,删除 src/tools/ - src/tools.ts 及 178 个 src/ 文件的 import 路径从 ./tools/ 改为 builtin-tools/tools/ - 删除 src/tools/ 整个目录(已迁移至 packages/builtin-tools/) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: 添加 builtin-tools 路径别名至 tsconfig,更新 bun.lock - tsconfig.json 新增 builtin-tools/* 和 builtin-tools 路径映射 - 新增 packages/builtin-tools/src 至 include Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: 为 builtin-tools、mcp-client、agent-tools 添加 @claude-code-best 作用域前缀 所有包名及 import 路径统一添加 @claude-code-best/ 前缀: - builtin-tools → @claude-code-best/builtin-tools - mcp-client → @claude-code-best/mcp-client - agent-tools → @claude-code-best/agent-tools Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: 修复 node 环境没有 bun 的问题 --------- Co-authored-by: Eric-Guo <eric.guocz@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
115
packages/builtin-tools/src/tools/BashTool/modeValidation.ts
Normal file
115
packages/builtin-tools/src/tools/BashTool/modeValidation.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import type { z } from 'zod/v4'
|
||||
import type { ToolPermissionContext } from 'src/Tool.js'
|
||||
import { splitCommand_DEPRECATED } from 'src/utils/bash/commands.js'
|
||||
import type { PermissionResult } from 'src/utils/permissions/PermissionResult.js'
|
||||
import type { BashTool } from './BashTool.js'
|
||||
|
||||
const ACCEPT_EDITS_ALLOWED_COMMANDS = [
|
||||
'mkdir',
|
||||
'touch',
|
||||
'rm',
|
||||
'rmdir',
|
||||
'mv',
|
||||
'cp',
|
||||
'sed',
|
||||
] as const
|
||||
|
||||
type FilesystemCommand = (typeof ACCEPT_EDITS_ALLOWED_COMMANDS)[number]
|
||||
|
||||
function isFilesystemCommand(command: string): command is FilesystemCommand {
|
||||
return ACCEPT_EDITS_ALLOWED_COMMANDS.includes(command as FilesystemCommand)
|
||||
}
|
||||
|
||||
function validateCommandForMode(
|
||||
cmd: string,
|
||||
toolPermissionContext: ToolPermissionContext,
|
||||
): PermissionResult {
|
||||
const trimmedCmd = cmd.trim()
|
||||
const [baseCmd] = trimmedCmd.split(/\s+/)
|
||||
|
||||
if (!baseCmd) {
|
||||
return {
|
||||
behavior: 'passthrough',
|
||||
message: 'Base command not found',
|
||||
}
|
||||
}
|
||||
|
||||
// In Accept Edits mode, auto-allow filesystem operations
|
||||
if (
|
||||
toolPermissionContext.mode === 'acceptEdits' &&
|
||||
isFilesystemCommand(baseCmd)
|
||||
) {
|
||||
return {
|
||||
behavior: 'allow',
|
||||
updatedInput: { command: cmd },
|
||||
decisionReason: {
|
||||
type: 'mode',
|
||||
mode: 'acceptEdits',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
behavior: 'passthrough',
|
||||
message: `No mode-specific handling for '${baseCmd}' in ${toolPermissionContext.mode} mode`,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if commands should be handled differently based on the current permission mode
|
||||
*
|
||||
* This is the main entry point for mode-based permission logic.
|
||||
* Currently handles Accept Edits mode for filesystem commands,
|
||||
* but designed to be extended for other modes.
|
||||
*
|
||||
* @param input - The bash command input
|
||||
* @param toolPermissionContext - Context containing mode and permissions
|
||||
* @returns
|
||||
* - 'allow' if the current mode permits auto-approval
|
||||
* - 'ask' if the command needs approval in current mode
|
||||
* - 'passthrough' if no mode-specific handling applies
|
||||
*/
|
||||
export function checkPermissionMode(
|
||||
input: z.infer<typeof BashTool.inputSchema>,
|
||||
toolPermissionContext: ToolPermissionContext,
|
||||
): PermissionResult {
|
||||
// Skip if in bypass mode (handled elsewhere)
|
||||
if (toolPermissionContext.mode === 'bypassPermissions') {
|
||||
return {
|
||||
behavior: 'passthrough',
|
||||
message: 'Bypass mode is handled in main permission flow',
|
||||
}
|
||||
}
|
||||
|
||||
// Skip if in dontAsk mode (handled in main permission flow)
|
||||
if (toolPermissionContext.mode === 'dontAsk') {
|
||||
return {
|
||||
behavior: 'passthrough',
|
||||
message: 'DontAsk mode is handled in main permission flow',
|
||||
}
|
||||
}
|
||||
|
||||
const commands = splitCommand_DEPRECATED(input.command)
|
||||
|
||||
// Check each subcommand
|
||||
for (const cmd of commands) {
|
||||
const result = validateCommandForMode(cmd, toolPermissionContext)
|
||||
|
||||
// If any command triggers mode-specific behavior, return that result
|
||||
if (result.behavior !== 'passthrough') {
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// No mode-specific handling needed
|
||||
return {
|
||||
behavior: 'passthrough',
|
||||
message: 'No mode-specific validation required',
|
||||
}
|
||||
}
|
||||
|
||||
export function getAutoAllowedCommands(
|
||||
mode: ToolPermissionContext['mode'],
|
||||
): readonly string[] {
|
||||
return mode === 'acceptEdits' ? ACCEPT_EDITS_ALLOWED_COMMANDS : []
|
||||
}
|
||||
Reference in New Issue
Block a user