Commit Graph

272 Commits

Author SHA1 Message Date
gnanam1990
2c6ec0119e fix: prevent keyboard freeze when MCP notification effects fire
React 19 requires `supportsMicrotasks: true` in the reconciler host
config so it can flush state updates from passive effects via
queueMicrotask. Without this, state updates triggered inside
useMcpConnectivityStatus were silently dropped, corrupting React's
internal executionContext and causing all keyboard input to freeze
after the "N MCP server(s) need auth" notification appeared.

Root cause (three-part fix):

1. reconciler.ts: declare supportsMicrotasks + scheduleMicrotask so
   React 19 schedules passive-effect flushes correctly.

2. useMcpConnectivityStatus.tsx: wrap the MCP auth notification effect
   in try/catch so any unexpected throw does not propagate into
   flushPassiveEffects and permanently corrupt executionContext.

3. notifications.tsx: wrap addNotification, removeNotification, and
   processQueue in try/catch for the same reason — these are called
   from 12+ notification hooks across passive effects.

Also fixes a pre-existing test isolation bug in context.test.ts where
assigning `undefined` to process.env produced the string "undefined",
polluting the env for subsequent test files.

Resolves: #169, #205, #77
2026-04-03 07:41:53 +05:30
Kevin Codex
089a42fc07 Merge pull request #211 from joetam/fix-image-paste-stubs
fix linux clipboard image paste for jpeg/gif/webp
2026-04-03 08:55:50 +08:00
jmt
f5b20fc517 fix: make clipboard images pasteable in OpenClaude
Images in the clipboard could fail to become pasted image attachments in OpenClaude. User-facing symptom: paste would detect that an image existed, but nothing would appear in the prompt, and bundled builds could also fail while converting BMP clipboard images into a format OpenClaude can send to the model.

Linux clipboard image paste had drifted between detection and extraction. checkImage accepted png/jpeg/jpg/gif/webp/bmp, but saveImage only tried image/png and image/bmp. When the clipboard advertised a JPEG, GIF, or WebP image, OpenClaude concluded that an image was present and then failed to write the temp screenshot file, so the paste path returned null and nothing was inserted into the prompt.

Bundled OpenClaude builds had a second failure mode. The build replaces image-processor-napi and sharp with explicit stub modules in bundled mode. getImageProcessor() treated those stubs as real processors, so BMP clipboard images reached sharp(imageBuffer).png() and then failed before they could be converted into a pasteable PNG for OpenClaude.

Keep the Linux clipboard commands generated from one MIME type list and reject __stub-marked image processors up front instead of failing in the middle of image paste.
2026-04-02 15:51:49 -07:00
Kevin Codex
cdf4bad95b Merge pull request #182 from wrenchpilot/development
Enhance local provider URL validation for private IP addresses
2026-04-03 01:56:20 +08:00
Kevin Codex
a6ed57d0f4 Merge pull request #161 from auriti/fix/block-update-for-3p-providers
fix: block update command for 3P providers, align thinking block handling
2026-04-03 01:52:54 +08:00
James Shawn Carnley
7b68eb1acb Enhance local provider URL detection for IPv6 and loopback ranges 2026-04-02 13:46:10 -04:00
Kevin Codex
84950642ae Merge pull request #168 from firecrawl/add-firecrawl
feat: add Firecrawl backend for WebSearch and WebFetch
2026-04-03 01:43:25 +08:00
Kevin Codex
a287597273 Merge pull request #162 from auriti/fix/provider-aware-error-messages
fix: provider-aware error messages and skip Anthropic key approval for 3P
2026-04-03 01:42:15 +08:00
Kevin Codex
47c53a18e8 Merge pull request #174 from gnanam1990/feat/provider-aware-rate-limit
feat: provider-aware rate limit reset delay for OpenAI/GitHub/Codex providers
2026-04-03 01:16:58 +08:00
James Shawn Carnley
5e77d82620 Merge branch 'Gitlawb:main' into development 2026-04-02 12:55:59 -04:00
Kevin Codex
11d9660a80 Merge pull request #157 from erdemozyol/fix/status-tab-highlight
fix: refresh tab highlight on horizontal navigation
2026-04-03 00:55:33 +08:00
Kevin Codex
1a57335d74 Merge pull request #160 from auriti/fix/shim-ids-azure-safety
fix: crypto.randomUUID for IDs, Azure Foundry detection, safety filter visibility
2026-04-03 00:54:49 +08:00
Kevin Codex
7bc903d875 Merge pull request #156 from auriti/fix/model-lookup-and-llama-context
fix: deterministic prefix matching and correct Llama 3.x context windows
2026-04-03 00:53:42 +08:00
Kevin Codex
4c22de2585 Merge pull request #179 from gnanam1990/fix/gemini-routing
fix: route CLAUDE_CODE_USE_GEMINI through OpenAI-compatible shim
2026-04-03 00:50:21 +08:00
James Shawn Carnley
2ee43d7ee8 Merge branch 'Gitlawb:main' into development 2026-04-02 12:43:24 -04:00
Kevin Codex
3581d3f83f Merge pull request #142 from skfallin/fix/anthropic-schema-format
Strip incompatible JSON Schema keywords from tool schemas
2026-04-03 00:26:45 +08:00
James Shawn Carnley
4a4394bb65 feat: enhance local provider URL validation to include private IPv4 and IPv6 addresses 2026-04-02 12:26:23 -04:00
gnanam1990
b4aa27183d fix: route CLAUDE_CODE_USE_GEMINI through OpenAI-compatible shim
The Gemini provider uses Google's OpenAI-compatible endpoint
(generativelanguage.googleapis.com/v1beta/openai) but the client
routing condition in client.ts only checked CLAUDE_CODE_USE_OPENAI
and CLAUDE_CODE_USE_GITHUB — CLAUDE_CODE_USE_GEMINI was missing.

