feat(ai): add CodeBuddy Code CLI provider
This commit is contained in:
1 parent
f5e7a37c8d
commit
1a3645a04d
38 files changed
+1697
-19
No files matched your search
@@ -0,0 +1 @@
|
||||
<svg width="873" height="612" viewBox="0 0 873 612" fill="none" xmlns="http://www.w3.org/2000/svg"><title>CodeBuddy Code</title><path d="M611.24 0C631.42 0.472994 652.67 0.151247 672.917 0.149414L783.53 0.125977L783.58 114.446C783.58 131.188 782.828 155.62 783.732 171.959C793.764 172.165 866.262 170.817 869.239 173.294C869.728 173.699 870.138 174.379 870.486 174.905L872.008 175.384C873.402 179.664 872.344 228.902 872.338 236.71C872.313 263.731 873.157 518.745 871.959 521.349C871.837 521.605 871.58 521.905 871.415 522.119L869.141 522.375C841.374 521.684 811.566 522.247 783.646 522.271C784.001 538.325 783.695 555.229 783.72 571.344C783.738 583.932 784.056 598.74 783.451 611.182C613.783 610.846 273.598 611.469 87.6807 611.041C87.3452 610.736 87.0093 610.436 86.6738 610.137L86.2393 607.375C86.831 602.028 86.4052 585.668 86.3984 579.416L86.2812 521.838C82.9453 522.522 63.9127 522.272 59.0283 522.266L0.391602 522.259L0.398438 278.798L0.427734 209.334C0.430803 201.523 0.934097 181.445 0 174.62C0.578928 172.779 0.0735528 173.48 1.33105 172.293C17.2444 171.377 36.4875 172.458 52.7188 172.065C59.0087 171.913 81.4327 171.805 86.0195 172.717L85.9805 56.9336L85.9072 21.3467C85.895 15.7024 85.6474 5.58945 86.2832 0.297852L89.3057 0.0224609C145.847 1.00635 204.767 0.149918 261.493 0.137695L261.571 58.8008C261.576 63.634 261.865 82.5764 261.06 86.293C288.984 85.6006 319.108 86.1736 347.17 86.1797L509.068 86.1846L576.67 86.1357C582.985 86.1314 604.124 85.7374 608.728 86.8135C607.982 81.7879 608.33 64.0733 608.33 58.0186L608.428 1.34473C609.424 -0.0534957 608.978 0.391111 611.24 0ZM697.12 173.048C694.553 171.797 619.805 172.389 610.134 172.389L279.41 172.397L201.266 172.392C193.899 172.39 184.497 172.27 176.995 172.399C175.636 172.423 175.324 173.65 174.702 174.81L172.704 175.383C172.033 177.999 172.341 204.836 172.348 208.9L172.398 294.312L172.37 445.969L172.349 494.032C172.347 501.781 172.011 513.954 172.658 521.324C174.533 523.401 174.111 521.52 174.854 522.534C175.611 523.561 175.655 525.034 177.928 525.016C181.545 524.988 185.335 524.97 189.044 524.966H347.752L604.785 524.96L669.054 525.009C673.406 525.009 693.575 525.296 696.857 524.643C697.499 523.408 697.493 523.505 697.542 522.118C696.815 500.607 697.389 475.931 697.389 454.243V327.045L697.383 228.248C697.383 211.843 696.729 190.781 697.64 174.935L697.12 173.048Z" fill="#00BC90"/><path d="M347.56 260.864L349.808 261.441C351.42 265.483 350.329 418.222 350.229 435.792C344.53 436.85 263.503 436.929 260.894 435.722L261.464 433.765C261.114 420.392 261.416 405.532 261.413 392.005L261.412 313.381C261.422 299.699 262.22 276.275 261.106 263.652C261.428 261.859 261.059 262.619 262.19 261.257C268.232 260.664 277.082 261.319 283.456 261.111C303.554 260.454 327.973 262.241 347.56 260.864Z" fill="#00BC90"/><path d="M608.752 260.881L610.641 261.353C612.854 266.169 610.268 347.019 611.302 358.962C611.693 363.539 611.436 434.199 610.892 435.767C610.293 435.847 609.248 436.027 608.685 436.028C584.88 436.436 548.549 435.89 523.533 435.943C522.702 435.945 522.567 435.098 522.127 434.149C522.787 429.284 522.445 415.565 522.445 410.114L522.415 362.246L522.457 298.316C522.463 288.598 522.94 272.837 522.097 263.668L522.586 261.78C525.887 259.891 595.756 261.699 608.752 260.881Z" fill="#00BC90"/></svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -2640,7 +2640,7 @@ function normalizeMaxRetries(value: number | undefined): number {
|
||||
const aiDeleteConfirmOpen = ref(false);
|
||||
const aiDeleteConfigId = ref<string | null>(null);
|
||||
|
||||
const CLI_AI_PROVIDERS = new Set<AiProvider>(["claude-code-cli", "codex-cli", "opencode-cli", "pi-agent-cli", "cursor-cli", "grok-cli"]);
|
||||
const CLI_AI_PROVIDERS = new Set<AiProvider>(["claude-code-cli", "codex-cli", "opencode-cli", "pi-agent-cli", "cursor-cli", "grok-cli", "codebuddy-cli"]);
|
||||
const OPENCODE_CONTROL_ENV = new Set(["OPENCODE_CONFIG", "OPENCODE_CONFIG_CONTENT", "OPENCODE_CONFIG_DIR", "OPENCODE_DB", "OPENCODE_PERMISSION", "OPENCODE_DISABLE_PROJECT_CONFIG"]);
|
||||
const CURSOR_CONTROL_ENV = new Set(["CURSOR_CONFIG_DIR", "CURSOR_DATA_DIR"]);
|
||||
const aiProviderOptions = computed(() => Object.values(AI_PROVIDER_PRESETS).filter((provider) => !isWeb || !CLI_AI_PROVIDERS.has(provider.provider)));
|
||||
@@ -2670,6 +2670,8 @@ const aiEditCursorCliPath = ref("");
|
||||
const aiEditCursorCliEnvRows = ref<AiEnvRow[]>([]);
|
||||
const aiEditGrokCliPath = ref("");
|
||||
const aiEditGrokCliEnvRows = ref<AiEnvRow[]>([]);
|
||||
const aiEditCodeBuddyCliPath = ref("");
|
||||
const aiEditCodeBuddyCliEnvRows = ref<AiEnvRow[]>([]);
|
||||
|
||||
const aiAnthropicMessagesMode = computed(() => aiEditApiStyle.value === "anthropic-messages");
|
||||
|
||||
@@ -2703,6 +2705,7 @@ const aiIsPiAgentCli = computed(() => aiEditProvider.value === "pi-agent-cli");
|
||||
const aiIsOpenCodeCli = computed(() => aiEditProvider.value === "opencode-cli");
|
||||
const aiIsCursorCli = computed(() => aiEditProvider.value === "cursor-cli");
|
||||
const aiIsGrokCli = computed(() => aiEditProvider.value === "grok-cli");
|
||||
const aiIsCodeBuddyCli = computed(() => aiEditProvider.value === "codebuddy-cli");
|
||||
const aiIsCliProvider = computed(() => CLI_AI_PROVIDERS.has(aiEditProvider.value));
|
||||
const aiCliProviderLabel = computed(() => selectedAiProviderPreset.value.label);
|
||||
const aiCliCommandName = computed(() => {
|
||||
@@ -2711,6 +2714,7 @@ const aiCliCommandName = computed(() => {
|
||||
if (aiIsOpenCodeCli.value) return "opencode";
|
||||
if (aiIsCursorCli.value) return "agent";
|
||||
if (aiIsGrokCli.value) return "grok";
|
||||
if (aiIsCodeBuddyCli.value) return "codebuddy";
|
||||
return "codex";
|
||||
});
|
||||
const aiCliLoginCommand = computed(() => {
|
||||
@@ -2719,6 +2723,7 @@ const aiCliLoginCommand = computed(() => {
|
||||
if (aiIsOpenCodeCli.value) return "opencode auth login";
|
||||
if (aiIsCursorCli.value) return "agent login";
|
||||
if (aiIsGrokCli.value) return "grok login";
|
||||
if (aiIsCodeBuddyCli.value) return "codebuddy";
|
||||
return "codex login";
|
||||
});
|
||||
const aiEditCliPath = computed({
|
||||
@@ -2728,6 +2733,7 @@ const aiEditCliPath = computed({
|
||||
if (aiIsOpenCodeCli.value) return aiEditOpenCodeCliPath.value;
|
||||
if (aiIsCursorCli.value) return aiEditCursorCliPath.value;
|
||||
if (aiIsGrokCli.value) return aiEditGrokCliPath.value;
|
||||
if (aiIsCodeBuddyCli.value) return aiEditCodeBuddyCliPath.value;
|
||||
return aiEditCodexCliPath.value;
|
||||
},
|
||||
set: (value: string) => {
|
||||
@@ -2741,6 +2747,8 @@ const aiEditCliPath = computed({
|
||||
aiEditCursorCliPath.value = value;
|
||||
} else if (aiIsGrokCli.value) {
|
||||
aiEditGrokCliPath.value = value;
|
||||
} else if (aiIsCodeBuddyCli.value) {
|
||||
aiEditCodeBuddyCliPath.value = value;
|
||||
} else {
|
||||
aiEditCodexCliPath.value = value;
|
||||
}
|
||||
@@ -2752,6 +2760,7 @@ const aiEditCliEnvRows = computed(() => {
|
||||
if (aiIsOpenCodeCli.value) return aiEditOpenCodeCliEnvRows.value;
|
||||
if (aiIsCursorCli.value) return aiEditCursorCliEnvRows.value;
|
||||
if (aiIsGrokCli.value) return aiEditGrokCliEnvRows.value;
|
||||
if (aiIsCodeBuddyCli.value) return aiEditCodeBuddyCliEnvRows.value;
|
||||
return aiEditCodexCliEnvRows.value;
|
||||
});
|
||||
watch(aiIsCliProvider, (isCliProvider) => {
|
||||
@@ -2850,6 +2859,8 @@ function removeCliEnvRow(id: string) {
|
||||
aiEditCursorCliEnvRows.value = aiEditCursorCliEnvRows.value.filter((row) => row.id !== id);
|
||||
} else if (aiIsGrokCli.value) {
|
||||
aiEditGrokCliEnvRows.value = aiEditGrokCliEnvRows.value.filter((row) => row.id !== id);
|
||||
} else if (aiIsCodeBuddyCli.value) {
|
||||
aiEditCodeBuddyCliEnvRows.value = aiEditCodeBuddyCliEnvRows.value.filter((row) => row.id !== id);
|
||||
} else {
|
||||
aiEditCodexCliEnvRows.value = aiEditCodexCliEnvRows.value.filter((row) => row.id !== id);
|
||||
}
|
||||
@@ -2884,6 +2895,8 @@ function currentAiEditConfig() {
|
||||
cursorCliEnv: aiIsCursorCli.value ? cliEnvFromRows(aiEditCursorCliEnvRows.value) : {},
|
||||
grokCliPath: aiEditGrokCliPath.value.trim() || undefined,
|
||||
grokCliEnv: aiIsGrokCli.value ? cliEnvFromRows(aiEditGrokCliEnvRows.value) : {},
|
||||
codebuddyCliPath: aiEditCodeBuddyCliPath.value.trim() || undefined,
|
||||
codebuddyCliEnv: aiIsCodeBuddyCli.value ? cliEnvFromRows(aiEditCodeBuddyCliEnvRows.value) : {},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2959,6 +2972,8 @@ function aiEnterEditMode(configId?: string) {
|
||||
aiEditCursorCliEnvRows.value = aiEnvRowsFromConfig(config.cursorCliEnv);
|
||||
aiEditGrokCliPath.value = config.grokCliPath ?? "";
|
||||
aiEditGrokCliEnvRows.value = aiEnvRowsFromConfig(config.grokCliEnv);
|
||||
aiEditCodeBuddyCliPath.value = config.codebuddyCliPath ?? "";
|
||||
aiEditCodeBuddyCliEnvRows.value = aiEnvRowsFromConfig(config.codebuddyCliEnv);
|
||||
}
|
||||
} else {
|
||||
aiEditConfigName.value = "";
|
||||
@@ -2986,6 +3001,8 @@ function aiEnterEditMode(configId?: string) {
|
||||
aiEditCursorCliEnvRows.value = [];
|
||||
aiEditGrokCliPath.value = "";
|
||||
aiEditGrokCliEnvRows.value = [];
|
||||
aiEditCodeBuddyCliPath.value = "";
|
||||
aiEditCodeBuddyCliEnvRows.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -142,6 +142,30 @@ describe("useAiModelCatalog", () => {
|
||||
expect(apiMock.aiListModels).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("tracks CodeBuddy executable and environment changes without depending on environment key order", async () => {
|
||||
const initial: AiConfigItem = {
|
||||
...config(),
|
||||
provider: "codebuddy-cli",
|
||||
endpoint: "",
|
||||
apiKey: "",
|
||||
model: "default",
|
||||
codebuddyCliPath: "/opt/homebrew/bin/codebuddy",
|
||||
codebuddyCliEnv: { HTTPS_PROXY: "http://127.0.0.1:7890", NO_PROXY: "localhost" },
|
||||
};
|
||||
apiMock.aiListModels.mockResolvedValueOnce([{ id: "first" }]).mockResolvedValueOnce([{ id: "second" }]);
|
||||
|
||||
await expect(catalog.loadModels(initial)).resolves.toEqual([{ id: "first" }]);
|
||||
await expect(
|
||||
catalog.loadModels({
|
||||
...initial,
|
||||
codebuddyCliEnv: { NO_PROXY: "localhost", HTTPS_PROXY: "http://127.0.0.1:7890" },
|
||||
}),
|
||||
).resolves.toEqual([{ id: "first" }]);
|
||||
await expect(catalog.loadModels({ ...initial, codebuddyCliPath: "/usr/local/bin/codebuddy" })).resolves.toEqual([{ id: "second" }]);
|
||||
|
||||
expect(apiMock.aiListModels).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("does not let a stale request overwrite a newer provider catalog", async () => {
|
||||
let resolveInitial: ((models: { id: string }[]) => void) | undefined;
|
||||
apiMock.aiListModels
|
||||
|
||||
@@ -59,6 +59,7 @@ function configSignature(config: AiConfigItem): string {
|
||||
piAgentCliPath: config.piAgentCliPath ?? null,
|
||||
opencodeCliPath: config.opencodeCliPath ?? null,
|
||||
cursorCliPath: config.cursorCliPath ?? null,
|
||||
codebuddyCliPath: config.codebuddyCliPath ?? null,
|
||||
connectionFingerprint: fingerprint(
|
||||
JSON.stringify({
|
||||
apiKey: config.apiKey,
|
||||
@@ -69,6 +70,7 @@ function configSignature(config: AiConfigItem): string {
|
||||
piAgentCliEnv: sortedRecord(config.piAgentCliEnv),
|
||||
opencodeCliEnv: sortedRecord(config.opencodeCliEnv),
|
||||
cursorCliEnv: sortedRecord(config.cursorCliEnv),
|
||||
codebuddyCliEnv: sortedRecord(config.codebuddyCliEnv),
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -52,6 +52,16 @@ const taggedAiCliErrorKeys: Record<string, string> = {
|
||||
grokCliMcpStartupFailed: "ai.cliErrors.grokCliMcpStartupFailed",
|
||||
grokCliCommandLineTooLong: "ai.cliErrors.grokCliCommandLineTooLong",
|
||||
grokCliRunFailed: "ai.cliErrors.grokCliRunFailed",
|
||||
codeBuddyNotInstalled: "ai.cliErrors.codeBuddyNotInstalled",
|
||||
codeBuddyCliPathInvalid: "ai.cliErrors.codeBuddyCliPathInvalid",
|
||||
codeBuddyEnvInvalid: "ai.cliErrors.codeBuddyEnvInvalid",
|
||||
codeBuddyEnvReserved: "ai.cliErrors.codeBuddyEnvReserved",
|
||||
codeBuddyNotAuthenticated: "ai.cliErrors.codeBuddyNotAuthenticated",
|
||||
codeBuddyTimeout: "ai.cliErrors.codeBuddyTimeout",
|
||||
codeBuddyMcpConfigInvalid: "ai.cliErrors.codeBuddyMcpConfigInvalid",
|
||||
codeBuddyMcpStartupFailed: "ai.cliErrors.codeBuddyMcpStartupFailed",
|
||||
codeBuddyProtocolError: "ai.cliErrors.codeBuddyProtocolError",
|
||||
codeBuddyRunFailed: "ai.cliErrors.codeBuddyRunFailed",
|
||||
cursorEnvInvalid: "ai.cliErrors.cursorEnvInvalid",
|
||||
cursorEnvReserved: "ai.cliErrors.cursorEnvReserved",
|
||||
cursorNotAuthenticated: "ai.cliErrors.cursorNotAuthenticated",
|
||||
|
||||
@@ -2362,6 +2362,16 @@ export default {
|
||||
grokCliMcpStartupFailed: "Grok loaded the MCP configuration but could not start DBX MCP Server. Check Settings > MCP and the diagnostics below.",
|
||||
grokCliCommandLineTooLong: "Windows rejected the Grok CLI command because it was too long. Update DBX and retry using the generated prompt file.",
|
||||
grokCliRunFailed: "Grok CLI exited unexpectedly. Use the error code and diagnostics below to identify the failing executable or CLI output.",
|
||||
codeBuddyNotInstalled: "CodeBuddy Code CLI was not found. Install CodeBuddy Code or set its executable path in Settings > AI.",
|
||||
codeBuddyCliPathInvalid: "The CodeBuddy Code CLI path is invalid. Select only the codebuddy executable and configure environment variables separately.",
|
||||
codeBuddyEnvInvalid: "A CodeBuddy environment variable name is invalid. Use names such as HTTPS_PROXY.",
|
||||
codeBuddyEnvReserved: "A DBX-managed MCP environment variable was overridden. Remove DBX_MCP_* variables from the provider configuration.",
|
||||
codeBuddyNotAuthenticated: "CodeBuddy Code is not authenticated. Open `codebuddy` in a terminal, sign in, and try again.",
|
||||
codeBuddyTimeout: "CodeBuddy Code CLI did not respond before the operation timed out.",
|
||||
codeBuddyMcpConfigInvalid: "CodeBuddy Code could not read the temporary DBX MCP configuration. Check the diagnostics below.",
|
||||
codeBuddyMcpStartupFailed: "CodeBuddy Code loaded the MCP configuration but could not start DBX MCP Server. Check Settings > MCP and the diagnostics below.",
|
||||
codeBuddyProtocolError: "CodeBuddy Code returned an invalid control response or JSON event stream. Check the CodeBuddy Code version and diagnostics below.",
|
||||
codeBuddyRunFailed: "CodeBuddy Code CLI exited unexpectedly. Use the error code and diagnostics below to identify the failing executable or CLI output.",
|
||||
cursorEnvInvalid: "A Cursor CLI environment variable name is invalid. Use names such as HTTPS_PROXY.",
|
||||
cursorEnvReserved: "A Cursor or DBX-managed environment variable was overridden. Remove CURSOR_CONFIG_DIR, CURSOR_DATA_DIR, and DBX_MCP_* variables from the provider configuration.",
|
||||
cursorNotAuthenticated: "Cursor CLI is not authenticated. Run `agent login` in a terminal and try again.",
|
||||
|
||||
@@ -2208,6 +2208,16 @@ export default withEnglishFallback({
|
||||
grokCliMcpStartupFailed: "Grok cargó la configuración MCP pero no pudo iniciar DBX MCP Server. Revisa Ajustes > MCP y los diagnósticos siguientes.",
|
||||
grokCliCommandLineTooLong: "Windows rechazó el comando de Grok CLI porque era demasiado largo. Actualiza DBX y vuelve a intentarlo con el archivo de prompt generado.",
|
||||
grokCliRunFailed: "Grok CLI terminó de forma inesperada. Usa el código de error y los diagnósticos siguientes para identificar el ejecutable o la salida fallida.",
|
||||
codeBuddyNotInstalled: "No se encontró CodeBuddy Code CLI. Instala CodeBuddy Code o configura la ruta del ejecutable en Ajustes > AI.",
|
||||
codeBuddyCliPathInvalid: "La ruta de CodeBuddy Code CLI no es válida. Selecciona solo el ejecutable codebuddy y configura las variables de entorno por separado.",
|
||||
codeBuddyEnvInvalid: "El nombre de una variable de entorno de CodeBuddy no es válido. Usa nombres como HTTPS_PROXY.",
|
||||
codeBuddyEnvReserved: "Se sobrescribió una variable MCP gestionada por DBX. Elimina las variables DBX_MCP_* de la configuración del proveedor.",
|
||||
codeBuddyNotAuthenticated: "CodeBuddy Code no está autenticado. Abre `codebuddy` en una terminal, inicia sesión y vuelve a intentarlo.",
|
||||
codeBuddyTimeout: "CodeBuddy Code CLI no respondió antes de que se agotara el tiempo de la operación.",
|
||||
codeBuddyMcpConfigInvalid: "CodeBuddy Code no pudo leer la configuración temporal de DBX MCP. Revisa los diagnósticos siguientes.",
|
||||
codeBuddyMcpStartupFailed: "CodeBuddy Code cargó la configuración MCP pero no pudo iniciar DBX MCP Server. Revisa Ajustes > MCP y los diagnósticos siguientes.",
|
||||
codeBuddyProtocolError: "CodeBuddy Code devolvió una respuesta de control o un flujo de eventos JSON no válido. Revisa la versión de CodeBuddy Code y los diagnósticos siguientes.",
|
||||
codeBuddyRunFailed: "CodeBuddy Code CLI terminó de forma inesperada. Usa el código de error y los diagnósticos siguientes para identificar el ejecutable o la salida fallida.",
|
||||
},
|
||||
run: "Ejecutar",
|
||||
readingSchema: "Leyendo esquema",
|
||||
|
||||
@@ -2348,6 +2348,16 @@ export default withEnglishFallback({
|
||||
grokCliMcpStartupFailed: "Grok ha caricato la configurazione MCP ma non ha potuto avviare DBX MCP Server. Controlla Impostazioni > MCP e i dettagli seguenti.",
|
||||
grokCliCommandLineTooLong: "Windows ha rifiutato il comando Grok CLI perché troppo lungo. Aggiorna DBX e riprova usando il file di prompt generato.",
|
||||
grokCliRunFailed: "Grok CLI è terminato in modo imprevisto. Usa il codice errore e i dettagli seguenti per identificare l'eseguibile o l'output non riuscito.",
|
||||
codeBuddyNotInstalled: "CodeBuddy Code CLI non è stato trovato. Installa CodeBuddy Code o imposta il percorso dell'eseguibile in Impostazioni > AI.",
|
||||
codeBuddyCliPathInvalid: "Il percorso di CodeBuddy Code CLI non è valido. Seleziona solo l'eseguibile codebuddy e configura separatamente le variabili d'ambiente.",
|
||||
codeBuddyEnvInvalid: "Il nome di una variabile d'ambiente di CodeBuddy non è valido. Usa nomi come HTTPS_PROXY.",
|
||||
codeBuddyEnvReserved: "È stata sovrascritta una variabile MCP gestita da DBX. Rimuovi le variabili DBX_MCP_* dalla configurazione del provider.",
|
||||
codeBuddyNotAuthenticated: "CodeBuddy Code non è autenticato. Apri `codebuddy` in un terminale, accedi e riprova.",
|
||||
codeBuddyTimeout: "CodeBuddy Code CLI non ha risposto prima della scadenza dell'operazione.",
|
||||
codeBuddyMcpConfigInvalid: "CodeBuddy Code non ha potuto leggere la configurazione temporanea di DBX MCP. Controlla i dettagli seguenti.",
|
||||
codeBuddyMcpStartupFailed: "CodeBuddy Code ha caricato la configurazione MCP ma non ha potuto avviare DBX MCP Server. Controlla Impostazioni > MCP e i dettagli seguenti.",
|
||||
codeBuddyProtocolError: "CodeBuddy Code ha restituito una risposta di controllo o un flusso di eventi JSON non valido. Controlla la versione di CodeBuddy Code e i dettagli seguenti.",
|
||||
codeBuddyRunFailed: "CodeBuddy Code CLI è terminato in modo imprevisto. Usa il codice errore e i dettagli seguenti per identificare l'eseguibile o l'output non riuscito.",
|
||||
},
|
||||
actions: {
|
||||
general: "Generale",
|
||||
|
||||
@@ -2242,6 +2242,16 @@ export default withEnglishFallback({
|
||||
grokCliMcpStartupFailed: "GrokはMCP設定を読み込みましたが、DBX MCP Serverを起動できません。設定 > MCPと以下の診断詳細を確認してください。",
|
||||
grokCliCommandLineTooLong: "Windowsが長すぎるGrok CLIコマンドを拒否しました。DBXを更新し、生成されたプロンプトファイルで再試行してください。",
|
||||
grokCliRunFailed: "Grok CLIが予期せず終了しました。エラーコードと以下の診断詳細から、失敗した実行ファイルまたはCLI出力を確認してください。",
|
||||
codeBuddyNotInstalled: "CodeBuddy Code CLIが見つかりません。CodeBuddy Codeをインストールするか、設定 > AIで実行ファイルのパスを指定してください。",
|
||||
codeBuddyCliPathInvalid: "CodeBuddy Code CLIのパスが無効です。codebuddy実行ファイルのみを選択し、環境変数は別に設定してください。",
|
||||
codeBuddyEnvInvalid: "CodeBuddyの環境変数名が無効です。HTTPS_PROXYのような有効な名前を使用してください。",
|
||||
codeBuddyEnvReserved: "DBXが管理するMCP環境変数が上書きされています。プロバイダー設定からDBX_MCP_*変数を削除してください。",
|
||||
codeBuddyNotAuthenticated: "CodeBuddy Codeにログインしていません。ターミナルで`codebuddy`を開いてログインし、再試行してください。",
|
||||
codeBuddyTimeout: "CodeBuddy Code CLIは操作のタイムアウト前に応答しませんでした。",
|
||||
codeBuddyMcpConfigInvalid: "CodeBuddy Codeは一時的なDBX MCP設定を読み込めませんでした。以下の診断情報を確認してください。",
|
||||
codeBuddyMcpStartupFailed: "CodeBuddy CodeはMCP設定を読み込みましたが、DBX MCP Serverを起動できません。設定 > MCPと以下の診断情報を確認してください。",
|
||||
codeBuddyProtocolError: "CodeBuddy Codeが無効な制御応答またはJSONイベントストリームを返しました。CodeBuddy Codeのバージョンと以下の診断情報を確認してください。",
|
||||
codeBuddyRunFailed: "CodeBuddy Code CLIが予期せず終了しました。エラーコードと以下の診断詳細から、失敗した実行ファイルまたはCLI出力を確認してください。",
|
||||
},
|
||||
run: "実行",
|
||||
readingSchema: "スキーマを読み取り中",
|
||||
|
||||
@@ -2226,6 +2226,16 @@ export default withEnglishFallback({
|
||||
grokCliMcpStartupFailed: "Grok이 MCP 구성을 불러왔지만 DBX MCP 서버를 시작할 수 없습니다. 설정 > MCP와 아래 진단을 확인하세요.",
|
||||
grokCliCommandLineTooLong: "명령이 너무 길어 Windows가 Grok CLI 명령을 거부했습니다. DBX를 업데이트하고 생성된 프롬프트 파일을 사용하여 다시 시도하세요.",
|
||||
grokCliRunFailed: "Grok CLI가 예기치 않게 종료되었습니다. 아래의 오류 코드와 진단을 사용하여 실패한 실행 파일이나 CLI 출력을 파악하세요.",
|
||||
codeBuddyNotInstalled: "CodeBuddy Code CLI를 찾을 수 없습니다. CodeBuddy Code를 설치하거나 설정 > AI에서 실행 파일 경로를 지정하세요.",
|
||||
codeBuddyCliPathInvalid: "CodeBuddy Code CLI 경로가 잘못되었습니다. codebuddy 실행 파일만 선택하고 환경 변수는 별도로 구성하세요.",
|
||||
codeBuddyEnvInvalid: "CodeBuddy 환경 변수 이름이 잘못되었습니다. HTTPS_PROXY 같은 유효한 이름을 사용하세요.",
|
||||
codeBuddyEnvReserved: "DBX가 관리하는 MCP 환경 변수가 재정의되었습니다. 공급자 구성에서 DBX_MCP_* 변수를 제거하세요.",
|
||||
codeBuddyNotAuthenticated: "CodeBuddy Code에 로그인되어 있지 않습니다. 터미널에서 `codebuddy`를 열어 로그인한 후 다시 시도하세요.",
|
||||
codeBuddyTimeout: "CodeBuddy Code CLI가 작업 제한 시간 전에 응답하지 않았습니다.",
|
||||
codeBuddyMcpConfigInvalid: "CodeBuddy Code가 임시 DBX MCP 구성을 읽지 못했습니다. 아래 진단을 확인하세요.",
|
||||
codeBuddyMcpStartupFailed: "CodeBuddy Code가 MCP 구성을 불러왔지만 DBX MCP Server를 시작하지 못했습니다. 설정 > MCP와 아래 진단을 확인하세요.",
|
||||
codeBuddyProtocolError: "CodeBuddy Code가 잘못된 제어 응답 또는 JSON 이벤트 스트림을 반환했습니다. CodeBuddy Code 버전과 아래 진단을 확인하세요.",
|
||||
codeBuddyRunFailed: "CodeBuddy Code CLI가 예기치 않게 종료되었습니다. 아래의 오류 코드와 진단을 사용하여 실패한 실행 파일이나 CLI 출력을 파악하세요.",
|
||||
},
|
||||
actions: {
|
||||
general: "일반",
|
||||
|
||||
@@ -2210,6 +2210,16 @@ export default withEnglishFallback({
|
||||
grokCliMcpStartupFailed: "O Grok carregou a configuração MCP, mas não conseguiu iniciar o DBX MCP Server. Verifique Configurações > MCP e os detalhes abaixo.",
|
||||
grokCliCommandLineTooLong: "O Windows rejeitou o comando do Grok CLI porque era muito longo. Atualize o DBX e tente novamente com o arquivo de prompt gerado.",
|
||||
grokCliRunFailed: "Grok CLI foi encerrado inesperadamente. Use o código do erro e os detalhes abaixo para identificar o executável ou a saída com falha.",
|
||||
codeBuddyNotInstalled: "O CodeBuddy Code CLI não foi encontrado. Instale o CodeBuddy Code ou defina o caminho do executável em Configurações > AI.",
|
||||
codeBuddyCliPathInvalid: "O caminho do CodeBuddy Code CLI é inválido. Selecione apenas o executável codebuddy e configure as variáveis de ambiente separadamente.",
|
||||
codeBuddyEnvInvalid: "O nome de uma variável de ambiente do CodeBuddy é inválido. Use nomes como HTTPS_PROXY.",
|
||||
codeBuddyEnvReserved: "Uma variável MCP gerenciada pelo DBX foi sobrescrita. Remova as variáveis DBX_MCP_* da configuração do provedor.",
|
||||
codeBuddyNotAuthenticated: "O CodeBuddy Code não está autenticado. Abra `codebuddy` em um terminal, entre na conta e tente novamente.",
|
||||
codeBuddyTimeout: "O CodeBuddy Code CLI não respondeu antes do tempo limite da operação.",
|
||||
codeBuddyMcpConfigInvalid: "O CodeBuddy Code não conseguiu ler a configuração temporária do DBX MCP. Verifique os detalhes abaixo.",
|
||||
codeBuddyMcpStartupFailed: "O CodeBuddy Code carregou a configuração MCP, mas não conseguiu iniciar o DBX MCP Server. Verifique Configurações > MCP e os detalhes abaixo.",
|
||||
codeBuddyProtocolError: "O CodeBuddy Code retornou uma resposta de controle ou um fluxo de eventos JSON inválido. Verifique a versão do CodeBuddy Code e os detalhes abaixo.",
|
||||
codeBuddyRunFailed: "O CodeBuddy Code CLI foi encerrado inesperadamente. Use o código do erro e os detalhes abaixo para identificar o executável ou a saída com falha.",
|
||||
},
|
||||
run: "Executar",
|
||||
readingSchema: "Lendo schema",
|
||||
|
||||
@@ -2287,6 +2287,16 @@ export default withEnglishFallback({
|
||||
grokCliMcpStartupFailed: "Grok 已加载 MCP 配置,但无法启动 DBX MCP Server。请检查 设置 > MCP 与下方诊断信息。",
|
||||
grokCliCommandLineTooLong: "命令行过长,Windows 拒绝执行 Grok CLI。请更新 DBX 并使用生成的 prompt 文件重试。",
|
||||
grokCliRunFailed: "Grok CLI 异常退出。请根据错误代码和下方诊断详情确认失败的可执行文件或 CLI 输出。",
|
||||
codeBuddyNotInstalled: "未找到 CodeBuddy Code CLI。请安装 CodeBuddy Code,或在 设置 > AI 中指定可执行文件路径。",
|
||||
codeBuddyCliPathInvalid: "CodeBuddy Code CLI 路径无效。请只选择 codebuddy 可执行文件,并单独配置环境变量。",
|
||||
codeBuddyEnvInvalid: "CodeBuddy 环境变量名称无效。请使用类似 HTTPS_PROXY 的名称。",
|
||||
codeBuddyEnvReserved: "覆盖了 DBX 管理的 MCP 环境变量。请从提供商配置中移除 DBX_MCP_* 变量。",
|
||||
codeBuddyNotAuthenticated: "CodeBuddy Code 尚未登录。请在终端打开 `codebuddy`,完成登录后重试。",
|
||||
codeBuddyTimeout: "CodeBuddy Code CLI 未在操作超时前响应。",
|
||||
codeBuddyMcpConfigInvalid: "CodeBuddy Code 无法读取临时 DBX MCP 配置。请检查下方诊断信息。",
|
||||
codeBuddyMcpStartupFailed: "CodeBuddy Code 已加载 MCP 配置,但无法启动 DBX MCP Server。请检查 设置 > MCP 与下方诊断信息。",
|
||||
codeBuddyProtocolError: "CodeBuddy Code 返回了无效的控制响应或 JSON 事件流。请检查 CodeBuddy Code 版本和下方诊断信息。",
|
||||
codeBuddyRunFailed: "CodeBuddy Code CLI 异常退出。请根据错误代码和下方诊断详情确认失败的可执行文件或 CLI 输出。",
|
||||
cursorEnvInvalid: "Cursor CLI 环境变量名称无效。请使用 HTTPS_PROXY 这类合法名称。",
|
||||
cursorEnvReserved: "配置覆盖了由 Cursor 或 DBX 管理的环境变量。请移除 CURSOR_CONFIG_DIR、CURSOR_DATA_DIR 和 DBX_MCP_* 变量。",
|
||||
cursorNotAuthenticated: "Cursor CLI 尚未登录。请在终端执行 `agent login` 后重试。",
|
||||
|
||||
@@ -2351,6 +2351,16 @@ export default withEnglishFallback({
|
||||
grokCliMcpStartupFailed: "Grok 已載入 MCP 設定,但無法啟動 DBX MCP Server。請檢查 設定 > MCP 與下方診斷資訊。",
|
||||
grokCliCommandLineTooLong: "命令列過長,Windows 拒絕執行 Grok CLI。請更新 DBX 並使用產生的 prompt 檔案重試。",
|
||||
grokCliRunFailed: "Grok CLI 異常結束。請依據錯誤代碼和下方診斷詳情確認失敗的可執行檔或 CLI 輸出。",
|
||||
codeBuddyNotInstalled: "找不到 CodeBuddy Code CLI。請安裝 CodeBuddy Code,或在 設定 > AI 中指定執行檔路徑。",
|
||||
codeBuddyCliPathInvalid: "CodeBuddy Code CLI 路徑無效。請只選擇 codebuddy 執行檔,並另外設定環境變數。",
|
||||
codeBuddyEnvInvalid: "CodeBuddy 環境變數名稱無效。請使用類似 HTTPS_PROXY 的名稱。",
|
||||
codeBuddyEnvReserved: "覆寫了 DBX 管理的 MCP 環境變數。請從供應商設定中移除 DBX_MCP_* 變數。",
|
||||
codeBuddyNotAuthenticated: "CodeBuddy Code 尚未登入。請在終端機開啟 `codebuddy`,完成登入後重試。",
|
||||
codeBuddyTimeout: "CodeBuddy Code CLI 未在操作逾時前回應。",
|
||||
codeBuddyMcpConfigInvalid: "CodeBuddy Code 無法讀取暫存 DBX MCP 設定。請檢查下方診斷資訊。",
|
||||
codeBuddyMcpStartupFailed: "CodeBuddy Code 已載入 MCP 設定,但無法啟動 DBX MCP Server。請檢查 設定 > MCP 與下方診斷資訊。",
|
||||
codeBuddyProtocolError: "CodeBuddy Code 回傳了無效的控制回應或 JSON 事件串流。請檢查 CodeBuddy Code 版本和下方診斷資訊。",
|
||||
codeBuddyRunFailed: "CodeBuddy Code CLI 異常結束。請依據錯誤代碼和下方診斷詳情確認失敗的執行檔或 CLI 輸出。",
|
||||
},
|
||||
actions: {
|
||||
general: "通用問答",
|
||||
|
||||
@@ -24,7 +24,7 @@ describe("isAiConfigModelCandidate", () => {
|
||||
expect(isAiConfigModelCandidate(config({ apiKey: "" }), true)).toBe(false);
|
||||
});
|
||||
|
||||
it.each(["codex-cli", "claude-code-cli", "opencode-cli", "pi-agent-cli", "cursor-cli", "grok-cli"] as const)("keeps %s configs eligible without endpoint, API key, or model metadata", (provider) => {
|
||||
it.each(["codex-cli", "claude-code-cli", "opencode-cli", "pi-agent-cli", "cursor-cli", "grok-cli", "codebuddy-cli"] as const)("keeps %s configs eligible without endpoint, API key, or model metadata", (provider) => {
|
||||
expect(
|
||||
isAiConfigModelCandidate(
|
||||
config({
|
||||
|
||||
@@ -23,12 +23,13 @@ describe("orderAiConfigsForDisplay", () => {
|
||||
{ id: "codex", provider: "codex-cli" },
|
||||
{ id: "opencode", provider: "opencode-cli" },
|
||||
{ id: "cursor", provider: "cursor-cli" },
|
||||
{ id: "codebuddy", provider: "codebuddy-cli" },
|
||||
{ id: "grok", provider: "grok-cli" },
|
||||
{ id: "pi", provider: "pi-agent-cli" },
|
||||
{ id: "custom", provider: "custom" },
|
||||
];
|
||||
|
||||
expect(orderAiConfigsForDisplay(configs).map((config) => config.id)).toEqual(["claude", "openai", "gemini", "deepseek", "qwen", "minimax", "ollama", "anthropic-compatible", "openai-compatible", "claude-code-1", "codex", "opencode", "cursor", "grok", "pi", "custom"]);
|
||||
expect(orderAiConfigsForDisplay(configs).map((config) => config.id)).toEqual(["claude", "openai", "gemini", "deepseek", "qwen", "minimax", "ollama", "anthropic-compatible", "openai-compatible", "claude-code-1", "codex", "opencode", "cursor", "codebuddy", "grok", "pi", "custom"]);
|
||||
});
|
||||
|
||||
it("preserves creation order for configs from the same provider", () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AiConfig } from "@/types/ai";
|
||||
|
||||
const CLI_PROVIDERS = new Set<AiConfig["provider"]>(["codex-cli", "claude-code-cli", "opencode-cli", "pi-agent-cli", "cursor-cli", "grok-cli"]);
|
||||
const CLI_PROVIDERS = new Set<AiConfig["provider"]>(["codex-cli", "claude-code-cli", "opencode-cli", "pi-agent-cli", "cursor-cli", "grok-cli", "codebuddy-cli"]);
|
||||
|
||||
export function isAiConfigModelCandidate(config: AiConfig, requiresApiKey: boolean): boolean {
|
||||
// CLI providers resolve their model and credentials externally, so keep the existing eligibility bypass.
|
||||
|
||||
@@ -488,6 +488,22 @@ describe("settingsStore AI API key normalization", () => {
|
||||
cursorCliEnv: { HTTPS_PROXY: "http://127.0.0.1:7890", EMPTY: "" },
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes CodeBuddy CLI path and environment settings", () => {
|
||||
expect(
|
||||
normalizeAiConfig({
|
||||
provider: "codebuddy-cli",
|
||||
codebuddyCliPath: " ~/.local/bin/codebuddy ",
|
||||
codebuddyCliEnv: { HTTPS_PROXY: "http://127.0.0.1:7890", EMPTY: null as unknown as string },
|
||||
}),
|
||||
).toMatchObject({
|
||||
provider: "codebuddy-cli",
|
||||
endpoint: "",
|
||||
model: "default",
|
||||
codebuddyCliPath: "~/.local/bin/codebuddy",
|
||||
codebuddyCliEnv: { HTTPS_PROXY: "http://127.0.0.1:7890", EMPTY: "" },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("settingsStore MCP policy persistence", () => {
|
||||
|
||||
@@ -253,6 +253,16 @@ export const AI_PROVIDER_PRESETS: Record<AiProvider, AiProviderPreset> = {
|
||||
authMethod: "bearer",
|
||||
requiresApiKey: false,
|
||||
},
|
||||
"codebuddy-cli": {
|
||||
label: "CodeBuddy Code",
|
||||
iconSlug: "codebuddy",
|
||||
provider: "codebuddy-cli",
|
||||
endpoint: "",
|
||||
model: "default",
|
||||
apiStyle: "completions",
|
||||
authMethod: "bearer",
|
||||
requiresApiKey: false,
|
||||
},
|
||||
"grok-cli": {
|
||||
label: "Grok CLI",
|
||||
iconSlug: "grok",
|
||||
@@ -335,6 +345,8 @@ export function normalizeAiConfig(config: Partial<AiConfig> | null | undefined):
|
||||
cursorCliEnv: normalizeAiEnv(config?.cursorCliEnv),
|
||||
grokCliPath: config?.grokCliPath?.trim() || undefined,
|
||||
grokCliEnv: normalizeAiEnv(config?.grokCliEnv),
|
||||
codebuddyCliPath: config?.codebuddyCliPath?.trim() || undefined,
|
||||
codebuddyCliEnv: normalizeAiEnv(config?.codebuddyCliEnv),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1497,7 +1509,7 @@ export const useSettingsStore = defineStore("settings", () => {
|
||||
const config = aiConfigs.value.find((c) => c.id === activeModel.value!.configId);
|
||||
if (!config) return false;
|
||||
const preset = AI_PROVIDER_PRESETS[config.provider];
|
||||
if (config.provider === "codex-cli" || config.provider === "claude-code-cli" || config.provider === "pi-agent-cli" || config.provider === "opencode-cli" || config.provider === "cursor-cli" || config.provider === "grok-cli") return true;
|
||||
if (config.provider === "codex-cli" || config.provider === "claude-code-cli" || config.provider === "pi-agent-cli" || config.provider === "opencode-cli" || config.provider === "cursor-cli" || config.provider === "grok-cli" || config.provider === "codebuddy-cli") return true;
|
||||
return !!config.endpoint && !!activeModel.value!.modelId && (!preset.requiresApiKey || !!config.apiKey);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type AiProvider = "claude" | "openai" | "gemini" | "deepseek" | "qwen" | "minimax" | "ollama" | "anthropic-compatible" | "openai-compatible" | "claude-code-cli" | "pi-agent-cli" | "codex-cli" | "opencode-cli" | "cursor-cli" | "grok-cli" | "custom";
|
||||
export type AiProvider = "claude" | "openai" | "gemini" | "deepseek" | "qwen" | "minimax" | "ollama" | "anthropic-compatible" | "openai-compatible" | "claude-code-cli" | "pi-agent-cli" | "codex-cli" | "opencode-cli" | "cursor-cli" | "grok-cli" | "codebuddy-cli" | "custom";
|
||||
export type AiApiStyle = "completions" | "responses" | "anthropic-messages";
|
||||
export type AiAuthMethod = "api-key" | "bearer";
|
||||
export type AiEffortLevel = "low" | "medium" | "high" | "xhigh" | "max";
|
||||
@@ -53,6 +53,8 @@ export interface AiConfig {
|
||||
cursorCliEnv?: Record<string, string>;
|
||||
grokCliPath?: string | null;
|
||||
grokCliEnv?: Record<string, string>;
|
||||
codebuddyCliPath?: string | null;
|
||||
codebuddyCliEnv?: Record<string, string>;
|
||||
runtimeEffort?: AiEffortSelection | null;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user