219 Commits

Author SHA1 Message Date
程序员阿江(Relakkes)
472ff73927 Stabilize OpenAI auth PR quality gates
PR 217 combined OpenAI OAuth model options with env-configured provider models, but the picker path returned before appending third-party model aliases. The desktop workspace test also exercised Prism highlighting for every expanded line, which was costly enough to time out on CI runners. The docs job did not need the root React Vite plugin; the desktop package owns that dependency.\n\nConstraint: PR Quality must pass server, desktop, and docs jobs before merge.\nRejected: Increase Vitest timeout | keeps the expensive render path and hides the CI regression.\nRejected: Add root Vite 8 peer dependencies | root only builds VitePress docs; React Vite plugin belongs in desktop/.\nConfidence: high\nScope-risk: narrow\nTested: npm ci --ignore-scripts; npm run docs:build; bun test src/server/__tests__/settings.test.ts src/server/__tests__/conversation-service.test.ts; bun run check:server; bun run check:desktop\nNot-tested: live provider OAuth login
2026-05-04 21:10:08 +08:00
Relakkes Yang
9eb7da5377 fix: preserve historical workspace changes on windows 2026-05-02 17:53:24 +08:00
程序员阿江(Relakkes)
0b87fd0f7e Merge commit '071975e0cc007f88e2424dc86d3310992cf1eb41' 2026-05-02 12:42:19 +08:00
程序员阿江(Relakkes)
071975e0cc Improve desktop failure diagnosis with exportable logs
Desktop failures were previously hard to debug from issue reports because server-side and CLI startup details were only partially visible in the UI. This adds a dedicated cc-haha diagnostics store with sanitized structured events, runtime error summaries, a Settings diagnostics view, and an exportable bundle that users can attach to reports.

Constraint: Diagnostic exports must not include chat content, file contents, full environment variables, API keys, bearer tokens, cookies, or OAuth tokens.
Rejected: Export raw server logs | easier to debug but too likely to leak secrets and private workspace data.
Rejected: Keep diagnostics only in transient UI errors | still leaves maintainers unable to diagnose later GitHub issues.
Confidence: high
Scope-risk: moderate
Directive: Do not add raw transcript, prompt, attachment, or environment dumps to diagnostics without a separate privacy review.
Tested: ANTHROPIC_API_KEY=test-key bun test src/server/__tests__/diagnostics-service.test.ts
Tested: ANTHROPIC_API_KEY=test-key bun test src/server/__tests__/conversation-service.test.ts
Tested: ANTHROPIC_API_KEY=test-key bun test src/server/__tests__/conversations.test.ts
Tested: cd desktop && bun run test src/__tests__/diagnosticsSettings.test.tsx --run
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: agent-browser E2E on local server/dev UI for CLI startup failure, provider test failure, diagnostics tab, copy summary, export bundle, and tar/secret scan
Not-tested: Destructive clear-logs button in browser E2E; local deletion was intentionally not clicked.
2026-05-02 12:41:31 +08:00
程序员阿江(Relakkes)
fe303c7a91 Merge session sidebar stability fixes 2026-05-02 12:05:07 +08:00
程序员阿江(Relakkes)
d50268c07c fix: prevent session sidebar stalls and title churn
Large desktop histories were making session discovery parse every JSONL
before pagination, while automatic title updates could still overwrite
manual names during resumed sessions. This keeps listing bounded to the
requested page, preserves custom titles, and blocks deleted placeholder
sessions from being recreated by prewarm startup.

Constraint: Desktop session storage remains JSONL-compatible with the CLI
Rejected: Virtualize the sidebar in this patch | does not fix backend JSONL parsing cost
Rejected: Disable title generation globally | would regress useful titles for unnamed sessions
Confidence: high
Scope-risk: moderate
Directive: Do not reintroduce all-file JSONL parsing on /api/sessions list paths without a heavy-session benchmark
Tested: ANTHROPIC_API_KEY=test-key bun test src/server/__tests__/title-service.test.ts src/server/__tests__/sessions.test.ts
Tested: ANTHROPIC_API_KEY=test-key bun test src/server/__tests__/conversations.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: heavy local preview with 240 sessions, 320 messages each, and 40 restored tabs
Not-tested: native packaged desktop runtime under Windows with the same heavy fixture
Related: https://github.com/NanmiCoder/cc-haha/issues/237
Related: https://github.com/NanmiCoder/cc-haha/issues/248
2026-05-02 12:04:51 +08:00
程序员阿江(Relakkes)
1d4d87a55e fix: Prevent light inspector panels in dark theme
The session inspector reused a one-off light palette, so /status, /cost,
and /context could render bright panels inside the dark desktop shell.
This moves the inspector and MCP switch control onto theme-scoped tokens
while preserving the existing light-theme look.

