22 Commits

Author SHA1 Message Date
程序员阿江(Relakkes)
5ed1081252 Default desktop startup to pure white
New desktop installs and settings payloads without an explicit theme now hydrate to the pure white workspace. The General settings selector keeps the other two themes available, but presents pure white first so the default and visible ordering agree.

Constraint: Existing persisted theme choices must continue to win over the default.
Rejected: Remove the warm classic theme | users still need the alternate light appearance.
Confidence: high
Scope-risk: narrow
Directive: Keep the localStorage and user-settings theme fallbacks aligned when changing desktop theme defaults.
Tested: cd desktop && bun run test src/stores/uiStore.test.ts src/stores/settingsStore.test.ts src/__tests__/generalSettings.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:desktop
Tested: git diff --check
Not-tested: Full root bun run verify.
2026-05-16 00:18:21 +08:00
程序员阿江(Relakkes)
c866adc951 Honor desktop thinking controls for provider streams
Desktop sessions must treat the global Thinking toggle as the source of truth across active CLI sessions, title generation, and provider-compatible request bodies. DeepSeek-style streams can start with reasoning blocks before text, so the WebSocket bridge now keeps the UI in thinking state until text content actually starts.

Constraint: DeepSeek and MiniMax use Anthropic-compatible surfaces but expose thinking behavior through provider-specific request and stream shapes
Rejected: Keep provider-specific disabled-thinking env defaults | stale defaults kept overriding the user's global Thinking setting
Rejected: Treat every non-tool stream block as text | reasoning-only startup blocks created a blank streaming gap before the visible thinking bubble
Confidence: high
Scope-risk: moderate
Directive: Do not change thinking stream state transitions without replaying reasoning-before-text provider events
Tested: bun test src/server/__tests__/ws-memory-events.test.ts
Tested: bun run check:server
Tested: bun run verify
Not-tested: Live DeepSeek provider smoke with real quota
2026-05-15 19:35:12 +08:00
程序员阿江(Relakkes)
4b62d354d6 Unify desktop zoom controls
PR #428 added a General Settings zoom slider after the desktop shortcut work already introduced a native-first app zoom controller. Keeping both paths would create double scaling and stale UI state, so the slider now routes through the existing controller and store state while the app shell no longer applies a second CSS zoom.

Constraint: UI zoom is device-local display state and should not be written into shared user settings.

Rejected: Keep cc-haha-ui-zoom plus AppShell style.zoom | it conflicts with shortcut zoom and multiplies visual scale.

Rejected: Persist zoom through /api/settings/user | it would sync display-specific state across machines.

Confidence: high

Scope-risk: moderate

Directive: Keep app zoom behind desktop/src/lib/appZoom.ts; do not add another storage key or DOM zoom application point without migration and shortcut sync tests.

Tested: cd desktop && bun run test -- --run src/lib/appZoom.test.ts src/hooks/useKeyboardShortcuts.test.tsx src/stores/settingsStore.test.ts src/__tests__/generalSettings.test.tsx src/lib/persistenceMigrations.test.ts src/lib/doctorRepair.test.ts

Tested: bun run check:desktop

Not-tested: Real Windows/Linux desktop runtime smoke.
2026-05-14 17:49:57 +08:00
DHX
8c124b29e9 feat(settings): add UI zoom slider to General Settings
- Add uiZoom field to UserSettings type and settingsStore with localStorage persistence
- Apply CSS zoom to AppShell root div for full-window scaling
- Add zoom slider in GeneralSettings (50%-200%, step 5%, centered at bottom-left)
- Export UI_ZOOM_MIN/MAX/STEP constants for consistent range control
- Add i18n support for UI zoom label and description (en/zh)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 22:02:38 +08:00
程序员阿江(Relakkes)
a381bf0412 Make pure white theme complete across desktop surfaces
The pure white appearance option needed to avoid warm-theme leakage while preserving the existing warm classic brand theme. This adds the white theme mode, keeps local browser startup from reusing stale H5 server URLs in dev, and moves visible legacy warm surfaces onto theme tokens.

