Skip to content

Conversation

@alfredolopez80
Copy link

@alfredolopez80 alfredolopez80 commented Jan 15, 2026

Summary

This PR introduces custom LLM API provider support and a unified architecture with centralized settings management, orchestrator agent coordination, and significant security improvements.


Part 1: Custom LLM Providers (Original)

Add support for custom LLM API providers, allowing users to configure and use alternative LLM backends instead of the default Claude Code settings.

Features

  • Provider Configuration UI: Modal for creating/editing custom LLM providers with name, baseUrl, authToken, and model configurations
  • Provider Selector: Dropdown in Sidebar to switch between default Claude Code and custom providers
  • IPC Handlers: Backend support for providers CRUD operations (list, save, delete)
  • Runner Integration: Custom provider environment variables override defaults (ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, etc.)
  • State Management: Zustand store with providers state and actions
  • Token Encryption: Secure storage of provider auth tokens

Technical Changes

  • src/electron/libs/provider-config.ts: Provider configuration management module
  • src/electron/ipc-handlers.ts: Provider event handlers
  • src/electron/libs/runner.ts: Integration of provider env vars into Claude execution
  • src/ui/components/ProviderModal.tsx: Provider configuration UI
  • src/ui/components/Sidebar.tsx: Provider selector dropdown
  • src/ui/store/useAppStore.ts: Provider state management
  • src/electron/types.ts & src/ui/types.ts: Type definitions for providers and events

Documentation

  • CUSTOM_PROVIDERS.md: User guide for configuring custom providers

Part 2: Unified Architecture & Security Improvements

New Modules

Module Purpose
settings-manager.ts Singleton for loading ~/.claude/settings.json with schema validation
unified-commands.ts Parser for slash commands (/help, /exit, /status, /clear)
unified-task-runner.ts Task context with system prompt stacking and think mode support
orchestrator-agent.ts Central coordinator for skills, hooks, commands, and task execution

Security Improvements (Codex Audit)

All findings from Codex security audit have been addressed:

Severity Issue Fix
MEDIUM cwd not validated in updateSession() Added sanitizePath() validation
MEDIUM cwd not validated on DB load Added validation in loadSessions()
MEDIUM settings.json accepted without schema validation Added validateSettings() with type checks
LOW getRawSettings() shallow copy allowed mutation Implemented deep copy for Maps
LOW processInput() no error handling Added try/catch with error event emission

Permission System

  • New PermissionMode type: "secure" (require user approval) or "free" (auto-approve)
  • parseAllowedTools() and isToolAllowed() utilities for tool restrictions
  • createCanUseTool() factory for configurable permission handling
  • Database migration adds permission_mode column to sessions table

Path Sanitization Fix (Critical Bug)

The original sanitizePath() was destroying all paths with an aggressive regex. New implementation:

  • Detects null bytes (CWE-626)
  • Blocks path traversal sequences before normalization
  • Rejects dangerous shell characters (CWE-78)
  • Validates directory existence
  • Uses proper normalize() + resolve() from Node.js path module

Architecture Changes

  • initializeHandlers() exported from ipc-handlers.ts for proper startup sequence
  • orchestratorAgent.initialize() called during app ready event
  • Settings loaded from ~/.claude/settings.json on startup
  • Support for permissionMode in session creation IPC events

Files Changed

New Files:

  • CLAUDE.md - Project documentation
  • src/electron/libs/settings-manager.ts
  • src/electron/libs/unified-commands.ts
  • src/electron/libs/unified-task-runner.ts
  • src/electron/libs/orchestrator-agent.ts
  • src/electron/libs/default-providers.ts

Modified Files:

  • src/electron/types.ts - Added PermissionMode type
  • src/electron/libs/session-store.ts - Security fixes + permissionMode support
  • src/electron/libs/runner.ts - Permission system + provider integration
  • src/electron/ipc-handlers.ts - Orchestrator integration + provider handlers
  • src/electron/main.ts - Initialization sequence

Test Plan

  • TypeScript compilation passes
  • Vite build succeeds
  • Codex security audit passed
  • Manual testing of session creation with different permission modes
  • Verify settings loading from ~/.claude/settings.json
  • Test path validation rejects traversal attempts
  • Test custom provider configuration and switching

Breaking Changes