Constraint: Desktop dark mode must keep the existing surface hierarchy and avoid changing global brand colors.
Rejected: Recolor the shared Material palette | too broad for a component-specific regression.
Confidence: high
Scope-risk: narrow
Directive: Keep slash inspector surfaces on semantic theme tokens; do not reintroduce fixed light hex classes.
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test src/__tests__/pages.test.tsx src/__tests__/mcpSettings.test.tsx
Tested: cd desktop && bun run build
Tested: agent-browser screenshots for /status, /usage, /context, and MCP settings on http://127.0.0.1:5184/
2026-05-02 11:46:42 +08:00
Relakkes Yang
465e043563 fix: hide blank assistant message bubbles 2026-05-01 22:09:55 +08:00
程序员阿江(Relakkes)
103a6cc42b fix: restore per-turn changed file cards
The chat timeline lost per-turn changed file cards when the visible user message ids did not match persisted transcript ids, and sessions without SDK file-history snapshots had no fallback source for turn changes. Match live cards by stable user-message index when needed and derive checkpoint previews from transcript tool calls when snapshots are absent.

Constraint: Right-side workspace changes already derive from transcript tool calls, so chat checkpoint data must remain consistent with that source.
Rejected: Force a history reload after every turn | would hide the id mismatch but add churn and still not cover transcript-only sessions.
Confidence: high
Scope-risk: moderate
Directive: Keep snapshot checkpoints as the preferred source, and use transcript extraction only as the compatibility fallback.
Tested: bun test src/server/__tests__/sessions.test.ts
Tested: bun test src/server/__tests__/workspace-service.test.ts
Tested: cd desktop && bun run test src/components/chat/MessageList.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test
Tested: git diff --check
Not-tested: Browser E2E against a live model session.
2026-05-01 21:43:17 +08:00
程序员阿江(Relakkes)
f5cf5932b4 fix: keep workspace changes and session checkpoints reliable
The desktop workspace panel and chat transcript were mixing project-level file state with per-turn session history, which made rewind, file attachment, and changed-file previews brittle across multi-turn and historical sessions. This keeps turn checkpoints durable in the transcript, makes workspace refreshes happen at the right lifecycle points, and hardens long file previews without blocking the UI.

Constraint: Right-side workspace changes are project working-tree state, while chat turn cards are session checkpoint state.
Rejected: Treat every changed-file panel entry as session-local | new sessions must still reveal existing dirty project files.
Confidence: high
Scope-risk: moderate
Directive: Do not couple global workspace status to session checkpoint cards without preserving both product meanings.
Tested: cd desktop && bun run test src/components/workspace/WorkspacePanel.test.tsx
Tested: cd desktop && bun run lint
Tested: git diff --check
Tested: cd desktop && bun run test
Not-tested: Packaged Tauri runtime smoke test
2026-05-01 20:53:04 +08:00
程序员阿江(Relakkes)
e6378af234 fix: prevent WebSearch save button wrapping
The WebSearch settings footer placed explanatory copy and the save action in one flex row. On narrower dark-mode layouts, the long localized hint could squeeze the button enough for Chinese text to wrap vertically.

Move the action onto its own right-aligned row and give the button a stable minimum width so the layout remains readable across localized settings screens.

Constraint: Settings screen must support Chinese dark-mode copy without vertical button text.
Rejected: Only widening the button in the same flex row | the hint text can still consume the row and compress the action.
Confidence: high
Scope-risk: narrow
Directive: Keep localized action buttons out of compressible text rows unless the container has explicit width guarantees.
Tested: cd desktop && bun run lint
Tested: agent-browser visual check in light and dark settings pages
2026-05-01 20:42:44 +08:00
程序员阿江(Relakkes)
3e62c15406 fix: expose desktop workspace tools from the start screen
The desktop start screen can already collect a project directory before the first chat turn, but workspace management is intentionally session-scoped. Creating a draft session immediately after project selection keeps the file manager, changed-file view, runtime selection, and terminal toolbar on the same path users see after sending the first message.

Constraint: Workspace file management state is keyed by session id.
Rejected: Add a separate non-session workspace mode | it would duplicate panel state and create a second lifecycle to maintain.
Confidence: high
Scope-risk: narrow
Directive: Keep workspace management session-scoped; create or reuse a session before exposing the workspace panel.
Tested: cd desktop && bun run test -- TabBar.test.tsx EmptySession.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Not-tested: Native Tauri folder dialog manual smoke test.
2026-05-01 17:30:28 +08:00
程序员阿江(Relakkes)
10b974dac3 Merge commit 'df52bea0d0cb5889f9c5e324c54f2bdce9e30378' 2026-05-01 17:19:31 +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)
80aca8c176 feat: 让工作区文件引用成为可回滚的聊天上下文
桌面端的工作区文件面板现在可以把文件或局部评论加入聊天,发送给 CLI 的内容保持为原生 @文件路径引用,聊天界面则保留用户可读的文件 chip。为了让本轮变更卡片和 checkpoint 回滚继续可靠,UI 消息会同时保存用于展示的内容和实际发给模型的 modelContent;历史转录里的 @文件路径也会在重载时还原成附件 chip。