This caused every Gemini request to fall through to the Anthropic
client path. Since ANTHROPIC_API_KEY is not set when using Gemini,
the Anthropic SDK threw:

  "Could not resolve authentication method. Expected either apiKey
   or authToken to be set."

Fix: add CLAUDE_CODE_USE_GEMINI to the OpenAI shim routing condition
so Gemini requests correctly reach createOpenAIShimClient(), which
maps GEMINI_API_KEY → OPENAI_API_KEY and sets OPENAI_BASE_URL to
the Google endpoint.

Closes #176

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 21:51:26 +05:30
gnanam1990
8501786852 feat: provider-aware rate limit reset delay
Previously getRateLimitResetDelayMs only read the Anthropic-specific
'anthropic-ratelimit-unified-reset' header (Unix timestamp), returning
null for every other provider. This meant OpenAI, GitHub, and Codex
users in persistent retry mode (CLAUDE_CODE_UNATTENDED_RETRY=1) always
fell back to dumb exponential backoff even when the server included an
exact reset time in the response headers.

This change makes the function provider-aware:

- firstParty (Anthropic): existing behaviour preserved — reads
  'anthropic-ratelimit-unified-reset' Unix timestamp
- openai / codex / github: reads 'x-ratelimit-reset-requests' and
  'x-ratelimit-reset-tokens' (OpenAI relative duration strings like
  "1s", "6m0s", "1h30m0s"), picks the larger of the two so retries
  don't fire before both token and request limits have reset
- bedrock / vertex / foundry / gemini: returns null (no standard
  reset header for these providers)

Adds parseOpenAIDuration() as an exported helper to convert OpenAI's
duration format into milliseconds.

16 new tests covering all provider paths and edge cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 21:30:05 +05:30
skfallin
37d4c21739 fix: make schema sanitization provider-specific 2026-04-02 17:57:42 +02:00
Kevin Codex
73db9b5fd3 Merge pull request #163 from erdemozyol/feat/codex-status-usage
Add Codex usage to /status
2026-04-02 23:54:07 +08:00
gnanam1990
942d09ca9c security: fix 5 findings from issue #42 — env leak, ant gate, depth DoS, URL parse, CA cert
Finding 1 [CRITICAL] — sessionRunner leaks full process.env to child
Extract buildChildEnv() with an explicit allowlist of safe OS/runtime vars.
Child process no longer inherits ANTHROPIC_API_KEY, OPENAI_API_KEY, DB
credentials, or any other secret present in the parent shell environment.
Only CLAUDE_CODE_* bridge vars, PATH, HOME, and standard OS env are passed.