None. All changes are backward compatible:

  • permissionMode defaults to "secure" if not specified
  • Settings manager gracefully handles missing settings.json
  • Database migration adds nullable column

🤖 Generated with Claude Code

alfredolopez80 and others added 4 commits January 15, 2026 15:39
- Add provider configuration modal UI for managing custom LLM API providers
- Add backend support for providers list, save, delete operations via IPC handlers
- Add runner integration to use custom provider environment variables (baseUrl, authToken, models)
- Add Sidebar provider selector to switch between default Claude Code and custom providers
- Add Zustand store actions for providers state management
- Add comprehensive types for LlmProviderConfig, provider events, and client/server event extensions

Features:
- Configure custom API providers (name, baseUrl, authToken, models per tier)
- Select active provider per session via dropdown in Sidebar
- Custom providers override default ANTHROPIC_* environment variables
- Full CRUD operations for provider configurations

Custom Providers documentation added: CUSTOM_PROVIDERS.md
…ture

- Resolve merge conflict in runner.ts combining:
  - Main branch: enhancedEnv, claudeCodePath from util.ts
  - Feature: custom provider support via getProviderEnv()
- Merge order: enhancedEnv first, then custom provider env overrides
- Single instance lock to prevent multiple windows
- Window lifecycle handlers with proper cleanup
- Polling cleanup on window close
- New throttle/debounce utilities for performance
- File permissions 0o600 for providers.json

Co-Authored-By: Claude <noreply@anthropic.com>
- FASE 2: Increase polling interval to 2000ms for better performance
- FASE 3: Add try-catch error handling in app.ready with dialog alerts
- FASE 4: Create WindowManager singleton class for window lifecycle
- Add app.on("activate") handler for Mac reactivation
- Fix preload path validation in initialization

Co-Authored-By: Claude <noreply@anthropic.com>
@alfredolopez80 alfredolopez80 changed the title Fix/electron windows Add support for custom LLM API providers, allowing users to configure and use alternative LLM backends instead of the default Claude Code settings. Jan 15, 2026
alfredolopez80 and others added 7 commits January 16, 2026 00:40
- Add include section to tsconfig.json for proper TypeScript compilation
- Increase POLLING_INTERVAL from 500ms to 2000ms to reduce CPU usage
- Update Makefile with run_dev and run_prod targets for better flexibility
- Use NODE_ENV=production with direct electron binary path

Co-Authored-By: Claude <noreply@anthropic.com>
- Add include section to tsconfig.json for proper TypeScript compilation
- Update Makefile with run_dev and run_prod targets for better flexibility
- Use NODE_ENV=production with direct electron binary path

Co-Authored-By: Claude <noreply@anthropic.com>
- Add custom LLM providers support
- Add URL validation in ProviderModal
- Add Electron stability improvements
- Add provider-config utilities

Co-Authored-By: Claude <noreply@anthropic.com>
- Encrypt auth tokens using Electron nativeSafeStorage
- Add decryptSensitiveData and encryptSensitiveData functions
- Set restrictive file permissions (0o600)
- Mitigate CWE-200 (Exposure of Sensitive Information)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add path sanitization to prevent CWE-22 (Path Traversal)
- Improve SQL query parameterization
- Validate cwd before creating session

Co-Authored-By: Claude <noreply@anthropic.com>
- Add .claude/ directory to .gitignore
- Add default-providers.ts with MiniMax default provider config
- Include envOverrides for default provider settings

Co-Authored-By: Claude <noreply@anthropic.com>
## New Modules
- settings-manager.ts: Load and validate ~/.claude/settings.json with schema validation
- unified-commands.ts: Parse slash commands (/help, /exit, /status, /clear)
- unified-task-runner.ts: Task context management with system prompt stacking
- orchestrator-agent.ts: Central coordinator for skills, hooks, and commands

## Security Improvements (Codex Audit)
- Fix sanitizePath() to properly validate paths without destroying them
- Add cwd re-validation in updateSession() and loadSessions()
- Add schema validation for settings.json (CWE-20 compliance)
- Deep copy in getRawSettings() to prevent mutation
- Error handling in processInput() with structured events

## Permission System
- Add PermissionMode type (secure/free) to types.ts
- Implement permission-based tool execution in runner.ts
- Add parseAllowedTools() and isToolAllowed() utilities
- Support permissionMode in session creation and IPC handlers