Constraint: CLI 侧最稳定的文件上下文入口仍是原生 @文件路径
Constraint: 聊天 UI 不能把绝对路径裸露成用户消息正文
Rejected: 只发送隐藏提示文本 | CLI 对 @文件路径已有稳定读取行为
Rejected: 只依赖前端展示内容做回滚校验 | 会和真实转录内容不一致
Confidence: high
Scope-risk: moderate
Directive: 修改附件展示或回滚校验时必须同时验证 modelContent 与 UI content 的分离
Tested: cd desktop && bun run test -- src/stores/chatStore.test.ts src/components/chat/MessageList.test.tsx src/stores/workspaceChatContextStore.test.ts src/components/workspace/WorkspacePanel.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: SKIP_INSTALL=1 ./desktop/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.1.8_aarch64.dmg
Tested: Computer Use macOS run with /private/tmp/cc-haha-computer-use-e2e verified file chip, @path model input, model sentinel response, workspace preview interactions
Not-tested: Deep unloaded-folder fuzzy search in all-files view
2026-05-01 00:00:32 +08:00
程序员阿江(Relakkes)
ba8c6b8828 fix: default empty workspace changes to file tree
The workspace panel now treats an empty changed-files status as a browsing case, so opening the panel shows the project tree instead of an empty changed-files view. The panel header controls were also reduced to keep the right workspace rail visually proportional in compact layouts.

Constraint: Users still need to manually inspect the empty changed-files view when they explicitly choose it.
Rejected: Always render the empty changed-files state | it makes the opened workspace feel broken when no files changed.
Confidence: high
Scope-risk: narrow
Directive: Do not auto-switch the workspace view after a user has explicitly selected a workspace view.
Tested: cd desktop && bun run test -- src/components/workspace/WorkspacePanel.test.tsx src/stores/workspacePanelStore.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Not-tested: Browser E2E visual screenshot pass was not rerun for this small header sizing change.
2026-04-30 19:27:22 +08:00
程序员阿江(Relakkes)
6d56f3c21d fix: remove legacy message rewind entry
The chat surface now relies on the current-turn changes card for file rollback, so the older per-message hover rewind affordance was removed to avoid two competing rollback models.

Constraint: Current-turn undo still depends on the existing checkpoint rewind API.
Rejected: Keep both rewind entry points | duplicate rollback affordances make the product harder to explain and test.
Confidence: high
Scope-risk: moderate
Directive: Prefer adding rollback behavior through the current-turn change card instead of restoring per-message hover rewind.
Tested: bun test src/server/__tests__/sessions.test.ts
Tested: cd desktop && bun run test
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Not-tested: Browser E2E scripts were updated but not executed in this commit.
2026-04-30 18:28:08 +08:00
程序员阿江(Relakkes)
bcfe042fc8 test: cover multi-turn workspace rollback behavior
The session workspace and current-turn undo surfaces now have regression coverage for multi-turn rollback semantics, stale current-turn cards, and dark theme workspace token usage.

Constraint: Workspace rollback must behave consistently for git and non-git session review flows.
Rejected: Rely on manual browser-only checks | they do not guard future regressions.
Confidence: high
Scope-risk: narrow
Directive: Keep rollback tests focused on target user message identity, not only visible index position.
Tested: bun test src/server/__tests__/sessions.test.ts
Tested: cd desktop && bun run test -- src/components/chat/MessageList.test.tsx src/components/workspace/WorkspacePanel.test.tsx src/stores/workspacePanelStore.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Not-tested: Full live multi-turn assistant generation E2E across a fresh temporary project.
2026-04-30 17:54:13 +08:00
程序员阿江(Relakkes)
aaf25159af fix: keep workspace review surfaces usable across sessions
Workspace inspection now shares the same diff renderer between chat change cards and panel previews, supports scoped preview-tab closing, confirms checkpoint undo, resolves rewind checkpoints from the prompt cwd, and removes light-only workspace chrome so dark theme remains coherent.

Constraint: Workspace review must keep working for existing transcript sessions and non-git session-derived changes.
Rejected: Keep a separate chat diff preview | it drifted from panel rendering and dark theme behavior.
Confidence: high
Scope-risk: moderate
Directive: Keep chat and workspace diff rendering shared so theme and truncation behavior do not diverge again.
Tested: cd desktop && bun run test -- src/components/workspace/WorkspacePanel.test.tsx src/components/chat/MessageList.test.tsx src/stores/workspacePanelStore.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: bun test src/server/__tests__/sessions.test.ts
Tested: Browser dark workspace preview at http://127.0.0.1:59468/ with src/App.jsx diff
Not-tested: macOS packaged app build
2026-04-30 14:30:20 +08:00
程序员阿江(Relakkes)
339a06b281 fix: keep local workspace previews available
Workspace file preview is a local desktop surface, so image files should not be blocked by the text preview byte cap. Large text files now return a bounded preview instead of an unusable too-large state, while binary files remain explicitly unsupported.

