mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-24 17:11:20 +08:00
feat(opencode): 全面升级OpenCode集成 (#2251)
- 修复ecc-hooks.ts中的硬编码ECC_VERSION(从package.json读取) - 改进错误处理机制(统一模式、详细错误信息) - 增强类型安全(添加ToolArgs、ToolInput等类型定义) - 改进跨平台兼容性(支持macOS、Windows、Linux) - 添加dependency-analyzer工具(依赖分析) - 改进format-code工具(错误处理、跨平台支持) - 改进lint-check工具(错误处理、跨平台支持) - 更新文档(代理26个、工具8个、命令26个) - 添加工具测试(6个测试用例) - 改进现有测试(7个测试用例) 所有测试通过(16/16) Co-authored-by: Pual-LI-6 <dj2112236494@outlook.com>
This commit is contained in:
committed by
GitHub
parent
e53b4d9e39
commit
3a08b0c7a8
@@ -3,68 +3,119 @@
|
||||
*
|
||||
* Returns the formatter command that should be run for a given file.
|
||||
* This avoids shell execution assumptions while still giving precise guidance.
|
||||
* Supports cross-platform command generation.
|
||||
*/
|
||||
|
||||
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
||||
import * as path from "path"
|
||||
import * as fs from "fs"
|
||||
|
||||
type Formatter = "biome" | "prettier" | "black" | "gofmt" | "rustfmt"
|
||||
type Formatter = "biome" | "prettier" | "black" | "gofmt" | "rustfmt" | "swift-format"
|
||||
|
||||
interface FormatResult {
|
||||
success: boolean
|
||||
formatter?: Formatter
|
||||
command?: string
|
||||
instructions?: string
|
||||
message?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
const formatCodeTool: ToolDefinition = tool({
|
||||
description:
|
||||
"Detect formatter for a file and return the exact command to run (Biome, Prettier, Black, gofmt, rustfmt).",
|
||||
"Detect formatter for a file and return the exact command to run (Biome, Prettier, Black, gofmt, rustfmt, swift-format). Supports cross-platform command generation.",
|
||||
args: {
|
||||
filePath: tool.schema.string().describe("Path to the file to format"),
|
||||
formatter: tool.schema
|
||||
.enum(["biome", "prettier", "black", "gofmt", "rustfmt"])
|
||||
.enum(["biome", "prettier", "black", "gofmt", "rustfmt", "swift-format"])
|
||||
.optional()
|
||||
.describe("Optional formatter override"),
|
||||
},
|
||||
async execute(args, context) {
|
||||
const cwd = context.worktree || context.directory
|
||||
const ext = args.filePath.split(".").pop()?.toLowerCase() || ""
|
||||
const detected = args.formatter || detectFormatter(cwd, ext)
|
||||
async execute(args, context): Promise<string> {
|
||||
try {
|
||||
const cwd = context.worktree || context.directory
|
||||
const ext = args.filePath.split(".").pop()?.toLowerCase() || ""
|
||||
const detected = args.formatter || detectFormatter(cwd, ext)
|
||||
|
||||
if (!detected) {
|
||||
if (!detected) {
|
||||
return JSON.stringify({
|
||||
success: false,
|
||||
message: `No formatter detected for .${ext} files`,
|
||||
supportedFormatters: ["biome", "prettier", "black", "gofmt", "rustfmt", "swift-format"],
|
||||
})
|
||||
}
|
||||
|
||||
const command = buildFormatterCommand(detected, args.filePath, cwd)
|
||||
return JSON.stringify({
|
||||
success: true,
|
||||
formatter: detected,
|
||||
command,
|
||||
instructions: `Run this command:\n\n${command}`,
|
||||
platform: process.platform,
|
||||
})
|
||||
} catch (error: unknown) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
return JSON.stringify({
|
||||
success: false,
|
||||
message: `No formatter detected for .${ext} files`,
|
||||
error: `Failed to detect formatter: ${errorMessage}`,
|
||||
filePath: args.filePath,
|
||||
})
|
||||
}
|
||||
|
||||
const command = buildFormatterCommand(detected, args.filePath)
|
||||
return JSON.stringify({
|
||||
success: true,
|
||||
formatter: detected,
|
||||
command,
|
||||
instructions: `Run this command:\n\n${command}`,
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
export default formatCodeTool
|
||||
|
||||
function detectFormatter(cwd: string, ext: string): Formatter | null {
|
||||
// Check for formatter config files
|
||||
const hasConfig = (configFiles: string[]): boolean => {
|
||||
return configFiles.some(configFile => fs.existsSync(path.join(cwd, configFile)))
|
||||
}
|
||||
|
||||
// JavaScript/TypeScript files
|
||||
if (["ts", "tsx", "js", "jsx", "json", "css", "scss", "md", "yaml", "yml"].includes(ext)) {
|
||||
if (fs.existsSync(path.join(cwd, "biome.json")) || fs.existsSync(path.join(cwd, "biome.jsonc"))) {
|
||||
if (hasConfig(["biome.json", "biome.jsonc"])) {
|
||||
return "biome"
|
||||
}
|
||||
return "prettier"
|
||||
}
|
||||
if (["py", "pyi"].includes(ext)) return "black"
|
||||
if (ext === "go") return "gofmt"
|
||||
if (ext === "rs") return "rustfmt"
|
||||
|
||||
// Python files
|
||||
if (["py", "pyi"].includes(ext)) {
|
||||
return "black"
|
||||
}
|
||||
|
||||
// Go files
|
||||
if (ext === "go") {
|
||||
return "gofmt"
|
||||
}
|
||||
|
||||
// Rust files
|
||||
if (ext === "rs") {
|
||||
return "rustfmt"
|
||||
}
|
||||
|
||||
// Swift files
|
||||
if (ext === "swift") {
|
||||
return "swift-format"
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function buildFormatterCommand(formatter: Formatter, filePath: string): string {
|
||||
function buildFormatterCommand(formatter: Formatter, filePath: string, cwd?: string): string {
|
||||
// Normalize path for cross-platform compatibility
|
||||
const normalizedPath = path.normalize(filePath)
|
||||
|
||||
// Build command based on formatter and platform
|
||||
const commands: Record<Formatter, string> = {
|
||||
biome: `npx @biomejs/biome format --write ${filePath}`,
|
||||
prettier: `npx prettier --write ${filePath}`,
|
||||
black: `black ${filePath}`,
|
||||
gofmt: `gofmt -w ${filePath}`,
|
||||
rustfmt: `rustfmt ${filePath}`,
|
||||
biome: `npx @biomejs/biome format --write ${normalizedPath}`,
|
||||
prettier: `npx prettier --write ${normalizedPath}`,
|
||||
black: `black ${normalizedPath}`,
|
||||
gofmt: `gofmt -w ${normalizedPath}`,
|
||||
rustfmt: `rustfmt ${normalizedPath}`,
|
||||
"swift-format": `swift-format format --in-place ${normalizedPath}`,
|
||||
}
|
||||
|
||||
return commands[formatter]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user