## Architecture
- Initialize orchestratorAgent in main.ts startup
- Export initializeHandlers() for proper initialization order
- Add database migration for permission_mode column

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
alfredolopez80 and others added 6 commits January 16, 2026 11:43
PHASE 1: API Key Security (Token Vault Architecture)
- Add SafeProviderConfig type (no tokens in IPC)
- Add ProviderSavePayload for secure token handling
- Tokens NEVER leave main process except to subprocess
- Add loadProvidersSafe(), saveProviderFromPayload(), getProviderEnvById()
- Update runner.ts to use providerEnv instead of provider object
- Fix safeStorage import in provider-config.ts

PHASE 2: Theme System (Light/Dark Mode)
- Add ThemeContext with localStorage persistence
- Add ThemeSettings modal for color customization
- Add theme toggle button in Sidebar
- Add CSS variables and dark mode styles
- Dynamic sidebar and workspace colors

PHASE 3: Provider UX Improvements
- Add default provider templates: Anthropic, MiniMax, OpenRouter, GLM, AWS Bedrock
- Add descriptions for each provider
- Add getDefaultProviderTemplates() for UI display

Security: Tokens encrypted with Electron safeStorage, never sent to renderer

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix H2: Encryption failures now throw errors instead of silently storing plaintext tokens
- Fix H1: Add URL validation for provider baseUrl to prevent SSRF attacks (CWE-918)
- Add proper error handling in IPC provider.save handler
- Improve decryption with legacy token migration warnings
- Add GitHub Actions CI pipeline for lint and build verification

Security: Token encryption now fails fast, refusing to store unencrypted credentials.
SSRF prevention blocks internal IPs (127.x, 10.x, 172.16-31.x, 192.168.x, localhost).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix React hooks called after conditional returns (EventCard.tsx)
- Add proper types and eslint-disable for unavoidable any types
- Fix hooks rules violations by moving hooks before early returns
- Add eslint-disable for valid setState-in-effect patterns
- Clean up unused eslint-disable directives
- Add proper IPC event types in main.ts and types.d.ts

All 32 ESLint errors resolved. Only 4 non-blocking warnings remain.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
P0 Critical:
- Add ENC:v1: prefix for deterministic encrypted token detection
- Add CLAUDE_COWORK_ALLOW_LOCAL_PROVIDERS env var for localhost/dev

P1 High Priority:
- Add validateModelConfig() for provider models validation
- Fix sanitizePath() to allow valid quote characters in paths
- Add isValidHookConfig() for deep hook structure validation
- Mark resetInstance() as @internal with test environment warning

P2 Medium Priority:
- Add IPC rate limiting (100 req/min per event type)
- Add 5-minute timeout for pending permission requests
- Make CI ESLint conditional (fail on main, warn on PRs)

P3 Low Priority:
- Refactor loadProviders with readProvidersFile() helper
- Add JSDoc documentation to new functions
- Fix ESLint config to ignore dist-electron/dist-react
- Fix useMemo for messages in App.tsx
- Allow hook exports in eslint react-refresh rule

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Partial progress on SDK integration:

- Add settingSources to load ~/.claude/ configuration (user, project, local)
- Implement getCustomAgents() to convert activeSkills to SDK AgentDefinition
- Add getLocalPlugins() for loading enabled plugins from ~/.claude/plugins/
- Pass agents, plugins, and settingSources to SDK query() options

UI fixes included:
- Fix provider configuration flow (modal now pre-populates with selected provider)
- Fix theme toggle icon (now shows action icon, not current state)
- Optimize PromptInput performance with debounced height calculation

Restrictions (WIP):
- Agents/skills invocation (@agent, /skill) requires further SDK integration
- Command routing still uses native SDK subagents instead of custom definitions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved 3 conflicts:

1. src/electron/ipc-handlers.ts
   - Combined cleanupAllSessions() from upstream with initializeHandlers()
   - Now exports both functions for proper app lifecycle

2. src/electron/main.ts
   - Kept WindowManager architecture (better encapsulation)
   - Added cleanupAllSessions() calls on app quit events
   - Maintained single instance lock for preventing multiple windows

3. src/electron/test.ts
   - Combined both cleanup approaches (cleanupPolling + stopPolling)
   - Better error handling with try/catch in polling
   - activePollingInterval reference for reliable cleanup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant