237 Commits

Author SHA1 Message Date
程序员阿江(Relakkes)
8d12fdbcff fix: keep background tasks visible after turn completion
Preserve background task visibility after the foreground turn completes and move task progress into an official-style background task drawer.

Keep tabs/sidebar active while background tasks run, delay foreground completion rows until background work is settled, and avoid hiding resumed agents after clearing prior finished entries.

Tested: bun run check:desktop
Confidence: high
Scope-risk: moderate
2026-06-28 10:51:02 +08:00
程序员阿江(Relakkes)
08c2d8cf5b fix(desktop): separate goal continuation turns
Emit a visible Goal continuing local-command marker before managed /goal continuations, then preserve it through server events, session history, and desktop history restore.

Render the marker as a compact divider so a new assistant continuation after end_turn is visually separated from the previous assistant output.

Related: #901

Tested: bun test src/query/stopHooks.test.ts src/server/__tests__/ws-memory-events.test.ts src/server/__tests__/sessions.test.ts && cd desktop && bun run test MessageList.test.tsx chatStore.test.ts

Tested: bun run check:server

Tested: bun run check:desktop

Not-tested: live release build and Windows v0.4.3 repro path; keep issue open until release validation.

Scope-risk: moderate

Confidence: high
2026-06-23 19:20:03 +08:00
程序员阿江(Relakkes)
46f612abd5 feat: allow deleting trace sessions
Adds an idempotent DELETE /api/traces/:sessionId path that removes only the local trace JSONL file and invalidates trace read cache. The Trace list now exposes a trash action behind a confirmation dialog that states chat history is not deleted.

Tested: bun test src/server/__tests__/trace-capture.test.ts

Tested: cd desktop && bun run test -- src/pages/TraceList.test.tsx --run

Tested: bun run check:server

Tested: bun run check:desktop

Tested: Browser smoke with temporary CLAUDE_CONFIG_DIR verified the Trace list delete button and confirmation dialog on ?traceWindow=1.

Constraint: GitHub issue #868 remains open until a release ships and post-release retest passes.

Confidence: high