Finding 2 [HIGH] — USER_TYPE=ant activatable by external users
Add isAntEmployee() -> false constant in src/utils/buildConfig.ts.
Replace all three direct process.env.USER_TYPE === 'ant' checks in
setup.ts and onChangeAppState.ts so no external user can activate
Anthropic-internal code paths (commit attribution, system prompt clearing,
dangerously-skip-permissions bypass) by setting USER_TYPE in their shell.

Finding 3 [HIGH] — memoryScan.ts unlimited directory walk
Add MAX_DEPTH=3 guard on readdir({ recursive: true }) results.
Deep or symlink-looped memory directories no longer cause an unbounded
blocking walk before the MAX_MEMORY_FILES cap takes effect.

Finding 5 [HIGH] — buildSdkUrl uses string.includes for protocol detection
Replace apiBaseUrl.includes('localhost') with new URL(apiBaseUrl).hostname
comparison so a remote URL containing 'localhost' in its path no longer
incorrectly gets ws:// (unencrypted) instead of wss://.

Finding 6 [HIGH] — upstream proxy writes unvalidated CA cert to disk
Add isValidPemContent() validation before writeFile in the CA cert download
path. A compromised proxy sending non-PEM data (HTML, JSON, scripts) is now
rejected before it can be appended to the system CA bundle.

Each fix is covered by new unit tests (25 tests across 5 new test files).
All 52 tests pass. Build verified clean on v0.1.7.

Fixes #42

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 21:04:10 +05:30
Leonardo Grigorio
ac4efae870 feat: add Firecrawl backend for WebSearch and WebFetch tools
WebSearch is currently disabled for all non-Anthropic providers (OpenAI
shim, DeepSeek, Ollama, etc.) because those providers have no native
search backend. This adds Firecrawl as a fallback that activates when
FIRECRAWL_API_KEY is set, unlocking web search for every model
openclaude supports.

WebFetch uses basic HTTP + Turndown for HTML-to-markdown conversion,
which fails silently on JS-rendered SPAs and bot-protected pages.
Firecrawl scrape replaces the fetch layer when FIRECRAWL_API_KEY is set,
returning clean markdown that handles dynamic content correctly.

Changes:
- WebSearchTool: add runFirecrawlSearch() using @mendable/firecrawl-js,
  respects allowed_domains (post-filter) and blocked_domains (-site: operators),
  includes result snippets alongside links. shouldUseFirecrawl() ensures
  firstParty/Vertex/Foundry/Codex providers keep their native backends.
- WebFetchTool: add scrapeWithFirecrawl(), drops into the existing
  applyPromptToMarkdown() pipeline so prompt processing is unchanged.
- Remove "Web search is only available in the US" restriction from
  prompt when Firecrawl is active (it works globally).
2026-04-02 12:18:20 -03:00
erdemozyol
5c25ac4e9a Add Codex usage to /status 2026-04-02 17:37:07 +03:00
erdemozyol
84ac06bac9 fix: show display version in status 2026-04-02 17:28:34 +03:00
Juan Camilo
c66b859342 fix: provider-aware error messages and skip Anthropic key approval for 3P
1. errors.ts: Add getCustomOffSwitchMessage() that returns a
   provider-neutral message for 3P users instead of the hardcoded
   "Opus is experiencing high load, please use /model to switch to
   Sonnet" which is misleading for OpenAI/Gemini/Ollama users.
   The original constant is preserved for backward-compatible string
   matching in error handlers.

2. Onboarding.tsx: Skip the "approve API key" step when a 3P provider
   is active. Previously, having ANTHROPIC_API_KEY in the environment
   (e.g., from a previous Anthropic setup) triggered an irrelevant
   Anthropic key approval UI even when using Gemini or OpenAI.
2026-04-02 16:23:12 +02:00
Juan Camilo
1709f5c098 fix: block update command for 3P providers, align thinking block handling
1. cli/update.ts: Block the update command for third-party providers.
   The update mechanism downloads from Anthropic's GCS bucket, which
   would silently replace the OpenClaude build (with the OpenAI shim)
   with the upstream Claude Code binary (without it). Now shows an
   actionable message directing users to rebuild from source.

