111 Commits

Author SHA1 Message Date
程序员阿江(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)
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)
10b974dac3 Merge commit 'df52bea0d0cb5889f9c5e324c54f2bdce9e30378' 2026-05-01 17:19:31 +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)
df52bea0d0 Merge branch 'main' into HEAD 2026-05-01 00:23:36 +08:00
程序员阿江(Relakkes)
dcf844b7e7 fix: keep old desktop sessions usable after provider changes
Desktop sessions can carry persisted runtime provider selections long after the provider index changes. The server now validates those session-level and active provider ids before launching the CLI, falls back to a valid default path, and includes non-secret launch diagnostics in startup failure messages so future issue reports expose the server-side context.

Constraint: Desktop users often report only the visible chat error, not sidecar console logs
Rejected: Frontend-only cleanup of stale localStorage selections | does not protect API or reconnect paths and loses server-side evidence
Confidence: high
Scope-risk: narrow
Directive: Do not pass session-scoped provider ids into CLI startup without validating they still exist in providers.json
Tested: bun test src/server/__tests__/conversations.test.ts
Tested: bun test src/server/__tests__/providers.test.ts
Tested: bun test src/server/__tests__/conversation-service.test.ts
2026-05-01 00:10:00 +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)
0508277998 fix: keep inspector context responsive
The session inspector now asks the resumed CLI for a fast structural context estimate instead of forcing the full token-counting API path. This preserves live CLI state for system prompt, tools, MCP tools, skills, and messages while avoiding the 20s timeout that made historical sessions appear stuck or fall back to transcript-only estimates.

Constraint: Inspector requests must return quickly for third-party providers and historical resumed sessions.

Rejected: Increase the server timeout | the slow path can still block on provider token counting and keeps the UI feeling broken.

Confidence: high

Scope-risk: narrow

Directive: Keep interactive inspector context on the estimateOnly control path unless the UI explicitly supports a slow precise refresh.

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: direct /api/sessions/:id/inspection?includeContext=1 returned live context in 0.046867s with System prompt, System tools, MCP tools, Messages

Tested: agent-browser automation verified no loading/error and visible System prompt/System tools/MCP tools/Messages

Not-tested: bare root tsc --noEmit, because current tsconfig scans existing desktop/src-tauri/target generated binary assets unrelated to this change
2026-04-28 23:05:52 +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)
15c0982159 fix: keep desktop sessions on active provider runtime
Default desktop sessions with an active third-party provider were only passing the selected model into the CLI startup path. That allowed the child CLI to fall back to stale cc-haha settings env instead of the provider index, so the UI-selected provider could diverge from the key and endpoint used by the subprocess.

Route default sessions through the active provider id and make third-party Sonnet capability overrides explicit with a non-empty sentinel. This keeps provider runtime env sourced from providers.json and avoids treating third-party Sonnet models as first-party thinking-capable models.

Constraint: Third-party provider behavior is the product baseline for desktop users.

Rejected: Rely on synced cc-haha/settings.json env | it can be stale and caused provider/key routing mismatches.

Confidence: high

Scope-risk: narrow

Directive: Third-party desktop sessions must carry providerId into ConversationService; do not depend on global settings env for active providers.

Tested: bun test src/server/__tests__/conversations.test.ts src/server/__tests__/conversation-service.test.ts src/server/__tests__/provider-presets.test.ts src/utils/__tests__/thinking.test.ts

Tested: git diff --check
2026-04-28 18:45:41 +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)
736bce8ac1 fix: Update Kimi preset to coding endpoint
Kimi Code documents a separate Anthropic-compatible coding endpoint from the Moonshot open platform, so the built-in Kimi preset should point Claude-compatible traffic at the coding endpoint instead of the retired Moonshot anthropic path.