Constraint: H5 server auth policy, CORS policy, SDK routes, adapter routes, and IM access paths must not change for a visual theme fix
Rejected: Rename the original light theme to pure white | the original theme is a warm classic palette, not a neutral white workspace
Confidence: high
Scope-risk: moderate
Directive: Keep structural white-theme borders neutral; reserve the warm brand color for selected states, primary actions, and small accents
Tested: cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx src/lib/desktopRuntime.test.ts src/lib/persistenceMigrations.test.ts src/stores/uiStore.test.ts src/stores/settingsStore.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: bun test src/server/__tests__/settings.test.ts src/server/__tests__/h5-access-policy.test.ts src/server/__tests__/h5-access-auth.test.ts src/server/middleware/cors.test.ts
Tested: Browser smoke at http://127.0.0.1:5173 with data-theme=white, no H5 token prompt, /status inspector visible, inspector border #DDE3EA
Not-tested: Full bun run verify gate
2026-05-13 10:38:13 +08:00
程序员阿江(Relakkes)
99c964e0ca Merge response language selector into main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 11:57:04 +08:00
程序员阿江(Relakkes)
b693aa53b4 feat: add response language selector in General settings
Expose the CLI's `language` setting in the desktop app's General tab.
Users can now pick from 21 pre-defined languages via a dropdown (value
maps directly to CLI language names such as "chinese", "japanese").
Selecting a language writes it to ~/.claude/settings.json so the CLI
injects the language instruction into every session's system prompt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 11:54:17 +08:00
程序员阿江(Relakkes)
4865b4f206 Keep H5 settings failures visible without persisting raw tokens
Limit the legacy fallback to missing H5 endpoints, preserve last known H5 settings on real load failures, and move the generated token lifetime into the General settings component so the raw token clears after copy or timeout instead of living in global state.

Constraint: Task 3 remains limited to desktop settings store, UI, and tests
Rejected: Treat every H5 load failure as disabled defaults | hides real outages and overwrites useful last-known state
Rejected: Keep raw tokens in Zustand until manually dismissed | re-exposes secrets after reopening Settings
Confidence: high
Scope-risk: narrow
Directive: Only 404/405 H5 endpoint misses should degrade to disabled defaults; all other H5 load failures must preserve state and surface h5AccessError
Tested: cd desktop && bunx vitest run src/__tests__/generalSettings.test.tsx src/stores/settingsStore.test.ts
Tested: cd desktop && bun run lint
Tested: git diff --check -- desktop/src/stores/settingsStore.ts desktop/src/pages/Settings.tsx desktop/src/stores/settingsStore.test.ts desktop/src/__tests__/generalSettings.test.tsx desktop/src/i18n/locales/en.ts desktop/src/i18n/locales/zh.ts
2026-05-10 00:14:34 +08:00
程序员阿江(Relakkes)
a677163e0d Make H5 browser access manageable from desktop settings
Add the desktop-side H5 settings client, store state, and General tab controls so users can opt in, regenerate tokens, manage origins, and copy the browser URL without touching unrelated desktop flows.

Constraint: Task 3 is limited to desktop Settings UI and store wiring only
Rejected: Expand into AppShell or browser runtime work now | reserved for later tasks in the plan
Confidence: high
Scope-risk: narrow
Directive: Keep H5 fetchAll integration tolerant of missing endpoint responses so existing settings loads do not regress
Tested: cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx src/stores/settingsStore.test.ts
Tested: cd desktop && bun run lint
2026-05-09 23:57:52 +08:00
程序员阿江(Relakkes)
5c5255b492 fix: make macOS notification delivery verifiable
Desktop notifications were enabled by default and depended on the Tauri notification plugin for both permission state and delivery. On macOS the plugin reports desktop permission as granted and can hide foreground delivery failures, so authorization prompts could appear in the app without a real system notification.

This moves macOS permission and delivery through a native UserNotifications bridge, keeps notifications opt-in by default, and sends a test notification after successful authorization.

