@@ -115,12 +115,6 @@ func applyCodexOAuthTransform(reqBody map[string]any) codexTransformResult {
|
|||||||
existingInstructions = strings.TrimSpace(existingInstructions)
|
existingInstructions = strings.TrimSpace(existingInstructions)
|
||||||
|
|
||||||
if instructions != "" {
|
if instructions != "" {
|
||||||
if existingInstructions != "" && existingInstructions != instructions {
|
|
||||||
if input, ok := reqBody["input"].([]any); ok {
|
|
||||||
reqBody["input"] = prependSystemInstruction(input, existingInstructions)
|
|
||||||
result.Modified = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if existingInstructions != instructions {
|
if existingInstructions != instructions {
|
||||||
reqBody["instructions"] = instructions
|
reqBody["instructions"] = instructions
|
||||||
result.Modified = true
|
result.Modified = true
|
||||||
@@ -129,7 +123,6 @@ func applyCodexOAuthTransform(reqBody map[string]any) codexTransformResult {
|
|||||||
|
|
||||||
if input, ok := reqBody["input"].([]any); ok {
|
if input, ok := reqBody["input"].([]any); ok {
|
||||||
input = filterCodexInput(input)
|
input = filterCodexInput(input)
|
||||||
input = normalizeOrphanedToolOutputs(input)
|
|
||||||
reqBody["input"] = input
|
reqBody["input"] = input
|
||||||
result.Modified = true
|
result.Modified = true
|
||||||
}
|
}
|
||||||
@@ -266,19 +259,6 @@ func filterCodexInput(input []any) []any {
|
|||||||
return filtered
|
return filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
func prependSystemInstruction(input []any, instructions string) []any {
|
|
||||||
message := map[string]any{
|
|
||||||
"role": "system",
|
|
||||||
"content": []any{
|
|
||||||
map[string]any{
|
|
||||||
"type": "input_text",
|
|
||||||
"text": instructions,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return append([]any{message}, input...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func normalizeCodexTools(reqBody map[string]any) bool {
|
func normalizeCodexTools(reqBody map[string]any) bool {
|
||||||
rawTools, ok := reqBody["tools"]
|
rawTools, ok := reqBody["tools"]
|
||||||
if !ok || rawTools == nil {
|
if !ok || rawTools == nil {
|
||||||
@@ -341,110 +321,6 @@ func normalizeCodexTools(reqBody map[string]any) bool {
|
|||||||
return modified
|
return modified
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeOrphanedToolOutputs(input []any) []any {
|
|
||||||
functionCallIDs := map[string]bool{}
|
|
||||||
localShellCallIDs := map[string]bool{}
|
|
||||||
customToolCallIDs := map[string]bool{}
|
|
||||||
|
|
||||||
for _, item := range input {
|
|
||||||
m, ok := item.(map[string]any)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
callID := getCallID(m)
|
|
||||||
if callID == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch m["type"] {
|
|
||||||
case "function_call":
|
|
||||||
functionCallIDs[callID] = true
|
|
||||||
case "local_shell_call":
|
|
||||||
localShellCallIDs[callID] = true
|
|
||||||
case "custom_tool_call":
|
|
||||||
customToolCallIDs[callID] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output := make([]any, 0, len(input))
|
|
||||||
for _, item := range input {
|
|
||||||
m, ok := item.(map[string]any)
|
|
||||||
if !ok {
|
|
||||||
output = append(output, item)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch m["type"] {
|
|
||||||
case "function_call_output":
|
|
||||||
callID := getCallID(m)
|
|
||||||
if callID == "" || (!functionCallIDs[callID] && !localShellCallIDs[callID]) {
|
|
||||||
output = append(output, convertOrphanedOutputToMessage(m, callID))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case "custom_tool_call_output":
|
|
||||||
callID := getCallID(m)
|
|
||||||
if callID == "" || !customToolCallIDs[callID] {
|
|
||||||
output = append(output, convertOrphanedOutputToMessage(m, callID))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case "local_shell_call_output":
|
|
||||||
callID := getCallID(m)
|
|
||||||
if callID == "" || !localShellCallIDs[callID] {
|
|
||||||
output = append(output, convertOrphanedOutputToMessage(m, callID))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output = append(output, m)
|
|
||||||
}
|
|
||||||
return output
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCallID(item map[string]any) string {
|
|
||||||
raw, ok := item["call_id"]
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
callID, ok := raw.(string)
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
callID = strings.TrimSpace(callID)
|
|
||||||
if callID == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return callID
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertOrphanedOutputToMessage(item map[string]any, callID string) map[string]any {
|
|
||||||
toolName := "tool"
|
|
||||||
if name, ok := item["name"].(string); ok && name != "" {
|
|
||||||
toolName = name
|
|
||||||
}
|
|
||||||
labelID := callID
|
|
||||||
if labelID == "" {
|
|
||||||
labelID = "unknown"
|
|
||||||
}
|
|
||||||
text := stringifyOutput(item["output"])
|
|
||||||
if len(text) > 16000 {
|
|
||||||
text = text[:16000] + "\n...[truncated]"
|
|
||||||
}
|
|
||||||
return map[string]any{
|
|
||||||
"type": "message",
|
|
||||||
"role": "assistant",
|
|
||||||
"content": fmt.Sprintf("[Previous %s result; call_id=%s]: %s", toolName, labelID, text),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringifyOutput(output any) string {
|
|
||||||
switch v := output.(type) {
|
|
||||||
case string:
|
|
||||||
return v
|
|
||||||
default:
|
|
||||||
if data, err := json.Marshal(v); err == nil {
|
|
||||||
return string(data)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%v", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func codexCachePath(filename string) string {
|
func codexCachePath(filename string) string {
|
||||||
home, err := os.UserHomeDir()
|
home, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
{{ platformDescription }}
|
{{ platformDescription }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- Client Tabs (only for Antigravity platform) -->
|
<!-- Client Tabs -->
|
||||||
<div v-if="platform === 'antigravity'" class="border-b border-gray-200 dark:border-dark-700">
|
<div v-if="clientTabs.length" class="border-b border-gray-200 dark:border-dark-700">
|
||||||
<nav class="-mb-px flex space-x-6" aria-label="Client">
|
<nav class="-mb-px flex space-x-6" aria-label="Client">
|
||||||
<button
|
<button
|
||||||
v-for="tab in clientTabs"
|
v-for="tab in clientTabs"
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- OS/Shell Tabs -->
|
<!-- OS/Shell Tabs -->
|
||||||
<div class="border-b border-gray-200 dark:border-dark-700">
|
<div v-if="showShellTabs" class="border-b border-gray-200 dark:border-dark-700">
|
||||||
<nav class="-mb-px flex space-x-4" aria-label="Tabs">
|
<nav class="-mb-px flex space-x-4" aria-label="Tabs">
|
||||||
<button
|
<button
|
||||||
v-for="tab in currentTabs"
|
v-for="tab in currentTabs"
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Usage Note -->
|
<!-- Usage Note -->
|
||||||
<div class="flex items-start gap-3 p-3 rounded-lg bg-blue-50 dark:bg-blue-900/20 border border-blue-100 dark:border-blue-800">
|
<div v-if="showPlatformNote" class="flex items-start gap-3 p-3 rounded-lg bg-blue-50 dark:bg-blue-900/20 border border-blue-100 dark:border-blue-800">
|
||||||
<Icon name="infoCircle" size="md" class="text-blue-500 flex-shrink-0 mt-0.5" />
|
<Icon name="infoCircle" size="md" class="text-blue-500 flex-shrink-0 mt-0.5" />
|
||||||
<p class="text-sm text-blue-700 dark:text-blue-300">
|
<p class="text-sm text-blue-700 dark:text-blue-300">
|
||||||
{{ platformNote }}
|
{{ platformNote }}
|
||||||
@@ -173,17 +173,28 @@ const { copyToClipboard: clipboardCopy } = useClipboard()
|
|||||||
|
|
||||||
const copiedIndex = ref<number | null>(null)
|
const copiedIndex = ref<number | null>(null)
|
||||||
const activeTab = ref<string>('unix')
|
const activeTab = ref<string>('unix')
|
||||||
const activeClientTab = ref<string>('claude') // Level 1 tab for antigravity platform
|
const activeClientTab = ref<string>('claude')
|
||||||
|
|
||||||
// Reset tabs when platform changes
|
// Reset tabs when platform changes
|
||||||
watch(() => props.platform, (newPlatform) => {
|
const defaultClientTab = computed(() => {
|
||||||
activeTab.value = 'unix'
|
switch (props.platform) {
|
||||||
if (newPlatform === 'antigravity') {
|
case 'openai':
|
||||||
activeClientTab.value = 'claude'
|
return 'codex'
|
||||||
|
case 'gemini':
|
||||||
|
return 'gemini'
|
||||||
|
case 'antigravity':
|
||||||
|
return 'claude'
|
||||||
|
default:
|
||||||
|
return 'claude'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Reset shell tab when client changes (for antigravity)
|
watch(() => props.platform, () => {
|
||||||
|
activeTab.value = 'unix'
|
||||||
|
activeClientTab.value = defaultClientTab.value
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// Reset shell tab when client changes
|
||||||
watch(activeClientTab, () => {
|
watch(activeClientTab, () => {
|
||||||
activeTab.value = 'unix'
|
activeTab.value = 'unix'
|
||||||
})
|
})
|
||||||
@@ -251,11 +262,32 @@ const SparkleIcon = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client tabs for Antigravity platform (Level 1)
|
const clientTabs = computed((): TabConfig[] => {
|
||||||
const clientTabs = computed((): TabConfig[] => [
|
if (!props.platform) return []
|
||||||
{ id: 'claude', label: t('keys.useKeyModal.antigravity.claudeCode'), icon: TerminalIcon },
|
switch (props.platform) {
|
||||||
{ id: 'gemini', label: t('keys.useKeyModal.antigravity.geminiCli'), icon: SparkleIcon }
|
case 'openai':
|
||||||
])
|
return [
|
||||||
|
{ id: 'codex', label: t('keys.useKeyModal.cliTabs.codexCli'), icon: TerminalIcon },
|
||||||
|
{ id: 'opencode', label: t('keys.useKeyModal.cliTabs.opencode'), icon: TerminalIcon }
|
||||||
|
]
|
||||||
|
case 'gemini':
|
||||||
|
return [
|
||||||
|
{ id: 'gemini', label: t('keys.useKeyModal.cliTabs.geminiCli'), icon: SparkleIcon },
|
||||||
|
{ id: 'opencode', label: t('keys.useKeyModal.cliTabs.opencode'), icon: TerminalIcon }
|
||||||
|
]
|
||||||
|
case 'antigravity':
|
||||||
|
return [
|
||||||
|
{ id: 'claude', label: t('keys.useKeyModal.cliTabs.claudeCode'), icon: TerminalIcon },
|
||||||
|
{ id: 'gemini', label: t('keys.useKeyModal.cliTabs.geminiCli'), icon: SparkleIcon },
|
||||||
|
{ id: 'opencode', label: t('keys.useKeyModal.cliTabs.opencode'), icon: TerminalIcon }
|
||||||
|
]
|
||||||
|
default:
|
||||||
|
return [
|
||||||
|
{ id: 'claude', label: t('keys.useKeyModal.cliTabs.claudeCode'), icon: TerminalIcon },
|
||||||
|
{ id: 'opencode', label: t('keys.useKeyModal.cliTabs.opencode'), icon: TerminalIcon }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Shell tabs (3 types for environment variable based configs)
|
// Shell tabs (3 types for environment variable based configs)
|
||||||
const shellTabs: TabConfig[] = [
|
const shellTabs: TabConfig[] = [
|
||||||
@@ -270,11 +302,13 @@ const openaiTabs: TabConfig[] = [
|
|||||||
{ id: 'windows', label: 'Windows', icon: WindowsIcon }
|
{ id: 'windows', label: 'Windows', icon: WindowsIcon }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const showShellTabs = computed(() => activeClientTab.value !== 'opencode')
|
||||||
|
|
||||||
const currentTabs = computed(() => {
|
const currentTabs = computed(() => {
|
||||||
|
if (!showShellTabs.value) return []
|
||||||
if (props.platform === 'openai') {
|
if (props.platform === 'openai') {
|
||||||
return openaiTabs // 2 tabs: unix, windows
|
return openaiTabs
|
||||||
}
|
}
|
||||||
// All other platforms (anthropic, gemini, antigravity) use shell tabs
|
|
||||||
return shellTabs
|
return shellTabs
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -308,6 +342,8 @@ const platformNote = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const showPlatformNote = computed(() => activeClientTab.value !== 'opencode')
|
||||||
|
|
||||||
const escapeHtml = (value: string) => value
|
const escapeHtml = (value: string) => value
|
||||||
.replace(/&/g, '&')
|
.replace(/&/g, '&')
|
||||||
.replace(/</g, '<')
|
.replace(/</g, '<')
|
||||||
@@ -329,6 +365,35 @@ const comment = (value: string) => wrapToken('text-slate-500', value)
|
|||||||
const currentFiles = computed((): FileConfig[] => {
|
const currentFiles = computed((): FileConfig[] => {
|
||||||
const baseUrl = props.baseUrl || window.location.origin
|
const baseUrl = props.baseUrl || window.location.origin
|
||||||
const apiKey = props.apiKey
|
const apiKey = props.apiKey
|
||||||
|
const baseRoot = baseUrl.replace(/\/v1\/?$/, '').replace(/\/+$/, '')
|
||||||
|
const ensureV1 = (value: string) => {
|
||||||
|
const trimmed = value.replace(/\/+$/, '')
|
||||||
|
return trimmed.endsWith('/v1') ? trimmed : `${trimmed}/v1`
|
||||||
|
}
|
||||||
|
const apiBase = ensureV1(baseRoot)
|
||||||
|
const antigravityBase = ensureV1(`${baseRoot}/antigravity`)
|
||||||
|
const antigravityGeminiBase = (() => {
|
||||||
|
const trimmed = `${baseRoot}/antigravity`.replace(/\/+$/, '')
|
||||||
|
return trimmed.endsWith('/v1beta') ? trimmed : `${trimmed}/v1beta`
|
||||||
|
})()
|
||||||
|
|
||||||
|
if (activeClientTab.value === 'opencode') {
|
||||||
|
switch (props.platform) {
|
||||||
|
case 'anthropic':
|
||||||
|
return [generateOpenCodeConfig('anthropic', apiBase, apiKey)]
|
||||||
|
case 'openai':
|
||||||
|
return [generateOpenCodeConfig('openai', apiBase, apiKey)]
|
||||||
|
case 'gemini':
|
||||||
|
return [generateOpenCodeConfig('gemini', apiBase, apiKey)]
|
||||||
|
case 'antigravity':
|
||||||
|
return [
|
||||||
|
generateOpenCodeConfig('antigravity-claude', antigravityBase, apiKey, 'opencode.json (Claude)'),
|
||||||
|
generateOpenCodeConfig('antigravity-gemini', antigravityGeminiBase, apiKey, 'opencode.json (Gemini)')
|
||||||
|
]
|
||||||
|
default:
|
||||||
|
return [generateOpenCodeConfig('openai', apiBase, apiKey)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (props.platform) {
|
switch (props.platform) {
|
||||||
case 'openai':
|
case 'openai':
|
||||||
@@ -336,12 +401,11 @@ const currentFiles = computed((): FileConfig[] => {
|
|||||||
case 'gemini':
|
case 'gemini':
|
||||||
return [generateGeminiCliContent(baseUrl, apiKey)]
|
return [generateGeminiCliContent(baseUrl, apiKey)]
|
||||||
case 'antigravity':
|
case 'antigravity':
|
||||||
// Both Claude Code and Gemini CLI need /antigravity suffix for antigravity platform
|
if (activeClientTab.value === 'gemini') {
|
||||||
if (activeClientTab.value === 'claude') {
|
|
||||||
return generateAnthropicFiles(`${baseUrl}/antigravity`, apiKey)
|
|
||||||
}
|
|
||||||
return [generateGeminiCliContent(`${baseUrl}/antigravity`, apiKey)]
|
return [generateGeminiCliContent(`${baseUrl}/antigravity`, apiKey)]
|
||||||
default: // anthropic
|
}
|
||||||
|
return generateAnthropicFiles(`${baseUrl}/antigravity`, apiKey)
|
||||||
|
default:
|
||||||
return generateAnthropicFiles(baseUrl, apiKey)
|
return generateAnthropicFiles(baseUrl, apiKey)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -456,6 +520,76 @@ requires_openai_auth = true`
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: string, pathLabel?: string): FileConfig {
|
||||||
|
const provider: Record<string, any> = {
|
||||||
|
[platform]: {
|
||||||
|
options: {
|
||||||
|
baseURL: baseUrl,
|
||||||
|
apiKey,
|
||||||
|
...(platform === 'openai' ? { store: false } : {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const openaiModels = {
|
||||||
|
'gpt-5.2-codex': {
|
||||||
|
name: 'GPT-5.2 Codex',
|
||||||
|
variants: {
|
||||||
|
low: {},
|
||||||
|
medium: {},
|
||||||
|
high: {},
|
||||||
|
xhigh: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const geminiModels = {
|
||||||
|
'gemini-3-pro-high': { name: 'Gemini 3 Pro High' },
|
||||||
|
'gemini-3-pro-low': { name: 'Gemini 3 Pro Low' },
|
||||||
|
'gemini-3-pro-preview': { name: 'Gemini 3 Pro Preview' },
|
||||||
|
'gemini-3-pro-image': { name: 'Gemini 3 Pro Image' },
|
||||||
|
'gemini-3-flash': { name: 'Gemini 3 Flash' },
|
||||||
|
'gemini-2.5-flash-thinking': { name: 'Gemini 2.5 Flash Thinking' },
|
||||||
|
'gemini-2.5-flash': { name: 'Gemini 2.5 Flash' },
|
||||||
|
'gemini-2.5-flash-lite': { name: 'Gemini 2.5 Flash Lite' }
|
||||||
|
}
|
||||||
|
const claudeModels = {
|
||||||
|
'claude-opus-4-5-thinking': { name: 'Claude Opus 4.5 Thinking' },
|
||||||
|
'claude-sonnet-4-5-thinking': { name: 'Claude Sonnet 4.5 Thinking' },
|
||||||
|
'claude-sonnet-4-5': { name: 'Claude Sonnet 4.5' }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platform === 'gemini') {
|
||||||
|
provider[platform].npm = '@ai-sdk/google'
|
||||||
|
provider[platform].models = geminiModels
|
||||||
|
} else if (platform === 'anthropic') {
|
||||||
|
provider[platform].npm = '@ai-sdk/anthropic'
|
||||||
|
} else if (platform === 'antigravity-claude') {
|
||||||
|
provider[platform].npm = '@ai-sdk/anthropic'
|
||||||
|
provider[platform].name = 'Antigravity (Claude)'
|
||||||
|
provider[platform].models = claudeModels
|
||||||
|
} else if (platform === 'antigravity-gemini') {
|
||||||
|
provider[platform].npm = '@ai-sdk/google'
|
||||||
|
provider[platform].name = 'Antigravity (Gemini)'
|
||||||
|
provider[platform].models = geminiModels
|
||||||
|
} else if (platform === 'openai') {
|
||||||
|
provider[platform].models = openaiModels
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = JSON.stringify(
|
||||||
|
{
|
||||||
|
provider,
|
||||||
|
$schema: 'https://opencode.ai/config.json'
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
path: pathLabel ?? 'opencode.json',
|
||||||
|
content,
|
||||||
|
hint: t('keys.useKeyModal.opencode.hint')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const copyContent = async (content: string, index: number) => {
|
const copyContent = async (content: string, index: number) => {
|
||||||
const success = await clipboardCopy(content, t('keys.copied'))
|
const success = await clipboardCopy(content, t('keys.copied'))
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|||||||
@@ -364,6 +364,12 @@ export default {
|
|||||||
note: 'Make sure the config directory exists. macOS/Linux users can run mkdir -p ~/.codex to create it.',
|
note: 'Make sure the config directory exists. macOS/Linux users can run mkdir -p ~/.codex to create it.',
|
||||||
noteWindows: 'Press Win+R and enter %userprofile%\\.codex to open the config directory. Create it manually if it does not exist.',
|
noteWindows: 'Press Win+R and enter %userprofile%\\.codex to open the config directory. Create it manually if it does not exist.',
|
||||||
},
|
},
|
||||||
|
cliTabs: {
|
||||||
|
claudeCode: 'Claude Code',
|
||||||
|
geminiCli: 'Gemini CLI',
|
||||||
|
codexCli: 'Codex CLI',
|
||||||
|
opencode: 'OpenCode',
|
||||||
|
},
|
||||||
antigravity: {
|
antigravity: {
|
||||||
description: 'Configure API access for Antigravity group. Select the configuration method based on your client.',
|
description: 'Configure API access for Antigravity group. Select the configuration method based on your client.',
|
||||||
claudeCode: 'Claude Code',
|
claudeCode: 'Claude Code',
|
||||||
@@ -376,6 +382,11 @@ export default {
|
|||||||
modelComment: 'If you have Gemini 3 access, you can use: gemini-3-pro-preview',
|
modelComment: 'If you have Gemini 3 access, you can use: gemini-3-pro-preview',
|
||||||
note: 'These environment variables will be active in the current terminal session. For permanent configuration, add them to ~/.bashrc, ~/.zshrc, or the appropriate configuration file.',
|
note: 'These environment variables will be active in the current terminal session. For permanent configuration, add them to ~/.bashrc, ~/.zshrc, or the appropriate configuration file.',
|
||||||
},
|
},
|
||||||
|
opencode: {
|
||||||
|
title: 'OpenCode Example',
|
||||||
|
subtitle: 'opencode.json',
|
||||||
|
hint: 'This is a group configuration example. Adjust model and options as needed.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
customKeyLabel: 'Custom Key',
|
customKeyLabel: 'Custom Key',
|
||||||
customKeyPlaceholder: 'Enter your custom key (min 16 chars)',
|
customKeyPlaceholder: 'Enter your custom key (min 16 chars)',
|
||||||
|
|||||||
@@ -361,6 +361,12 @@ export default {
|
|||||||
note: '请确保配置目录存在。macOS/Linux 用户可运行 mkdir -p ~/.codex 创建目录。',
|
note: '请确保配置目录存在。macOS/Linux 用户可运行 mkdir -p ~/.codex 创建目录。',
|
||||||
noteWindows: '按 Win+R,输入 %userprofile%\\.codex 打开配置目录。如目录不存在,请先手动创建。',
|
noteWindows: '按 Win+R,输入 %userprofile%\\.codex 打开配置目录。如目录不存在,请先手动创建。',
|
||||||
},
|
},
|
||||||
|
cliTabs: {
|
||||||
|
claudeCode: 'Claude Code',
|
||||||
|
geminiCli: 'Gemini CLI',
|
||||||
|
codexCli: 'Codex CLI',
|
||||||
|
opencode: 'OpenCode',
|
||||||
|
},
|
||||||
antigravity: {
|
antigravity: {
|
||||||
description: '为 Antigravity 分组配置 API 访问。请根据您使用的客户端选择对应的配置方式。',
|
description: '为 Antigravity 分组配置 API 访问。请根据您使用的客户端选择对应的配置方式。',
|
||||||
claudeCode: 'Claude Code',
|
claudeCode: 'Claude Code',
|
||||||
@@ -373,6 +379,11 @@ export default {
|
|||||||
modelComment: '如果你有 Gemini 3 权限可以填:gemini-3-pro-preview',
|
modelComment: '如果你有 Gemini 3 权限可以填:gemini-3-pro-preview',
|
||||||
note: '这些环境变量将在当前终端会话中生效。如需永久配置,请将其添加到 ~/.bashrc、~/.zshrc 或相应的配置文件中。',
|
note: '这些环境变量将在当前终端会话中生效。如需永久配置,请将其添加到 ~/.bashrc、~/.zshrc 或相应的配置文件中。',
|
||||||
},
|
},
|
||||||
|
opencode: {
|
||||||
|
title: 'OpenCode 配置示例',
|
||||||
|
subtitle: 'opencode.json',
|
||||||
|
hint: '示例仅用于演示分组配置,模型与选项可按需调整。',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
customKeyLabel: '自定义密钥',
|
customKeyLabel: '自定义密钥',
|
||||||
customKeyPlaceholder: '输入自定义密钥(至少16个字符)',
|
customKeyPlaceholder: '输入自定义密钥(至少16个字符)',
|
||||||
|
|||||||
Reference in New Issue
Block a user