Constraint: Avoid unbounded text payloads that can freeze the desktop renderer
Rejected: Remove all read limits | large generated files can still overload JSON transport and syntax rendering
Confidence: high
Scope-risk: moderate
Directive: Keep image preview detection before text-size limiting so local images remain renderable
Tested: bun test src/server/__tests__/workspace-service.test.ts
Tested: bun test src/server/__tests__/sessions.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test -- src/components/workspace/WorkspacePanel.test.tsx
Tested: cd desktop && bun run build
Not-tested: Full packaged macOS smoke after this commit
2026-04-30 00:35:26 +08:00
程序员阿江(Relakkes)
3a6f45d173 feat: make current turn changes reviewable and undoable
Workspace inspection was visible only as a side panel, while file restore still lived behind the older per-message rewind affordance. This adds a chat-flow change card for the completed turn, keeps undo routed through checkpoint rewind, and tightens the workspace split layout so narrow and fullscreen windows keep both chat and file preview usable.

Constraint: Current session file changes must work for non-Git directories when transcript tool edits are available
Constraint: Workspace preview must remain right-docked without horizontal overflow across narrow and wide desktop viewports
Rejected: Keep only hover rewind | users could not clearly see what the current turn changed before undoing it
Rejected: Use Git as the only changed-file source | many desktop sessions run in temporary or non-Git directories
Confidence: high
Scope-risk: moderate
Directive: Keep checkpoint rewind as the source of truth for undo semantics; workspace diffs are a preview surface, not the restore authority
Tested: bun test src/server/__tests__/sessions.test.ts src/server/__tests__/workspace-service.test.ts
Tested: cd desktop && bun run test -- src/components/chat/MessageList.test.tsx src/components/workspace/WorkspacePanel.test.tsx src/stores/workspacePanelStore.test.ts src/pages/ActiveSession.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: bun /tmp/cc-haha-layout-e2e/run-layout-e2e.mjs
Not-tested: Native Tauri packaged app window chrome behavior
2026-04-29 19:29:54 +08:00
程序员阿江(Relakkes)
b811ffb8f1 feat: make session workspace changes inspectable
Expose a workspace inspector for desktop sessions so users can browse the active project, preview files, inspect session-derived changes, and review diffs even when the work directory is not a git repository.

Constraint: The workspace view must work for temporary and non-git project directories.
Rejected: Rely only on git status | non-git sessions would lose the changed-files surface.
Confidence: medium
Scope-risk: moderate
Directive: Keep undo semantics separate from workspace browsing; checkpoint-backed rewind should remain the source of truth for rollback.
Tested: bun test src/server/__tests__/sessions.test.ts src/server/__tests__/workspace-service.test.ts
Tested: cd desktop && bun run test -- src/components/workspace/WorkspacePanel.test.tsx src/stores/workspacePanelStore.test.ts
Tested: cd desktop && bun run lint
Tested: git diff --check
Not-tested: Full desktop packaged app build after this commit
2026-04-29 17:28:53 +08:00
程序员阿江(Relakkes)
f57f163604 fix: prevent session inspector context stalls
Session inspection was coupling quick status and usage rendering to live context control requests, so a slow get_context_usage path could leave the desktop inspector stuck on a loading state. The desktop panel now loads basic inspection data first, renders a transcript-based context estimate immediately, and only asks for live context details as a background refinement.

The translation hook now returns a stable function per locale so effects that depend on translation do not reset and re-fetch after every render.

Constraint: Third-party provider sessions may not expose reliable live context capabilities through the control request path.
Rejected: Keep waiting on live get_context_usage for the context tab | it recreates the user-visible loading stall.
Rejected: Hardcode provider-specific context windows | provider capabilities are not always known from the desktop session record.
Confidence: high
Scope-risk: moderate
Directive: Do not make the inspector first render depend on live CLI control requests without a transcript or cached fallback.
Tested: bun test src/server/__tests__/conversations.test.ts -t "structured session inspection|Sonnet 4.6 transcript usage"
Tested: cd desktop && bun run test -- --run src/i18n/index.test.tsx
Tested: cd desktop && bun run build
Tested: git diff --check
Tested: agent-browser verified /context renders transcript estimate without Loading context data
Not-tested: Provider-specific true context-window discovery for every third-party vendor
2026-04-28 22:52:18 +08:00
程序员阿江(Relakkes)
165cb1777a fix: keep provider sessions on compatible model capabilities
Third-party Anthropic-compatible providers can expose Claude model names without supporting every first-party runtime capability. Desktop sessions now preserve provider-specific capability overrides, keep selected provider runtime state across reconnects and restarts, and keep the provider dialog behavior aligned with the updated presets.

Constraint: Custom ANTHROPIC_BASE_URL endpoints must not be treated as first-party Anthropic for adaptive thinking support.
Rejected: Rename provider default Sonnet models | that would hide the compatibility issue instead of fixing runtime capability detection.
Confidence: high
Scope-risk: moderate
Directive: Do not enable Claude first-party capability defaults for custom Anthropic-compatible base URLs without provider verification.
Tested: bun test src/utils/__tests__/thinking.test.ts src/server/__tests__/conversation-service.test.ts src/server/__tests__/provider-presets.test.ts src/server/__tests__/conversations.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test src/components/shared/Modal.test.tsx --run
Tested: git diff --check
2026-04-28 17:35:56 +08:00
程序员阿江(Relakkes)
5e9303fe44 feat: tighten provider settings and support links
Provider setup now keeps API keys hidden by default while still allowing an explicit reveal, and the About page links users directly to release notes and issue feedback. Provider preset copy was also adjusted so promotional text stays intentional and current.