Constraint: Kimi Code Anthropic-compatible base URL is https://api.kimi.com/coding/ and this app appends /v1/messages at runtime.
Rejected: Use https://api.moonshot.cn/coding | official Kimi docs distinguish Kimi Code from the Moonshot open platform URLs.
Confidence: high
Scope-risk: narrow
Directive: Do not switch Kimi back to api.moonshot.cn/anthropic without rechecking current Kimi Code docs.
Tested: bun test src/server/__tests__/provider-presets.test.ts
Not-tested: Live Kimi API call with a real user key
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)
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)
664c6ebd9f Prevent desktop turns from hanging after CLI exits
A desktop session can pass the startup grace window and then lose its CLI subprocess before a result arrives. Previously that path only deleted the active process record, leaving the WebSocket client in an active turn with no terminal message. The process-exit handler now emits a synthetic CLI error result through the existing translation path so the UI receives both an error and message_complete. The mock SDK fixture can reproduce post-startup exits, and the integration test locks the terminal event behavior.

Constraint: The frontend already relies on result is_error translation to emit error plus message_complete.

Rejected: Add a separate WebSocket process-exit message type | it would duplicate existing result-error handling and require another frontend state path.

Confidence: high

Scope-risk: narrow

Directive: Keep process-exit failures on the same result-error path unless the client protocol gains a dedicated terminal error event.

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

Tested: cd desktop && bun run lint

Tested: agent-browser against http://127.0.0.1:1421 with mock CLI late exit; page showed CLI process exited unexpectedly and composer became editable again
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
869aeb0e77 fix: honor session model for provider runtime 2026-04-27 10:57:25 +08:00
Relakkes Yang
55c11b481b fix(server): preload macros for Windows dev CLI 2026-04-25 13:58:02 +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)
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)
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)
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)
467debcd8b feat: add a desktop setup terminal without blocking shell restarts
The desktop Settings flow needed a real shell for bundled CLI setup, but the
restart path could hang behind old PTY teardown. Wire an xterm.js panel to a
portable-pty backend, inject the bundled CLI into the shell bootstrap, and
switch to the new session before cleaning up the previous one so restart work
stays off the frontend critical path.

Constraint: The desktop app must ship its own CLI entrypoint instead of depending on a global Claude install
Constraint: PTY teardown must not block the Tauri invoke path
Rejected: Reuse the install chat for arbitrary shell commands | it does not provide a real interactive PTY
Rejected: Close the old PTY before adopting the new session | it keeps restart vulnerable to hung child shutdown
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep PTY teardown off the invoke path and preserve session handoff ordering when changing terminal lifecycle code
Tested: bunx vitest run src/__tests__/terminalPanel.test.tsx src/components/settings/TerminalPanel.restart.test.tsx; bun run lint; cargo check
Not-tested: End-to-end command echo inside the packaged desktop terminal still needs follow-up runtime verification
2026-04-22 18:06:29 +08:00
程序员阿江(Relakkes)
d8a44c0a54 Stop provider model selection from inheriting global Claude settings
The desktop provider flow was still mixing provider-managed state with
`~/.claude/settings.json`, which let unrelated tools leak fields like
`ANTHROPIC_REASONING_MODEL` and `model` back into the active provider path.
This change moves the provider JSON editor onto `~/.claude/cc-haha/settings.json`,
routes provider settings through dedicated `/api/providers/settings` endpoints,
and makes model reads/writes under an active provider use the managed cc-haha
settings instead of the global user settings file.

Constraint: Active provider model selection must be isolated from legacy ~/.claude/settings.json
Rejected: Keep merging provider JSON with settingsApi.getUser() | external tools can reintroduce unrelated model fields into the provider flow
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Any future provider-model UI or runtime change should read/write cc-haha managed settings first, not the global user settings file
Tested: bun test src/server/__tests__/provider-presets.test.ts src/server/__tests__/settings.test.ts; cd desktop && bun run lint
Not-tested: Manual desktop provider modal interaction after the cc-haha settings API switch
2026-04-22 17:19:12 +08:00
程序员阿江(Relakkes)
e0142b286b Keep built-in provider presets aligned with vendor-supported model IDs
The provider picker had two separate preset definitions and some defaults had
started to drift from the model IDs vendors document for Claude Code /
Anthropic-compatible usage. This change moves built-in presets to one
server-side JSON source, serves that source through the existing presets API,
and makes the desktop settings page consume the API instead of a duplicated
frontend constant. The preset defaults were then corrected against vendor docs
so the built-in values match documented model IDs and casing.

