package adapter import ( "fmt" "os" "path/filepath" "strings" "skillmgr/internal/types" ) // OpenCodeAdapter OpenCode 平台适配器 type OpenCodeAdapter struct{} // GetSkillInstallPath 获取 skill 安装路径 func (a *OpenCodeAdapter) GetSkillInstallPath(scope types.Scope, skillName string) (string, error) { base, err := getBasePath(scope) if err != nil { return "", err } if scope == types.ScopeGlobal { // 全局: ~/.config/opencode/skills// return filepath.Join(base, ".config", "opencode", "skills", skillName), nil } // 项目级: ./.opencode/skills// return filepath.Join(base, ".opencode", "skills", skillName), nil } // GetCommandInstallPath 获取 command 安装路径 func (a *OpenCodeAdapter) GetCommandInstallPath(scope types.Scope, commandGroup string) (string, error) { base, err := getBasePath(scope) if err != nil { return "", err } if scope == types.ScopeGlobal { // 全局: ~/.config/opencode/commands/(扁平化,所有命令在同一目录) return filepath.Join(base, ".config", "opencode", "commands"), nil } // 项目级: ./.opencode/commands/ return filepath.Join(base, ".opencode", "commands"), nil } // AdaptSkill 适配 skill(与 Claude 相同,保持目录结构) func (a *OpenCodeAdapter) AdaptSkill(sourcePath, destBasePath string) (map[string]string, error) { mapping := make(map[string]string) err := filepath.Walk(sourcePath, func(path string, info os.FileInfo, err error) error { if err != nil { return err } relPath, err := filepath.Rel(sourcePath, path) if err != nil { return fmt.Errorf("计算相对路径失败: %w", err) } destPath := filepath.Join(destBasePath, relPath) if !info.IsDir() { mapping[path] = destPath } return nil }) return mapping, err } // AdaptCommand 适配 command(扁平化文件名:-.md) func (a *OpenCodeAdapter) AdaptCommand(sourcePath, destBasePath, commandGroup string) (map[string]string, error) { mapping := make(map[string]string) files, err := filepath.Glob(filepath.Join(sourcePath, "*.md")) if err != nil { return nil, err } for _, file := range files { fileName := filepath.Base(file) baseName := strings.TrimSuffix(fileName, ".md") // 重命名:init.md → lyxy-kb-init.md newName := commandGroup + "-" + baseName + ".md" destPath := filepath.Join(destBasePath, newName) mapping[file] = destPath } return mapping, nil }