小橙子 2b6202d381
fix(handoff): reuse empty session + ship raw tail for v0.5.8 (#5)
Two bugs in the v0.5.7 "Continue from here" hand-off path landed in
the wild and the user caught them while exercising 0.5.8 prep:

1. **Stray empty session.** When the user previously opened a "New
   session in X" tab from the sidebar, then closed the tab to
   declutter, the freshly-created empty session was already on disk
   and visible in the sidebar. Coming back to the welcome screen
   (activeTabId = null → EmptySession route) and clicking "Continue
   from here" called `createSession` unconditionally, minting yet
   another empty session next to the now-stale one. The user ended up
   with `Untitled Session 27 minutes ago` lingering in the sidebar
   while the hand-off ran in a completely separate fresh session.

   Extract the picker into `desktop/src/lib/sessionReuse.ts` —
   `pickReusableEmptySession(sessions, workDir, excludeSessionId?)`
   filters by exact-workDir match, `messageCount === 0`, excludes the
   previous session being handed off FROM, and sorts by `modifiedAt`
   desc. Caller in `EmptySession.onAutoHandoff` runs this before
   `createSession`; on hit, openTab on the existing sessionId and let
   ContentRouter switch to ActiveSession naturally; on miss, create
   fresh as before.

   7 unit tests cover the boundaries: workDir mismatch, non-zero
   messageCount, excludeSessionId honored, null workDir treated as
   "no candidates" (so we never silently merge home-dir sessions
   into a project hand-off), empty workDir argument, empty session
   list, freshness sort order.

2. **Summary too abstract; AI doesn't know specific recent state.**
   The previous implementation only injected the LLM-summarized
   `main` + `recent` paragraphs into the next session's system
   prompt. That summarization tends to wash out exact wording, file
   paths, error messages, and the user's literal last question — the
   user reported "AI doesn't know what we just hit a wall on."

   Add `recentRaw?: string` to `SessionSummary`. New helper
   `buildRecentRawSlice` keeps the LAST ~12 turns (env-tunable via
   `CLAUDE_CODE_HANDOFF_RAW_TURNS`, range 0–50, default 12), each
   truncated to 400 chars preserving the `USER:` / `ASSISTANT:`
   role prefix, total capped at ~8000 chars (env-tunable via
   `CLAUDE_CODE_HANDOFF_RAW_CHARS`, range 500–30000, default 8000).
   Older turns drop first when the total cap is busted by dense
   recent turns.

   `formatHandoffSystemPrompt` renders the raw slice inside a fenced
   code block AFTER the abstracted recent summary, so the next
   session sees both the digest and the literal text. Section is
   omitted entirely when `recentRaw` is absent — v0.5.7 caches still
   load and produce the exact same prompt bytes (back-compat).

   8 unit tests cover the formatter's back-compat path, the raw
   block placement, fence rendering, tail-N selection, all-fits
   case, per-turn truncation with role prefix preservation, total
   cap busting (older drops first), and the `RAW_TURNS=0` opt-out.

Both fixes fold into the unreleased v0.5.8 — release-notes/v0.5.8.md
gets two new fix bullets and the 范围 / 验证 sections call out the
new files and 15 added tests.

desktop/package.json bump to 0.5.8 stays as-is (preset earlier in
the same worktree before this commit).

Tested:
- bun run lint (desktop) clean
- bunx vitest run sessionReuse.test.ts → 7/7 pass
- bun test sessionSummaryService.test.ts → 8/8 pass
- bunx vitest run EmptySession.test.tsx → 22/22 pass (regression check
  after the helper extraction — the existing tests don't go through
  the hand-off branch but exercise the rest of the file)

Confidence: high
Scope-risk: narrow (no shape changes to any persistence — recentRaw
is an additive field, old caches deserialize cleanly because
`tryParseSummaryResponse` already only required main+recent)

Co-authored-by: 你的姓名 <you@example.com>
2026-06-10 20:46:46 +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