Constraint: Built-in provider defaults must match official vendor Claude Code or Anthropic docs
Rejected: Keep duplicated frontend and backend preset lists | values and casing drifted independently
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Update src/server/config/providerPresets.json and rerun provider-presets tests before changing built-in provider defaults again
Tested: bun test src/server/__tests__/provider-presets.test.ts; cd desktop && bun run lint
Not-tested: Manual desktop settings UI interaction after fetching presets from the API
2026-04-22 17:06:35 +08:00
程序员阿江(Relakkes)
49e1367659 fix: avoid blocking MCP list on live health checks
Desktop MCP settings was synchronously probing every configured server from /api/mcp, which made the list page scale with connection latency and surface brittle behavior as installs accumulated more MCPs. Return lightweight snapshot rows from the list API, keep explicit status checks separate, and let the desktop UI refresh status in a constrained background lane while preserving project-aware server identity.

Constraint: MCP list must stay responsive even with many configured servers
Rejected: Probe all servers from the list view without limits | still fans out with server count and can overload slow installs
Rejected: Keep servers permanently unchecked until detail view | misses the desired loading feedback when the MCP page opens
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep /api/mcp as a configuration snapshot endpoint; do not reintroduce per-row live connect work on list load
Tested: bun test src/server/__tests__/mcp.test.ts; cd desktop && bun run test -- mcpSettings.test.tsx; cd desktop && bun x tsc --noEmit --ignoreDeprecations 5.0
Not-tested: Real desktop interaction against an environment with dozens of live MCP servers
2026-04-22 15:34:36 +08:00
Relakkes Yang
4bc6e135dd fix: restore computer use setup for python 3.8 2026-04-22 14:28:36 +08:00
程序员阿江(Relakkes)
de736c49f7 Unify plugin capabilities with the desktop management views
Desktop plugin details now route into the shared Skills, Agents, and MCP management surfaces instead of maintaining separate read-only drilldowns. This also extends the desktop/server skill aggregation so plugin-provided skills appear in the shared list, groups MCP entries by source, and preserves detail-view back navigation based on where the user entered the page.

The implementation keeps plugin detail as the high-level capability hub while pushing real inspection into the existing management pages. Disabled plugins no longer expose false navigation paths into shared views, and the agent-browser regression script was expanded to exercise the new end-to-end flows.

Constraint: Shared Agents data only includes enabled plugin agents, so disabled plugins cannot deep-link into agent detail
Rejected: Keep duplicating full Skills/Agents/MCP detail inside Plugin detail | creates divergent UI flows and stale data paths
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: If a detail view can be opened from multiple entry points, keep the return target in store state rather than hardcoding a single back destination
Tested: desktop vitest for plugins/skills/agents/mcp; desktop tsc --noEmit; desktop vite build; server skills API test; agent-browser web regression on plugin->skill/mcp and plugin->agent back navigation
Not-tested: packaged desktop app regression after rebuilding the Tauri bundle
2026-04-22 12:31:57 +08:00
程序员阿江(Relakkes)
6c02904e58 Keep slash-command entry surfaces aligned with MCP desktop management
Merged the desktop MCP management work into local main and retained
existing plugin settings affordances while resolving router and settings-tab
conflicts. The resulting flow keeps MCP settings global-only for speed and
uses slash-command cards to route users into concrete MCP or skill targets.

