π File detail
voice/voiceModeEnabled.ts
π§© .tsπ 55 linesπΎ 2,332 bytesπ text
β Back to All Filesπ― Use case
This file lives under βvoice/β, which covers voice capture, STT, and keyterm plumbing. On the API surface it exposes isVoiceGrowthBookEnabled, hasVoiceAuth, and isVoiceModeEnabled β mainly functions, hooks, or classes. Dependencies touch bun:bundle. It composes internal code from services and utils (relative imports).
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
import { feature } from 'bun:bundle' import { getFeatureValue_CACHED_MAY_BE_STALE } from '../services/analytics/growthbook.js' import { getClaudeAIOAuthTokens, isAnthropicAuthEnabled,
π€ Exports (heuristic)
isVoiceGrowthBookEnabledhasVoiceAuthisVoiceModeEnabled
π External import roots
Package roots from from "β¦" (relative paths omitted).
bun:bundle
π₯οΈ Source preview
import { feature } from 'bun:bundle'
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../services/analytics/growthbook.js'
import {
getClaudeAIOAuthTokens,
isAnthropicAuthEnabled,
} from '../utils/auth.js'
/**
* Kill-switch check for voice mode. Returns true unless the
* `tengu_amber_quartz_disabled` GrowthBook flag is flipped on (emergency
* off). Default `false` means a missing/stale disk cache reads as "not
* killed" β so fresh installs get voice working immediately without
* waiting for GrowthBook init. Use this for deciding whether voice mode
* should be *visible* (e.g., command registration, config UI).
*/
export function isVoiceGrowthBookEnabled(): boolean {
// Positive ternary pattern β see docs/feature-gating.md.
// Negative pattern (if (!feature(...)) return) does not eliminate
// inline string literals from external builds.
return feature('VOICE_MODE')
? !getFeatureValue_CACHED_MAY_BE_STALE('tengu_amber_quartz_disabled', false)
: false
}
/**
* Auth-only check for voice mode. Returns true when the user has a valid
* Anthropic OAuth token. Backed by the memoized getClaudeAIOAuthTokens β
* first call spawns `security` on macOS (~20-50ms), subsequent calls are
* cache hits. The memoize clears on token refresh (~once/hour), so one
* cold spawn per refresh is expected. Cheap enough for usage-time checks.
*/
export function hasVoiceAuth(): boolean {
// Voice mode requires Anthropic OAuth β it uses the voice_stream
// endpoint on claude.ai which is not available with API keys,
// Bedrock, Vertex, or Foundry.
if (!isAnthropicAuthEnabled()) {
return false
}
// isAnthropicAuthEnabled only checks the auth *provider*, not whether
// a token exists. Without this check, the voice UI renders but
// connectVoiceStream fails silently when the user isn't logged in.
const tokens = getClaudeAIOAuthTokens()
return Boolean(tokens?.accessToken)
}
/**
* Full runtime check: auth + GrowthBook kill-switch. Callers: `/voice`
* (voice.ts, voice/index.ts), ConfigTool, VoiceModeNotice β command-time
* paths where a fresh keychain read is acceptable. For React render
* paths use useVoiceEnabled() instead (memoizes the auth half).
*/
export function isVoiceModeEnabled(): boolean {
return hasVoiceAuth() && isVoiceGrowthBookEnabled()
}