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,136 @@
import { mock, describe, expect, test } from "bun:test";
// Mock heavy deps
mock.module("src/utils/model/agent.js", () => ({
getDefaultSubagentModel: () => undefined,
}));
mock.module("src/utils/settings/constants.js", () => ({
getSourceDisplayName: (source: string) => source,
}));
const {
resolveAgentOverrides,
compareAgentsByName,
AGENT_SOURCE_GROUPS,
} = await import("../agentDisplay");
function makeAgent(agentType: string, source: string): any {
return { agentType, source, name: agentType };
}
describe("resolveAgentOverrides", () => {
test("marks no overrides when all agents active", () => {
const agents = [makeAgent("builder", "userSettings")];
const result = resolveAgentOverrides(agents, agents);
expect(result).toHaveLength(1);
expect(result[0].overriddenBy).toBeUndefined();
});
test("marks inactive agent as overridden", () => {
const allAgents = [
makeAgent("builder", "projectSettings"),
makeAgent("builder", "userSettings"),
];
const activeAgents = [makeAgent("builder", "userSettings")];
const result = resolveAgentOverrides(allAgents, activeAgents);
const projectAgent = result.find(
(a: any) => a.source === "projectSettings",
);
expect(projectAgent?.overriddenBy).toBe("userSettings");
});
test("overriddenBy shows the overriding agent source", () => {
const allAgents = [makeAgent("tester", "localSettings")];
const activeAgents = [makeAgent("tester", "policySettings")];
const result = resolveAgentOverrides(allAgents, activeAgents);
expect(result[0].overriddenBy).toBe("policySettings");
});
test("deduplicates agents by (agentType, source)", () => {
const agents = [
makeAgent("builder", "userSettings"),
makeAgent("builder", "userSettings"), // duplicate
];
const result = resolveAgentOverrides(agents, agents.slice(0, 1));
expect(result).toHaveLength(1);
});
test("preserves agent definition properties", () => {
const agents = [{ agentType: "a", source: "userSettings", name: "Agent A" }] as any[];
const result = resolveAgentOverrides(agents, agents);
expect((result[0] as any).name).toBe("Agent A");
expect(result[0].agentType).toBe("a");
});
test("handles empty arrays", () => {
expect(resolveAgentOverrides([], [])).toEqual([]);
});
test("handles agent from git worktree (duplicate detection)", () => {
const agents = [
makeAgent("builder", "projectSettings"),
makeAgent("builder", "projectSettings"),
makeAgent("builder", "localSettings"),
];
const result = resolveAgentOverrides(agents, agents.slice(0, 1));
// Deduped: projectSettings appears once, localSettings once
expect(result).toHaveLength(2);
});
});
describe("compareAgentsByName", () => {
test("sorts alphabetically ascending", () => {
const a = makeAgent("alpha", "userSettings");
const b = makeAgent("beta", "userSettings");
expect(compareAgentsByName(a, b)).toBeLessThan(0);
});
test("returns negative when a.name < b.name", () => {
const a = makeAgent("a", "s");
const b = makeAgent("b", "s");
expect(compareAgentsByName(a, b)).toBeLessThan(0);
});
test("returns positive when a.name > b.name", () => {
const a = makeAgent("z", "s");
const b = makeAgent("a", "s");
expect(compareAgentsByName(a, b)).toBeGreaterThan(0);
});
test("returns 0 for same name", () => {
const a = makeAgent("same", "s");
const b = makeAgent("same", "s");
expect(compareAgentsByName(a, b)).toBe(0);
});
test("is case-insensitive (sensitivity: base)", () => {
const a = makeAgent("Alpha", "s");
const b = makeAgent("alpha", "s");
expect(compareAgentsByName(a, b)).toBe(0);
});
});
describe("AGENT_SOURCE_GROUPS", () => {
test("contains expected source groups in order", () => {
expect(AGENT_SOURCE_GROUPS).toHaveLength(7);
expect(AGENT_SOURCE_GROUPS[0]).toEqual({
label: "User agents",
source: "userSettings",
});
expect(AGENT_SOURCE_GROUPS[6]).toEqual({
label: "Built-in agents",
source: "built-in",
});
});
test("has unique labels", () => {
const labels = AGENT_SOURCE_GROUPS.map((g) => g.label);
expect(new Set(labels).size).toBe(labels.length);
});
test("has unique sources", () => {
const sources = AGENT_SOURCE_GROUPS.map((g) => g.source);
expect(new Set(sources).size).toBe(sources.length);
});
});