2. codexShim.ts: Filter thinking blocks from assistant history, matching
   the openaiShim behavior. Without this, thinking blocks were included
   as plain text in assistant messages for the Codex transport but
   excluded for the OpenAI transport — causing inconsistent history
   when switching providers mid-session.
2026-04-02 16:18:10 +02:00
Juan Camilo
5d6443799a fix: crypto.randomUUID for IDs, Azure Foundry detection, safety filter visibility
Three targeted fixes:

1. Replace Math.random() with crypto.randomUUID() for message and tool
   call IDs in both openaiShim.ts and codexShim.ts. Math.random() is
   not cryptographically secure and predictable in seeded environments.

2. Anchor Azure endpoint detection to parsed hostname instead of raw
   URL regex. Adds support for Azure AI Foundry (services.ai.azure.com)
   alongside existing cognitiveservices and openai Azure endpoints.
   Prevents SSRF-style bypass via path segments.

3. Surface content safety filter blocks to the user. When Gemini or
   Azure returns finish_reason 'content_filter' or 'safety', emit a
   visible text block '[Content blocked by provider safety filter]'
   instead of silently returning empty/truncated content with
   stop_reason 'end_turn'. Applied to both streaming and non-streaming.
2026-04-02 16:14:35 +02:00
erdemozyol
6f4aa02123 fix: refresh tab highlight on horizontal navigation 2026-04-02 16:58:45 +03:00
Juan Camilo
b65921e8c3 fix: deterministic prefix matching and correct Llama 3.x context windows
Two fixes in openaiContextWindows.ts:

1. Sort lookup keys by length descending in lookupByModel() so the most
   specific prefix always wins. Without this, 'gpt-4-turbo-preview'
   could match 'gpt-4' (8k) instead of 'gpt-4-turbo' (128k) depending
   on V8's object key iteration order.

2. Update Llama 3.1/3.2/3.3 context windows from 8,192 to 128,000.
   These models support 128k context natively (Meta official specs).
   The previous 8k value was Ollama's default num_ctx, not the model's
   actual capability, causing premature auto-compact warnings.
2026-04-02 15:50:52 +02:00
skfallin
0fe8551d33 Merge branch 'main' into fix/anthropic-schema-format 2026-04-02 15:50:16 +02:00
Kevin Codex
145c99b297 Merge pull request #151 from auriti/fix/gemini-auth-dummy-key-bypass
fix: prevent ANTHROPIC_API_KEY from interfering with Gemini provider auth
2026-04-02 21:43:04 +08:00
skfallin
6319df02f0 Merge upstream/main into fix/anthropic-schema-format 2026-04-02 15:42:28 +02:00
Kevin Codex
3c8c63a78e Merge pull request #153 from auriti/fix/report-openai-cached-tokens
fix: report cached tokens from OpenAI prompt_tokens_details
2026-04-02 21:41:47 +08:00
Kevin Codex
35676be381 Merge pull request #143 from sooth/codex/repl-memory-and-schema-hardening
[codex] fix: trim persisted tool results and sanitize MCP schemas
2026-04-02 21:41:30 +08:00
Juan Camilo
d430ddd568 fix: prevent ANTHROPIC_API_KEY from interfering with Gemini provider auth
Two fixes for issue #133 where setting ANTHROPIC_API_KEY=dummy alongside
CLAUDE_CODE_USE_GEMINI=1 causes "Invalid API key" errors:

1. auth.ts: In the CI branch of getAnthropicApiKeyWithSource(), the
   ANTHROPIC_API_KEY value was returned without checking isUsing3PServices().
   A dummy key leaked into the Anthropic key resolution pipeline even when
   Gemini was the active provider. Now guards with isUsing3PServices().

2. errors.ts: The x-api-key error handler surfaced "Invalid API key" for
   any provider. Added getAPIProvider() === 'firstParty' guard so 3P users
   see the real underlying error instead of a misleading auth message.