Constraint: Tauri notification plugin desktop permission state is always granted.
Constraint: macOS foreground delivery needs explicit native presentation handling.
Rejected: Keep using the plugin with retries | it still cannot report real macOS permission or delivery failures.
Confidence: high
Scope-risk: moderate
Directive: Do not remove the macOS bridge without verifying foreground banners from an installed app bundle.
Tested: cd desktop && bun run test --run src/lib/desktopNotifications.test.ts src/stores/settingsStore.test.ts src/__tests__/generalSettings.test.tsx src/stores/chatStore.test.ts
Tested: bun run check:desktop
Tested: bun run check:native
Tested: SKIP_INSTALL=1 ./scripts/build-macos-arm64.sh
Tested: codesign --verify --deep --strict --verbose=2 desktop/build-artifacts/macos-arm64/Claude Code Haha.app
Tested: hdiutil verify desktop/build-artifacts/macos-arm64/Claude Code Haha_0.2.0_aarch64.dmg
Tested: Computer Use macOS Settings and Bash authorization notifications, confirmed usernoted displayed banners.
Not-tested: Windows toast delivery on a real installed Windows build.
2026-05-05 20:33:12 +08:00
程序员阿江(Relakkes)
fa5fda24d0 feat: notify users when desktop attention is needed
Add native system notifications as a desktop-wide attention channel for permission prompts and scheduled task completion. The implementation keeps notification presentation owned by the OS, adds a user-facing enable switch with permission handling, and lets scheduled tasks choose desktop notifications without routing that channel through IM adapters.

Constraint: Notifications must use OS-native APIs without custom sound playback.
Constraint: Desktop channel is local-only and must not be sent through IM adapter delivery.
Rejected: Browser Notification API | not reliable inside the packaged Tauri desktop runtime.
Rejected: Treat desktop as an IM channel | would leak a local-only channel into server-side adapter sending.
Confidence: high
Scope-risk: moderate
Directive: Keep notification styling at the OS layer; business code should only provide title, body, dedupe, and routing decisions.
Tested: bun run check:desktop
Tested: bun run quality:pr
Tested: Computer Use macOS debug app verification for settings toggle, permission prompt, scheduled task desktop channel, and task-run polling dedupe
Not-tested: Windows and Linux native runtime smoke tests on physical hosts
2026-05-03 16:45:32 +08:00
程序员阿江(Relakkes)
3a6bad0e03 fix: keep WebSearch usable across third-party models
Native Anthropic web search is only reliable for Claude-family model names,
while many configured providers either do not implement the server tool schema
or reject it through proxy layers. This routes WebSearch through a single
resolver, adds Tavily and Brave fallbacks, and exposes provider key setup in
the desktop settings page.

Constraint: Third-party Anthropic-compatible endpoints may reject web_search_20250305 even when the model name is Claude-like
Constraint: Non-Claude models still need a usable WebSearch path when users configure an external search provider
Rejected: Gate native WebSearch by base URL | third-party Claude proxies can support it and official-looking URLs are not the real capability boundary
Rejected: Always expose Anthropic native WebSearch | unsupported providers loop on schema or tool errors
Confidence: high
Scope-risk: moderate
Directive: Keep WebSearch capability resolution centralized in WebSearchTool/backend.ts before adding more search providers
Tested: bun test src/tools/WebSearchTool/backend.test.ts
Tested: cd desktop && bun run test -- generalSettings.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: agent-browser Settings E2E for Tavily/Brave links and settings persistence
Tested: live Tavily and Brave fallback searches returned results using transient keys
Not-tested: automatic LLM decision to invoke WebSearch end-to-end against a paid model session
2026-05-01 10:14:02 +08:00
程序员阿江(Relakkes)
9ecc178c7a fix: prevent third-party thinking mode mismatches
Desktop users can now disable thinking for new sessions, and Anthropic-compatible providers that opt in receive explicit disabled-thinking requests across main turns, side queries, and AI title generation.

Constraint: DeepSeek/Kimi/GLM Anthropic-compatible endpoints need a non-thinking path without scattering provider-specific logic through the CLI.
Rejected: Per-model if/else branches | centralized provider preset env keeps the native CLI surface smaller and easier to audit.
Confidence: high
Scope-risk: moderate
Tested: bun test src/utils/__tests__/thinking.test.ts src/server/__tests__/title-service.test.ts src/server/__tests__/provider-presets.test.ts src/server/__tests__/conversations.test.ts
Tested: cd desktop && bun run test -- generalSettings.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: agent-browser DeepSeek desktop E2E with transparent proxy captured main and title requests with thinking.type=disabled
2026-05-01 10:13:10 +08:00
程序员阿江(Relakkes)
6d40b2befa fix: Keep desktop chats on selected provider runtimes
Desktop sessions can switch provider and model while a CLI subprocess is already alive, so the server now serializes runtime restarts and marks provider-managed launches to prevent stale settings env from overriding the selected provider. Provider settings also write API key env consistently and clear stale managed keys before syncing.

This includes the related desktop/docs brand asset refresh and keeps the desktop locale default in Chinese, with tests updated to match the current provider semantics.

