Commit Graph

24 Commits

Author SHA1 Message Date
nehan
4cb963e660 feat(api): improve local provider reliability with readiness and self-healing (#738)
* feat(api): classify openai-compatible provider failures

* Update src/services/api/providerConfig.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/services/api/errors.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat(api): harden openai-compatible diagnostics and env fallback

* Update src/services/api/openaiShim.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/services/api/openaiShim.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/services/api/errors.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/services/api/errors.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix openaiShim duplicate requests and diagnostics

* remove unused url from http failure classifier

* dedupe env diagnostic warnings

* Remove hardcoded URLs from OpenAI error tests

Removed hardcoded URLs from network failure classification tests.

* Update providerConfig.envDiagnostics.test.ts

* fix(openai-shim): return successful responses and restore localhost classifier tests

* Update src/services/api/openaiShim.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/services/api/openaiShim.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/services/api/openaiShim.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat(provider): add truthful local generation readiness checks

Implement Phase 2 provider readiness behavior by adding structured Ollama generation probes, wiring setup flows to readiness states, extending system-check with generation readiness output, and updating focused tests.

* feat(api): add local self-healing fallback retries

Implement Phase 3 self-healing behavior for local OpenAI-compatible providers: retry base URL fallbacks for localhost resolution and endpoint mismatches, plus capability-gated toolless retry for tool-incompatible local models; include diagnostics and focused tests.

* fix(api): address review blockers for local provider reliability

* Update src/utils/providerDiscovery.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/services/api/openaiShim.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: harden readiness probes and cross-platform test stability

* fix: refresh toolless retry payload and stabilize osc clipboard test

* fix: harden Ollama readiness parsing and redact provider URLs

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-20 16:24:02 +08:00
Nourrisse Florian
c1beea9867 feat: open useful USER_TYPE-gated features to all users (#644)
* feat: open useful USER_TYPE-gated features to all users

Remove 13 process.env.USER_TYPE === 'ant' gates that restricted useful
features to Anthropic employees. These features work without Anthropic
infrastructure and are now available to all open-build users.

Features opened:
- Agent nesting (sub-agents can spawn sub-agents)
- Effort 'max' persistence in settings
- Plan mode interview phase (controlled by feature flags)
- Sandbox disabled commands (via ~/.claude/feature-flags.json)
- All tips visible to all users (plan mode, feedback, shift-tab)

Simplified:
- Fullscreen defaults to off (use /config to enable)
- Explore agent always uses haiku model
- Plan mode tool uses conservative prompt for all users

Continues the USER_TYPE cleanup from #637 (dead code) and builds
on #639 (local feature flags).

* fix: address Copilot review comments — remove residual dead code

1. bridgeConfig.ts: ungate bridge override functions — return env vars
   directly instead of hardcoded undefined
2. bridgeMain.ts + initReplBridge.ts: ungate sessionIngressUrl — read
   CLAUDE_BRIDGE_SESSION_INGRESS_URL without USER_TYPE check
3. tools.ts: remove dead ConfigTool/TungstenTool imports, narrow
   eslint-disable scope, stub REPLTool/SuggestBackgroundPRTool to null
4. readOnlyValidation.ts: remove orphaned ANT_ONLY_COMMAND_ALLOWLIST
   and unused GH_READ_ONLY_COMMANDS import
5. insights.ts: remove entire remote collection plumbing (types,
   functions, options, display logic)
6. osc.ts: hardcode supportsTabStatus() to false (internal-only feature)
7. state.ts: simplify addSlowOperation/getSlowOperations to no-ops,
   remove dead constants

* fix: address Copilot review on PR #644

1. settings/types.ts: allow 'max' effort level for all users in Zod
   schema — was still gated behind USER_TYPE=ant, causing 'max' to be
   silently dropped on settings reload
2. shouldUseSandbox.ts: defensively normalize disabledCommands from
   feature flag config with Array.isArray() guards

* fix: address second round of Copilot review on PR #644

1. shouldUseSandbox.ts: validate top-level shape of disabledCommands
   before accessing properties (handles null/primitive from feature flag)
2. fullscreen.ts: update JSDoc to reflect removal of USER_TYPE default
3. osc.ts: update JSDoc — "Ant-only" → "Currently disabled"
2026-04-14 19:08:54 +08:00
Alina Lisova
6e94dd9136 fix(ink): restore host prop updates in React 19 reconciler (#589)
React 19's react-reconciler@0.33 mutation path calls commitUpdate with
(instance, type, oldProps, newProps, fiber), but our Ink host config
still expected an updatePayload from prepareUpdate. That left mounted
ink-* nodes with stale onKeyDown, tabIndex, and textStyles, making menu
navigation and highlights appear stuck until remount.

Diff old/new props directly inside commitUpdate and add regression tests
covering in-place updates for ink-box handlers/attributes and ink-text
styles.
2026-04-11 21:19:39 +08:00
Kevin Codex
42b121bd0d Fix/openclaude diagnostics settings (#483)
* fix: use openclaude paths in diagnostics and settings

* fix: strip leaked reasoning from assistant output

* fix: preserve legacy claude config compatibility

* fix: tighten path and reasoning compatibility

* fix: buffer streamed reasoning leak preambles

* test: cover openclaude migration and reasoning fixes

* test: isolate execFileNoThrow from cross-file mocks
2026-04-09 20:42:51 +08:00
sooth
e30ad17ae0 fix(tui): restore prompt rendering on startup (#498)
* fix(tui): restore prompt rendering on startup

* test(tui): document render-time command split

* fix(tui): reduce ghostty prompt repaint scope
2026-04-09 20:40:06 +08:00
KRATOS
b4bd95b477 fix: normalize malformed Bash tool arguments from OpenAI-compatible providers (#385)
* fix: normalize malformed Bash tool arguments from OpenAI-compatible providers

* fix: keep invalid Bash tool args from becoming commands

* fix: preserve malformed Bash JSON literals

* test: stabilize rebased PR 385 checks

* test: isolate provider profile env assertions

* fix: extend tool argument normalization to all tools and harden edge cases

- Extend STRING_ARGUMENT_TOOL_FIELDS to normalize Read, Write, Edit,
  Glob, and Grep plain-string arguments (fixes "Invalid tool parameters"
  errors reported by VennDev)
- Normalize streaming Bash args regardless of finish_reason, not only
  when finish_reason is 'tool_calls'
- Broaden isLikelyStructuredObjectLiteral to catch malformed object-shaped
  strings like {command:"pwd"} and {'command':'pwd'} (fixes CR2 from
  Vasanthdev2004)
- Apply blank/object-literal guard to all tools, not just Bash
- Extract duplicated JSON repair suffix combinations into shared constant
- Add 32 isolated unit tests for toolArgumentNormalization

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

* fix: skip streaming normalization on finish_reason length

Truncated tool calls (finish_reason: 'length') now preserve the raw
buffer instead of normalizing into executable commands, preventing
incomplete commands from becoming runnable.

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

* fix: comprehensive tool argument normalization hardening

- Remove all { raw: ... } returns that caused InputValidationError with
  z.strictObject schemas — return {} instead for clean Zod errors
- Extend normalizeAtStop buffering to all mapped tools (Read, Write,
  Edit, Glob, Grep) so streaming paths also get normalized
- Make repairPossiblyTruncatedObjectJson generic — repair any valid
  JSON object, not just ones with a command field
- Export hasToolFieldMapping for streaming normalizeAtStop decision
- Skip normalization on finish_reason: length to preserve raw truncated
  buffer
- Update all test expectations to match new behavior

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:08:45 +08:00
Otávio Carvalho
1e057025d6 Fix GLM-5 and other reasoning models appearing to hang via OpenAI shim (#365)
* Fix GLM-5 and other reasoning models appearing to hang via OpenAI shim

Reasoning models like GLM-5 and DeepSeek stream chain-of-thought in
`reasoning_content` while `content` stays empty (""). The OpenAI shim
only read `delta.content`, so it saw empty strings and never emitted
any Anthropic stream events — causing the UI to appear frozen.

- Add `reasoning_content` to streaming chunk and non-streaming response types
- Emit `reasoning_content` as thinking blocks (thinking_delta) in streaming mode
- Properly transition from thinking to text blocks when content phase begins
- Fall back to `reasoning_content` in non-streaming mode when content is null

Fixes #214

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

* Fix non-streaming reasoning_content fallback and add tests

- Use explicit empty-string check instead of || for content fallback
  so content: "" doesn't leak reasoning_content as visible text
- Close thinking block before tool call blocks in streaming path
- Add non-streaming and streaming reasoning_content tests

Co-Authored-By: GLM-5.1 <noreply@openclaude.dev>

* Fix flaky Ink reconciler tests caused by react-compiler memoization

Remove hard throw in createTextInstance that crashed when hostContext.isInsideText
was stale due to react-compiler element caching. Add timeout guards to prevent
test hangs when render errors prevent exit() from firing.

Co-Authored-By: Claude GLM-5.1 <noreply@openclaude.dev>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: GLM-5.1 <noreply@openclaude.dev>
2026-04-06 22:02:29 +08:00
KRATOS
c1934974aa fix: preserve unicode in Windows clipboard fallback (#388)
* fix: preserve unicode in Windows clipboard fallback

* fix: avoid Windows clipboard stdin codepage issues

* test: fix Windows clipboard temp path fixture
2026-04-06 16:12:10 +08:00
Anandan
462a985d7e Remove embedded source map directives from tracked sources (#329)
Inline base64 source maps had been checked into tracked src files. This strips those comments from the repository without changing runtime behavior or adding ongoing guardrails, per the requested one-time cleanup scope.

Constraint: Keep this change limited to tracked source cleanup only
Rejected: Add CI/source verification guard | user requested one-time cleanup only
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If these directives reappear, fix the producing transform instead of reintroducing repo-side cleanup code
Tested: rg -n "sourceMappingURL" ., bun run smoke, bun run verify:privacy, bun run test:provider, npm run test:provider-recommendation
Not-tested: bun run typecheck (repository has many pre-existing unrelated failures)

Co-authored-by: anandh8x <test@example.com>
2026-04-04 21:19:27 +08:00
KRATOS
afed73fa5a fix: resolve keyboard input freeze on Windows and Mac at startup (#285)
Three compounding issues caused keyboard input to appear frozen or drop
characters on startup, particularly on Windows CMD/PowerShell and Mac
terminal environments.

Issue 1 — earlyInput disabled (cli.tsx):
The rebrand commit gated startCapturingEarlyInput() behind an opt-in
env flag (OPENCLAUDE_ENABLE_EARLY_INPUT=1), which meant any characters
typed before React finished mounting were silently dropped. Users who
type immediately after launch saw an empty input box with no indication
their keystrokes were lost. Flipped to an opt-out flag
(OPENCLAUDE_DISABLE_EARLY_INPUT=1) so early input capture is on by
default, matching the original upstream behaviour.

Issue 2 — stdin.resume() called before listener attached (App.tsx):
stdin.resume() put the stream into flowing mode before the data/readable
listener was registered. Any input arriving in that gap was queued and
delivered in a burst when the listener connected, which could flood
React's scheduler and stall input processing. Moved resume() to after
the listener is attached so the stream only flows once the handler is
ready.

Issue 3 — AnimatedAsterisk fires ~60 React re-renders in 3s (AnimatedAsterisk.tsx):
The startup screen colour sweep animation runs at 50ms intervals for
3000ms total. Each tick triggers a full re-render of the startup screen
subtree, which competes with stdin event processing in React's microtask
queue. On Windows, where the event loop scheduler is slower, this
reliably caused typing to lag or freeze for the first few seconds after
launch. The animation is now skipped on Windows (process.platform ===
'win32'), showing the icon in its settled state immediately. Mac and
Linux are unaffected.

Closes #228, #220, #205
2026-04-04 01:34:41 +08:00
KRATOS
c1e5e363cd fix: resolve keyboard freeze via sync render path and stable useAppState selectors (#266)
* fix: resolve keyboard freeze via sync render path and stable useAppState selectors

Two compounding React 19 defects caused keyboard input to freeze after
MCP notifications or rapid state updates:

Defect 2 (ink.tsx): The render() path used async updateContainer, which
batches updates across scheduler ticks. Keyboard events dispatched mid-render
drained faster than React processed them, causing input to appear frozen.
Fixed by switching to updateContainerSync + flushSyncWork (same pattern
already used in the unmount path).

Defect 4 (AppState.tsx): useAppState and useAppStateMaybeOutsideOfProvider
used React Compiler _c cache invalidation tied to selector identity. Inline
arrow selectors (new reference each render) invalidated the cache every cycle,
producing a new `get` function. useSyncExternalStore treats a new `get` as a
tearing signal, re-syncing state and re-rendering — causing a loop that
starved the input handler. Fixed with useRef + useCallback(fn, []) to give
useSyncExternalStore a permanently stable snapshot reference.

Note: AppState.tsx is React Compiler output. The _c bypass for these two
hooks is intentional — compiler cache invalidation on inline selectors is
the root cause of the tearing loop.

All 200 tests pass. Build and smoke test verified.

Closes #77, #220, #228

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

* fix: update selector refs during render instead of useLayoutEffect

Addresses review feedback on PR #266. The previous useLayoutEffect approach
updated selectorRef.current after the render phase, meaning a changed selector
(e.g. s => s.tasks[attachment.taskId] when taskId changes) would still read
stale data during the render it changed in.

Fix: assign selectorRef.current and storeRef.current directly during render
before useSyncExternalStore calls get(). Ref mutation during render is safe
here — it's synchronous and happens before the snapshot is read. get()
identity stays stable via useCallback(fn, []) so useSyncExternalStore never
sees a new subscription function and won't trigger re-render loops.

This is the standard pattern used by zustand and jotai for selector stability.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 22:33:16 +08:00
Kevin Codex
66bbb75836 Merge pull request #221 from gnanam1990/fix/keyboard-freeze-mcp-notifications
fix: prevent keyboard freeze when MCP notification effects fire
2026-04-03 10:27:11 +08:00
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
Vasanthdev2004
ffbc1f8f6e fix: support CSI-u printable input on Windows 2026-04-02 10:05:16 +05:30
vp
c8a780a9bd fix: follow up Codex launcher and input handling 2026-04-01 19:15:37 +03:00
Kevin Codex
6b6407018d Merge pull request #17 from Kartvya69/fix/tui-freeze-style-rerender
Fix TUI freeze without dropping prompt styles
2026-04-01 19:54:12 +08:00
Kartvya69
9ee20cfd4a fix: preserve tui styles while fixing freeze 2026-04-01 11:33:08 +00:00
Kevin Codex
2d7aa9c841 feat: rebrand as Open Claude and harden OpenAI REPL 2026-04-01 13:31:18 +08:00
Kevin
c957d495ac fix: prevent interactive stream crash on node removal 2026-04-01 11:23:47 +08:00
Kevin
770e16dadb fix: restore interactive OpenAI REPL on React 18 2026-04-01 09:52:00 +08:00
Reservieren
009c29d318 refactor: update import paths for react/compiler-runtime to react-compiler-runtime
feat: add OpenClaude local agent playbook for setup and usage instructions

chore: implement provider bootstrap script for profile initialization

chore: create provider launch script to manage provider execution

chore: add system check script for runtime diagnostics and validation

feat: implement useEffectEventCompat hook for React 18 compatibility
2026-03-31 22:09:56 -03:00
Kevin
747be9c2f3 fix: restore interactive OpenAI REPL startup 2026-04-01 05:16:40 +08:00
did:key:z6MkqDnb7Siv3Cwj7pGJq4T5EsUisECqR8KpnDLwcaZq5TPr
3e652cafdf feat: add build system, stubs, and npm packaging — openclaude is now runnable
- package.json with all 70+ dependencies
- Bun build script with feature flag shims, native module stubs, otel externals
- Stubs for ~15 missing source files (snapshot gaps)
- tsconfig.json for TypeScript
- bin/openclaude entry point
- Builds to single 19MB dist/cli.mjs
- Verified: --version and --help work

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 02:36:07 +08:00
did:key:z6MkqDnb7Siv3Cwj7pGJq4T5EsUisECqR8KpnDLwcaZq5TPr
d2542c9a62 asdf
Squash the current repository state back into one baseline commit while
preserving the README reframing and repository contents.

Constraint: User explicitly requested a single squashed commit with subject "asdf"
Confidence: high
Scope-risk: broad
Reversibility: clean
Directive: This commit intentionally rewrites published history; coordinate before future force-pushes
Tested: git status clean; local history rewritten to one commit; force-pushed main to origin and instructkr
Not-tested: Fresh clone verification after push
2026-03-31 03:34:03 -07:00