Commit Graph
634 Commits
Author SHA1 Message Date
chioarub 1aa8aab84c fix(monitor): close permission dialog after selection (#1225)
* Fix monitor permission dialog lifecycle

* test(monitor): cover persistent allow continuation path
2026-05-20 01:37:09 +08:00
JATMN a9f8642aa8 fix(input): preserve split utf8 keypresses (#1241)
Buffer incomplete UTF-8 byte sequences across stdin parser reads so interactive IME input does not turn split multibyte characters into replacement text.

Keep the existing high-bit meta-key fallback when a lone pending byte is flushed, and continue to route completed text through the existing terminal tokenizer.

Add regression coverage for Vietnamese input arriving one byte at a time, matching the live typing failure mode from issue #1233.

Validation: bun test src\ink\parse-keypress.test.ts; bun test src\components\TextInput.test.tsx src\ink\parse-keypress.test.ts; bun run build; git diff --check.
2026-05-20 01:36:21 +08:00
chioarub f71e769237 fix(query): stop repeated tool-failure loops (#1219) 2026-05-18 07:23:36 +08:00
Evert Junior 0fba1541a8 fix(TaskListV2): revert overflowX hidden that hides task text labels (#1215)
The overflowX="hidden" added in #1211 clips task subject text to
nothing when TaskItems are nested inside MessageResponse (the └
prefix constrains available width). The icon survives at 2 chars
but the text gets fully clipped, leaving orphaned ✓/■ without
any label.

Reverts the overflowX="hidden" portion of #1211.
2026-05-17 14:55:00 +08:00
github-actions[bot] f102b601c5 chore(main): release 0.13.0 (#1208)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
v0.13.0
2026-05-17 11:13:06 +08:00
Kevin Codex e5535577aa docs: add Xiaomi MiMo sponsor (#1213)
* docs: add Xiaomi MiMo sponsor

* feat(tips): add Xiaomi MiMo sponsored tips
2026-05-17 11:01:06 +08:00
Kevin Codex 2d20109edc fix(gemini): parse raw tool call text (#1212) 2026-05-17 10:13:28 +08:00
Nik c53ef18716 fix(bashPermissions): apply MAX_SUBCOMMANDS cap in sandbox auto-allow path (#1057) (#1166)
* fix(bashPermissions): apply MAX_SUBCOMMANDS cap in sandbox auto-allow path (#1057)

The cap from #21405 is enforced in `bashToolHasPermission`, but the
`checkSandboxAutoAllow` shortcut path called `splitCommand` and iterated
`matchingRulesForInput` once per subcommand before the main-path cap got
a chance to run. With auto-allow-bash-if-sandboxed enabled, a crafted
compound command whose legacy `splitCommand` output explodes could
trigger N rule lookups in this path.

Mirror the existing cap (MAX_SUBCOMMANDS_FOR_SECURITY_CHECK = 50) in
`checkSandboxAutoAllow` right after the `splitCommand(command)` call:
log + return `ask` with the same decision-reason shape as the main path.

Regression test in bashPermissions.test.ts exercises sandbox auto-allow
with 60 echo subcommands and asserts the `ask` short-circuit.

* ci: re-trigger checks (likely-flaky failures on unrelated profile/SDK/KG tests)

* fix(bashPermissions): gate sandbox cap on legacy splitter path (CC-643)

Address reviewer feedback on #1057: the previous patch applied
MAX_SUBCOMMANDS_FOR_SECURITY_CHECK in checkSandboxAutoAllow
unconditionally on splitCommand output. The main bashToolHasPermission
path only applies that cap when astSubcommands === null, because the
fanout/ReDoS concern is specific to the legacy splitter — AST-parseable
compound commands (e.g. long echo chains) are already bounded by
structural parse and should not be downgraded to ask.

Thread astSubcommands into checkSandboxAutoAllow and only fire the cap
when AST is unavailable. Export checkSandboxAutoAllow so the symmetric
behavior is directly testable without depending on tree-sitter WASM
availability in the test runtime.

Tests:
- Legacy path (CLAUDE_CODE_DISABLE_COMMAND_INJECTION_CHECK=1 OR
  astSubcommands=null) over 50 subcommands -> ask, cap reason.
- AST-validated path (astSubcommands provided) with 60 subcommands ->
  allow, sandbox auto-allow reason.
2026-05-17 09:55:27 +08:00
chioarub 271bad4209 feat(export): add Markdown and JSON conversation exports (#1193) 2026-05-17 09:54:33 +08:00
JATMN a7f4b02db9 test: add shared mutation lock timeout guard (#1209)
Give acquireSharedMutationLock a default five-minute timeout so missed releases fail with a scoped error instead of hanging the smoke suite indefinitely.

Keep explicit timeout overrides intact and add isolated mutex coverage for default timeout, override timeout, and release handoff behavior.
2026-05-17 09:46:07 +08:00
Evert Junior 8470832e5c fix(spinner): prevent layout shift during thinking and orphaned task icons (#1211)
The spinner row used flexWrap="wrap" which caused the status text
(thinking indicator, timer, token count) to wrap to a new line when
content width hit a boundary condition. This produced a visible
layout jump — especially during thinking transitions when the status
text changes width.

Additionally, TaskItem rendered icons without overflow constraints,
so when text content overflowed the available width, orphaned icon
characters (checkmarks, squares) leaked into visible rows.

Changes:
- Use flexWrap="nowrap" on spinner row containers to keep status on
  one line, relying on the existing progressive width gating to hide
  elements that don't fit
- Replace magic number in availableSpace calculation with a named
  constant for clarity
- Add overflowX="hidden" on TaskItem to clip overflowing content
2026-05-17 09:45:23 +08:00
Nik b3b771476d fix(websearch): surface adapter failure when auto mode falls back to native (#994) (#1168)
* fix(websearch): surface adapter failure when auto mode falls back to native (#994)

When `WEB_SEARCH_PROVIDER=auto` and the configured adapter chain fails
on a recoverable error (DuckDuckGo "rate-limited from this network",
adapter timeout, 5xx, etc.), the tool falls through to the native
Anthropic / Codex web-search path silently. The only signal that the
adapter failed is a `console.error` line — it never reaches the tool
result the user sees. On rate-limit-prone networks (datacenter IPs,
VPNs) this manifests as "no results found" with no actionable hint,
exactly the symptom reported in #994.

This change captures the adapter error in `adapterFallthroughNotice`
inside the catch branch and prepends it to the eventual native / Codex
output via a small pure helper, `withAdapterFallthroughNotice`. The
hits-present and native-error paths are unchanged; the helper only
mutates a shallow copy when a notice is set, and is a no-op otherwise.

Result: users on a rate-limited adapter chain who get native results
also see *why* the adapter failed, and users whose native search also
returns nothing finally get the actionable diagnostic (configure
TAVILY_API_KEY / FIRECRAWL_API_KEY / etc.) instead of a silent empty.

Test coverage in WebSearchTool.test.ts asserts the pure-helper
contract: no-op when notice is undefined, prepend-not-mutate when a
notice is provided.

* fix(websearch): narrow #994 fix to the reachable adapter-failure surface

Address @techbrewboss feedback: the previous patch's
`adapterFallthroughNotice` machinery and the
`withAdapterFallthroughNotice` helper were unreachable under the
current provider selection.

`shouldUseAdapterProvider()` and `hasNativeSearchFallback()` are
mutually exclusive in auto mode — when a native path exists
(firstParty/vertex/foundry/Codex) the adapter is never tried, and when
the adapter IS tried (openai-shim providers) there is no native
fallback. So the assignment at `adapterFallthroughNotice = ...` and
both `withAdapterFallthroughNotice(...)` call sites could never fire.

Narrow the PR to the path that #994 actually hits today: an
openai-shim provider (moonshot/minimax/nvidia-nim/github copilot) where
the adapter fails transiently and there is no native fallback. The
existing throw at that branch already surfaces the underlying adapter
error verbatim; extract `buildAdapterUnavailableError(provider, errMsg)`
so it is directly testable and cannot regress, and replace the dead
notice helper + its tests with focused coverage of the reachable
message.

Drop the no-op shallow-copy `withAdapterFallthroughNotice` helper and
its two tests; keep the descriptive error throw as the single,
reachable surfacing path.
2026-05-17 05:35:28 +08:00
github-actions[bot] ca357cc78d chore(main): release 0.12.1 (#1202)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
v0.12.1
2026-05-17 05:31:30 +08:00
3kin0x bd7d42cb69 fix(ui): prevent prompt layout corruption when renaming session (#1206) 2026-05-17 05:31:10 +08:00
Kevin Codex 13a090162f fix(gemini): preserve tool calls through opengateway (#1204) 2026-05-17 05:12:07 +08:00
ArkhAngelLifeJiggy 4d0603e990 fix(entrypoint): apply --max-old-space-size=8192 universally, not just CCR (#1191)
Closes #402 — JavaScript heap OOM during large tasks.

The CLI entry point only set --max-old-space-size=8192 when
CLAUDE_CODE_REMOTE=true, leaving local users with V8's ~2 GB default
ceiling. Long agentic tasks (multi-file refactors, large prompts, tool
loops) hit that ceiling and abort with:
  FATAL ERROR: Ineffective mark-compacts near heap limit
  Allocation failed - JavaScript heap out of memory

Fix: remove the CCR gate and apply the 8 GB cap unconditionally, with a
user-override guard -- if the runner already set NODE_OPTIONS
--max-old-space-size to an explicit value, their setting is preserved
(no silent clobbering).

Files changed:
- src/entrypoints/cli.tsx — remove CLAUDE_CODE_REMOTE guard, add
  user-override predicate, update comments
- src/entrypoints/cli.test.ts — 6 regression tests (new file)
2026-05-16 22:16:31 +08:00
github-actions[bot] 5959763e48 chore(main): release 0.12.0 (#1173)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
v0.12.0
2026-05-16 15:24:20 +08:00
4d04f5bf4f feat(opengateway): add Gemini 3.1 Flash Lite + GLM 5.1 FP8 to catalog (#1194)
* feat(opengateway): add Gemini 3.1 Flash Lite + GLM 5.1 FP8 to catalog

Opengateway now routes non-Xiaomi models through GMI Cloud (configured
in opengateway/src/providers.ts via modelIds:
  - google/gemini-3.1-flash-lite-preview
  - zai-org/GLM-5.1-FP8

Adding both as catalog entries on the gitlawb-opengateway gateway
descriptor so openclaude users see them in the model picker when the
Opengateway preset is active. Each catalog entry reuses the existing
upstream model descriptor (`gemini-3.1-flash-lite-preview`, `GLM-5.1`)
for capability metadata; the apiName uses the full vendor-prefixed
form the gateway routes on.

No new model/brand/vendor descriptors needed — only the gateway
catalog gets the new IDs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* update opengateway

---------

Co-authored-by: OpenClaude <openclaude@gitlawb.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 15:20:30 +08:00
JATMN f12eb1c9e8 Harden test isolation for smoke stability (#1192)
* Fix flaky smoke build checks

Replace feature-flag build preprocessing with a Bun onLoad transform so smoke/build no longer rewrites tracked src files while tests may be reading them.

Keep telemetry stubs ahead of the feature transform in both CLI and SDK builds, preserve non-empty text token counts in hybrid context splitting, and make the corrupted Orama stress test assert against the actual project directory used by the test.

Verified with bun run smoke, bun test src/utils/hybridContextStrategy.test.ts, bun test src/utils/knowledgeGraph.stress.test.ts --rerun-each 3, and bun test --max-concurrency=1.

* Harden KnowledgeGraph smoke stress isolation

Give each KnowledgeGraph stress test its own temporary config directory and remove it during teardown so Orama, SQLite, and corrupted-file state cannot bleed between stress cases or later PR test runs.

Reviewed at least 20 open PRs and found the recurring smoke-and-tests failure cluster is the full unit suite, especially KnowledgeGraph corrupted Orama recovery. Verified with bun test src/utils/knowledgeGraph.stress.test.ts --rerun-each 5, bun test --max-concurrency=1, and bun run smoke.

* Harden smoke test isolation

Audit and harden broad smoke-adjacent test suites for process-global leaks, including env/config restoration, shared registry/module mock cleanup, fetch/axios/mock restoration, and global MACRO/platform/sandbox mutations.

Replace fragile render sleeps in interactive tests with output-driven waits, and isolate provider/model/profile tests behind the shared mutation lock so unrelated PRs do not inherit stale process state.

Make SQLite knowledge graph cleanup clear closed on-disk databases before best-effort file cleanup, with coverage for the stale database reset path.

Verified: bun run smoke; bun test --max-concurrency=1; python -m pytest -q python/tests; bun run security:pr-scan -- --base origin/main; bun run test:provider; npm run test:provider-recommendation.

* Harden test isolation across smoke suite

Guard process-global test mutations with the shared mutation lock across env, module mock, config cache, and storage tests.\n\nDeep-copy global config snapshots, restore transient globals precisely, and make plugin/LSP mocks expose compatible export surfaces so concurrent test loading does not poison unrelated suites.\n\nReplace fixed SDK cleanup sleeps with call polling to remove timing sensitivity.\n\nVerification:\n- bun test --max-concurrency=1\n- bun run smoke\n- python -m pytest -q python/tests\n- bun run test:provider\n- npm run test:provider-recommendation\n- bun run security:pr-scan -- --base origin/main\n- git diff --check

* Close remaining test global-state leaks

Guard remaining cache, plugin, console, and VS Code module-mock tests with the shared mutation lock.\n\nThis follow-up audit covers non-env process-global state that can leak across test files: tool schema cache, cache stats tracker state, plugin loader caches, console.error replacement, and VS Code mock.module usage.\n\nVerification:\n- leak-surface scans for env/global/mock.module/cache outliers\n- duplicate top-level mock collision cluster\n- affected tests cluster\n- bun test --max-concurrency=1\n- bun run smoke\n- git diff --check

* Guard remaining mock restore cleanup

Lock tests that call bun:test mock.restore without installing module mocks themselves.\n\nmock.restore is process-global, so these cleanup hooks can still tear down another test file's active module mocks when files run concurrently.\n\nVerification:\n- expanded leak scans for env, globals, module mocks, mock.restore, timers, argv, and caches\n- bun test src/components/useCodexOAuthFlow.test.tsx src/services/github/deviceFlow.test.ts\n- bun test --max-concurrency=1\n- bun run smoke\n- git diff --check

* Harden test isolation for smoke stability

Serialize tests that mutate process-global state behind the shared mutation lock, including process.env, transient globals, global config/cache state, storage mocks, and Bun module mocks.

Add isolated env mutex instances for SDK mutex tests so timeout coverage no longer manipulates the live process-global mutex.

Move top-level mock.module setup behind lock acquisition and restore mocks before releasing locks to prevent cross-file leakage under parallel smoke runs.

Verified with: bun test --max-concurrency=1; bun test; bun run smoke.
2026-05-16 15:18:42 +08:00
JATMN 94e8ff3941 chore: centralize Bun version and refresh CI tool pins (#1171)
* chore: centralize Bun version and refresh CI tool pins

- add .bun-version as the shared Bun source of truth for workflows and Docker builds
- update PR and release workflows to read Bun from bun-version-file
- refresh pinned GitHub Actions and Docker action SHAs to newer low-risk releases
- align contributor docs with Bun 1.3.13 guidance

* test: stabilize reset and provider profile persistence

Harden knowledge graph reset behavior across Windows file-lock scenarios by improving SQLite and JSON reset signaling, preserving a safe JSON source of truth when SQLite cannot be cleared, and adding direct storage regression coverage.

Also centralize deterministic config-home handling for tests, tighten provider profile persistence path resolution and cleanup semantics, isolate environment-sensitive suites with the env mutex, and remove flaky external npx dependency from the SDK consumer type test.

* test: fix Codex OAuth callback flake

Investigate the real provider smoke failure from GitHub Actions and fix the root cause instead of patching the symptom.

- make Codex OAuth callback host explicit and consistent across redirect URI generation and listener binding
- allow safe loopback host overrides for localhost, 127.0.0.1, and ::1
- harden Codex OAuth tests with env/fetch isolation so they do not poison neighboring provider suites
- pin the OAuth callback tests to 127.0.0.1 to avoid localhost IPv4/IPv6 family mismatch flakes in CI

Validated with bun test src/services/api/codexOAuth.test.ts, bun test src/services/api/providerConfig.codexSecureStorage.test.ts, and bun run test:provider.

* test: harden Codex OAuth callback tests

Investigate the recurring provider-smoke OAuth failures across multiple PR runs and fix the flaky callback test design at the root.

- remove the free-port reservation race from Codex OAuth tests
- add bounded callback retry only for loopback listener warm-up during the in-process OAuth test flow
- move ephemeral callback port support into an explicit CodexOAuthService test seam instead of widening production env parsing
- keep runtime callback-port semantics unchanged while adding regression coverage for callback host and port parsing

Validated with targeted Codex OAuth tests and repeated provider-bucket reruns to check for recurring flake.

* test: serialize provider shared-state suites

Fix the recurring provider smoke flake at the root cause by serializing test suites that mutate process.env or globalThis.fetch.

Add a shared test mutation lock and wire it into the provider bucket so Codex OAuth no longer races with unrelated provider/config/openai shim tests under Bun's parallel test execution. Cleanup now releases the lock in finally blocks, and the shared lock waits indefinitely by default to avoid timeout-based CI flakes.

* test: fix smoke root causes and noisy suites

Replace the Codex OAuth test's live loopback listener dependency with an injected listener seam, avoid module-mock leakage across provider suites, and clean up the auth-code listener test setup.

Also harden noisy storage and search tests by asserting expected log output, isolating SQLite masterpiece persistence per test cwd, and removing routine benchmark/stress logging from passing runs.

* build: harden Bun version install in Docker

Validate the repo-tracked .bun-version value before using it in the Docker build stage, strip line endings, and install Bun through a quoted semver-only variable instead of raw shell expansion.

* test: replace flaky conversation arc benchmark

Fix the recurring smoke failure caused by an absolute wall-clock assertion in the normal unit suite. Replace the CI-speed-sensitive conversation arc benchmark with deterministic regression coverage that verifies repeated fact extraction, expected entity shapes, bounded graph growth, and populated-summary behavior.

* test: isolate shared-state smoke suites

* test: restore codex credential mocks between suites

* test: fix shared-state and provider init-order flakes

* test: isolate remaining shared-state smoke suites

Serialize the remaining smoke-sensitive suites that mutate process env, CLAUDE_CONFIG_DIR, fetch, or SDK session globals.

Add shared lock coverage to discovery, agent/skills loading, platform storage, and SDK lifecycle/preserved-segment tests. Restore session and cwd state inside the lock boundary so parallel files cannot leak bootstrap state into knowledge graph and SDK isolation tests.

Validated with repeated smoke and full-suite passes:
- bun run smoke (2x)
- bun test
- bun test --max-concurrency=1
- bun run test:provider
- python -m pytest -q python/tests
- npm run test:provider-recommendation
2026-05-15 13:07:39 +08:00
6174d75e98 fix(openai-shim): surface in-stream errors and truncation hints (#1174)
Two related fixes to the OpenAI-compatible streaming parser:

1. Detect `data: {"error": {...}}` events inside the stream and throw a
   proper APIError. OpenAI sends this when a stream fails after headers
   have been sent, and intermediaries (gateways, proxies) use it to
   signal structured failures without dropping the TCP connection.
   Previously this chunk was silently dropped and the parser kept
   waiting for [DONE], producing the confusing "unexpected response"
   error after the stream ended without a proper close.

2. When finish_reason is "length" (model hit max_tokens, OR an upstream
   watchdog synthesized a graceful end after detecting a stalled
   stream), append a visible "[Response truncated]" hint inline. Mirrors
   the existing content_filter hint pattern. Users now know to ask the
   model to continue rather than wondering why the answer cut off.

Co-authored-by: OpenClaude <openclaude@gitlawb.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 09:44:50 +08:00
TechBrewBoss c433d20fdc FIX: Reduce stable stringify heap usage (#1104)
* fix stable stringify heap usage

* test stable stringify spacing

* Fix stableStringify spacing guard for fractional values

* fix stable stringify top-level result typing
2026-05-15 00:19:31 +08:00
github-actions[bot] b187fe91b8 chore(main): release 0.11.0 (#1108)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
v0.11.0
2026-05-14 22:44:12 +08:00
5b5ba8853b feat(provider): add Gitlawb Opengateway as default provider with MiMo (#1165)
* feat(provider): add Gitlawb Opengateway as default provider with MiMo

Registers https://opengateway.gitlawb.com/v1/xiaomi-mimo as a first-class
gateway descriptor in openclaude. Pins it first in the provider picker
order (ahead of anthropic) and surfaces it with a green [FREE] badge in
the picker UI. Wires detectBestProvider() to fall back to opengateway
with mimo-v2.5-pro when no other credentials or local services are
detected, making fresh installs work zero-config during the Xiaomi
free-inference partnership window.

- src/integrations/gateways/gitlawb-opengateway.ts: gateway descriptor,
  static catalog of all five mimo models, requiresAuth: false
- src/integrations/artifactGenerator.ts: sort comparator pins
  gitlawb-opengateway before anthropic
- src/utils/providerAutoDetect.ts: opengateway is the last-resort
  fallback; OPENGATEWAY_BASE_URL env override for local dev;
  skipOpengatewayFallback escape hatch for tests
- src/components/ProviderManager.tsx: getPresetLabel renders a green
  [FREE] badge for the opengateway preset, matching the existing
  [Sponsor] badge pattern used for xiaomi-mimo

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(provider): keep Codex OAuth after DeepSeek with Opengateway pinned

Pinning Gitlawb Opengateway at the top of the preset list shifted every
subsequent index by 1, which dropped Codex OAuth from "after DeepSeek"
to "before DeepSeek" because the splice insertion index was a hardcoded
6. Bumps the insertion index to 7 to keep Codex OAuth in its established
position, and updates PRESET_ORDER in ProviderManager.test.tsx so the
keyboard-navigation harness lines up with the new layout.

Restores 9 ProviderManager tests that were timing out because
navigateToPreset() was landing on the wrong row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: OpenClaude <openclaude@gitlawb.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 22:24:29 +08:00
Dolph Prefect 74e3947d88 fix(agent): prevent mid-flight peeking and taking over of forks (#1153)
- Added 'Don't take over' rule to AgentTool prompt to prevent models from overriding forks based on partial output.
- Refined 'Don't peek' rule to explicitly direct models to use SendMessage for course-correction instead of Read.
- Clarified that override decisions belong to the Review phase.
2026-05-14 22:20:55 +08:00
0xfandom b8c9d90703 docs(ollama): drop ollama launch openclaude instructions (#1163)
The `ollama launch openclaude` syntax in README and advanced-setup.md
was docs-only (added in #716), gated on the companion
ollama/ollama#15618 integration that has not landed upstream. Users
following these instructions get `Error: unknown integration:
openclaude` (issue #744 originally, #1134 now).

Remove the misleading section + table mention so the env-var setup
above remains the documented path. Can be re-added once the upstream
ollama integration ships.

Closes #1134
2026-05-14 22:00:20 +08:00
JATMN 4d2de51679 Fix provider profile startup precedence (#1157)
Prevent the legacy .openclaude-profile.json fallback from overriding startup env when a modern configured provider profile has already selected a concrete provider configuration.

Thread the configured-profile signal from CLI bootstrap into buildStartupEnvFromProfile(), add a concrete-selection helper for the new guard, and preserve the legacy file as a first-run fallback when startup env is incomplete.

Also fix the follow-up falsey-flag regression so disabled CLAUDE_CODE_USE_* values do not count as active startup selections, and add regression tests covering stale legacy overrides, incomplete startup env, and falsey provider flags.

Verified with: bun test src/utils/providerProfile.test.ts --test-name-pattern " buildStartupEnvFromProfile\
2026-05-14 08:39:47 +08:00
18483e4d96 feat(provider): add Xiaomi MiMo integration (#1152)
* feat(provider): add Xiaomi MiMo integration

Add Xiaomi MiMo as an official OpenAI-compatible provider with provider-profile persistence, env-only detection, and sponsor labeling in the provider picker.

Co-Authored-By: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>

* feat(provider): rebase Xiaomi MiMo as top-level provider

Promote Xiaomi MiMo from generic OpenAI-compatible shim route to a
first-class top-level provider matching the MiniMax pattern. Includes
brand/model descriptors, env-only detection, provider auto-detect,
status labels, legacy provider type, model picker, and profile env
persistence.

Co-Authored-By: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>

* Fix Xiaomi MiMo provider integration

Promote Xiaomi MiMo as a first-tier OpenAI-compatible vendor and align its descriptor with the integration guide.

Use the resolving Xiaomi MiMo API host while normalizing the stale docs host alias, wire Xiaomi catalog options into /model, and ensure model selection/display uses OPENAI_MODEL for Xiaomi instead of Claude defaults.

Update provider profile/startup handling, OpenAI shim detection, docs, generated integration artifacts, and focused regression tests.

Verification: bun run integrations:check; focused bun test provider/model suites; bun run build; bun run smoke.

* Fix MiMo startup profile base URL normalization

---------

Co-authored-by: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>
Co-authored-by: JATMN <the@jat.mn>
2026-05-14 07:48:26 +08:00
KRATOS cac11dce0d fix(integrations): cap gpt-5.5 context window at Codex effective limit (#1118) (#1141)
The gpt-5.5 model descriptor was set to the OpenAI API ceiling of
1,050,000 tokens, but in this repo gpt-5.5 is primarily routed through
the Codex transport (src/services/api/providerConfig.ts), whose practical
request limit is ~272k. The mismatch caused /context to under-report
usage and auto-compact to fire after the request had already exceeded the
effective window, surfacing as a mid-turn 500 'input exceeds the context
window of this model'.

Pin the descriptor to the Codex limit so /context shows realistic
budgets and auto-compact triggers before the failure. Provider-aware
context windows via the existing route catalog system remain the
correct long-term fix; this is the conservative interim.

Fixes #1118
2026-05-13 22:27:16 +08:00
Meetpatel006 a65bdb41b8 feat(groq): dynamic model discovery with mapModel filtering and hybrid catalog (#1143)
* feat(groq): implement dynamic model discovery for OpenAI compatibility

* fix(groq): use hybrid catalog, fix model filter regex to exclude guard/whisper/safeguard/orpheus models, map contextWindow, and add mapModel test coverage
2026-05-13 22:26:47 +08:00
Rayan Weragala 3af092441d fix: surface actionable error when fetch fails in _doOpenAIRequest (#447)
* fix: surface actionable error when fetch fails in _doOpenAIRequest

* fix: restore structured transport errors in openai shim
2026-05-13 20:20:45 +08:00
Anandan 9e8ce138d0 Streamline preset provider setup (#1115)
Known provider presets already carry endpoint and advanced transport defaults, so their create flow now asks only for the user-controlled model and any required API key while keeping Custom on the full setup path. Preset defaults also ignore stale generic OpenAI endpoint/model env values so xAI and other vendors keep their descriptor-backed defaults.

Constraint: Preset providers still need model choice because users may want a provider-specific default model.

Rejected: Save known presets without asking for model | this removed a real user choice and caused provider/model confusion.

Confidence: high

Scope-risk: moderate

Directive: Keep full endpoint/API mode/header setup reserved for Custom unless a preset explicitly needs user-entered advanced transport details.

Tested: bun test src/components/ProviderManager.test.tsx src/utils/providerProfiles.test.ts src/integrations/routeMetadata.test.ts src/integrations/index.test.ts

Tested: git diff --check
2026-05-13 20:08:00 +08:00
Vasanth TandOpenClaude Worker 3 5328f57a72 fix: update vulnerable dependencies (#1149)
* fix: update vulnerable dependencies

* fix: update pytest asyncio compatibility

---------

Co-authored-by: OpenClaude Worker 3 <worker-3@openclaude.local>
2026-05-13 19:59:52 +08:00
Nik 0f6668f554 feat(nvidia-nim): add latest chat models, remove duplicate Mixtral 8x22B entry. Verified against integrate.api.nvidia.com/v1/models on 2026-05-13. Tracks #1099. (#1145) 2026-05-13 18:45:03 +08:00
KRATOS 921594efc4 fix(errors): surface re-auth hint on OAuth token expiry 401s (#1042) (#1142)
GitHub Models onboarding (and Codex) hand out OAuth tokens that expire.
When they do, the API returns 401 with a body like 'IDE token expired:
unauthorized: token expired'. The classifier was returning the generic
'Verify API key, token source, and endpoint-specific auth headers' hint,
which sends users hunting for an API key they never set — the actual fix
is to re-run /onboard-github (or /login for Codex/Claude).

Detect the token-expired signal in the 401/403 body and surface a
re-auth-pointing hint. Other 401 cases (bad API key) keep the existing
generic hint. Regression tests cover both branches.

Fixes #1042
2026-05-13 18:03:11 +08:00
Kevin CodexandOpenClaude 2c71e09394 chore(build): clean up external dependency validation warnings (#1124)
* chore(build): clean up external dependency validation warnings

Remove 2 unused externals (@opentelemetry/sdk-trace-node, ink) and add
12 missing packages to package.json that are dynamically imported at
runtime but weren't declared as dependencies. Also remove the unused
@opentelemetry/sdk-trace-node dependency.

This eliminates all 13 build validation warnings:
- 8 missing OTel exporter deps (http, proto, grpc variants + prometheus)
- 4 missing AWS SDK deps (bedrock, bedrock-runtime, sts, credential-providers)
- 1 missing Azure dep (@azure/identity)
- ink external pointed to local reimplementation, not npm package
- sdk-trace-node was declared external but never imported

Build validation now passes cleanly with 0 warnings.

Co-Authored-By: OpenClaude <openclaude@gitlawb.com>

* chore(build): eliminate external validation warnings

Remove unused @opentelemetry/sdk-trace-node from externals and package.json
(it's not imported anywhere in src/). Remove ink from SDK_ONLY_EXTERNALS
(the project reimplements ink locally at src/ink/). Add OPTIONAL_RUNTIME_EXTERNALS
list for packages that are dynamically imported but intentionally not direct
deps — OTel protocol exporters and cloud provider SDKs are resolved from
transitive deps or installed by users who need them.

Validation now passes with 0 warnings instead of 13.

Co-Authored-By: OpenClaude <openclaude@gitlawb.com>

* feat(telemetry): full OpenTelemetry purge — remove all tracking dependencies

Replace all @opentelemetry/* runtime dependencies with no-op stubs,
delete OTel-only source modules, and remove 10 @opentelemetry packages
from package.json plus @growthbook/growthbook.

Key changes:
- Delete 5 OTel-only modules (instrumentation, betaSessionTracing,
  bigqueryExporter, logger, firstPartyEventLoggingExporter)
- Replace 9 modules with no-op stubs (sessionTracing, events,
  telemetryAttributes, firstPartyEventLogger, growthbook, index,
  sink, datadog, sinkKillswitch, perfettoTracing)
- Remove all @opentelemetry/* imports from bootstrap/state.ts,
  entrypoints/init.ts, and ~20 caller files
- Remove all OTel counter types, meter/provider state from state.ts
- Clean externals.ts: remove 27 @opentelemetry/* entries
- Clean build.ts: remove OTel native-stub namespace exports
- Simplify no-telemetry-plugin.ts: remove redundant source-level stubs
- Remove 10 @opentelemetry/* + @growthbook/growthbook from package.json
- GrowthBook stub reads local ~/.claude/feature-flags.json for overrides

Co-Authored-By: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>

* fix format

* chore: regenerate lockfile after OTel dependency removal

Co-Authored-By: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>

* fix(growthbook): route gate helpers through local flag overrides

checkStatsigFeatureGate_CACHED_MAY_BE_STALE() and
checkGate_CACHED_OR_BLOCKING() now resolve from
~/.claude/feature-flags.json like getFeatureValue_* does,
so gates like tengu_thinkback, tengu_ccr_bridge, and
VS Code upsells can be flipped on locally. Security gates
(checkSecurityRestrictionGate) remain hard-false.

Also adds 5 tests covering gate helper override behavior
and unifies JSDoc wording for _getFlagValue-routed functions.

Co-Authored-By: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>

---------

Co-authored-by: OpenClaude <openclaude@gitlawb.com>
2026-05-13 17:07:45 +08:00
Kevin CodexandOpenClaude a4cbb78585 feat: add sponsored tips with frequency-gated display (#1140)
Implement sponsored tip system with registry, scheduler integration,
and config-gated frequency control. Sponsored tips appear based on
startup count frequency (default: 1 per 10 startups) and are
tracked separately from regular tip history.

Co-authored-by: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>
2026-05-13 16:43:22 +08:00
chioarub 877b4dc886 fix: replace raw abort signal timeouts (#1123) 2026-05-13 11:10:01 +08:00
Anandan 382b738537 Keep Codex OAuth provider active after onboarding (#1112)
Codex OAuth first-run setup saved the new provider profile without making it the active provider profile, while still switching the current process environment. That left the current session and next startup disagreeing about which provider should be used.

This makes the saved OAuth profile active unless it is already active, preserving the existing current-session activation and credential persistence flow.

Constraint: First-run setup intentionally creates the profile with makeActive: false before OAuth credentials are persisted.

Rejected: Only update the current session env | next startup would still use the previous active provider.

Confidence: high

Scope-risk: narrow

Directive: Codex OAuth onboarding must keep activeProviderProfileId, stored credential profileId, and current-session provider env aligned.

Tested: bun test src/components/ProviderManager.test.tsx

Tested: git diff --check

Not-tested: repo-wide bun run typecheck, existing unrelated missing-module/type errors block it
2026-05-13 10:58:09 +08:00
RodrigoandClaude Sonnet 4.6 4a98a4a227 fix(bashPermissions): block command substitution in array subscript position (#1111)
stripAllLeadingEnvVars used [^\]]* for the array subscript component of the
ENV_VAR_PATTERN, which accepted $(cmd), ${var}, and backtick expressions.
Bash evaluates subscripts during assignment parsing, so a command like
FOO[$(denied_cmd)]=val harmless executed the denied command as a side effect
while the deny-rule check only saw `harmless`.

Changed subscript character class to [^\]$`{(]* to exclude the characters
that introduce all bash expansion forms:
  - $ blocks $(cmd), ${var}, $((expr))
  - ` blocks backtick command substitution
  - { and ( are belt-and-suspenders guards

Safe numeric and identifier subscripts (FOO[0], FOO[idx]) continue to match.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 10:52:15 +08:00
JATMN cf33f03755 fix: hide missing-module slash command stubs (#1136)
Prevent generated missing-module noop functions from entering the built-in command registry.

Add a runtime isCommand guard in src/types/command.ts and apply it when building the COMMANDS() list so bare noopN tree-shaking stubs are excluded before they can appear in slash-command autocomplete.

Add focused tests covering rejection of noop-style stubs and acceptance of valid command objects.

Refs Gitlawb/openclaude#1132.
2026-05-13 08:53:01 +08:00
TechBrewBoss f34650a10c Migrate legacy config home to .openclaude (#1122) 2026-05-12 21:59:12 +08:00
7ea74f29f0 fix(codex): normalize empty MCP object schemas (#1121)
* fix(codex): default missing 'type' on MCP tool properties to avoid 400 (#1114)

MCP tools sometimes register properties without an explicit `type` (e.g. a
generic `value` field intended to accept any JSON). Codex Responses strict
mode then rejects the tool registration with
`schema must have a 'type' key`. Add `ensureSchemaType()` to infer a type
from sibling keys (`properties` -> object, `items` -> array, `enum`/`const`
-> value type) and fall back to `string` for fully empty nodes.
Combinator-only schemas (`anyOf`/`oneOf`/`allOf`) are left alone so their
branches keep their semantics.

Fixes #1114

* fix(codex): normalize empty MCP object schemas

Ensure Codex strict tool schemas include an explicit empty properties object when MCP tools provide required keys without properties.

Co-Authored-By: OpenClaude (gpt-5.5) <openclaude@gitlawb.com>

---------

Co-authored-by: gnanam1990 <gnanasekaran.sekareee@gmail.com>
Co-authored-by: OpenClaude (gpt-5.5) <openclaude@gitlawb.com>
2026-05-12 14:16:06 +08:00
3kin0x e12432eaf6 feat: implement high-performance SQLite storage layer with JSON audit log (Phase 2 Masterpiece) (#1106) 2026-05-12 01:56:19 +08:00
Kevin CodexandOpenClaude f9621ab575 feat(provider): add Venice official provider (#1109)
Adds Venice as a descriptor-backed OpenAI-compatible provider with VENICE_API_KEY support, provider UI metadata, startup persistence, and regression coverage.

Co-authored-by: OpenClaude (gpt-5.5) <openclaude@gitlawb.com>
2026-05-11 22:06:09 +08:00
Nik 0c88defbe0 fix(bashSecurity): tighten fc -e detection to avoid long-flag false positives (#1107)
Closes #1051 (BUG-01).

The regex `/\s-\S*e/` in `validateZshDangerousCommands` only required
`e` to appear *somewhere* after `-`, so any flag that happened to
contain `e` — `-reset`, `-reverse`, `-message`, etc. — tripped the
"dangerous fc" path and surfaced an interactive permission prompt to
the user even though those flags do not invoke an editor and have
nothing to do with the `fc -e <editor>` eval vector the check is
trying to catch.

Replace with `/\s-[a-zA-Z]{0,3}e(?:\s|$)/` so:

  * `e` must be the last letter in the flag bundle (followed by
    whitespace or end-of-string), not anywhere inside it
  * the bundle is capped at 4 chars total, matching the shape of
    real POSIX `fc` short-flag bundles (`-e`, `-le`, `-lne`)

The bundle cap is what distinguishes us from the issue's initial
suggested fix `/\s-[a-zA-Z]*e(?:\s|$)/`, which still false-positives
on `-reverse` and `-message` because both end in `e` and the unbounded
`*` swallows the entire word.

New regression tests in `bashSecurity.test.ts` cover the real-flag
positive cases (`-e`, `-le`, `-lne`) and the long-flag negative cases
called out in the bug report (`-reset`, `-reverse`, `-message`), plus
`-l` to confirm the safe list flag still passes through.
2026-05-11 19:54:36 +08:00
github-actions[bot] 7166400660 chore(main): release 0.10.0 (#1039)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
v0.10.0
2026-05-11 08:13:50 +08:00
RodrigoandClaude Sonnet 4.6 ebc9c70bb5 fix(bashSecurity): reject nested heredoc ranges in stripSafeHeredocSubstitutions (#1050)
* fix(bashSecurity): reject nested heredoc ranges in stripSafeHeredocSubstitutions

isSafeHeredoc already rejects nested $(cat <<'A'...A) matches to prevent
stale-index corruption when stripping in reverse order. Apply the same guard
to stripSafeHeredocSubstitutions, which was missing it.

Without the check, a nested inner range stripped first leaves outer.end stale.
result.slice(outer.end) then skips any trailing content (e.g., `; rm -rf /`),
silently hiding it from downstream validators.

Fix: return null on nested ranges so callers fall back to full command validation.

* test(bashSecurity): add regression tests for stripSafeHeredocSubstitutions

Covers: single heredoc strip, nested heredoc null-return (stale-index
regression), no heredoc present, and multiple non-nested heredocs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 08:07:40 +08:00
0xfandom 20bc6aec21 fix(openai-shim): redact ?auth=, ?passwd=, ?pwd= in diagnostic URLs (#1070)
* refactor(urlRedaction): export shouldRedactUrlQueryParam as the single source of truth

The credential-param-name list lives in `src/utils/urlRedaction.ts` and
is the canonical coverage used by `redactUrlForDisplay`. A second copy
in `src/services/api/openaiShim.ts` had drifted, dropping `passwd`,
`pwd`, `auth`, and `apikey` — see follow-up commit replacing the shim
copy with this export.

Tests pin the four regression cases (`?passwd=`, `?pwd=`, `?auth=`,
`?apikey=`) and assert the helper accepts the same set across both
underscore and dash separators, so any future fork trips the test
instead of silently re-introducing the leak.

Refs #1069

* fix(openai-shim): use shared shouldRedactUrlQueryParam to redact ?auth/?passwd/?pwd in diagnostics

The shim's local `SENSITIVE_URL_QUERY_PARAM_NAMES` (10 entries) had
drifted from the canonical 14-entry list in `urlRedaction.ts`. Three
of the missing names — `passwd`, `pwd`, `auth` — are not substrings
of any shim-list token, so `redactUrlForDiagnostics` was emitting
them verbatim into the self-heal retry log, transport-error log,
HTTP-error log, and toolless retry log.

Replace the local copy with an import from the canonical module so
both code paths stay in lock-step. The post-redaction
`redactSecretValueForDisplay` env-secret pass is preserved — it's
the second layer that catches credentials hardcoded directly into
the URL string when the param name itself is non-obvious.

Closes #1069
2026-05-11 08:01:47 +08:00
0xfandom 4fad5d25da perf(local): add OPENCLAUDE_LOCAL_FAST_PATH to skip cloud-only transforms (#1068)
* feat(providerConfig): add OPENCLAUDE_LOCAL_FAST_PATH opt-out for local backends

Local OpenAI-compatible endpoints (llama.cpp, vLLM, Ollama, LM Studio,
…) do not implement the cloud-side caching/strict-validation behaviours
that several pre-send transforms target — byte-stable serialization
hashes nothing, strict tool-schema rewrites are accepted as-is, and
tool-result tiering compresses against contexts that already live in
local RAM.

`getLocalFastPathConfig(baseUrl)` returns a flag bundle so callers can
skip those transforms uniformly. By default the helper auto-detects via
the existing `isLocalProviderUrl` (loopback / RFC1918 / .local / ULA).
`OPENCLAUDE_LOCAL_FAST_PATH=1|0|auto` overrides the detection — useful
when a remote LAN host needs the same treatment, or when a user wants
to keep the cloud transforms even on localhost while debugging.

Tests cover auto-detect on every host class, all truthy/falsy aliases,
the explicit `env` argument override, and `auto`/empty/garbage fall-
through to detection.

Refs #1016

* perf(openai-shim): wire local fast path through compress/strict/serialize

Apply the local fast-path opt-out at the three pre-send transforms that
showed up in the issue #1016 audit of v0.5+ regressions against ~45
tok/s local backends:

  - compressToolHistory: skip the tool_result tier walk; on a single-
    user local box the conversation lives in RAM and the tier-walk is
    pure CPU per request.
  - convertTools strict mode: drop the recursive
    `additionalProperties: false` rewrite; local llama.cpp / vLLM /
    Ollama accept the original Anthropic schema unchanged.
  - request body serialization: fall back to native `JSON.stringify`
    instead of `stableStringify`; local backends do not implement
    implicit prefix caching, so the deep key-sort hashes nothing.

Behaviour for cloud providers is unchanged — every call site still
runs the full pipeline when `getLocalFastPathConfig(baseUrl).enabled`
is false. The GitHub Copilot `/responses` retry path (which is GitHub-
specific and never reachable for a local baseUrl) keeps the byte-
stable serialization to preserve the existing prefix-caching contract.

Refs #1016
2026-05-11 08:01:04 +08:00