Scope-risk: moderate
2026-06-23 16:20:11 +08:00
程序员阿江(Relakkes)
54a8f3107c fix(desktop): support 1M provider context declarations (#814)
Add per-model 1M capability flags for custom providers and persist them through provider settings.
When a model is marked as 1M-capable, runtime env uses the local [1m] marker and the desktop form auto-fills a 1000000-token context window when needed.

Tested: bun test src/server/__tests__/providers.test.ts -t "custom providers can mark main and role models as 1M-capable"
Tested: cd desktop && bun run test -- generalSettings.test.tsx -t "normalizes blank model mappings|saves 1M model declarations"
Tested: bun run check:desktop
Tested: bun run check:server
Not-tested: bun run verify / coverage gates were not run for this scoped local handoff.
Confidence: high
Scope-risk: moderate
2026-06-16 14:03:07 +08:00
程序员阿江(Relakkes)
381d5f14e0 fix(provider): default Tool Search for Anthropic providers (#823)
Add a provider-level Tool Search capability that defaults on for native Anthropic Messages providers and writes ENABLE_TOOL_SEARCH through the managed provider env path. Keep OpenAI proxy formats opted out because the proxy transforms do not support Anthropic tool_reference history yet.

Preserve upgrade safety by normalizing missing or stringly typed stored values instead of dropping saved providers.

Tested: bun test src/server/__tests__/provider-runtime-env.test.ts src/server/__tests__/providers.test.ts

Tested: cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx --run

Tested: cd desktop && bun run lint

Tested: bun run check:server

Confidence: high

Scope-risk: moderate
2026-06-15 23:29:42 +08:00
程序员阿江(Relakkes)
f5a97ac21c fix(desktop): expand workbench panels into tabs (#730)
Tested: cd desktop && bun run test -- --run src/components/workbench/WorkbenchPanel.test.tsx
Tested: cd desktop && bun run test -- --run src/components/layout/ContentRouter.test.tsx
Tested: cd desktop && bun run test -- --run src/stores/tabStore.test.ts
Tested: bun run check:desktop
Confidence: high
Scope-risk: moderate
2026-06-15 19:41:57 +08:00
程序员阿江(Relakkes)
a4799ae5ea Merge branch 'claude/brave-hofstadter-bc68ae': global session full-text search 2026-06-15 19:08:10 +08:00
程序员阿江(Relakkes)
1a050242b7 feat(search): global session full-text search
Add a Codex-style global search dialog (Cmd+K / sidebar button) that
full-text searches across all session transcripts, replacing the old
title-only sidebar filter.

Backend: rewrite searchService.searchSessions as a two-phase engine —
ripgrep finds candidate files + matched lines, then those lines are
parsed to keep only user/assistant text, re-confirmed against the
cleaned text to drop JSON/UUID/base64 false positives, and windowed into
highlighted snippets. Results carry real session titles (new
sessionService.getSessionTitleAndMeta reusing the list title
precedence), project path, mtime, role and match counts; falls back to a
JS scan when ripgrep is unavailable.

Frontend: new GlobalSearchModal (debounced, stale-response-safe, keyboard
nav, role badges, highlighting, recent-chats empty state); Cmd+K now
opens it; the sidebar input is replaced by a search trigger button.

Tests: 15 backend cases (searchService.sessions) + 12 frontend cases
(GlobalSearchModal); existing Sidebar/pages tests updated for the new
trigger.
2026-06-15 19:06:00 +08:00
程序员阿江(Relakkes)
18c6a43033 fix(desktop): collapse workspace navigator during previews (#706, #709)
Keep the file navigator hidden when a preview is active so code and diff tabs get the full workspace width.

Defer all-files tree loading until the navigator is explicitly opened to avoid unnecessary tree requests while previewing.

Tested: cd desktop && bun run test src/components/workspace/WorkspacePanel.test.tsx --run

Tested: bun run check:desktop

Confidence: high

Scope-risk: narrow
2026-06-15 17:17:38 +08:00
程序员阿江(Relakkes)
384fcea85e fix(desktop): show tool write/edit progress (#707, #751)
Add live line and character stats to desktop tool cards while Write and Edit inputs stream, and show Writer preview stats before the 120-line windowing threshold.

Tested: cd desktop && bun run test -- --run src/components/chat/chatBlocks.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:desktop
Not-tested: bun run verify / coverage; scoped desktop UI handoff only.
Confidence: high
Scope-risk: narrow
2026-06-15 17:17:07 +08:00
程序员阿江(Relakkes)
52682a4c76 fix(desktop): stop pending tool spinners on interrupt (#703)
When the user stops generation, finalize local streaming state by flushing any buffered assistant text into the transcript and marking pending tool-use cards as stopped instead of leaving them in a generating state.

Tested: cd desktop && bun run test -- src/stores/chatStore.test.ts src/components/chat/MessageList.test.tsx src/components/chat/chatBlocks.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:desktop
Confidence: high
Scope-risk: narrow
2026-06-15 16:50:45 +08:00
程序员阿江(Relakkes)
ea82c6ec70 fix(trace): record aborted API calls instead of leaving them pending (#766)
When an upstream request was aborted mid-stream (SDK client timeout,
stream idle watchdog, non-streaming fallback timeout, or user
cancellation), the trace fetch hook waited on a clone of the response
body that could hang forever, so the call never left "pending" in the
trace panel — exactly the silent stall that misled the #766 report.

- captureResponseTraceSnapshot reads the body with abort awareness:
  reader.cancel() on abort keeps the partial body, with a 2s grace
  backstop for runtimes where cancel cannot wake a hung read.
- The fetch hook now records an error-state call on abort with the
  abort reason (e.g. the watchdog's stream idle timeout), duration,
  partial response body, and an api_call_aborted event; non-abort
  capture failures also record an error instead of inferring ok, and
  pre-response fetch rejections carry an aborted flag.
- The trace detail panel shows an "Aborted" badge plus guidance for
  aborted calls, and labels the new api_call_aborted phase in all
  locales.

Tested: bun test src/server/__tests__/trace-capture.test.ts
Tested: bun run check:server
Tested: cd desktop && bun run test -- --run && bun run lint
2026-06-12 18:35:18 +08:00
程序员阿江(Relakkes)
67660ab4e5 fix(desktop): surface non-streaming fallback in chat status (#766)
api_retry heartbeats already reach the desktop status bar, but the
streaming-to-non-streaming fallback had no signal at all: the CLI only
flipped an internal flag, and the one-shot fallback response can take
minutes with zero incremental output, so the UI showed a bare spinner
the whole time.

- CLI: yield a {type:'system', subtype:'streaming_fallback', cause}
  message at both fallback sites (stream error/watchdog and 404 stream
  creation), mirroring the existing api_error -> api_retry path through
  query.ts passthrough, QueryEngine SDK output, and the SDK schema.
- Server: translate it to a streaming_fallback ServerMessage;
  unrecognized causes normalize to 'unknown' instead of dropping the
  event.
- Desktop: track it as active-turn state (cleared at the same 12 sites
  as apiRetry; a fallback notice supersedes the stale retry banner) and
  render a neutral pill with the turn timer - expected state, not an
  error, so no amber styling and nothing in the diagnostics panel.
- Retry banner now shows "retrying now" once the countdown elapses
  instead of sticking at "waiting 0s".

With 62241a31 disabling the non-streaming fallback for desktop CLI
sessions, this notice mainly covers the 404 gateway path (which skips
the disable check), callers that re-enable fallback via env, and
non-desktop SDK consumers.

Constraint: Retries and fallbacks are expected states per the
diagnostics severity standard - lightweight active-turn UI only, no
error-panel entries, no transcript persistence.
Tested: bun test src/server/__tests__/ws-memory-events.test.ts
Tested: bun run check:server
Tested: cd desktop && bun run test -- --run
Tested: cd desktop && bun run lint
Not-tested: live provider outage reproduction; verified via unit
coverage of the translation, store lifecycle, and indicator rendering.
2026-06-12 18:32:28 +08:00
程序员阿江(Relakkes)
62241a31e5 fix(desktop): stop killing slow provider streams (#766)
Desktop injected a far stricter timeout stack than the terminal CLI, so
healthy-but-slow third-party providers (sensenova/bailian/zhipu) died at
exactly API_TIMEOUT_MS while the UI showed "running" forever:

- API_TIMEOUT_MS is the SDK client's time-to-first-byte budget for
  streaming requests; these gateways send zero bytes (no headers, no
  SSE ping) until prefill finishes, which takes minutes at large
  contexts. Raise the default from 120s to the SDK's own 600s and widen
  the configurable range to 30-1800s.
- Widen the desktop-forced stream watchdog idle window to 240s so
  silent thinking/prefill phases stop tripping the 90s default.
- Disable the non-streaming fallback for desktop CLI sessions: a
  non-streaming request only responds after the FULL generation, so it
  can never finish inside the same budget and loops timeout aborts
  forever while the UI spins (also avoids double tool execution,
  upstream inc-4258). All three knobs respect caller env overrides.

Repro: mock upstream whose SSE stays silent for 150s before a complete
event sequence — terminal env completes; desktop env aborts at exactly
120s (client timeout) or 90s watchdog + non-streaming fallback loop;
the fixed env completes both variants.

Tested: bun test src/server/__tests__/network-settings.test.ts src/server/__tests__/conversation-service.test.ts src/server/__tests__/proxy-network-settings.test.ts
Tested: cd desktop && bun run test -- src/stores/settingsStore.test.ts src/__tests__/generalSettings.test.tsx
Tested: cd desktop && bun run lint
Confidence: high
Scope-risk: medium
2026-06-12 17:57:33 +08:00
程序员阿江(Relakkes)
5cf8c1bb67 fix(desktop): queue active-turn prompts (#755)
Add pending user-message queue controls while a desktop turn is running, replay queued prompts into the transcript when the CLI accepts them, and flush remaining prompts after turn completion.

Tested: cd desktop && bun run test -- src/components/chat/ChatInput.test.tsx
Tested: cd desktop && bun run test -- src/stores/chatStore.test.ts
Tested: bun test src/server/__tests__/ws-memory-events.test.ts
Tested: bun run check:desktop
Not-tested: bun run check:server remains blocked by unrelated E2E CORS preflight expectation, expected 403 but got 204.
Confidence: medium
Scope-risk: moderate
2026-06-12 16:44:52 +08:00
程序员阿江(Relakkes)
90a50eca1c Merge H5 access stability fixes (#767, #764) 2026-06-12 16:37:09 +08:00
程序员阿江(Relakkes)
53d8e7ad77 feat(desktop): stabilize H5 access tokens, ports, and background sessions (#767, #764)
H5 远程访问的三处不稳定来源修复,让手机出门在外也能稳定连接、长任务不丢。

#767 令牌与端口固定:
- 令牌明文持久化到 cc-haha/settings.json,重启后二维码/令牌随时可查、可复制;
  enable 复用现有令牌、disable 保留令牌,仅 regenerate 才轮换。手改 token 字段
  即自定义固定令牌。完整令牌只经 local-trusted 面返回,远端 403。
- 新增可选固定端口 fixedPort,并在未配置时复用上次端口(desktop-server-state.json
  sticky,Electron/Tauri 双壳共享),反向代理/手机书签跨重启不失效;占用时回退随机。

#764 断连不杀正在运行的 CLI:
- 客户端断开时若该会话仍在跑一轮任务,不再 30s 后强杀子进程,而是等任务跑完;
  手机锁屏/切后台时长任务在后台跑完,重连即见结果。
- 空闲清理超时改为可配 disconnectGraceSeconds(H5 访问设置页,默认 30s),
  经 disconnectGraceConfig 同步缓存供 close 处理读取。

server / Electron / Tauri / React 四层 + 五语言 i18n + 配套单测全部覆盖。
2026-06-12 16:37:00 +08:00
程序员阿江(Relakkes)
8c99b0f892 feat(providers): support drag-and-drop reordering of the providers list
为服务商列表添加拖拽排序(#753)。复用项目已有的原生 HTML5 拖拽模式(对齐
Sidebar),零新增依赖;通过重排 providers.json 的数组顺序持久化,不引入 order
字段;仅行首手柄可拖,避免与行内操作按钮冲突;采用乐观更新 + 失败回滚。

后端: reorderProviders service、PUT /api/providers/reorder 路由、
ReorderProvidersSchema(校验 orderedIds 为现有 id 的排列)。
前端: providersApi.reorder、store action、Settings 拖拽手柄 UI、中/英/日/韩/繁文案。
测试: 后端 9 用例 + 前端 3 用例。
2026-06-12 16:21:58 +08:00
程序员阿江(Relakkes)
f144700b57 Merge: unify token usage display across desktop and CLI (#757) 2026-06-12 15:26:46 +08:00
程序员阿江(Relakkes)
a94e5b641a fix: unify token usage display across desktop and CLI (#757)
Token counts were rendered with five inconsistent formats across the
chat UI (header "181,117 t", in-progress bare "↓ 2514", background
agents "12,345 tokens", compact summary "1.5k", trace "1.2k"), and the
in-progress count was actually stale: the server never set the status
event's tokens field, so the indicator showed the previous turn's value
(hence "first message shows nothing", "sometimes appears, never moves").

- Add shared desktop lib/formatTokenCount; route header, streaming
  indicator, background agents, compact summary, and trace through it.
- Header shows compact "124.3k tokens" with the exact count on hover.
- Add common.tokens i18n key (en/zh/zh-TW/jp/kr).
- Estimate the in-progress count from streamed chars (÷4, mirroring the
  CLI spinner) via a new streamingResponseChars per-session field, reset
  on each send; drop the dead status.tokens/elapsed fields.
- CLI spinner rows use formatTokens to drop the "1.0k" artifact.
2026-06-12 15:25:56 +08:00
程序员阿江(Relakkes)
8a0eef4ad4 fix(desktop): clarify MCP configuration title
Replace the editable MCP server heading with neutral configuration copy so the settings page does not imply an update action is running.

Fixes #763

Tested: cd desktop && bun run test -- src/__tests__/mcpSettings.test.tsx
Tested: cd desktop && bun run lint
Not-tested: full verify and coverage, scoped desktop copy/test change only
Confidence: high
Scope-risk: narrow
2026-06-12 12:46:05 +08:00
程序员阿江(Relakkes)
d7b8fb032c fix(desktop): preview exit plan approvals (#793)
Show ExitPlanMode approvals as a rendered plan preview in desktop chat,
forward plan feedback and requested prompt permissions through the desktop
WebSocket permission response, and keep permission-mode restoration owned by
the CLI runtime.

Tested: bun run verify
Confidence: high
Scope-risk: moderate
2026-06-12 11:16:31 +08:00
程序员阿江(Relakkes)
52aa3c5c02 feat(desktop): add Auto-dream setting (#800)
Expose the existing CLI Auto-dream switch in General settings with an explicit opt-in confirmation before enabling background memory consolidation.

Tested: bun run check:desktop
Tested: ./bin/claude-haha --help
Tested: CLAUDE_CONFIG_DIR temp settings true/false autoDreamEnabled check
Tested: real provider Auto-dream trigger against temporary memory copy
Scope-risk: narrow
Confidence: high
2026-06-12 10:51:24 +08:00
程序员阿江(Relakkes)
00b4ead0ca fix(trace): show tool call durations (#799)
Compute tool spans from paired tool results, surface session wall/model/tool timing, and keep pending spans updated with elapsed time.

Tested: cd desktop && bun run test -- --run src/lib/traceViewModel.test.ts src/pages/TraceSession.test.tsx
Tested: cd desktop && bun run test -- --run src/pages/TraceList.test.tsx
Tested: bun run check:desktop
Scope-risk: narrow
2026-06-12 10:50:55 +08:00
程序员阿江(Relakkes)
58d5221ca1 feat(activity): add plugin and skill usage insights
Add historical tool and skill aggregation to activity stats, compact the token summary, and show Codex-style activity insights with plugin/skill ranking.

Tested: bun test src/utils/__tests__/stats.test.ts
Tested: bun run check:persistence-upgrade
Tested: bun run check:desktop
Not-tested: bun run check:server (previous full run exposed unrelated conversations WebSocket timeouts; focused stats and persistence checks passed)
Confidence: medium
Scope-risk: moderate
2026-06-12 10:41:52 +08:00
程序员阿江(Relakkes)
d9ce2f09e1 refactor(desktop): move trace entry into Settings
Trace is a low-frequency diagnostic feature, so its entry points no
longer sit in primary chrome:

- Remove the Trace nav item above the session list in the sidebar
- Remove the trace open/open-window buttons from the session header
- Add a Trace tab in Settings between Token usage and Diagnostics,
  embedding the existing TraceList page full-bleed
- Add settings.tab.trace and drop unused sidebar.traces across locales
2026-06-11 01:42:40 +08:00
程序员阿江(Relakkes)
d3d7566f0c refactor(trace): redesign trace UI with LangSmith-style two-pane layout
UI rebuild (desktop):
- TraceSession: replace 3-column layout with two panes — turn-grouped
  timeline tree (draggable splitter, search/filter, keyboard nav) and a
  section-flow detail panel (Response / Messages / System Prompt /
  Tools / Parameters / Raw), collapse state persists across spans
- Render LLM requests/responses semantically: messages as role-colored
  conversation with tool_use/tool_result pairing instead of raw JSON
  dumps; Raw fallback via CodeViewer for legacy truncated records
- TraceList: row-style list with model chips, mono metrics, hover
  actions; content-visibility rows (no virtualization, WebKit-safe)
- i18n synced across zh/en/jp/kr/zh-TW (+25/-55 keys)

Data & capture (server):
- Capture full bodies: preview cap 2048 -> 240k chars, stream cap
  256KB -> 1MB; list API trims previews to keep polling light; new
  GET /api/sessions/:id/trace/calls/:callId returns the full record
- Extract per-call token usage at read time (SSE + JSON + proxy
  wrapped); mtime-keyed read cache for the polling path
- Fix sensitive-key regex redacting *_tokens count fields, which made
  token stats always report 0

Frontend data layer:
- SSE stream reassembly (Anthropic + OpenAI chat) adapted from
  claude-tap (MIT, attribution in THIRD_PARTY_LICENSES.md), request/
  response body parsers, shared formatters, on-demand call detail
  cache; traceViewModel gains tokenUsage/isLifecycleNoise, drops
  fullRaw

Tested:
- bun run check:server (1201 pass)
- bun run check:desktop (lint + 1358 tests + build)
- Chromium walkthrough against real local traces: list, session tree,
  LLM semantic detail (new format), legacy fallback, tool detail
2026-06-11 01:02:51 +08:00
程序员阿江(Relakkes)
ae09a39e55 fix(desktop): update IM adapter setup guidance
Put Telegram first in the IM adapter settings, add a single documentation link in the setup copy, and keep per-platform settings focused on configuration.

Tested: cd desktop && bun run test AdapterSettings.test.tsx
Tested: bun run check:desktop
Scope-risk: narrow
Confidence: high
2026-06-11 00:09:01 +08:00
程序员阿江(Relakkes)
0d45439fbe feat(trace): add session trace monitoring (#606)
Tested:
- cd desktop && bun run test -- --run src/pages/TraceList.test.tsx
- bun test src/server/__tests__/trace-capture.test.ts
- bun run check:desktop
- bun run check:server

Scope-risk: broad
2026-06-10 17:13:27 +08:00
程序员阿江(Relakkes)
56661c7967 fix: support desktop output style config (#652)
Fixes #652.

Add desktop/server output style settings APIs and a General Settings picker
that mirrors the Claude CLI outputStyle sources.

Persist active-project choices to .claude/settings.local.json and global
choices to user settings, and route /config to the local settings UI.

Tested:
- bun test src/server/__tests__/settings.test.ts
- cd desktop && bun run test -- src/components/chat/composerUtils.test.ts src/stores/settingsStoreOutputStyle.test.ts src/pages/SettingsOutputStyle.test.tsx
- cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx
- bun run check:desktop
- bun run check:server
- bun run verify

Confidence: high
Scope-risk: moderate
2026-06-10 15:24:37 +08:00
程序员阿江(Relakkes)
ddcfa5faae feat(adapters): add WhatsApp linked-device support (#573)
Add a WhatsApp adapter backed by Baileys linked-device auth, plus desktop QR binding UI, server config endpoints, sidecar startup wiring, tests, and documentation.

Constraint: Uses WhatsApp Web linked-device auth, not Meta WhatsApp Business Cloud API.

Tested:
- cd adapters && bun run check:adapters
- bun test src/server/__tests__/adapters.test.ts
- cd desktop && bun run check:desktop
- bun run check:native
- bun run check:persistence-upgrade
- bun run check:docs

Not-tested:
- Live WhatsApp QR pairing, because no WhatsApp account/device was exercised here.
- bun run check:server, because the existing src/server/__tests__/conversations.test.ts timeout still fails independently.

Confidence: medium
Scope-risk: moderate
2026-06-09 21:31:46 +08:00
程序员阿江(Relakkes)
d11748d61a fix(desktop): make memory files preview-first (#533)
Tested: cd desktop && bun run test src/__tests__/memorySettings.test.tsx
Tested: bun run check:desktop
Scope-risk: narrow
Confidence: high
2026-06-09 16:39:17 +08:00
程序员阿江(Relakkes)
0a8f247781 feat(desktop): add plugin list bulk toggles (#527)
Tested:
- cd desktop && bun run test -- src/__tests__/pluginsSettings.test.tsx src/stores/pluginStore.test.ts --run --reporter=verbose --pool=forks --maxWorkers=1 --minWorkers=1
- bun run check:desktop
- git diff --check

Scope-risk: moderate
Confidence: high
2026-06-09 16:33:15 +08:00
程序员阿江(Relakkes)
561ae1aefe feat(desktop): fill jp/kr/zh-TW keys added since the PR branched
Main added two TranslationKeys after this branch's base — 'thinking.labelDone'
(the "Thought" label shown after thinking completes) and
'slashCmd.agent.description' — which the jp/kr/zh-TW locale files did not yet
cover, so the Record<TranslationKey, string> contract failed tsc after merging
main. Add both keys to each new locale:

- jp: '思考完了' / '選択した Agent でプロンプトを実行'
- kr: '사고 완료' / '선택한 Agent로 프롬프트 실행'
- zh-TW: '已思考' / '使用指定 Agent 執行提示'

en/zh are unchanged. `tsc --noEmit` is now clean and the i18n + timestamp
suites pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:20:55 +08:00
程序员阿江(Relakkes)
54b8c3f841 Merge commit '892f5e19' into i18n-fill-717 2026-06-04 23:13:43 +08:00
程序员阿江(Relakkes)
449ff0b0ff fix(desktop): show "已思考" label after thinking completes (#732)
The thinking block title always rendered the static "思考中"/"Thinking"
label; isActive only toggled the animated dots. Once thinking finished
the dots disappeared but the in-progress text stayed. Switch the label
to "已思考"/"Thought" when the block is no longer active.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:19:11 +08:00
tw199501
f02ea93018 feat(desktop): add Japanese, Korean, and Traditional Chinese locales
Add jp / kr / zh-TW translations and wire them into the i18n runtime so the
desktop app can switch among English, Simplified Chinese, Traditional Chinese,
Japanese, and Korean.

- new locale files jp.ts / kr.ts / zh-TW.ts with full TranslationKey coverage
- register the locales in the i18n index and extend the Locale union
- accept the new codes in settingsStore.getStoredLocale (default stays zh)
- add language-switcher entries (简体中文 / 繁體中文 / 日本語 / 한국어)
- localize chat message timestamps: Han 年月日 for zh/zh-TW/jp, Intl ko-KR for kr
- extend the DATE_LOCALES map in ActivitySettings (ja-JP / ko-KR / zh-TW)
- tests: formatMessageTimestamp locale branches + i18n locale resolution

Korean terminology follows the Microsoft Korean localization style guide
(새로 고침 / 사용·사용 안 함 / 이름 바꾸기, 합니다-style sentences).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 09:55:38 +08:00
程序员阿江(Relakkes)
16f4137954 fix(desktop): stabilize Electron proxy and fullscreen handling
Electron desktop runs network-sensitive OpenAI OAuth token exchange in the sidecar process, so the sidecar now receives system proxy env derived from Electron's cross-platform proxy resolver and the OAuth token client uses the existing proxy fetch options. General manual proxy settings also document and preserve authenticated proxy URLs.

The macOS fullscreen black-screen path is addressed by avoiding native fullscreen Spaces for app fullscreen toggles and by leaving fullscreen before hiding or closing the window.

Constraint: Electron packaged apps may not inherit shell HTTPS_PROXY env when launched from Finder.
Constraint: Manual authenticated proxies must remain standard HTTP(S) proxy URLs for Bun/undici compatibility.
Rejected: Store proxy username and password as separate fields | would require new secret-storage semantics and migration beyond this bugfix.
Rejected: Use native macOS fullscreen Spaces for the desktop app | reproduced black-screen behavior when hiding/closing from fullscreen.
Confidence: high
Scope-risk: moderate
Directive: Do not remove sidecar proxy env injection without retesting OpenAI OAuth from a packaged app launched outside a shell.
Tested: bun test src/services/openaiAuth/client.test.ts src/server/__tests__/haha-openai-oauth-service.test.ts
Tested: bun test src/server/__tests__/network-settings.test.ts
Tested: cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx --run
Tested: cd desktop && bun run check:electron
Tested: git diff --check
Not-tested: bun run check:server blocked by expired quarantine entries server:cron-scheduler, server:providers-real, server:tasks, server:e2e:business-flow, server:e2e:full-flow
Not-tested: live OpenAI OAuth through a corporate authenticated proxy
2026-06-02 21:37:35 +08:00
程序员阿江(Relakkes)
386a41e606 feat(desktop): enable Electron migration path
Introduce the Electron desktop shell alongside the existing React renderer and local Bun server boundary. The migration keeps the DesktopHost contract explicit across Tauri, Electron, and browser runtimes while adding Electron main/preload services for dialogs, shell, notifications, updates, tray/window lifecycle, terminal, preview WebContentsView, app mode, and release/package validation.

The commit also carries the latest local main desktop command updates, including agent slash entries and hidden-by-default markdown thinking details, so the packaged Electron build matches the current main UX surface.

Constraint: React renderer, local Bun server, REST/WebSocket, and sidecar boundaries must remain reusable during the migration
Constraint: macOS dev packages are ad-hoc signed and cannot prove Developer ID notarization or Gatekeeper release launch
Rejected: Browser-only smoke validation | it cannot exercise native dialogs, keychain prompts, notification behavior, or packaged app startup
Confidence: medium
Scope-risk: broad
Directive: Do not remove Tauri host support until signed Electron release artifacts pass native OS smoke on macOS, Windows, and Linux
Tested: bun run check:desktop
Tested: cd desktop && bun run check:electron
Tested: CSC_IDENTITY_AUTO_DISCOVERY=false bun run electron📦dir
Tested: bun run test:package-smoke --platform macos --package-kind dir --artifacts-dir desktop/build-artifacts/electron
Tested: Computer Use read packaged Electron app window at desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app
Not-tested: Developer ID signed/notarized Gatekeeper launch
Not-tested: Real OS notification click-to-session action
Not-tested: Windows and Linux packaged app smoke on real hosts
2026-06-01 22:43:16 +08:00
程序员阿江(Relakkes)
7ca702a253 fix(desktop): simplify changed-file open-with menus
Changed-file rows are easier to scan when previewable files are grouped before source-only files, and the file open-with menu should only expose useful preview, editor, and reveal actions. Output target cards also no longer need a separate copy control now that open/open-with are the primary actions.

Constraint: Keep the existing open-with API and menu components shared across changed files, workspace context menus, and output target cards.
Rejected: Keep system-default open for files | it duplicated less predictable platform behavior and added a low-value final menu item.
Confidence: high
Scope-risk: narrow
Directive: File open-with menus should stay ordered by immediate preview/open usefulness before editor and reveal actions.
Tested: cd desktop && bun run test src/lib/openWithItems.test.ts src/components/workspace/WorkspaceFileOpenWith.test.tsx src/components/chat/AssistantOutputTargetCard.test.tsx src/components/chat/CurrentTurnChangeCard.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: git diff --check
2026-06-01 01:43:36 +08:00
程序员阿江(Relakkes)
998e85efab fix: localize synthetic business errors
Synthetic API errors were carrying only English display text, so desktop chat could not distinguish our compatibility guidance from raw upstream failures and recovery logic depended on those English strings.

Add stable business error codes for media, PDF, request-size, prompt-length, and auto-mode errors. Desktop chat now resolves those codes through locale keys and suppresses the stale English fallback for known business errors, while normalizeMessagesForAPI still supports legacy text matching for old transcripts.

Constraint: Raw upstream provider details must remain available for diagnostics but should not drive localized business UX.

Rejected: Localize src/services/api/errors.ts strings directly | that would make persisted transcript text and media recovery depend on the active UI language.

Confidence: high

Scope-risk: moderate

Directive: Add new user-facing synthetic API errors with businessErrorCode values before localizing their display text.

Tested: bun test src/services/api/errors.test.ts tests/mediaRecoveryAndEstimation.test.ts src/server/__tests__/ws-memory-events.test.ts

Tested: cd desktop && bun run test -- run src/stores/chatStore.test.ts src/components/chat/MessageList.test.tsx

Tested: bun run check:server

Tested: bun run check:desktop

Not-tested: Manual desktop screenshot smoke for the rendered Chinese error card
2026-06-01 00:36:29 +08:00
程序员阿江(Relakkes)
587922ba75 fix(desktop): refine activity profile editing
The token usage profile header had too much top spacing, the edit action competed with the content from the top-right corner, and the profile subtitle was fixed to the default project link. This keeps the profile controls close to the identity block, moves the modal scrim to the document body so it covers the whole desktop shell, and persists a user-editable second line with URL auto-linking.

Constraint: Preserve existing profile preferences and backfill older records that do not have a subtitle field.
Rejected: Keep the top-right edit button | it kept the action visually detached from the profile content.
Rejected: Store the second line only in desktop local state | the preference already has a server-backed profile shape.
Confidence: high
Scope-risk: narrow
Directive: Keep profile preference schema changes backward-compatible with older desktop-ui preference files.
Tested: cd desktop && bun run test --run src/pages/ActivitySettings.test.tsx src/api/desktopUiPreferences.test.ts
Tested: bun test src/server/__tests__/desktop-ui-preferences.test.ts
Tested: bun run check:persistence-upgrade
Tested: bun run check:server
Tested: bun run check:desktop
Tested: git diff --check
Not-tested: Full Tauri native shell smoke; renderer flow was smoke-tested in browser only.
2026-05-31 17:42:30 +08:00
程序员阿江(Relakkes)
3b1b96022f feat: add activity profile and themed usage heatmap
Add a local profile surface to the desktop token usage page, including avatar
persistence, display-name editing, cumulative usage metrics, and daily, weekly,
and cumulative heatmap views. Align heatmap color ramps and hover treatment with
the supported white, warm, and dark desktop themes.

Constraint: User profile data must stay local under cc-haha desktop preferences.
Rejected: Keep a separate profile edit panel | the requested design favors a compact profile header with modal editing.
Rejected: Use a blue heatmap ramp | it conflicted with the app theme palettes.
Confidence: high
Scope-risk: moderate
Tested: bun run check:desktop
Tested: bun test src/server/__tests__/desktop-ui-preferences.test.ts
Tested: bun run check:persistence-upgrade
Tested: bun run check:coverage
Not-tested: Full bun run verify
2026-05-31 17:42:30 +08:00
程序员阿江(Relakkes)
1110e5ab30 fix: make desktop updates non-blocking
Move update downloads into the background and prompt only after the update is ready, so the global update UI no longer pins a progress panel over the app. Keep the About page as the detailed status surface and make failed downloads or installs retryable without losing the prepared update.

Constraint: Tauri updater install still needs an explicit user restart action after download
Rejected: Keep showing global download progress | it preserves the blocking top-right experience that triggered the complaint
Confidence: high
Scope-risk: moderate
Directive: Do not show the global update prompt before status is downloaded without rechecking the desktop UX complaint
Tested: bun run test -- src/stores/updateStore.test.ts src/components/shared/UpdateChecker.test.tsx --run
Tested: bun run check:desktop
Tested: bun run check:native
Tested: bun run check:coverage
Tested: bun run verify
Not-tested: Real signed release artifact update from an installed older desktop build
2026-05-31 17:42:30 +08:00
程序员阿江(Relakkes)
6ca7ee48a8 fix: unify desktop confirmation dialogs
Desktop destructive confirmations had split implementations: shared ConfirmDialog, hand-rolled modals, inline task popovers, and a diagnostics window.confirm path. This adds shared ActionDialog and ConfirmPopover primitives, keeps ConfirmDialog as the simple two-action wrapper, and migrates the known desktop confirmation flows onto those shared surfaces.

Constraint: Running-tab close needs three actions, so the two-button ConfirmDialog API was not enough.
Rejected: Force every confirmation through ConfirmDialog | would either lose the keep-running action or make ConfirmDialog too broad for inline popovers.
Confidence: high
Scope-risk: moderate
Directive: Add new desktop confirmation flows through ActionDialog, ConfirmDialog, or ConfirmPopover instead of hand-rolled overlays.
Tested: cd desktop && bun run test -- AdapterSettings.test.tsx mcpSettings.test.tsx TabBar.test.tsx PermissionModeSelector.test.tsx diagnosticsSettings.test.tsx
Tested: bun run check:desktop
Tested: git diff --check
Tested: Chrome DevTools smoke for provider delete and diagnostics clear-log confirmation dialogs
Not-tested: Agent Browser smoke because the local agent-browser CLI hung on open/snapshot/doctor/close commands.
2026-05-31 17:42:30 +08:00
程序员阿江(Relakkes)
f559ed31dc fix: keep MCP and history navigation responsive (#648)
MCP settings could remount into a full-page spinner even when cached server data was available, and overlapping refreshes could let stale responses replace newer state. Historical chat sessions also had no explicit history-loading state, so slow transcript reads looked like a blank session.

This keeps cached MCP/session lists visible during refresh, ignores stale list responses, clears the selected MCP server when returning to the list, and gives historical sessions explicit loading/error states with de-duped history loads.

Constraint: Fix must stay local-state focused and avoid changing MCP config persistence.
Rejected: Add a broad transcript/session indexing layer | too large for the issue-level stall fix.
Confidence: high
Scope-risk: moderate
Directive: Do not remove the stale-response guards without re-testing rapid settings navigation and session switching.
Tested: cd desktop && bun run test -- mcpSettings.test.tsx
Tested: cd desktop && bun run test -- sessionStore.test.ts
Tested: cd desktop && bun run test -- chatStore.test.ts
Tested: cd desktop && bun run test -- ActiveSession.test.tsx
Tested: bun test src/server/__tests__/sessions.test.ts src/server/__tests__/mcp.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run check:desktop
Tested: bun run check:server
Not-tested: Manual Windows desktop reproduction for issue #648.
2026-05-31 17:42:09 +08:00
程序员阿江(Relakkes)
f17b0828a0 feat(desktop): change-card row opens the workspace diff instead of an inline diff
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:40:46 +08:00
程序员阿江(Relakkes)
1d9f4c9cb7 feat(desktop): unify right panel into Workbench with file/browser mode switch
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:40:46 +08:00
程序员阿江(Relakkes)
f2f230914d feat(desktop): collapse long change-file lists in the turn card (show N more)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:40:46 +08:00
程序员阿江(Relakkes)
95d1ba997a feat(desktop): render message-complete previewable refs as rich cards (drop inline pill)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:40:46 +08:00