Constraint: Reuse the existing settings page structure and provider preset schema
Confidence: high
Scope-risk: moderate
Reversibility: clean
Tested: cd desktop && bun run test -- generalSettings.test.tsx
Not-tested: Full desktop lint and production build
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
3fc7200eb2 feat: help users configure sponsored and local providers without guesswork
Provider setup now carries the metadata needed for sponsored and local Anthropic-compatible providers, while keeping provider URLs and API keys editable in the desktop form. The desktop UI also exposes API-key links, optional sponsor copy, full key visibility, and local no-key presets that can be activated into runtime settings.

Constraint: Local LM Studio and Ollama integrations require Anthropic-compatible root URLs rather than OpenAI /v1 URLs
Rejected: Keep local providers at the top of the preset list | user requested them immediately before Custom
Confidence: high
Scope-risk: moderate
Directive: Do not change local provider base URLs to /v1 without rechecking Anthropic compatibility docs
Tested: bun test src/server/__tests__/provider-presets.test.ts src/server/__tests__/providers.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test src/__tests__/generalSettings.test.tsx --run
Tested: git diff --cached --check
Tested: Web UI provider creation plus real sessions for LM Studio, Ollama, JiekouAI, and Shengsuanyun
Not-tested: Production packaged Tauri build
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
3d3dfdad76 feat: Keep terminal workflows inside desktop tabs
The desktop terminal already supported independent PTY sessions, but it only lived inside settings. This change promotes it to a first-class tab workflow so users can open multiple host terminals without leaving the chat-oriented desktop layout.

Constraint: Tauri terminal sessions are process-backed and must stay mounted while switching tabs.
Rejected: Reuse the settings terminal as a navigated page only | it cannot support multiple independent terminal tabs.
Rejected: Hide inactive xterm panes with display none | xterm lost visible output after tab switches during E2E.
Confidence: high
Scope-risk: moderate
Directive: Keep inactive terminal panes mounted and avoid display none unless xterm repaint behavior is reverified.
Tested: bun run test src/components/layout/ContentRouter.test.tsx src/components/layout/Sidebar.test.tsx src/components/layout/TabBar.test.tsx src/pages/TerminalSettings.test.tsx
Tested: bun run lint
Tested: bun run build
Tested: ./scripts/build-macos-arm64.sh
Tested: Computer Use E2E against build-artifacts/macos-arm64 app for multiple terminals, command output retention, tab switching, and terminal cleanup
Not-tested: Intel macOS package
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
e0abea6c46 fix: Keep subagent tool activity nested in desktop transcripts
Subagent transcripts are stored in sidecar JSONL files, so the desktop history loader now links completed Agent results back to their sidecar tool activity and namespaces child tool ids before rendering. The chat renderer then keeps parented tool calls and orphaned child results out of the root session stream, while the Agent result preview strips runtime metadata from the user-facing answer.

Constraint: Subagent tool activity may live under ~/.claude/projects/{project}/{session}/subagents instead of the main session JSONL
Rejected: Rely only on adjacent message ordering | interleaved messages can split parent and child tool activity
Rejected: Show final Agent output inside the expanded card | expanded cards should show process activity while the modal shows the final answer
Confidence: high
Scope-risk: moderate
Directive: Do not remove child tool id namespacing without proving multiple subagents cannot emit colliding tool ids
Tested: bun test src/server/__tests__/sessions.test.ts
Tested: cd desktop && bun run test -- MessageList.test.tsx chatStore.test.ts
Tested: cd desktop && bun run lint
Tested: agent-browser E2E with two dispatched subagents in /tmp/cc-haha-agent-e2e-q4Xm2s
Not-tested: Live streaming of sidecar subagent tool activity before the sidecar file is persisted
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
628c4e16f9 feat: support ESC key to close slash command panels 2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
e1474b5c30 Improve dark model selection contrast
The model selector reused the light-theme primary fixed surface for selected rows, which made dark mode render a pale block with poor text contrast. This gives the selector its own selected-row tokens so dark mode can keep a low-luminance surface while light mode preserves the existing look.

Constraint: Keep the fix scoped to desktop theme tokens and the existing selector component
Rejected: Change primary-fixed globally | too broad because other components rely on that token semantics
Confidence: high
Scope-risk: narrow
Directive: Do not point selected model rows back to primary-fixed without checking dark-mode contrast
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: git diff --check
Not-tested: Browser screenshot capture blocked by an existing Chrome DevTools profile instance
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
91a28d949f Restore context percentages in the desktop inspector
The context tab needs both absolute token counts and percent-of-window values to stay scannable. Category rows now show the percent next to each token count, and the free-space summary card also reports remaining percent.