Note: The cli.tsx Gemini validation fix (originally part of this PR) was
independently implemented in PR #121 and is already on main.
2026-04-02 15:40:07 +02:00
Kevin Codex
1514220ee7 Merge pull request #144 from Meetpatel006/main
feat: add Codex/OpenAI effort picker and stabilize model/suggestion navigation and its display the current model with effort
2026-04-02 21:25:48 +08:00
Kevin Codex
680cd69d8a Merge pull request #150 from Vasanthdev2004/slash-highlight-fix
fix: make selected slash suggestion visibly highlighted
2026-04-02 21:24:04 +08:00
Juan Camilo
708a0a18fe fix: report cached tokens from OpenAI prompt_tokens_details
OpenAI returns cached token counts in usage.prompt_tokens_details.cached_tokens
but the shim hardcoded cache_read_input_tokens to 0. This made prompt
caching invisible to the cost tracker and session summary even when
OpenAI's automatic caching was actively reducing costs.

Changes:
- Extend OpenAIStreamChunk usage interface with prompt_tokens_details
- Map cached_tokens to cache_read_input_tokens in convertChunkUsage()
- Same fix in _convertNonStreamingResponse() for non-streaming path
- cache_creation_input_tokens remains 0 (OpenAI auto-caching has no
  creation cost — it is free and automatic)
2026-04-02 15:21:37 +02:00
sooth
5c4469fe81 fix: trim persisted tool results and sanitize MCP schemas 2026-04-02 09:20:40 -04:00
Meet Patel
8f50f17674 feat: Refactor model handling & reasoning effort across navigation, typeahead, OpenAI/Codex providers, API shim, configs, and UI (adds EffortPicker, new mappings/options, unique suggestion IDs, effort utilities; removes deprecated aliases; defaults Codex to gpt-5.4; improves selection logic and status display) 2026-04-02 18:49:07 +05:30
Kevin Codex
9f48bb4431 Merge pull request #135 from auriti/fix/shim-reliability-and-protocol-compliance
fix: shim reliability and protocol compliance overhaul
2026-04-02 21:15:44 +08:00
Vasanthdev2004
4d0886a4fe fix: keep slash highlight in sync in fullscreen 2026-04-02 18:42:56 +05:30
Kevin Codex
0a1ac92341 Merge pull request #138 from erdemozyol/fix/codex-websearch-and-agent-fallback
fix: support Codex web tools and non-git agents
2026-04-02 21:02:43 +08:00
Kevin Codex
1ee2ce931a Merge pull request #117 from auriti/fix/context-isenvtruthy-mismatch
fix: use isEnvTruthy() for provider detection in context window lookup
2026-04-02 21:01:15 +08:00
Kevin Codex
bc2a4bcdd5 Merge pull request #121 from Vasanthdev2004/provider-setup-wizard
feat: add guided /provider setup for saved profiles
2026-04-02 21:00:41 +08:00
Vasanthdev2004
118b0793e0 fix: move slash suggestion highlight with selection 2026-04-02 18:25:52 +05:30
Vasanthdev2004
5ccda35941 fix: highlight selected slash suggestion 2026-04-02 18:18:48 +05:30
Juan Camilo
f385740bd6 fix: use isEnvTruthy() for provider detection in context window lookup
Replace raw === '1' || === 'true' comparisons with isEnvTruthy() in
context.ts for consistency with getAPIProvider() in providers.ts.
This also covers the newly added CLAUDE_CODE_USE_GITHUB provider.

Add native Gemini model entries (without google/ prefix) to both
context window and max output token tables. Corrects gemini-2.5-pro
and gemini-2.5-flash max output tokens to 65,536 (was 8,192/32,768).
2026-04-02 14:43:03 +02:00
Juan Camilo
f4818dc213 fix: shim reliability and protocol compliance overhaul
Addresses the most critical remaining issues in the provider shim layer,
building on top of #124 (recursive schema normalization + try/finally).

openaiShim.ts:
- Throw APIError via SDK factory instead of plain Error — enables retry
  on 429/503 (was completely broken: zero retries for all 3P providers)
- Guard stop_reason !== null before emitting usage-only message_delta
  (Azure/Groq send usage before finish_reason)
- Fix assistant content: join text parts instead of invalid as-string cast
  (Mistral rejects array content on assistant role)
- Expose real HTTP Response in withResponse() for header inspection
- Skip stream_options for local providers (Ollama < 0.5 compatibility)

codexShim.ts:
- Throw APIError at all 4 throw sites (HTTP + 3 streaming errors)
- Add tool_choice 'none' mapping (was silently ignored)
- Forward is_error flag with Error: prefix (matching openaiShim)
2026-04-02 14:41:40 +02:00