Constraint: local main already had plugin settings and API routes that had to remain available
Rejected: Favor the worktree version wholesale during merge | would have dropped local plugin tab and router support on main
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep slash-command entry flows and settings tabs additive during future merges; do not collapse MCP and plugin navigation into one another
Tested: Conflict resolution review during merge; source commit 66edded validated with bun test src/server/__tests__/mcp.test.ts; cd desktop && bun run test -- pages.test.tsx mcpSettings.test.tsx; cd desktop && bun x tsc --noEmit --ignoreDeprecations 5.0
Not-tested: Re-running full desktop/manual verification from the merged main worktree after merge completion
Related: 66edded
2026-04-21 23:29:11 +08:00
程序员阿江(Relakkes)
66edded2d7 Make desktop MCP management and slash entry points directly operable
Desktop MCP management now has a working server API, a global-only settings surface,
and slash-command entry points that surface MCP and skills from the composer before
routing users into the right settings view.

Constraint: Project-scoped MCP browsing in settings was too slow and noisy because it scanned multiple workdirs
Rejected: Keep project MCP aggregation on the settings homepage | duplicated entries and poor responsiveness
Rejected: Route /mcp directly on Enter without an intermediate card | removed the user's ability to choose a specific target first
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep settings focused on global MCP; add project-scoped MCP affordances in the chat-context slash surfaces instead of re-expanding the settings homepage
Tested: bun test src/server/__tests__/mcp.test.ts; cd desktop && bun run test -- pages.test.tsx mcpSettings.test.tsx; cd desktop && bun x tsc --noEmit --ignoreDeprecations 5.0
Not-tested: Manual IAB verification after this final commit/merge cycle
2026-04-21 23:28:06 +08:00
程序员阿江(Relakkes)
89911bd6bf Merge commit '375d587' 2026-04-21 23:21:25 +08:00
程序员阿江(Relakkes)
375d587ed1 Expose desktop plugin management through first-class APIs
The desktop app could read plugin-produced skills and agents, but it had no
plugin control plane of its own. This adds a dedicated Settings tab backed by
server-side plugin APIs so installed plugins can be inspected, enabled,
disabled, updated, reloaded, and uninstalled from the WebUI.

The implementation also teaches browser-based desktop dev sessions to honor a
custom backend URL, which made it possible to run isolated worktree ports for
real UI automation. During verification, the long-lived desktop server kept a
stale installed-plugin snapshot after external CLI mutations, so cache clearing
now resets that session-level plugin installation state as well.

Constraint: Desktop WebUI needed an isolated backend URL instead of the hard-coded 127.0.0.1:3456 fallback
Constraint: Reuse existing plugin operations and loaders instead of rebuilding plugin lifecycle logic in the desktop layer
Rejected: Fold plugin management into Skills or Adapters | mixed unrelated lifecycles and hid plugin-specific health/actions
Rejected: Expose only read-only plugin status in desktop | did not satisfy enable-disable-reload-uninstall verification needs
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep desktop plugin actions routed through the shared plugin operation layer and clear installed-plugin session caches when plugin state changes externally
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test -- src/__tests__/pluginsSettings.test.tsx
Tested: bun test src/server/__tests__/plugins.test.ts src/server/__tests__/skills.test.ts
Tested: Browser automation against isolated ports 15120/38456 covering discord plugin list/detail/disable/apply/enable/update/uninstall flows
Not-tested: Full desktop session runtime parity with CLI /reload-plugins AppState refresh beyond the new desktop API path
2026-04-21 23:21:16 +08:00
程序员阿江(Relakkes)
044e9b6cc8 Make desktop rewind restore both transcript state and file checkpoints
The desktop client already had a conversation-level rewind UI concept on the
CLI side, but the web/desktop surface lacked the protocol, session trimming,
and file checkpoint restore path needed to make rewind trustworthy. This change
adds a desktop-specific rewind API, wires the message-level UI affordance and
confirmation modal, enables SDK file checkpointing for desktop sessions, and
covers the restore path with service tests plus a real agent-browser workflow.