Constraint: Keep the compact terminal-inspired layout while restoring the numeric detail users rely on.

Confidence: high

Scope-risk: narrow

Tested: cd desktop && bun run lint

Tested: git diff --check

Tested: agent-browser smoke test on http://127.0.0.1:2024/ for /context percentages

Not-tested: Packaged Tauri build.
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
b4142c8221 Make desktop slash commands useful outside the terminal
Desktop slash commands now separate local UI panels from CLI turn execution. The session inspector exposes status, usage, and context data from the active session, including transcript and context fallbacks, so /status, /cost, and /context can render structured desktop UI instead of raw terminal text. The inspector and help surfaces now use the existing desktop i18n catalogs for English and Chinese labels.

Constraint: Desktop read-only slash commands must not spawn duplicate CLI processes or depend on submitting a normal user turn.

Rejected: Render raw CLI command text in chat | it keeps terminal-specific layout constraints and does not fit the desktop panel UX.

Confidence: high

Scope-risk: moderate

Directive: Keep /status, /cost, and /context routed through the local inspector unless the CLI exposes a structured interactive command protocol.

Tested: cd desktop && bun run lint

Tested: cd desktop && bun test src/components/chat/composerUtils.test.ts

Tested: bun test src/server/__tests__/conversations.test.ts

Tested: cd desktop && bun run build

Tested: agent-browser smoke test on http://127.0.0.1:2024/ for /context localized inspector

Tested: git diff --check

Not-tested: Full packaged Tauri desktop build.
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
bc93493ed1 Prevent desktop rewind from trimming the wrong turn
Desktop rewind previously used the visible user-message index as the primary selector. That can drift from the persisted active chain when hidden or non-rendered user messages exist, so the API now prefers a stable user message id and checks the selected prompt text before mutating transcript or files.

Constraint: Desktop UI can hide transcript entries that still exist in the persisted session chain
Rejected: Keep index-only rewind | can target an earlier user message after UI/server chain drift
Confidence: high
Scope-risk: moderate
Directive: Do not remove targetUserMessageId or expectedContent guards without reproducing shifted visible-index sessions
Tested: bun test src/server/__tests__/sessions.test.ts --timeout 20000
Tested: cd desktop && bun run test MessageList.test.tsx chatStore.test.ts -- --run
Tested: desktop/scripts/e2e-rewind-agent-browser.sh
Tested: desktop/scripts/e2e-rewind-complex-agent-browser.sh
Not-tested: Full desktop Vitest suite still has unrelated locale-sensitive failures
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
1631c449f6 fix: tighten desktop slash command edge cases
Desktop slash command handling needed a few follow-up guards after adding
CLI parity. Bare /clear remains a local desktop reset, but /clear with
arguments is rejected instead of silently discarding user text. Clear also
resets cached slash commands, compact boundaries preserve CLI-provided text,
and the help panel now discloses when the More section is truncated.

Constraint: Preserve the desktop /clear fast path without accepting accidental arguments
Rejected: Let /clear arguments fall through to the CLI | the CLI command still clears context and would keep the footgun
Confidence: high
Scope-risk: narrow
Directive: Keep desktop-local slash command guards in sync with CLI command argument semantics
Tested: cd desktop && bun run test src/stores/chatStore.test.ts src/__tests__/pages.test.tsx --run -t "clears local desktop chat state|ActiveSession routes /help"
Tested: bun test src/server/__tests__/conversations.test.ts
Tested: cd desktop && bun run lint
Tested: git diff --check
Not-tested: Full pages.test.tsx because unrelated locale-sensitive assertions are already present in that file
2026-04-28 16:38:16 +08:00
程序员阿江(Relakkes)
caa164b62c fix: make desktop slash commands behave like the CLI
Desktop had no reliable handling for common local slash commands, so
commands like /clear, /help, /context, /cost, and /compact either looked
unresponsive or lost their CLI-specific side effects. This routes desktop
commands by behavior: local panels stay local, stateful clear resets the
session transcript, and CLI-local outputs are rendered in chat.

Constraint: Preserve existing CLI semantics for prompt, local, local-jsx, and compact slash commands
Rejected: Send every slash command through the normal chat path | local commands need desktop UI or session state side effects
Confidence: high
Scope-risk: moderate
Directive: Keep hidden aliases such as /plugins out of the visible command list unless they become canonical CLI commands
Tested: cd desktop && bun run test src/components/chat/composerUtils.test.ts src/stores/chatStore.test.ts --run
Tested: cd desktop && bun run test src/__tests__/pages.test.tsx --run -t "ActiveSession routes /plugin|ActiveSession routes /help|EmptySession slash picker includes dynamic skills"
Tested: bun test src/server/__tests__/conversations.test.ts
Tested: cd desktop && bun run lint
Tested: agent-browser E2E for /help, /plugin, /plugins, /cost, /clear, /context, /compact, /mcp, and normal text input
Not-tested: Root tsc project because it currently includes generated Tauri target assets and extracted native files
2026-04-28 16:38:16 +08:00
Relakkes Yang
2961a49fc3 fix: show desktop server startup diagnostics 2026-04-27 10:40:50 +08:00
Relakkes Yang
e63db20136 fix: respect manual chat scroll position 2026-04-25 13:59:22 +08:00
Relakkes Yang
f911d9e79d fix: suppress mermaid error overlay 2026-04-25 13:24:26 +08:00
Relakkes Yang
55c5958b55 fix(desktop): stop sidecars before updater install 2026-04-25 13:21:31 +08:00
Relakkes Yang
928be2a4ff fix(desktop): remove install center 2026-04-24 23:05:45 +08:00
程序员阿江(Relakkes)
761031c036 fix: Make desktop MCP tools ready before first turn
Desktop sessions could show MCP configuration in the UI while the CLI SDK child process still started cold on the first user message. Start eligible desktop chat sessions as soon as their websocket is connected, keep init metadata cached but muted, and wait briefly for MCP startup in SDK print mode so turn one sees the tools.

