mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-30 00:05:33 +08:00
3b79aab95881d18315a0574ddbff52df85ffba52
13 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
374e9de719 |
feat: add opencode support (#762)
* feat: add opencode support
* fix: stabilize opencode session startup
* fix: /models
* fix: improveUI for commands
* fix: format commands.js
* feat: load models through provider adapters
Provider model selection had outgrown a single hardcoded service.
The old service mixed shared caching with provider catalogs and CLI lookup details.
That made stale model lists more likely as providers changed on separate schedules.
Move model discovery behind each provider so lookup lives next to the integration.
The shared service now focuses on provider resolution, caching, persistence, and dedupe.
Return cache metadata and add bypassCache because model availability changes outside the app.
The UI and /models command can show freshness and let users force a provider refresh.
Surface model descriptions while keeping fallback catalogs for unavailable CLIs or SDKs.
* feat(models): resolve active session models through provider adapters
The model inventory command was showing a mix of catalog defaults and
composer-local state instead of the model that is actually active for a
real provider session. That made /models, /cost, and /status
misleading once a session had already started, especially for providers
whose effective runtime model can differ from the optimistic model value
held in the UI.
Introduce an explicit getCurrentActiveModel() contract on
IProviderModels so model resolution lives next to each provider's
catalog logic and uses the provider-native source of truth:
- Claude reads the init event from a resumed stream-json run
- Codex reads model from ~/.codex/config.toml
- Cursor reads lastUsedModel from the chat store.db
- OpenCode reads the persisted session model from opencode.db
- Gemini intentionally returns its default because the CLI does not
provide a reliable active-session lookup
Keep the returned shape intentionally minimal ({ model }). The goal is
to expose only what downstream command consumers need and avoid leaking
provider-specific metadata into a shared transport shape that would
create extra UI coupling and future cleanup cost.
Also make command behavior session-aware: when there is no concrete
session id, do not spawn provider processes or inspect provider session
storage just to answer /models, /cost, or /status. In a new-session
view the correct answer is simply the provider default, and doing more
work there adds latency and unnecessary side effects for no user value.
As part of this, centralize two supporting concerns:
- add a shared helper for building the default current-model result from
a provider catalog so fallbacks stay aligned with DEFAULT
- move leaf-directory validation into shared utils so Cursor session
readers and model lookup code enforce the same path-safety rule
Tests were expanded to cover both the new service delegation path and
the sessionless command behavior, while keeping cache-sensitive tests
isolated from persisted host cache state.
Why this change:
- command output should reflect the model actually driving a session
- new-session views should stay fast and side-effect free
- provider-specific active-model lookup should not be scattered across
routes or UI code
- fallback behavior should be explicit, consistent, and limited to the
provider default when no true active model can be resolved
* feat: support session-scoped model overrides
Model selection was acting like a provider-level preference.
That made resumed sessions drift back to a default or request-time model.
Users expect /models changes made inside a conversation to affect that session.
Store explicit session choices in app-owned ~/.cloudcli state.
This avoids editing provider transcripts or native provider config.
Resolve the effective model before launching each provider runtime.
Claude, Cursor, Codex, Gemini, and OpenCode now honor stored resume choices.
Expose a backend active-model change endpoint for existing sessions.
The models modal can now distinguish default changes from session overrides.
It also shows when a selected model will apply on the next response.
For Claude, stop probing active model state by resuming with a dummy prompt.
Read the indexed JSONL transcript from the end instead.
This preserves provider history while honoring /model stdout or model fields.
Add service tests for adapter delegation and resume-model precedence.
The tests keep cache state, override state, and requested fallback separate.
* feat: make command modal more compact
* fix: preserve opencode session creation events
OpenCode emits the real session id asynchronously on its first JSON output. The runner
registered that id from a helper that could not see the spawned process because
the process reference was scoped inside the model-resolution callback. That
ReferenceError was swallowed by the generic JSON parse fallback, so the client
never received session_created. Without that event, a new OpenCode chat stayed
on / and the assistant stream was not attached to the new session view.
Keep the process reference in the outer spawn scope so registration can update
the active-process map and websocket writer as soon as OpenCode announces the
session id. Split JSON parsing from event processing so malformed non-JSON
output can still stream as raw text, while registration or adapter failures are
surfaced as real errors instead of being hidden as assistant content.
Add a fake opencode executable regression test to lock in the expected lifecycle
ordering: session_created must be sent before live assistant messages, and the
same session id must carry through stream_end and complete.
* fix: clarify model refresh and onboarding providers
OpenCode is now a supported chat provider, but first-run onboarding still only offered
Claude, Cursor, Codex, and Gemini. That made OpenCode harder to discover and
forced users to finish setup before finding the provider in settings or chat.
Adding it to onboarding keeps first-run setup aligned with the providers the
application already supports elsewhere.
The model refresh control was also doing too much visual work. In the new chat
model picker, the previous Hard Refresh label looked like the dialog heading,
which made the primary task unclear. Users open that dialog to choose a model;
refreshing catalogs is only a secondary maintenance action for stale cached
provider model lists.
Rename and reposition the refresh affordance so the model picker reads as a
model picker first. The copy now explains why catalogs are cached, when a refresh
is useful, and that the refresh checks every provider. The /models modal gets the
same clarification so both model-selection surfaces describe the cache behavior
consistently.
* fix: format opencode model catalog labels
OpenCode returns provider-prefixed ids directly from the CLI. Passing those ids through as
labels made the model picker hard to scan: users saw values like
anthropic/claude-3-5-sonnet-20241022 or lowercased, hyphen-split text instead
of readable model names.
Keep the exact OpenCode id as the option value because that is what the CLI
expects, but derive a presentation label for the frontend. The formatter is
intentionally generic rather than a catalog of known providers. It handles common
identifier structure such as provider/model, hyphen-delimited words, v-prefixed
versions, adjacent numeric version tokens, and 8-digit date suffixes.
This keeps OpenCode usable as its model list expands across many upstream
providers without requiring code changes for every new provider or model family.
The description keeps the raw provider-prefixed id visible so users can still
confirm the precise model being selected.
* feat: add more fallback models for cursor
* docs: move model catalog out of shared
The model catalog is no longer a frontend/backend runtime contract.
Keeping it under shared made ownership misleading. It implied the catalog was
application code shared by runtime consumers, even though it now only supports
README links and public API documentation.
Move the catalog into public so it lives beside the docs surfaces that need it.
This gives the API docs a stable, served module and gives README readers a
linkable source without suggesting frontend or backend runtime dependency.
Render the API docs model list from the exported provider registry instead of a
hardcoded Claude/Cursor/Codex subset. That keeps Gemini and OpenCode visible and
makes future provider documentation changes flow through one docs-specific file.
Update README links, provider maintenance notes, and package files so published
artifacts include the standalone docs page and model catalog without relying on
the old shared path.
* fix: simplify empty-state model selector
Keep the provider empty state focused on the setup action users need there:
choosing a model.
The refresh control, cache timestamp, and refresh explanation made the dialog feel
like a cache-management surface.
That extra action is out of place in the empty state, where the goal is to start
a chat with the selected provider and model.
Remove the refresh-specific UI from ProviderSelectionEmptyState and drop the
now-unused refresh/cache props from the ChatMessagesPane pass-through.
Refresh behavior remains available in the dedicated command result flow.
|
||
|
|
039696c2de | Fix/websocket streaming issues (#748) | ||
|
|
49dd3cfb23 |
Refactor provider runtimes for sessions, auth, and MCP management (#666)
* feat: implement MCP provider registry and service
- Add provider registry to manage LLM providers (Claude, Codex, Cursor, Gemini).
- Create provider routes for MCP server operations (list, upsert, delete, run).
- Implement MCP service for handling server operations and validations.
- Introduce abstract provider class and MCP provider base for shared functionality.
- Add tests for MCP server operations across different providers and scopes.
- Define shared interfaces and types for MCP functionality.
- Implement utility functions for handling JSON config files and API responses.
* chore: remove dead code related to MCP server
* refactor: put /api/providers in index.js and remove /providers prefix from provider.routes.ts
* refactor(settings): move MCP server management into provider module
Extract MCP server settings out of the settings controller and agents tab into a
dedicated frontend MCP module. The settings UI now delegates MCP rendering and
behavior to a single module that only needs the selected provider and current
projects.
Changes:
- Add `src/components/mcp` as the single frontend MCP module
- Move MCP server list rendering into `McpServers`
- Move MCP add/edit modal into `McpServerFormModal`
- Move MCP API/state logic into `useMcpServers`
- Move MCP form state/validation logic into `useMcpServerForm`
- Add provider-specific MCP constants, types, and formatting helpers
- Use the unified `/api/providers/:provider/mcp/servers` API for all providers
- Support MCP management for Claude, Cursor, Codex, and Gemini
- Remove old settings-owned Claude/Codex MCP modal components
- Remove old provider-specific `McpServersContent` branching from settings
- Strip MCP server state, fetch, save, delete, and modal ownership from
`useSettingsController`
- Simplify agents settings props so MCP only receives `selectedProvider` and
`currentProjects`
- Keep Claude working-directory unsupported while preserving cwd support for
Cursor, Codex, and Gemini
- Add progressive MCP loading:
- render user/global scope first
- load project/local scopes in the background
- append project results as they resolve
- cache MCP lists briefly to avoid slow tab-switch refetches
- ignore stale async responses after provider switches
Verification:
- `npx eslint src/components/mcp`
- `npm run typecheck`
- `npm run build:client`
* fix(mcp): form with multiline text handling for args, env, headers, and envVars
* feat(mcp): add global MCP server creation flow
Add a separate global MCP add path in the settings MCP module so users can create
one shared MCP server configuration across Claude, Cursor, Codex, and Gemini from
the same screen.
The provider-specific add flow is still kept next to it because these two actions
have different intent. A global MCP server must be constrained to the subset of
configuration that every provider can accept, while a provider-specific server can
still use that provider's own supported scopes, transports, and fields. Naming the
buttons as "Add Global MCP Server" and "Add <Provider> MCP Server" makes that
distinction explicit without forcing users to infer it from the selected tab.
This also moves the explanatory copy to button hover text to keep the MCP toolbar
compact while still documenting the difference between global and provider-only
adds at the point of action.
Implementation details:
- Add global MCP form mode with shared user/project scopes and stdio/http transports.
- Submit global creates through `/api/providers/mcp/servers/global`.
- Reuse the existing MCP form modal with configurable scopes, transports, labels,
and descriptions instead of duplicating form logic.
- Disable provider-only fields for the global flow because those fields cannot be
safely written to every provider.
- Clear the MCP server cache globally after a global add because every provider tab
may have changed.
- Surface partial global add failures with provider-specific error messages.
Validation:
- npx eslint src/components/mcp/view/McpServers.tsx
- npm run typecheck
- npm run build:client
* feat: implement platform-specific provider visibility for cursor agent
* refactor(providers): centralize message handling in provider module
Move provider-specific normalizeMessage and fetchHistory logic out of the legacy
server/providers adapters and into the refactored provider classes so callers can
depend on the main provider contract instead of parallel adapter plumbing.
Add a providers service to resolve concrete providers through the registry and
delegate message normalization/history loading from realtime handlers and the
unified messages route. Add shared TypeScript message/history types and normalized
message helpers so provider implementations and callers use the same contract.
Remove the old adapter registry/files now that Claude, Codex, Cursor, and Gemini
implement the required behavior directly.
* refactor(providers): move auth status checks into provider runtimes
Move provider authentication status logic out of the CLI auth route so auth checks
live with the provider implementations that understand each provider's install
and credential model.
Add provider-specific auth runtime classes for Claude, Codex, Cursor, and Gemini,
and expose them through the shared provider contract as `provider.auth`. Add a
provider auth service that resolves providers through the registry and delegates
status checks via `auth.getStatus()`.
Keep the existing `/api/cli/<provider>/status` endpoints, but make them thin route
adapters over the new provider auth service. This removes duplicated route-local
credential parsing and makes auth status a first-class provider capability beside
MCP and message handling.
* refactor(providers): clarify provider auth and MCP naming
Rename provider auth/MCP contracts to remove the overloaded Runtime suffix so
the shared interfaces read as stable provider capabilities instead of execution
implementation details.
Add a consistent provider-first auth class naming convention by renaming
ClaudeAuthProvider, CodexAuthProvider, CursorAuthProvider, and GeminiAuthProvider
to ClaudeProviderAuth, CodexProviderAuth, CursorProviderAuth, and
GeminiProviderAuth.
This keeps the provider module API easier to scan and aligns auth naming with
the main provider ownership model.
* refactor(providers): move session message delegation into sessions service
Move provider-backed session history and message normalization calls out of the
generic providers service so the service name reflects the behavior it owns.
Add a dedicated sessions service for listing session-capable providers,
normalizing live provider events, and fetching persisted session history through
the provider registry. Update realtime handlers and the unified messages route to
depend on `sessionsService` instead of `providersService`.
This separates session message operations from other provider concerns such as
auth and MCP, keeping the provider services easier to navigate as the module
grows.
* refactor(providers): move auth status routes under provider API
Move provider authentication status endpoints out of the legacy `/api/cli` route
namespace so auth status is exposed through the same provider module that owns
provider auth and MCP behavior.
Add `GET /api/providers/:provider/auth/status` to the provider router and route
it through the provider auth service. Remove the old `cli-auth` route file and
`/api/cli` mount now that provider auth status is handled by the unified provider
API.
Update the frontend provider auth endpoint map to call the new provider-scoped
routes and rename the endpoint constant to reflect that it is no longer CLI
specific.
* chore(api): remove unused backend endpoints after MCP audit
Remove legacy backend routes that no longer have frontend or internal
callers, including the old Claude/Codex MCP APIs, unused Cursor and Codex
helper endpoints, stale TaskMaster detection/next/initialize routes,
and unused command/project helpers.
This reduces duplicated MCP behavior now handled by the provider-based
MCP API, shrinks the exposed backend surface, and removes probe/service
code that only existed for deleted endpoints.
Add an MCP settings API audit document to capture the route-usage
analysis and explain why the legacy MCP endpoints were considered safe
to remove.
* refactor(providers): remove debug logging from Claude authentication status checks
* refactor(cursor): lazy-load better-sqlite3 and remove unused type definitions
* refactor(cursor): remove SSE from CursorMcpProvider constructor and error message
* refactor(auth): standardize API response structure and remove unused error handling
* refactor: make providers use dedicated session handling classes
* refactor: remove legacy provider selection UI and logic
* fix(server/providers): harden and correct session history normalization/pagination
Address correctness and safety issues in provider session adapters while
preserving existing normalized message shapes.
Claude sessions:
- Ensure user text content parts generate unique normalized message ids.
- Replace duplicate `${baseId}_text` ids with index-suffixed ids to avoid
collisions when one user message contains multiple text segments.
Cursor sessions:
- Add session id sanitization before constructing SQLite paths to prevent
path traversal via crafted session ids.
- Enforce containment by resolving the computed DB path and asserting it stays
under ~/.cursor/chats/<cwdId>.
- Refactor blob parsing to a two-pass flow: first build blobMap and collect
JSON blobs, then parse binary parent refs against the fully populated map.
- Fix pagination semantics so limit=0 returns an empty page instead of full
history, with consistent total/hasMore/offset/limit metadata.
Gemini sessions:
- Honor FetchHistoryOptions pagination by reading limit/offset and slicing
normalized history accordingly.
- Return consistent hasMore/offset/limit metadata for paged responses.
Validation:
- eslint passed for touched files.
- server TypeScript check passed (tsc --noEmit -p server/tsconfig.json).
---------
|
||
|
|
9ef1ab533d |
Refactor CLI authentication module location (#660)
* refactor: move cli-auth.js to the providers folder * fix: expired oauth token returns no error message |
||
|
|
a4632dc4ce |
feat: unified message architecture with provider adapters and session store (#558)
- Add provider adapter layer (server/providers/) with registry pattern
- Claude, Cursor, Codex, Gemini adapters normalize native formats to NormalizedMessage
- Shared types.js defines ProviderAdapter interface and message kinds
- Registry enables polymorphic provider lookup
- Add unified REST endpoint: GET /api/sessions/:id/messages?provider=...
- Replaces four provider-specific message endpoints with one
- Delegates to provider adapters via registry
- Add frontend session-keyed store (useSessionStore)
- Per-session Map with serverMessages/realtimeMessages/merged
- Dedup by ID, stale threshold for re-fetch, background session accumulation
- No localStorage for messages — backend JSONL is source of truth
- Add normalizedToChatMessages converter (useChatMessages)
- Converts NormalizedMessage[] to existing ChatMessage[] UI format
- Wire unified store into ChatInterface, useChatSessionState, useChatRealtimeHandlers
- Session switch uses store cache for instant render
- Background WebSocket messages routed to correct session slot
|
||
|
|
45e71a0e73 |
feat: introduce notification system and claude notifications (#450)
* feat: introduce notification system and claude notifications * fix(sw): prevent caching of API requests and WebSocket upgrades * default to false for webpush notifications and translations for the button * fix: notifications orchestrator and add a notification when first enabled * fix: remove unused state update and dependency in settings controller hook * fix: show notifications settings tab * fix: add notifications for response completion for all providers * feat: show session name in notification and don't reload tab on clicking --- the notification --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Haileyesus <something@gmail.com> |
||
|
|
a77f213dd5 |
fix: numerous bugs (#528)
* fix(shell): copy terminal selections from xterm buffer
The shell was delegating Cmd/Ctrl+C to document.execCommand('copy'),
which copied the rendered DOM selection instead of xterm's logical
buffer text. Wrapped values like login URLs could pick up row
whitespace or line breaks and break when pasted.
Route keyboard copy through terminal.getSelection() and the shared
clipboard helper. Also intercept native copy events on the terminal
container so mouse selection and browser copy actions use the same
normalized terminal text.
Remove the copy listener during teardown to avoid leaking handlers
across terminal reinitialization.
* fix(shell): restore terminal focus when switching to the shell tab
Pass shell activity state from MainContent through StandaloneShell and use it
inside Shell to explicitly focus the xterm instance once the terminal is both
initialized and connected.
Previously, switching to the Shell tab left focus on the tab button because
isActive was being ignored and the terminal never called focus() after the tab
activation lifecycle completed. As a result, users had to click inside the
terminal before keyboard input would be accepted.
This change wires isActive through the shell stack, removes the unused prop
handling in Shell, and adds a focus effect that runs when the shell becomes
active and ready. The effect uses both requestAnimationFrame and a zero-delay
timeout so focus is applied reliably after rendering and connection state
updates settle.
This restores immediate typing when opening the shell tab and also improves the
reconnect path by re-focusing the terminal after the shell connection is ready.
* fix(shell): remove fallback command for codex and claude session resumes
The `|| claude` and `|| codex` fallback commands were causing errors as they are not valid commands.
* fix: use fallback while resuming codex and claude sessions for linux and windows
* feat(git): add revert latest local commit action in git panel
Add a complete revert-local-commit flow so users can undo the most recent
local commit directly from the Git header, placed before the refresh icon.
Backend
- add POST /api/git/revert-local-commit endpoint in server/routes/git.js
- validate project input and repository state before executing git operations
- revert latest commit with `git reset --soft HEAD~1` to keep changes staged
- handle initial-commit edge case by deleting HEAD ref when no parent exists
- return clear success and error responses for UI consumption
Frontend
- add useRevertLocalCommit hook to encapsulate API call and loading state
- wire hook into GitPanel and refresh git data after successful revert
- add new toolbar action in GitPanelHeader before refresh icon
- route action through existing confirmation modal flow
- disable action while request is in flight and show activity indicator
Shared UI and typing updates
- extend ConfirmActionType with `revertLocalCommit`
- add confirmation title, label, and style mappings for new action
- render RotateCcw icon for revert action in ConfirmActionModal
Result
- users can safely undo the latest local commit from the UI
- reverted commit changes remain staged for immediate recommit/edit workflows
* fix: run cursor with --trust if workspace trust prompt is detected, and retry once
* fix(git): handle repositories without commits across status and remote flows
Improve git route behavior for repositories initialized with `git init` but with
no commits yet. Previously, several routes called `git rev-parse --abbrev-ref HEAD`,
which fails before the first commit and caused noisy console errors plus a broken
Git panel state.
What changed
- add `getGitErrorDetails` helper to normalize git process failure text
- add `isMissingHeadRevisionError` helper to detect no-HEAD/no-revision cases
- add `getCurrentBranchName` helper:
- uses `git symbolic-ref --short HEAD` first (works before first commit)
- falls back to `git rev-parse --abbrev-ref HEAD` for detached HEAD and edge cases
- add `repositoryHasCommits` helper using `git rev-parse --verify HEAD`
Status route improvements
- replace inline branch/HEAD error handling with shared helpers
- keep returning valid branch + `hasCommits: false` for fresh repositories
Remote status improvements
- avoid hard failure when repository has no commits
- return a safe, non-error payload with:
- `hasUpstream: false`
- `ahead: 0`, `behind: 0`
- detected remote name when remotes exist
- message: "Repository has no commits yet"
- preserve existing upstream detection behavior for repositories with commits
Consistency updates
- switch fetch/pull/push/publish branch lookup to shared `getCurrentBranchName`
to ensure the same branch-resolution behavior everywhere
Result
- `git init` repositories no longer trigger `rev-parse HEAD` ambiguity failures
- Git panel remains usable before the first commit
- backend branch detection is centralized and consistent across git operations
* fix(git): resolve file paths against repo root for paths with spaces
Fix path resolution for git file operations when project directories include spaces
or when API calls are issued from subdirectories inside a repository.
Problem
- operations like commit/discard/diff could receive file paths that were valid from
repo root but were executed from a nested cwd
- this produced pathspec errors like:
- warning: could not open directory '4/4/'
- fatal: pathspec '4/hello_world.ts' did not match any files
Root cause
- file arguments were passed directly to git commands using the project cwd
- inconsistent path forms (repo-root-relative vs cwd-relative) were not normalized
Changes
- remove unsafe fallback decode in `getActualProjectPath`; fail explicitly when the
real project path cannot be resolved
- add repository/file-path helpers:
- `getRepositoryRootPath`
- `normalizeRepositoryRelativeFilePath`
- `parseStatusFilePaths`
- `buildFilePathCandidates`
- `resolveRepositoryFilePath`
- update file-based git endpoints to resolve paths before executing commands:
- GET `/diff`
- GET `/file-with-diff`
- POST `/commit`
- POST `/generate-commit-message`
- POST `/discard`
- POST `/delete-untracked`
- stage/restore/reset operations now use `--` before pathspecs for safer argument
separation
Behavioral impact
- git operations now work reliably for repositories under directories containing spaces
- file operations are consistent even when project cwd is a subdirectory of repo root
- endpoint responses continue to preserve existing payload shapes
Verification
- syntax check: `node --check server/routes/git.js`
- typecheck: `npm run typecheck`
- reproduced failing scenario in a temp path with spaces; confirmed root-resolved
path staging succeeds where subdir-cwd pathspec previously failed
* fix(git-ui): prevent large commit diffs from freezing the history tab
Harden commit diff loading/rendering so opening a very large commit no longer hangs
the browser tab.
Problem
- commit history diff viewer rendered every diff line as a React node
- very large commits could create thousands of nodes and lock the UI thread
- backend always returned full commit patch payloads, amplifying frontend pressure
Backend safeguards
- add `COMMIT_DIFF_CHARACTER_LIMIT` (500,000 chars) in git routes
- update GET `/api/git/commit-diff` to truncate oversized diff payloads
- include `isTruncated` flag in response for observability/future UI handling
- append truncation marker text when server-side limit is applied
Frontend safeguards
- update `GitDiffViewer` to use bounded preview rendering:
- character cap: 200,000
- line cap: 1,500
- move diff preprocessing into `useMemo` for stable, one-pass preview computation
- show a clear "Large diff preview" notice when truncation is active
Impact
- commit diff expansion remains responsive even for high-change commits
- UI still shows useful diff content while avoiding tab lockups
- changes apply to shared diff viewer usage and improve resilience broadly
Validation
- `node --check server/routes/git.js`
- `npm run typecheck`
- `npx eslint src/components/git-panel/view/shared/GitDiffViewer.tsx`
* fix(cursor-chat): stabilize first-run UX and clean cursor message rendering
Fix three Cursor chat regressions observed on first message runs:
1. Full-screen UI refresh/flicker after first response.
2. Internal wrapper tags rendered in user messages.
3. Duplicate assistant message on response finalization.
Root causes
- Project refresh from chat completion used the global loading path,
toggling app-level loading UI.
- Cursor history conversion rendered raw internal wrapper payloads
as user-visible message text.
- Cursor response handling could finalize through overlapping stream/
result paths, and stdout chunk parsing could split JSON lines.
Changes
- Added non-blocking project refresh plumbing for chat/session flows.
- Introduced fetch options in useProjectsState (showLoadingState flag).
- Added refreshProjectsSilently() to update metadata without global loading UI.
- Wired window.refreshProjects to refreshProjectsSilently in AppContent.
- Added Cursor user-message sanitization during history conversion.
- Added extractCursorUserQuery() to keep only <user_query> payload.
- Added sanitizeCursorUserMessageText() to strip internal wrappers:
<user_info>, <agent_skills>, <available_skills>,
<environment_context>, <environment_info>.
- Applied sanitization only for role === 'user' in
convertCursorSessionMessages().
- Hardened Cursor backend stream parsing and finalization.
- Added line-buffered stdout parser for chunk-split JSON payloads.
- Flushed trailing unterminated stdout line on process close.
- Removed redundant content_block_stop emission on Cursor result.
- Added frontend duplicate guard in cursor-result handling.
- Skips a second assistant bubble when final result text equals
already-rendered streamed content.
Code comments
- Added focused comments describing silent refresh behavior,
tag stripping rationale, duplicate guard behavior, and line buffering.
Validation
- ESLint passes for touched files.
- Production build succeeds.
Files
- server/cursor-cli.js
- src/components/app/AppContent.tsx
- src/components/chat/hooks/useChatRealtimeHandlers.ts
- src/components/chat/utils/messageTransforms.ts
- src/hooks/useProjectsState.ts
---------
Co-authored-by: Haileyesus <something@gmail.com>
Co-authored-by: Simos Mikelatos <simosmik@gmail.com>
|
||
|
|
b3c6e95971 | fix: don't stream response to another session | ||
|
|
babe96eedd | fix: API would be stringified twice. That is now fixed. | ||
|
|
eda89ef147 |
feat(api): add API for one-shot prompt generatio, key authentication system and git commit message generation
Implement comprehensive API key management functionality including generation, validation, and CRUD operations. Changes: - Add API key database schema and operations (create, validate, delete, toggle) - Generating a commit message will now work properly with claude sdk and cursor cli and return a suggested commit message - Implement crypto-based key generation with 'ck_' prefix - Add session ID tracking in claude-sdk.js and cursor-cli.js - Update database layer with API key validation and last_used tracking - Support multi-user API key management with user association This enables secure programmatic access to the agent service |
||
|
|
6dd303a321 |
feat: Multiple features, improvements, and bug fixes (#208)
* feat: Add token budget tracking and multiple improvements ## Features - **Token Budget Visualization**: Added real-time token usage tracking with pie chart display showing percentage used (blue < 50%, orange < 75%, red ≥ 75%) - **Show Thinking Toggle**: Added quick settings option to show/hide reasoning sections in messages - **Cache Clearing Utility**: Added `/clear-cache.html` page for clearing service workers, caches, and storage ## Improvements - **Package Upgrades**: Migrated from deprecated `xterm` to `@xterm/*` scoped packages - **Testing Setup**: Added Playwright for end-to-end testing - **Build Optimization**: Implemented code splitting for React, CodeMirror, and XTerm vendors to improve initial load time - **Deployment Scripts**: Added `scripts/start.sh` and `scripts/stop.sh` for cleaner server management with automatic port conflict resolution - **Vite Update**: Upgraded Vite from 7.0.5 to 7.1.8 ## Bug Fixes - Fixed static file serving to properly handle routes vs assets - Fixed session state reset to preserve token budget on initial load - Updated default Vite dev server port to 5173 (Vite's standard) ## Technical Details - Token budget is parsed from Claude CLI `modelUsage` field in result messages - Budget updates are sent via WebSocket as `token-budget` events - Calculation includes input, output, cache read, and cache creation tokens - Token budget state persists during active sessions but resets on session switch * feat: Add session processing state persistence Fixes issue where "Thinking..." banner and stop button disappear when switching between sessions. Users can now navigate freely while Claude is processing without losing the ability to monitor or stop the session. Features: - Processing state tracked in processingSessions Set (App.jsx) - Backend session status queries via check-session-status WebSocket message - UI state (banner + stop button) restored when returning to processing sessions - Works after page reload by querying backend's authoritative process maps - Proper cleanup when sessions complete in background Backend Changes: - Added sessionId to claude-complete, cursor-result, session-aborted messages - Exported isClaudeSessionActive, isCursorSessionActive helper functions - Exported getActiveClaudeSessions, getActiveCursorSessions for status queries - Added check-session-status and get-active-sessions WebSocket handlers Frontend Changes: - processingSessions state tracking in App.jsx - onSessionProcessing/onSessionNotProcessing callbacks - Session status check on session load and switch - Completion handlers only update UI if message is for current session - Always clean up processing state regardless of which session is active * feat: Make context window size configurable via environment variables Removes hardcoded 160k token limit and makes it configurable through environment variables. This allows easier adjustment for different Claude models or use cases. Changes: - Added CONTEXT_WINDOW env var for backend (default: 160000) - Added VITE_CONTEXT_WINDOW env var for frontend (default: 160000) - Updated .env.example with documentation - Replaced hardcoded values in token usage calculations - Replaced hardcoded values in pie chart display Why 160k? Claude Code reserves ~40k tokens for auto-compact feature, leaving 160k available for actual usage from the 200k context window. * fix: Decode HTML entities in chat message display HTML entities like < and > were showing as-is instead of being decoded to < and > characters. Added decodeHtmlEntities helper function to properly display angle brackets and other special characters. Applied to: - Regular message content - Streaming content deltas - Session history loading - Both string and array content types * refactor: Align package.json with main branch standards - Revert to main branch's package.json scripts structure - Remove custom scripts/start.sh and scripts/stop.sh - Update xterm dependencies to scoped @xterm packages (required for code compatibility) - Replace xterm with @xterm/xterm - Replace xterm-addon-fit with @xterm/addon-fit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: Replace CLI implementation with Claude Agents SDK This commit completes the migration to the Claude Agents SDK, removing the legacy CLI-based implementation and making the SDK the exclusive integration method. Changes: - Remove claude-cli.js legacy implementation - Add claude-sdk.js with full SDK integration - Remove CLAUDE_USE_SDK feature flag (SDK is now always used) - Update server/index.js to use SDK functions directly - Add .serena/ to .gitignore for AI assistant cache Benefits: - Better performance (no child process overhead) - Native session management with interrupt support - Cleaner codebase without CLI/SDK branching - Full feature parity with previous CLI implementation - Maintains compatibility with Cursor integration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Update server/claude-sdk.js Whoops. This is correct. Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update server/index.js Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/components/ChatInterface.jsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/components/ChatInterface.jsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/components/ChatInterface.jsx Left my test code in, but that's fixed. Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: Prevent stale token-usage data from updating state on session switch - Add AbortController to cancel in-flight token-usage requests when session/project changes - Capture session/project IDs before fetch and verify they match before updating state - Handle AbortError gracefully without logging as error - Prevents race condition where old session data overwrites current session's token budget 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Update src/components/TokenUsagePie.jsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: viper151 <simosmik@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> |
||
|
|
db7ce4dd74 | feat: Update README to include Cursor CLI support and enhance chat message handling with streaming improvements | ||
|
|
cf6f0e7321 |
feat: Enhance session management and tool settings for Claude and Cursor
- Updated ClaudeStatus component to accept a provider prop for better flexibility. - Added CursorLogo component for displaying cursor sessions. - Modified MainContent to conditionally display session names based on provider. - Updated Shell component to show session names and summaries based on provider. - Enhanced Sidebar to handle both Claude and Cursor sessions, including sorting and displaying session icons. - Introduced new ToolsSettings functionality to manage tools for both Claude and Cursor, including allowed and disallowed commands. - Implemented fetching and saving of Cursor-specific settings and commands. - Added UI elements for managing Cursor tools, including permission settings and command lists. |