privacy: remove external data transmissions & add GitHub release workflow

Remove three active external data transmission paths:

1. WebFetch domain blocklist (api.anthropic.com/api/web/domain_info)
   - src/tools/WebFetchTool/utils.ts
   - Was sending every domain a user tried to fetch to Anthropic
   - Replaced with always-allowed stub; tool permission dialog is
     the primary security boundary

2. Codex API router (chatgpt.com/backend-api/codex/responses)
   - src/services/api/codex-fetch-adapter.ts
   - Would have forwarded full conversation content to OpenAI
   - createCodexFetch now returns HTTP 403 stub

3. OpenAI API adapter (api.openai.com/v1/chat/completions)
   - src/utils/codex-fetch-adapter.ts
   - Would have forwarded messages to OpenAI
   - fetchCodexResponse now throws immediately

Already-disabled paths (no changes needed):
- Analytics logEvent/logEventAsync: empty stubs in services/analytics/index.ts
- GrowthBook/Statsig: local cache only, no outbound requests
- Auto-updater GCS: already guarded by CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
- MCP registry: already guarded by CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
- Release notes GitHub: already guarded by isEssentialTrafficOnly()

Add .github/workflows/release.yml:
- Builds self-contained binaries for macOS (x64+arm64), Linux (x64+arm64),
  Windows (x64) using bun compile on each native runner
- Triggers on version tags (v*.*.*) or manual workflow_dispatch
- Publishes binaries + SHA256SUMS.txt as a GitHub Release with
  per-platform install instructions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-14 15:46:47 +08:00
parent 9ba783f10b
commit 7dd3095974
4 changed files with 199 additions and 144 deletions

View File

@@ -83,53 +83,22 @@ function convertToOpenAIMessage(message: Message): OpenAIMessage {
}
/**
* Make a request to OpenAI Codex API
* fetchCodexResponse is disabled: sending conversation content to
* api.openai.com would leak user data to a third-party service.
* This function is retained as a stub to avoid breaking any call sites.
*/
export async function fetchCodexResponse(
messages: Message[],
model: string,
options: {
_messages: Message[],
_model: string,
_options: {
apiKey?: string
baseUrl?: string
stream?: boolean
} = {}
): Promise<OpenAIResponse> {
const { apiKey, baseUrl = 'https://api.openai.com/v1', stream = false } = options
if (!apiKey) {
throw new Error('OpenAI API key is required for Codex requests')
}
const openAIMessages = messages.map(convertToOpenAIMessage)
const requestBody = {
model,
messages: openAIMessages,
stream,
temperature: 0.7,
max_tokens: 4096,
}
try {
const response = await fetch(`${baseUrl}/chat/completions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
},
body: JSON.stringify(requestBody),
})
if (!response.ok) {
throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`)
}
const data = await response.json() as OpenAIResponse
return data
} catch (error) {
logError(error)
throw error
}
throw new Error(
'OpenAI Codex API calls are disabled for privacy. External data forwarding has been removed.',
)
}
/**