Constraint: Desktop sessions run the CLI in SDK/print mode, so file checkpointing had to be enabled explicitly for that path
Constraint: main branch is checked out in a separate worktree, so merge-back must happen from the primary worktree after commit
Rejected: UI-only rewind that only trims local state | would leave persisted transcript and disk state inconsistent after refresh
Rejected: Reuse getLastSessionLog as the sole snapshot source | active rewind must read file-history metadata directly from the session file
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep desktop rewind keyed to persisted user-message order unless the UI model starts carrying stable transcript UUIDs end-to-end
Tested: bun test src/server/__tests__/conversation-service.test.ts src/server/__tests__/sessions.test.ts; desktop MessageList vitest; desktop tsc no-emit; live agent-browser E2E on isolated ports with file edit then rewind
Not-tested: Browser E2E matrix for multi-file and second-edit scenarios is still covered at service-test level rather than full UI level
2026-04-21 21:34:41 +08:00
程序员阿江(Relakkes)
5377eb596f Keep desktop session history and reconnect recovery trustworthy
Desktop session interruptions were leaving two different classes of stale UI
artifacts behind: reconnects could silently lose in-flight output, and history
reloads could replay synthetic interruption or internal command breadcrumbs as
if they were user-facing transcript content. This change rebinds active session
output to the latest client websocket on reconnect, preserves queued outbound
messages across transient disconnects, and filters synthetic transcript entries
before they reach the desktop history API so reloads reconstruct only the
messages users should actually see.

Constraint: Desktop transcript history is shared with CLI JSONL files and must stay compatible with persisted message shapes
Rejected: Hide these artifacts only in React renderers | other transcript consumers would still receive polluted history
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep transcript filtering aligned with real synthetic/internal message shapes before adding new hidden message types
Tested: bun test src/server/__tests__/sessions.test.ts
Tested: bun test src/server/__tests__/conversations.test.ts
Tested: cd /Users/nanmi/.codex/worktrees/e7ac/claude-code-haha/desktop && bun run test -- websocket.test.ts
Tested: cd /Users/nanmi/.codex/worktrees/e7ac/claude-code-haha/desktop && bun run lint
Not-tested: Manual browser verification of the refreshed session transcript after interrupt on this exact session
2026-04-21 17:55:15 +08:00
程序员阿江(Relakkes)
16d716e773 fix: keep completed task lists from leaking into the next turn
Completed desktop task bars were only being dismissed locally, which let the
persisted task list resurface on refresh or bleed into the next user turn.
This wires the existing server-side reset path into the desktop stores and
session flow so a finished task cycle is summarized once, cleared locally,
and removed remotely before the next round starts.

Constraint: Existing task persistence already lives behind the server task-list API and must stay compatible with persisted JSON task files
Rejected: Only hide the completed task bar in UI state | left stale persisted tasks behind and reintroduced them on reload
Rejected: Clear desktop state without a task summary | dropped useful completion context from the chat transcript
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep desktop task dismissal and task-list persistence behavior aligned; do not reintroduce local-only clearing without covering reload and next-turn flows
Tested: `cd desktop && bun run lint`
Tested: `cd desktop && bun run test src/stores/cliTaskStore.test.ts src/stores/chatStore.test.ts src/components/chat/SessionTaskBar.test.tsx src/components/chat/ComputerUsePermissionModal.test.tsx`
Tested: `bun test src/server/__tests__/e2e/business-flow.test.ts --test-name-pattern "Task Lists API"`
Not-tested: Full `bun test src/server/__tests__/e2e/business-flow.test.ts` suite still has unrelated pre-existing failures in Models and Sessions sections
2026-04-21 00:46:29 +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)
e78b973e8c Restore sidebar project filter metadata and dropdown layering
The sidebar project filter had regressed to lossy projectPath strings, so the
UI showed broken folder-name fragments and the dropdown could not match the
richer project chooser used in session creation. This switches the sidebar back
to recent-project metadata, renders the filter menu through a portal, and keeps
session filtering behavior unchanged while restoring readable labels and paths.