Constraint: Session-scoped model selection must win over cc-haha/settings.json and inherited ANTHROPIC_* values.
Rejected: Store the selected model as a global provider activeModel | chat runtime selection is per session.
Confidence: high
Scope-risk: moderate
Directive: Do not remove CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST without validating Desktop provider switching against stale settings env.
Tested: bun test src/server/__tests__/conversation-service.test.ts src/server/__tests__/conversations.test.ts src/server/__tests__/providers.test.ts src/server/__tests__/providers-real.test.ts
Tested: cd desktop && bun run test src/stores/settingsStore.test.ts
Tested: cd desktop && bun run lint
Tested: git diff --check
Not-tested: Full desktop production package/signing.
2026-04-24 13:24:31 +08:00
程序员阿江(Relakkes)
7651b24a50 Reduce desktop first-token latency in sdk-url sessions
Desktop-managed sessions were blocking the first visible token on slow or failing
regular MCP connections, which made the UI feel much slower than direct bin runs.
This keeps partial assistant streaming enabled for desktop sessions and moves
regular MCP connection work off the critical path only for sdk-url startup.

Constraint: Desktop sdk-url sessions must preserve chat responsiveness even when local MCP endpoints fail or hang
Rejected: Leave MCP startup fully blocking in sdk-url mode | first visible token stayed several seconds behind direct CLI runs
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep blocking MCP startup for plain -p sessions unless you re-measure first-turn latency and tool availability tradeoffs
Tested: bun test src/server/__tests__/conversation-service.test.ts src/server/__tests__/conversations.test.ts; same-prompt timing comparison for direct bin vs sdk-url session path
Not-tested: Immediate first-turn availability of slow regular MCP tools in desktop sdk-url sessions
2026-04-21 00:41:02 +08:00
程序员阿江(Relakkes)
febd842557 Keep desktop WebFetch usable on third-party providers
Desktop sessions were failing before the actual fetch because Anthropic's domain preflight can be unreachable on restricted networks, and the next runtime path was missing turndown for HTML-to-Markdown conversion.

This change defaults desktop sessions to skip the preflight unless the user explicitly overrides it, exposes that behavior as a desktop General setting, seeds new settings JSON with the desktop-safe default, and adds regression coverage for both the runtime default and the UI toggle. It also adds the missing turndown dependency so successful fetches can continue through HTML reduction instead of failing at module resolution.

Constraint: Desktop must keep an escape hatch for users who want upstream preflight restored explicitly
Rejected: Force skipWebFetchPreflight globally for every session | would silently change CLI and non-desktop behavior
Rejected: UI-only toggle without runtime default | existing desktop users would still fail until they manually opened settings
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep desktop-specific WebFetch behavior scoped to desktop session detection and explicit user settings; do not broaden it to general CLI flows without separate validation
Tested: bun test src/tools/WebFetchTool/utils.test.ts; cd desktop && bun run lint; cd desktop && bunx vitest run src/__tests__/generalSettings.test.tsx; runtime import verification for turndown via node
Not-tested: End-to-end desktop packaging smoke test against a freshly built DMG/app bundle
2026-04-20 20:53:03 +08:00
程序员阿江(Relakkes)
76823047f4 Add a switchable dark theme for the desktop workspace
This introduces a persisted light/dark appearance setting, maps the desktop shell onto semantic theme tokens, and reworks the highest-traffic chat/settings surfaces so the new dark mode is usable without regressing the original light theme.

The same pass tightens markdown rendering for chat replies by improving inline code, table overflow handling, and safe external-link behavior so dark-mode content stays legible in real conversations.

Constraint: Preserve the existing light theme while adding a user-selectable dark theme in Settings > General
Constraint: Avoid introducing new dependencies for styling or markdown handling
Rejected: Replacing the light palette with a single dual-purpose palette | would risk broad visual regressions across the existing desktop UI
Rejected: Implementing dark mode only for shell chrome | leaves chat markdown, diffs, and permission flows visually broken
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: New desktop UI should use semantic theme variables instead of hard-coded color literals so both themes stay aligned
Tested: bun run lint; bun run test; bun run build; browser review of theme switching, provider/permission states, and chat surfaces
Not-tested: Prototype-style pages with remaining hard-coded colors (scheduled/session control mock surfaces) were not fully normalized in this change
2026-04-20 10:23:19 +08:00
程序员阿江(Relakkes)
8888e1c3fb chore: comprehensive code review fixes — security, perf, leaks, quality, docs
- security: XSS sanitization with DOMPurify in Markdown/Mermaid/PermissionDialog;
  path whitelist in filesystem API; fake keys in test/config files
