程序员阿江(Relakkes) 57cac856f1 refactor(desktop): establish the theme and behavior foundation
First of a series that extracts a component library out of the desktop
UI. Intermediate commits in this series do not build on their own — the
directory move and the call-site updates cannot be separated per file.

Theme layer fixes, all previously invisible to any test:

- `dark:` compiled to `prefers-color-scheme` and so followed the OS, not
  `<html data-theme>`. With the OS in light mode the variant never fired,
  which is why the streaming retry banner rendered near-white under the
  dark theme. Bound it with `@custom-variant`.
- Six tokens were referenced but never defined, leaving borders falling
  back to `currentColor` and panels transparent. Five were renamed to the
  tokens they meant; `--color-on-primary-container` was genuinely missing
  and is now defined per theme.
- Status colors now come in pairs: `--color-<tone>-container` with a
  matching `--color-on-<tone>-container`. Using the accent as its own
  foreground measured 2.66:1 in the light theme, well under AA.
- One ordered z-index scale replaces 17 ad-hoc values. Two orderings are
  load-bearing: dropdowns sit above dialogs (a modal blocks the page, so
  an open dropdown belongs to the topmost dialog — this is why
  DirectoryPicker had to hardcode `zIndex: 9999`), and toasts sit above
  sheets (otherwise feedback raised from a sheet is invisible).
- `animate-in slide-in-from-*` came from `tailwindcss-animate`, removed
  in the shadcn rollback. Toast and Dropdown kept the classes and lost
  their entrance animation entirely; real keyframes now back them.
- The embedded terminal hardcoded 20 hex values, bypassing the per-theme
  `--color-terminal-*` tokens that were already defined. `terminalTheme.ts`
  resolves them for xterm, which cannot read CSS variables itself.

Behavior:

- `useDismissable` replaces 21 hand-rolled outside-click effects, split
  across `mousedown` (14), `click` (3) and `pointerdown` (3). It defaults
  to `pointerdown`: `mousedown` is unreliable for touch, which is the
  shape of the "tapping outside doesn't close the menu" reports on H5.
- `useAnchoredPosition` merges four viewport calculations whose margins
  had drifted to 8, 8, 12 and 0, only one of which flipped.
- `chat/clipboard.ts` moves to `lib/` — it had a base primitive
  (`CopyButton`) depending on a feature directory.

Guards, because conventions in prose do not hold:

- `tokenUsage.test.ts` — every `var(--token)` resolves, and no raw
  z-index escapes the scale. A typo'd token throws no error; it just
  renders transparent.
- `contrast.test.ts` — computes real ratios for 3 themes x 6 tones and
  requires AA. Verified by reverting the fix and watching it reproduce
  2.66:1 exactly.
- `paletteEscapes.test.ts` — a ratchet on stock Tailwind palette classes,
  which do not follow `data-theme` and which `tokenUsage` cannot see
  because they are not `var()` references.
2026-07-26 18:29:17 +08:00
..

Claude Code Haha Desktop

基于 Tauri 2 + React 的桌面客户端。

开发

bun install
bun run tauri dev

构建

# macOS (Apple Silicon)
./scripts/build-macos-arm64.sh

# Windows (x64, MSI only)
.\scripts\build-windows-x64.ps1

构建产物位于 build-artifacts/ 目录,文件名会显式包含平台、架构和包类型。

常见问题

macOS 提示"已损坏,无法打开"

xattr -cr /Applications/Claude\ Code\ Haha.app