Constraint: Sidebar filtering still needs to target existing session projectPath values without migrating store shape
Constraint: The desktop sidebar dropdown must escape local stacking and overflow constraints to render reliably
Rejected: Keep deriving labels from sanitized projectPath strings | lost repo names and full paths, causing misleading project choices
Rejected: Rebuild sessionStore around recent-project objects in this fix | broader state migration than needed for the regression
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep sidebar project displays aligned with /api/sessions/recent-projects metadata instead of reintroducing string-splitting fallbacks
Tested: cd desktop && bunx vitest run src/components/layout/ProjectFilter.test.tsx src/components/layout/Sidebar.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Not-tested: Manual desktop visual pass of the repaired dropdown in a live Tauri window
2026-04-20 23:45:53 +08:00
程序员阿江(Relakkes)
9fdbfafd4d Prevent settings races and stale session teardown in local services
Concurrent writes to the same settings file could interleave and leave user
preferences in a partially updated state, and a restarted conversation session
could still be torn down by an older process exit callback. This serializes
per-file settings writes, hardens temp-file handling, adds regression coverage
for both service behaviors, and drops an unused sidecar external from the
build exclude list.

Constraint: Settings writes must remain atomic while allowing multiple service entry points to update the same JSON file
Rejected: Keep fire-and-forget writes with unique temp names only | still allows stale reads and last-writer races between callers
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Preserve the per-file write lock when adding new settings mutation paths so concurrent writes keep one serialization point
Tested: bun test src/server/__tests__/settings.test.ts src/server/__tests__/conversations.test.ts (new settings/conversation cases passed)
Not-tested: Root lint script is unavailable; Models API tests in src/server/__tests__/settings.test.ts still fail in this checkout with changed default model/effort expectations
2026-04-20 23:13:45 +08:00
程序员阿江(Relakkes)
0f7494006f Prevent misleading empty @-file menus when filesystem access fails
Desktop @-mentions were collapsing filesystem browse failures into an empty
state, which made /private/tmp aliases on macOS look like real empty
directories. The server now treats /private/tmp as the same temp root as
/tmp on Darwin, and the menu surfaces explicit access/load errors instead of
pretending the directory has no files.

Constraint: Desktop browse/file APIs must stay restricted to approved roots
Constraint: Native macOS pickers and realpath() may canonicalize /tmp to /private/tmp
Rejected: Expanding filesystem access to arbitrary system paths | too broad for this targeted fix
Rejected: Keeping silent empty-state fallback | hides permission and path bugs from users
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep filesystem error states visible in the composer; do not collapse API failures back into empty-directory messaging
Tested: bun test src/server/__tests__/filesystem.test.ts
Tested: cd desktop && bun run test -- FileSearchMenu.test.tsx
Tested: cd desktop && bun run lint
Not-tested: Manual desktop packaging or end-to-end Tauri app run after this patch
2026-04-20 23:07:15 +08:00
程序员阿江(Relakkes)
0d3933c2c9 Keep desktop AskUserQuestion flows from stalling in plan mode
Desktop chat was rendering AskUserQuestion twice: once as an inline question card and again as a generic permission request. That split also dropped the structured answers on the floor because the websocket permission_response shape only carried allow/deny state.

This change keeps AskUserQuestion on the permission pipeline end-to-end. The desktop websocket contract now carries toolUseId and updatedInput, AskUserQuestion submits answers through permission_response, and the generic permission card is suppressed for that tool so the user sees a single question flow.

Constraint: AskUserQuestion answers must round-trip through updatedInput.answers for the CLI tool contract to complete
Rejected: Leave AskUserQuestion as a plain chat reply in desktop | the tool never receives structured answers and the pending approval UI remains stuck
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep AskUserQuestion bound to the permission-response path unless the desktop protocol grows a separate structured elicitation channel
Tested: desktop lint; vitest src/components/chat/AskUserQuestion.test.tsx src/stores/chatStore.test.ts; bun test src/server/__tests__/conversations.test.ts
Not-tested: Manual desktop click-through against a live plan-mode session after bundling
2026-04-20 23:07:15 +08:00
Relakkes Yang
4b513271ee fix: improve windows computer use and desktop rendering 2026-04-20 17:59:42 +08:00