Constraint: Desktop wraps the existing CLI SDK bridge rather than owning MCP startup directly.
Rejected: Prewarm every restored tab | synthetic tabs such as settings would start unnecessary CLI subprocesses.
Confidence: high
Scope-risk: moderate
Directive: Do not remove the synthetic-tab guard without validating restored settings and scheduled-task tabs in the browser.
Tested: bun test src/server/__tests__/conversations.test.ts src/server/__tests__/conversation-service.test.ts src/server/__tests__/mcp.test.ts
Tested: cd desktop && bun run test -- chatStore.test.ts mcpSettings.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: agent-browser E2E new session prewarm plus first message reuse with mock CLI
Not-tested: Full desktop Vitest suite still has pre-existing English-vs-Chinese copy assertion failures.
2026-04-24 17:11:03 +08:00
程序员阿江(Relakkes)
77d2cbfab8 fix: Prevent plugin detail hook mismatch during reload
Plugin actions refresh the selected plugin detail after mutating enabled state. The detail component can enter its loading branch while a plugin is still selected, so every hook must run before that early return.

Constraint: React hook order must stay identical across the detail and loading render paths.
Rejected: Clear the selected plugin before reload | would hide the current context and add UI churn during short refreshes.
Confidence: high
Scope-risk: narrow
Directive: Keep PluginDetail hooks before loading and empty-state returns when adding detail-derived memoization.
Tested: cd desktop && bun run test src/__tests__/pluginsSettings.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Not-tested: Full desktop Vitest suite has pre-existing locale assertion failures unrelated to this plugin fix.
2026-04-24 14:47:17 +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)
f911b16ada Merge host terminal support into post-release test branch
The detached worktree implementation adds a Settings terminal for command-based setup flows. The merge keeps the target branch's current adapter/runtime dependencies while adding the new portable-pty backend, xterm frontend, UTF-8 output handling, and host-shell environment propagation.

Constraint: Target branch had newer desktop dependency changes, including anyhow in the Tauri crate.
Constraint: Existing uncommitted work in the main worktree had to stay out of this merge commit.
Rejected: Fast-forward the checked-out branch under a dirty worktree | would risk mixing unrelated local changes into the branch state.
Confidence: high
Scope-risk: moderate
Directive: Treat the terminal as host-shell integration; keep PATH and UTF-8 locale handling together when changing startup behavior.
Tested: cargo fmt --check
Tested: cargo test --lib
Tested: cargo check
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test src/pages/TerminalSettings.test.tsx
Tested: git diff --check
Not-tested: Rebuilt macOS DMG from the target branch after merge.
2026-04-24 09:38:02 +08:00
程序员阿江(Relakkes)
0c58a9f36f Give desktop users a real terminal for command-based setup
Some setup flows end in a shell command instead of a natural-language install path, so Settings now exposes a host PTY terminal backed by portable-pty and xterm. The terminal inherits the user's login-shell environment, forces a UTF-8 locale when needed, and preserves split UTF-8 output so Chinese paths render correctly.

Constraint: Desktop GUI apps do not inherit the user's interactive shell PATH on macOS.
Constraint: Command output may split UTF-8 characters across PTY reads.
Rejected: Use Tauri shell commands only | users need an interactive PTY for copy-pasted install flows.
Rejected: Ask users to edit shell profiles | terminal setup should work out of the box.
Confidence: high
Scope-risk: moderate
Directive: Keep terminal startup tied to host environment checks; do not bundle runtimes to solve PATH issues.
Tested: cargo fmt --check; cargo test --lib; cargo check; cd desktop && bun run lint; cd desktop && bun run test src/pages/TerminalSettings.test.tsx; cd desktop && bun run build; cd desktop && bun run build:macos-arm64
Tested: Computer Use verified npm is available in the built macOS app terminal and Chinese output renders after UTF-8 decoding fix.
Not-tested: Native Windows/Linux package runtime validation.
2026-04-24 09:36:00 +08:00
程序员阿江(Relakkes)
773a8a703f Keep desktop chats on the selected provider/model
The desktop model picker now stores a session-scoped provider/model selection instead of relying on the global active provider. That selection is replayed on connect, passed into the CLI startup path, and preserved across turns until the user changes it again.

