mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 14:25:51 +00:00
feat: 添加 GrowthBook 自定义服务器适配器
通过 CLAUDE_GB_ADAPTER_URL/KEY 环境变量连接自定义 GrowthBook 实例, 无配置时所有 feature 读取返回代码默认值。支持 GrowthBook Cloud(非 remoteEval), 含完整文档和 feature key 列表。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,10 @@ import { isEnvTruthy } from '../utils/envUtils.js'
|
||||
// Lazy read so ENABLE_GROWTHBOOK_DEV from globalSettings.env (applied after
|
||||
// module load) is picked up. USER_TYPE is a build-time define so it's safe.
|
||||
export function getGrowthBookClientKey(): string {
|
||||
// 适配器优先:自定义 GrowthBook 服务器
|
||||
const adapterKey = process.env.CLAUDE_GB_ADAPTER_KEY
|
||||
if (adapterKey) return adapterKey
|
||||
|
||||
return process.env.USER_TYPE === 'ant'
|
||||
? isEnvTruthy(process.env.ENABLE_GROWTHBOOK_DEV)
|
||||
? 'sdk-yZQvlplybuXjYh6L'
|
||||
|
||||
@@ -420,6 +420,10 @@ function syncRemoteEvalToDisk(): void {
|
||||
* Check if GrowthBook operations should be enabled
|
||||
*/
|
||||
function isGrowthBookEnabled(): boolean {
|
||||
// 适配器模式:有自定义服务器配置时直接启用
|
||||
if (process.env.CLAUDE_GB_ADAPTER_URL && process.env.CLAUDE_GB_ADAPTER_KEY) {
|
||||
return true
|
||||
}
|
||||
// GrowthBook depends on 1P event logging.
|
||||
return is1PEventLoggingEnabled()
|
||||
}
|
||||
@@ -495,15 +499,17 @@ const getGrowthBookClient = memoize(
|
||||
|
||||
const attributes = getUserAttributes()
|
||||
const clientKey = getGrowthBookClientKey()
|
||||
const baseUrl =
|
||||
process.env.CLAUDE_GB_ADAPTER_URL
|
||||
|| (process.env.USER_TYPE === 'ant'
|
||||
? process.env.CLAUDE_CODE_GB_BASE_URL || 'https://api.anthropic.com/'
|
||||
: 'https://api.anthropic.com/')
|
||||
const isAdapterMode = !!(process.env.CLAUDE_GB_ADAPTER_URL && process.env.CLAUDE_GB_ADAPTER_KEY)
|
||||
if (process.env.USER_TYPE === 'ant') {
|
||||
logForDebugging(
|
||||
`GrowthBook: Creating client with clientKey=${clientKey}, attributes: ${jsonStringify(attributes)}`,
|
||||
)
|
||||
}
|
||||
const baseUrl =
|
||||
process.env.USER_TYPE === 'ant'
|
||||
? process.env.CLAUDE_CODE_GB_BASE_URL || 'https://api.anthropic.com/'
|
||||
: 'https://api.anthropic.com/'
|
||||
|
||||
// Skip auth if trust hasn't been established yet
|
||||
// This prevents executing apiKeyHelper commands before the trust dialog
|
||||
@@ -518,7 +524,8 @@ const getGrowthBookClient = memoize(
|
||||
const authHeaders = hasTrust
|
||||
? getAuthHeaders()
|
||||
: { headers: {}, error: 'trust not established' }
|
||||
const hasAuth = !authHeaders.error
|
||||
// 适配器模式下不需要 auth,GrowthBook Cloud 用 clientKey 即可
|
||||
const hasAuth = isAdapterMode || !authHeaders.error
|
||||
clientCreatedWithAuth = hasAuth
|
||||
|
||||
// Capture in local variable so the init callback operates on THIS client,
|
||||
@@ -527,9 +534,10 @@ const getGrowthBookClient = memoize(
|
||||
apiHost: baseUrl,
|
||||
clientKey,
|
||||
attributes,
|
||||
remoteEval: true,
|
||||
// Re-fetch when user ID or org changes (org change = login to different org)
|
||||
cacheKeyAttributes: ['id', 'organizationUUID'],
|
||||
// remoteEval only works with Anthropic internal API, GrowthBook Cloud doesn't support it
|
||||
remoteEval: !isAdapterMode,
|
||||
// cacheKeyAttributes only valid with remoteEval
|
||||
...(!isAdapterMode ? { cacheKeyAttributes: ['id', 'organizationUUID'] } : {}),
|
||||
// Add auth headers if available
|
||||
...(authHeaders.error
|
||||
? {}
|
||||
@@ -566,7 +574,7 @@ const getGrowthBookClient = memoize(
|
||||
|
||||
if (process.env.USER_TYPE === 'ant') {
|
||||
logForDebugging(
|
||||
`GrowthBook initialized successfully, source: ${result.source}, success: ${result.success}`,
|
||||
`GrowthBook initialized, source: ${result.source}, success: ${result.success}`,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user