fix: update OpenCode use-key examples

This commit is contained in:
cyhhao
2026-01-11 20:29:32 +08:00
parent abbde130ab
commit aa1a3b9a74
3 changed files with 178 additions and 22 deletions

View File

@@ -28,8 +28,8 @@
{{ platformDescription }}
</p>
<!-- Client Tabs (only for Antigravity platform) -->
<div v-if="platform === 'antigravity'" class="border-b border-gray-200 dark:border-dark-700">
<!-- Client Tabs -->
<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">
<button
v-for="tab in clientTabs"
@@ -51,7 +51,7 @@
</div>
<!-- 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">
<button
v-for="tab in currentTabs"
@@ -111,7 +111,7 @@
</div>
<!-- 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" />
<p class="text-sm text-blue-700 dark:text-blue-300">
{{ platformNote }}
@@ -173,17 +173,28 @@ const { copyToClipboard: clipboardCopy } = useClipboard()
const copiedIndex = ref<number | null>(null)
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
watch(() => props.platform, (newPlatform) => {
activeTab.value = 'unix'
if (newPlatform === 'antigravity') {
activeClientTab.value = 'claude'
const defaultClientTab = computed(() => {
switch (props.platform) {
case 'openai':
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, () => {
activeTab.value = 'unix'
})
@@ -251,11 +262,32 @@ const SparkleIcon = {
}
}
// Client tabs for Antigravity platform (Level 1)
const clientTabs = computed((): TabConfig[] => [
{ id: 'claude', label: t('keys.useKeyModal.antigravity.claudeCode'), icon: TerminalIcon },
{ id: 'gemini', label: t('keys.useKeyModal.antigravity.geminiCli'), icon: SparkleIcon }
])
const clientTabs = computed((): TabConfig[] => {
if (!props.platform) return []
switch (props.platform) {
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)
const shellTabs: TabConfig[] = [
@@ -270,11 +302,13 @@ const openaiTabs: TabConfig[] = [
{ id: 'windows', label: 'Windows', icon: WindowsIcon }
]
const showShellTabs = computed(() => activeClientTab.value !== 'opencode')
const currentTabs = computed(() => {
if (!showShellTabs.value) return []
if (props.platform === 'openai') {
return openaiTabs // 2 tabs: unix, windows
return openaiTabs
}
// All other platforms (anthropic, gemini, antigravity) use shell tabs
return shellTabs
})
@@ -308,6 +342,8 @@ const platformNote = computed(() => {
}
})
const showPlatformNote = computed(() => activeClientTab.value !== 'opencode')
const escapeHtml = (value: string) => value
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
@@ -329,6 +365,35 @@ const comment = (value: string) => wrapToken('text-slate-500', value)
const currentFiles = computed((): FileConfig[] => {
const baseUrl = props.baseUrl || window.location.origin
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) {
case 'openai':
@@ -336,12 +401,11 @@ const currentFiles = computed((): FileConfig[] => {
case 'gemini':
return [generateGeminiCliContent(baseUrl, apiKey)]
case 'antigravity':
// Both Claude Code and Gemini CLI need /antigravity suffix for antigravity platform
if (activeClientTab.value === 'claude') {
return generateAnthropicFiles(`${baseUrl}/antigravity`, apiKey)
if (activeClientTab.value === 'gemini') {
return [generateGeminiCliContent(`${baseUrl}/antigravity`, apiKey)]
}
return [generateGeminiCliContent(`${baseUrl}/antigravity`, apiKey)]
default: // anthropic
return generateAnthropicFiles(`${baseUrl}/antigravity`, apiKey)
default:
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 success = await clipboardCopy(content, t('keys.copied'))
if (success) {

View File

@@ -364,6 +364,12 @@ export default {
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.',
},
cliTabs: {
claudeCode: 'Claude Code',
geminiCli: 'Gemini CLI',
codexCli: 'Codex CLI',
opencode: 'OpenCode',
},
antigravity: {
description: 'Configure API access for Antigravity group. Select the configuration method based on your client.',
claudeCode: 'Claude Code',
@@ -376,6 +382,11 @@ export default {
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.',
},
opencode: {
title: 'OpenCode Example',
subtitle: 'opencode.json',
hint: 'This is a group configuration example. Adjust model and options as needed.',
},
},
customKeyLabel: 'Custom Key',
customKeyPlaceholder: 'Enter your custom key (min 16 chars)',

View File

@@ -361,6 +361,12 @@ export default {
note: '请确保配置目录存在。macOS/Linux 用户可运行 mkdir -p ~/.codex 创建目录。',
noteWindows: '按 Win+R输入 %userprofile%\\.codex 打开配置目录。如目录不存在,请先手动创建。',
},
cliTabs: {
claudeCode: 'Claude Code',
geminiCli: 'Gemini CLI',
codexCli: 'Codex CLI',
opencode: 'OpenCode',
},
antigravity: {
description: '为 Antigravity 分组配置 API 访问。请根据您使用的客户端选择对应的配置方式。',
claudeCode: 'Claude Code',
@@ -373,6 +379,11 @@ export default {
modelComment: '如果你有 Gemini 3 权限可以填gemini-3-pro-preview',
note: '这些环境变量将在当前终端会话中生效。如需永久配置,请将其添加到 ~/.bashrc、~/.zshrc 或相应的配置文件中。',
},
opencode: {
title: 'OpenCode 配置示例',
subtitle: 'opencode.json',
hint: '示例仅用于演示分组配置,模型与选项可按需调整。',
},
},
customKeyLabel: '自定义密钥',
customKeyPlaceholder: '输入自定义密钥至少16个字符',