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:
claude-code-best
2026-04-13 09:52:05 +08:00
committed by GitHub
parent bbb8b613a9
commit 2fb1c9dcd8
559 changed files with 9346 additions and 1837 deletions

View File

@@ -0,0 +1,89 @@
import { z } from 'zod/v4'
import type { ToolResultBlockParam } from 'src/Tool.js'
import { buildTool } from 'src/Tool.js'
import { lazySchema } from 'src/utils/lazySchema.js'
import { REPL_TOOL_NAME } from './constants.js'
const inputSchema = lazySchema(() =>
z.strictObject({
code: z
.string()
.describe(
'The code to execute in the REPL. Can call any primitive tool (Read, Write, Edit, Glob, Grep, Bash, NotebookEdit, Agent) via their APIs.',
),
}),
)
type InputSchema = ReturnType<typeof inputSchema>
type REPLInput = z.infer<InputSchema>
type REPLOutput = { result: string; tool_calls: number }
export const REPLTool = buildTool({
name: REPL_TOOL_NAME,
searchHint: 'repl execute batch code read write edit glob grep bash',
maxResultSizeChars: 100_000,
strict: true,
get inputSchema(): InputSchema {
return inputSchema()
},
async description() {
return 'Execute code in the REPL environment with access to all primitive tools'
},
async prompt() {
return `Execute code in the REPL — a sandboxed environment with direct access to primitive tools (Read, Write, Edit, Glob, Grep, Bash, NotebookEdit, Agent).
When REPL mode is active, primitive tools are only accessible through this tool. Use REPL for:
- Batch operations across many files
- Complex multi-step file transformations
- Operations that benefit from programmatic control flow
- Combining search results with edits in a single turn
The REPL runs in a VM context with tool APIs available as functions. Results from each tool call are collected and returned together.`
},
isConcurrencySafe() {
return false
},
isReadOnly() {
return false
},
isTransparentWrapper() {
return true
},
userFacingName() {
return REPL_TOOL_NAME
},
renderToolUseMessage(input: Partial<REPLInput>) {
const code = input.code ?? ''
const preview = code.length > 80 ? code.slice(0, 77) + '...' : code
return `REPL: ${preview}`
},
mapToolResultToToolResultBlockParam(
content: REPLOutput,
toolUseID: string,
): ToolResultBlockParam {
return {
tool_use_id: toolUseID,
type: 'tool_result',
content: content.result,
}
},
async call(_input: REPLInput) {
// REPL execution engine is provided by the ant-native runtime.
// This stub satisfies the tool interface; the actual VM dispatch
// is wired in the ant build. Without the ant runtime, REPL is
// not available and callers should be informed.
return {
data: {
result: 'Error: REPL tool is not available in this build. The REPL execution engine requires the ant-native runtime.',
tool_calls: 0,
},
}
},
})

View File

@@ -0,0 +1,46 @@
import { isEnvDefinedFalsy, isEnvTruthy } from 'src/utils/envUtils.js'
import { AGENT_TOOL_NAME } from '../AgentTool/constants.js'
import { BASH_TOOL_NAME } from '../BashTool/toolName.js'
import { FILE_EDIT_TOOL_NAME } from '../FileEditTool/constants.js'
import { FILE_READ_TOOL_NAME } from '../FileReadTool/prompt.js'
import { FILE_WRITE_TOOL_NAME } from '../FileWriteTool/prompt.js'
import { GLOB_TOOL_NAME } from '../GlobTool/prompt.js'
import { GREP_TOOL_NAME } from '../GrepTool/prompt.js'
import { NOTEBOOK_EDIT_TOOL_NAME } from '../NotebookEditTool/constants.js'
export const REPL_TOOL_NAME = 'REPL'
/**
* REPL mode is default-on for ants in the interactive CLI (opt out with
* CLAUDE_CODE_REPL=0). The legacy CLAUDE_REPL_MODE=1 also forces it on.
*
* SDK entrypoints (sdk-ts, sdk-py, sdk-cli) are NOT defaulted on — SDK
* consumers script direct tool calls (Bash, Read, etc.) and REPL mode
* hides those tools. USER_TYPE is a build-time --define, so the ant-native
* binary would otherwise force REPL mode on every SDK subprocess regardless
* of the env the caller passes.
*/
export function isReplModeEnabled(): boolean {
if (isEnvDefinedFalsy(process.env.CLAUDE_CODE_REPL)) return false
if (isEnvTruthy(process.env.CLAUDE_REPL_MODE)) return true
return (
process.env.USER_TYPE === 'ant' &&
process.env.CLAUDE_CODE_ENTRYPOINT === 'cli'
)
}
/**
* Tools that are only accessible via REPL when REPL mode is enabled.
* When REPL mode is on, these tools are hidden from Claude's direct use,
* forcing Claude to use REPL for batch operations.
*/
export const REPL_ONLY_TOOLS = new Set([
FILE_READ_TOOL_NAME,
FILE_WRITE_TOOL_NAME,
FILE_EDIT_TOOL_NAME,
GLOB_TOOL_NAME,
GREP_TOOL_NAME,
BASH_TOOL_NAME,
NOTEBOOK_EDIT_TOOL_NAME,
AGENT_TOOL_NAME,
])

View File

@@ -0,0 +1,39 @@
import type { Tool } from 'src/Tool.js'
import { AgentTool } from '../AgentTool/AgentTool.js'
import { BashTool } from '../BashTool/BashTool.js'
import { FileEditTool } from '../FileEditTool/FileEditTool.js'
import { FileReadTool } from '../FileReadTool/FileReadTool.js'
import { FileWriteTool } from '../FileWriteTool/FileWriteTool.js'
import { GlobTool } from '../GlobTool/GlobTool.js'
import { GrepTool } from '../GrepTool/GrepTool.js'
import { NotebookEditTool } from '../NotebookEditTool/NotebookEditTool.js'
let _primitiveTools: readonly Tool[] | undefined
/**
* Primitive tools hidden from direct model use when REPL mode is on
* (REPL_ONLY_TOOLS) but still accessible inside the REPL VM context.
* Exported so display-side code (collapseReadSearch, renderers) can
* classify/render virtual messages for these tools even when they're
* absent from the filtered execution tools list.
*
* Lazy getter — the import chain collapseReadSearch.ts → primitiveTools.ts
* → FileReadTool.tsx → ... loops back through the tool registry, so a
* top-level const hits "Cannot access before initialization". Deferring
* to call time avoids the TDZ.
*
* Referenced directly rather than via getAllBaseTools() because that
* excludes Glob/Grep when hasEmbeddedSearchTools() is true.
*/
export function getReplPrimitiveTools(): readonly Tool[] {
return (_primitiveTools ??= [
FileReadTool,
FileWriteTool,
FileEditTool,
GlobTool,
GrepTool,
BashTool,
NotebookEditTool,
AgentTool,
])
}