From ebdf6485023c22070fcd1e8e8dd6cb0129ae7b16 Mon Sep 17 00:00:00 2001 From: michaelbguo Date: Sat, 28 Mar 2026 19:59:24 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20claudeInternal?= =?UTF-8?q?=20=E4=B8=8E=20codexInternal=20=E6=9E=9A=E4=B8=BE=E5=8F=8A?= =?UTF-8?q?=E5=86=85=E9=83=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chops/Models/ToolSource.swift | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Chops/Models/ToolSource.swift b/Chops/Models/ToolSource.swift index d20deab..f87a72c 100644 --- a/Chops/Models/ToolSource.swift +++ b/Chops/Models/ToolSource.swift @@ -3,9 +3,11 @@ import SwiftUI enum ToolSource: String, Codable, CaseIterable, Identifiable { case agents case claude + case claudeInternal case cursor case windsurf case codex + case codexInternal case copilot case aider case amp @@ -21,9 +23,11 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { var displayName: String { switch self { case .claude: "Claude Code" + case .claudeInternal: "Claude Internal" case .cursor: "Cursor" case .windsurf: "Windsurf" case .codex: "Codex" + case .codexInternal: "Codex Internal" case .copilot: "Copilot" case .aider: "Aider" case .amp: "Amp" @@ -41,9 +45,11 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { var iconName: String { switch self { case .claude: "brain.head.profile" + case .claudeInternal: "brain.head.profile" case .cursor: "cursorarrow.rays" case .windsurf: "wind" case .codex: "book.closed" + case .codexInternal: "book.closed" case .copilot: "airplane" case .aider: "wrench.and.screwdriver" case .amp: "bolt.fill" @@ -61,8 +67,10 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { var logoAssetName: String? { switch self { case .claude: "tool-claude" + case .claudeInternal: "tool-claude" case .cursor: "tool-cursor" case .codex: "tool-codex" + case .codexInternal: "tool-codex" case .windsurf: "tool-windsurf" case .copilot: "tool-copilot" case .amp: "tool-amp" @@ -76,9 +84,11 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { var color: Color { switch self { case .claude: .orange + case .claudeInternal: .brown case .cursor: .blue case .windsurf: .teal case .codex: .green + case .codexInternal: .mint case .copilot: .purple case .aider: .yellow case .amp: .pink @@ -96,8 +106,10 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { let home = FileManager.default.homeDirectoryForCurrentUser.path switch self { case .claude: return ["\(home)/.claude/agents"] + case .claudeInternal: return ["\(home)/.claude-internal/agents"] case .cursor: return ["\(home)/.cursor/agents"] case .codex: return ["\(home)/.codex/agents"] + case .codexInternal: return ["\(home)/.codex-internal/agents"] default: return [] } } @@ -112,9 +124,11 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { }() switch self { case .claude: return ["\(home)/.claude/skills"] + case .claudeInternal: return ["\(home)/.claude-internal/skills"] case .cursor: return ["\(home)/.cursor/skills", "\(home)/.cursor/rules"] case .windsurf: return ["\(home)/.codeium/windsurf/memories", "\(home)/.windsurf/rules"] case .codex: return ["\(home)/.codex/skills"] + case .codexInternal: return ["\(home)/.codex-internal/skills"] case .copilot: return ["\(home)/.copilot/skills"] case .aider: return [] case .amp: return ["\(configHome)/amp/skills"] @@ -141,6 +155,10 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { || fm.fileExists(atPath: "\(home)/.claude/CLAUDE.md") || fm.fileExists(atPath: "\(home)/.claude/plugins/installed_plugins.json") || Self.cliBinaryExists("claude") + case .claudeInternal: + return fm.fileExists(atPath: "\(home)/.claude-internal/settings.json") + || fm.fileExists(atPath: "\(home)/.claude-internal/CLAUDE.md") + || Self.cliBinaryExists("claude-internal") case .cursor: return fm.fileExists(atPath: "/Applications/Cursor.app") || fm.fileExists(atPath: "\(home)/.cursor/argv.json") @@ -151,6 +169,10 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { return fm.fileExists(atPath: "\(home)/.codex/config.toml") || fm.fileExists(atPath: "\(home)/.codex/auth.json") || Self.cliBinaryExists("codex") + case .codexInternal: + return fm.fileExists(atPath: "\(home)/.codex-internal/config.toml") + || fm.fileExists(atPath: "\(home)/.codex-internal/auth.json") + || Self.cliBinaryExists("codex-internal") case .amp: let configHome = ProcessInfo.processInfo.environment["XDG_CONFIG_HOME"] .flatMap { $0.isEmpty ? nil : $0 } ?? "\(home)/.config" From 41eb3e75248725bab8ee817e524b7897feaba306 Mon Sep 17 00:00:00 2001 From: michaelbguo Date: Sat, 28 Mar 2026 20:12:29 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20claudeInternal?= =?UTF-8?q?=20=E4=B8=8E=20codexInternal=20=E5=86=85=E9=83=A8=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chops/Models/ToolSource.swift | 11 +++++++++++ .../tool-codebuddy.imageset/Contents.json | 16 ++++++++++++++++ .../tool-codebuddy.imageset/logo.svg | 1 + Chops/Services/SkillScanner.swift | 2 ++ Chops/Views/Shared/NewSkillSheet.swift | 9 ++++++--- Chops/Views/Shared/ToolBadge.swift | 3 +++ 6 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/Contents.json create mode 100644 Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/logo.svg diff --git a/Chops/Models/ToolSource.swift b/Chops/Models/ToolSource.swift index f87a72c..82d81f0 100644 --- a/Chops/Models/ToolSource.swift +++ b/Chops/Models/ToolSource.swift @@ -8,6 +8,7 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { case windsurf case codex case codexInternal + case codebuddy case copilot case aider case amp @@ -28,6 +29,7 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { case .windsurf: "Windsurf" case .codex: "Codex" case .codexInternal: "Codex Internal" + case .codebuddy: "CodeBuddy" case .copilot: "Copilot" case .aider: "Aider" case .amp: "Amp" @@ -50,6 +52,7 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { case .windsurf: "wind" case .codex: "book.closed" case .codexInternal: "book.closed" + case .codebuddy: "hammer" case .copilot: "airplane" case .aider: "wrench.and.screwdriver" case .amp: "bolt.fill" @@ -71,6 +74,7 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { case .cursor: "tool-cursor" case .codex: "tool-codex" case .codexInternal: "tool-codex" + case .codebuddy: "tool-codebuddy" case .windsurf: "tool-windsurf" case .copilot: "tool-copilot" case .amp: "tool-amp" @@ -89,6 +93,7 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { case .windsurf: .teal case .codex: .green case .codexInternal: .mint + case .codebuddy: .blue case .copilot: .purple case .aider: .yellow case .amp: .pink @@ -110,6 +115,7 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { case .cursor: return ["\(home)/.cursor/agents"] case .codex: return ["\(home)/.codex/agents"] case .codexInternal: return ["\(home)/.codex-internal/agents"] + case .codebuddy: return ["\(home)/.codebuddy/agents"] default: return [] } } @@ -129,6 +135,7 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { case .windsurf: return ["\(home)/.codeium/windsurf/memories", "\(home)/.windsurf/rules"] case .codex: return ["\(home)/.codex/skills"] case .codexInternal: return ["\(home)/.codex-internal/skills"] + case .codebuddy: return ["\(home)/.codebuddy/skills"] case .copilot: return ["\(home)/.copilot/skills"] case .aider: return [] case .amp: return ["\(configHome)/amp/skills"] @@ -173,6 +180,10 @@ enum ToolSource: String, Codable, CaseIterable, Identifiable { return fm.fileExists(atPath: "\(home)/.codex-internal/config.toml") || fm.fileExists(atPath: "\(home)/.codex-internal/auth.json") || Self.cliBinaryExists("codex-internal") + case .codebuddy: + return fm.fileExists(atPath: "\(home)/.codebuddy/settings.json") + || fm.fileExists(atPath: "\(home)/.codebuddy/CODEBUDDY.md") + || Self.cliBinaryExists("codebuddy") case .amp: let configHome = ProcessInfo.processInfo.environment["XDG_CONFIG_HOME"] .flatMap { $0.isEmpty ? nil : $0 } ?? "\(home)/.config" diff --git a/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/Contents.json b/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/Contents.json new file mode 100644 index 0000000..69c1978 --- /dev/null +++ b/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "logo.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/logo.svg b/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/logo.svg new file mode 100644 index 0000000..450caea --- /dev/null +++ b/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/logo.svg @@ -0,0 +1 @@ + diff --git a/Chops/Services/SkillScanner.swift b/Chops/Services/SkillScanner.swift index 42d7a2e..6fec064 100644 --- a/Chops/Services/SkillScanner.swift +++ b/Chops/Services/SkillScanner.swift @@ -56,6 +56,8 @@ final class SkillScanner { (".cursor/agents", .cursor, .agent), (".codex/skills", .codex, .skill), (".codex/agents", .codex, .agent), + (".codebuddy/skills", .codebuddy, .skill), + (".codebuddy/agents", .codebuddy, .agent), (".windsurf/rules", .windsurf, .skill), (".github", .copilot, .skill), (".github/agents", .copilot, .agent), diff --git a/Chops/Views/Shared/NewSkillSheet.swift b/Chops/Views/Shared/NewSkillSheet.swift index 782607d..bbc9948 100644 --- a/Chops/Views/Shared/NewSkillSheet.swift +++ b/Chops/Views/Shared/NewSkillSheet.swift @@ -9,8 +9,8 @@ struct NewSkillSheet: View { @State private var selectedTool: ToolSource = .claude @State private var errorMessage: String? - private let skillCreatableTools: [ToolSource] = [.claude, .agents, .cursor, .codex, .amp, .opencode, .pi, .antigravity] - private let agentCreatableTools: [ToolSource] = [.claude, .cursor, .codex] + private let skillCreatableTools: [ToolSource] = [.claude, .agents, .cursor, .codex, .codebuddy, .amp, .opencode, .pi, .antigravity] + private let agentCreatableTools: [ToolSource] = [.claude, .cursor, .codex, .codebuddy] private var itemKind: ItemKind { appState.newItemKind } private var isAgent: Bool { itemKind == .agent } @@ -113,6 +113,9 @@ struct NewSkillSheet: View { case .codex: basePath = "\(fm.homeDirectoryForCurrentUser.path)/.codex/skills/\(sanitizedName)" fileName = "SKILL.md" + case .codebuddy: + basePath = "\(fm.homeDirectoryForCurrentUser.path)/.codebuddy/skills/\(sanitizedName)" + fileName = "SKILL.md" case .amp: basePath = "\(configHome)/amp/skills/\(sanitizedName)" fileName = "SKILL.md" @@ -204,7 +207,7 @@ struct NewSkillSheet: View { Add your skill instructions here. """ - case .codex, .amp, .opencode, .pi, .agents, .antigravity: + case .codex, .codebuddy, .amp, .opencode, .pi, .agents, .antigravity: return """ --- name: \(skillID) diff --git a/Chops/Views/Shared/ToolBadge.swift b/Chops/Views/Shared/ToolBadge.swift index bdbcfc1..3b45477 100644 --- a/Chops/Views/Shared/ToolBadge.swift +++ b/Chops/Views/Shared/ToolBadge.swift @@ -37,9 +37,12 @@ extension ToolSource { var shortLabel: String { switch self { case .claude: "CC" + case .claudeInternal: "CI" case .cursor: "CU" case .windsurf: "WS" case .codex: "CX" + case .codexInternal: "XI" + case .codebuddy: "CB" case .copilot: "CP" case .aider: "AI" case .amp: "AM" From 5235dfedc5e6710cb7e6ec4da3e2930d36ac09c6 Mon Sep 17 00:00:00 2001 From: michaelbguo Date: Sat, 28 Mar 2026 20:12:37 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20template-render?= =?UTF-8?q?ing-intent=20=E5=B1=9E=E6=80=A7=E4=B8=BA=20original?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets.xcassets/tool-codebuddy.imageset/Contents.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/Contents.json b/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/Contents.json index 69c1978..1c138b6 100644 --- a/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/Contents.json +++ b/Chops/Resources/Assets.xcassets/tool-codebuddy.imageset/Contents.json @@ -11,6 +11,6 @@ }, "properties" : { "preserves-vector-representation" : true, - "template-rendering-intent" : "template" + "template-rendering-intent" : "original" } }