To make that true end-to-end, the server now restarts the session process when runtime selection changes, injects provider-scoped env for third-party providers, and routes proxy traffic by provider id. The selector UI was also tightened so provider grouping stays visible while the actual model choice remains readable.

Constraint: Different providers can expose the same model id, so chat runtime selection cannot be derived from model id alone
Constraint: A desktop session reuses one CLI subprocess across turns, so runtime changes must restart that process to take effect
Rejected: Keep using Settings active provider as the chat selector | conflates defaults with live session state and breaks overlapping models
Rejected: UI-only runtime switching without server restart | later turns would continue using the old CLI subprocess configuration
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep provider defaults and session runtime overrides separate, and preserve provider-scoped proxy routing when extending model selection surfaces
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test src/stores/chatStore.test.ts
Tested: cd desktop && bun run test src/__tests__/generalSettings.test.tsx
Tested: bun test src/server/__tests__/conversation-service.test.ts
Tested: bun test src/server/__tests__/conversations.test.ts
Tested: bun -e "await import('./src/server/services/titleService.ts'); await import('./src/server/ws/handler.ts')"
Not-tested: Real third-party provider round-trip from the desktop UI against a live upstream account
2026-04-23 13:41:27 +08:00
程序员阿江(Relakkes)
1137c99d5c Clarify how to use shared CLI install commands after desktop setup
The Install Center now spells out the two supported terminal flows after the
bundled launcher is available: keep using `claude` when the official Claude
Code CLI is already installed, or use `claude-haha` otherwise. It also shows
copyable example commands so users understand that Skills, Plugins, and MCP
configuration is shared between both command names.

Constraint: The worktree contains unrelated icon, provider-label, and other UI edits, so this commit stages only the Install Center hint copy and its focused test
Rejected: Leave the launcher status card without command guidance | users would still not know when to use `claude` versus `claude-haha`
Rejected: Duplicate the same explanation in a new settings section | it adds UI weight without improving discoverability over the existing CLI card
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep the examples aligned with the real supported command surface; if launcher behavior changes, update both zh/en copy and the InstallCenter test together
Tested: cd desktop && bun x vitest run src/components/settings/InstallCenter.test.tsx; cd desktop && bun run lint
Not-tested: Full desktop production build and manual Settings page click-through after this copy-only follow-up
2026-04-23 12:51:17 +08:00
程序员阿江(Relakkes)
5fea7033e3 Expose the bundled desktop CLI outside the app
The desktop app already shipped a bundled sidecar, but only desktop-managed
sessions could see it. This change installs a `claude-haha` launcher into the
user bin directory, wires PATH setup so new terminals can resolve it, and keeps
desktop installer sessions aligned on the same bundled sidecar resolution path.
The desktop install surface now also reports whether the launcher is ready or
still waiting on a terminal restart.

Constraint: The worktree already contains unrelated icon, docs, and UI changes, so this commit stages only the bundled CLI launcher slice
Rejected: Tell users to install the official Claude CLI separately | it breaks the desktop out-of-box install story
Rejected: Keep the bundled CLI reachable only inside desktop-managed shells | system terminals would still be unable to call the packaged runtime
Rejected: Symlink directly into the app bundle instead of copying to user bin | moving or replacing the app bundle would leave a stale launcher behind
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Proxy-backed non-Anthropic providers still depend on the desktop server; do not assume this launcher makes every provider fully standalone
Tested: bun test src/server/__tests__/desktop-cli-launcher.test.ts src/server/__tests__/settings.test.ts; bun test src/server/__tests__/conversation-service.test.ts; bun test src/utils/shell/bashProvider.test.ts; cd desktop && bun x vitest run sidecars/launcherRouting.test.ts src/components/settings/InstallCenter.test.tsx; cd desktop && bun run lint; cd desktop && bun run build; cargo check --manifest-path desktop/src-tauri/Cargo.toml
Not-tested: Manual packaged desktop app install plus real Terminal/iTerm/PowerShell invocation on fresh macOS and Windows machines
2026-04-23 12:12:49 +08:00
程序员阿江(Relakkes)
90c3db1790 Prevent task-progress updates from corrupting streamed reply formatting
Desktop chat currently reuses one status channel for assistant streaming and
background task progress. When a task update arrived mid-turn, the store
flushed the in-flight markdown into a completed message, which caused the
remaining deltas to render as a second bubble and broke markdown styling.

Keep the reply in streaming state until the turn actually becomes idle, and
lock the behavior with a regression test that injects task progress between
text deltas.

Constraint: Background task progress currently shares the same status channel as assistant streaming
Rejected: Retune markdown renderer styles | would hide the symptom without preserving message integrity
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Do not flush streaming assistant text on non-idle status transitions unless the turn is actually ending
Tested: bun run test src/stores/chatStore.test.ts; bun run lint
Not-tested: Manual desktop UI verification with a live agent session
2026-04-23 12:11:30 +08:00