- perf: fine-grained Zustand selectors in Sidebar/StatusBar/ContentRouter;
  50ms throttle on streaming deltas; React.memo + useMemo in MessageList;
  useRef for frequent keyboard shortcut state; AbortController 30s timeout
- leaks: WS session TTL timers (5-min cleanup on close); batch splice for
  sdkMessages/stderrLines; folderPath validation in cronScheduler
- quality: optimistic update rollback in settingsStore; error state in
  providerStore/teamStore; i18n for all hardcoded English strings
- docs: desktop architecture and features docs updated; VitePress nav fixed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 22:27:17 +08:00
程序员阿江(Relakkes)
a2bf92079b feat: add i18n support with English and Chinese locales
Add a lightweight custom i18n system supporting English (default)
and Chinese, with a language switcher in Settings > General.
All 35+ UI components internationalized with ~270 translation keys,
including 189 Chinese spinner verbs and server error code mapping.
2026-04-07 22:18:16 +08:00
程序员阿江(Relakkes)
f9c42c3b40 feat: Tauri desktop app with sidecar, brand identity, and CORS fix
- Add Tauri sidecar architecture: Rust shell spawns claude-server binary,
  dynamic port allocation, health-check wait loop, graceful shutdown
- Fix CORS middleware to accept `tauri://localhost` and `https://tauri.localhost`
  origins from Tauri WebView, and add CORS headers to /health endpoint
- Enable native macOS window decorations (traffic lights) with Overlay title bar,
  add data-tauri-drag-region on sidebar for window dragging
- Conditionally apply desktop-only padding (44px for traffic lights) vs web (12px)
- Generate brand identity: light-background app icon, horizontal logo, full icon
  set (icns/ico/png) for Tauri bundle
- Add brand mark + GitHub link in sidebar, replace mascot SVG with app icon
  in EmptySession page
- Update README (zh/en) and docs hero image with new branding
- Add sidecar build scripts and launcher entry points
- Gitignore Rust target/, Tauri gen/, and brand-assets candidates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 16:07:38 +08:00
程序员阿江(Relakkes)
d059a8b487 feat: add Provider management UI, CLI Tasks page, and enhance NewTaskModal
- Settings: new Providers tab with full CRUD, activation, and connectivity
  test; Model tab shows active provider name; General tab simplified
- Tasks: new CLI Tasks page displaying task lists from ~/.claude/tasks/
  with status, owner, and dependency (blocks/blockedBy) visualization
- NewTaskModal: add Advanced options (model, permission mode, working dir)
- Backend: fix TaskService to parse CLI V2 task format; extend /api/tasks
  with /lists endpoint for grouped queries
- Fix ModelInfo.context type from number to string

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 10:05:50 +08:00
程序员阿江(Relakkes)
993b96cd39 Stabilize the desktop transcript so long agent sessions stay readable
The desktop app now keeps the composer stable while turns are active,
reduces low-signal tool noise in the transcript, restores project context
under the composer after session creation, and relies on the CLI's own
permission requests instead of injecting broader desktop-side Bash asks.

This also brings in the supporting desktop app source tree and the server
routes/session metadata needed for git info, filesystem browsing, session
resume, slash commands, and SDK-backed permission bridging so the UI can
operate as a coherent feature instead of a partial patch.

Constraint: Desktop transcript needs to stay usable during long multi-tool sessions without hiding file-change diffs
Constraint: Permission prompts must mirror CLI behavior closely enough that read-only commands do not get desktop-only prompts
Rejected: Keep rendering Read/Bash bodies inline | too noisy and unlike the intended transcript model
Rejected: Commit only the touched desktop files | would leave the newly introduced desktop app incomplete in git history
Confidence: medium
Scope-risk: broad
Reversibility: messy
Directive: Treat non-writing tools as summary-first transcript events; do not re-expand them by default without validating the UX against long sessions
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test -- --run
Tested: bun test src/server/__tests__/conversations.test.ts
Not-tested: Manual visual regression against the exact screenshots in a live desktop session
Not-tested: Full root TypeScript check (repository still has unrelated extracted-native parse failures)
2026-04-06 20:37:44 +08:00