小橙子 3fb246ca6a
feat: CodeMirror editor + atomic save + conflict banner foundation (Phase 2) (#24)
* feat(desktop): add CodeMirror deps + bundle budget + encoding utils

Phase 2 foundation pieces (tasks 6-7 of editor-lsp-foundation):

- Add 9 @codemirror/* dependencies (state, view, commands, search, language,
  autocomplete, lang-{javascript,json,markdown}). Tree-shaking keeps the
  current bundle delta at +0.00 KB until WorkspaceEditor.tsx imports them
  in task 8.
- Add scripts/check-bundle-budget.ts + bun script "check:bundle-budget".
  Asserts dist/assets/*.js gzipped total <= baseline + 100 KB. Baseline
  captured at origin/main @ 95931d49 (post-R5, pre-CodeMirror) = 3299.76 KB.
- Add encodingDetect.ts: detectEncoding(bytes) -> 'utf-8' | 'utf-8-bom' |
  'unsupported' (uses TextDecoder fatal:true to map invalid UTF-8 to
  unsupported); detectLineEnding(text) -> 'LF' | 'CRLF' | 'CR' (dominant
  style with LF as fallback for empty/single-line buffers).

Tested:
- bun run test src/components/workspace/encodingDetect.test.ts -- --run (18/18 pass)
- bun run scripts/check-bundle-budget.ts (OK, +0.00 KB delta)

_Requirements: 1.3, 1.6, 1.7, 1.8_

* feat(server,desktop): workspace file save endpoint + buffer/conflict store

Phase 2 backend pieces (tasks 9-12 of editor-lsp-foundation):

Server:
- src/server/events/workspaceFileSaved.ts: shared emitter
  emitWorkspaceFileSaved() so both write paths (user now, agent in PR-4)
  funnel through one well-typed WS message shape.
- src/server/services/workspaceFileService.ts: WriteWorkspaceFileSchema
  (Zod), atomic write (temp file + fsync + rename, Windows EBUSY/EPERM
  retry 3x50ms), realpath-based symlink containment, BOM/CRLF/CR
  round-trip, sha256 stale-base check (409 on hash mismatch), structured
  400/404/409/500 error bodies, post-write workspace.file.saved emit.
- src/server/api/sessions.ts: POST /api/sessions/:id/workspace/file
  routes through new handleSessionWorkspacePost; GET path unchanged.
- src/server/services/workspaceFileService.test.ts: 17 tests covering
  200 / 400 (bad request, path-escape, parent-missing, absolute-path) /
  404 session-missing / 409 stale-base / BOM round-trip / CRLF round-trip /
  CR round-trip / temp-file-not-leaked / 10 MiB content cap. Includes
  symlink-escape coverage on POSIX (skipped on Windows where symlink
  creation needs elevation).

Desktop store:
- desktop/src/stores/workspacePanelStore.ts: bufferStateByTabId record,
  WorkspaceBufferState/Conflict types, initBuffer / setBufferState /
  applyExternalSave / acknowledgeConflict / clearBuffer actions.
  applyExternalSave is the WS-driven entry point — clean buffers rebase
  silently when content is supplied; dirty buffers raise a conflict
  banner. acknowledgeConflict('reload') resets to base, 'keepMine' /
  'openConflict' just dismiss the banner. closePreviewTabs and
  clearSession now drop matching buffer state to prevent leaks.

Tested:
- bun test src/server/services/workspaceFileService.test.ts (17/17 pass)
- bun run lint (server tsc clean)
- bun run test src/stores/workspacePanelStore.test.ts (24/24 pass — store
  extension is purely additive, R5 tests still green)

Note: pre-existing e2e/business-flow failures in src/server/__tests__/e2e
remain untouched by this change (44 fails on baseline, no new fails
introduced).

_Requirements: 1.5, 2.1-2.9, 3.1-3.3_

* feat(desktop): WorkspaceEditor + ConflictBanner + UnsavedChangesModal

Phase 2 UI pieces (tasks 8, 13, 14, 15 of editor-lsp-foundation):

- desktop/src/components/workspace/WorkspaceEditor.tsx: CodeMirror 6
  editor wrapping the workspace panel buffer state. Hooks
  EditorView.updateListener -> setBufferState for live dirty tracking,
  picks language by extension (ts/tsx/js/jsx/json/md), wires Save to
  sessionsApi.saveWorkspaceFile (R2 atomic write endpoint), refreshes
  base hash on success, falls back to a read-only message when
  detectEncoding returns 'unsupported'. External rebases (e.g. clean
  buffer applyExternalSave) are pushed back into the EditorView via
  dispatch.
- desktop/src/components/workspace/ConflictBanner.tsx: clean buffer ->
  single Reload button; dirty buffer -> three buttons (Reload (discard),
  Keep mine, Open conflict view). Renders workspace-relative path,
  hash first 8 hex, relative timestamp refreshing every 60 s.
- desktop/src/components/workspace/UnsavedChangesModal.tsx: Discard /
  Save / Cancel modal. Cancel is the default focus, Esc triggers it.
  While saving, all three buttons disable and the host calls onSave
  which only resolves close on success. 30 s in-prompt timeout fires
  onTimeout (host owns the toast).
- desktop/src/components/workspace/WorkspaceEditor.test.tsx: 8 RTL
  tests covering buffer init / encoding detection / unsupported
  fallback / dirty marker / unsaved-changes modal flows / conflict
  banner clean-vs-dirty layouts.
- desktop/src/api/sessions.ts: SaveWorkspaceFileInput +
  SaveWorkspaceFileResult types and sessionsApi.saveWorkspaceFile
  POST helper.

Bundle delta: +0.28 KB gz (CodeMirror 6 + 3 lang packs imported but
WorkspaceEditor is not yet wired into WorkspacePanel — that integration
ships in a follow-up PR alongside Phase 3 LSP work, keeping this PR
focused on the foundation).

Tested:
- bun run lint (tsc --noEmit clean)
- bun run test (workspacePanelStore 24/24, encodingDetect 18/18,
  WorkspaceEditor 8/8, WorkspacePanel 27/27 — 77/77 across 4 files)
- bun run check:bundle-budget (delta +0.28 KB gz, 99.72 KB headroom)
- bun run build (clean, 1.20s)

_Requirements: 1.1-1.8, 3.2-3.5, 4.1-4.6_

---------

Co-authored-by: 你的姓名 <you@example.com>
2026-06-12 07:36:52 +08:00
2026-06-11 20:55:46 +08:00
2026-04-01 10:30:17 +08:00

Claude Code Haha

Claude Code Haha

GitHub Stars GitHub Forks GitHub Issues GitHub Pull Requests License 中文 English Docs

A Claude Code build repaired from the source leaked from Anthropic's npm registry on 2026-03-31. Claude Code Haha is now primarily a desktop Claude Code workspace for macOS, Windows, and Linux: sessions, projects, branch / Worktree launch, right-side file changes, code diffs, permission review, provider setup, Computer Use, H5 remote access, IM integration, and scheduled tasks in one app.

Desktop Preview · Install · Highlights · Sponsorship · More Docs


Desktop Preview

The Claude Code Haha desktop app brings sessions, multi-project navigation, branch / Worktree controls, right-side file changes, code diffs, permission review, provider setup, and remote access into one graphical workspace for daily development flows beyond the terminal.

Download Desktop   Install Guide

Desktop workspace
Desktop Workspace
Right-side changes and Worktree
Right-side Changes & Worktree
Code editing
Code Editing & Diff View
Permission control
Permission Review & AI Questions
H5 remote access
H5 Remote Access
Token usage
Token Usage
Computer Use
Computer Use
Scheduled tasks
Scheduled Tasks

Install the Desktop App

  1. Download the macOS / Windows / Linux desktop installer from Releases.
  2. On first launch, configure your model provider, API key, and default model in Settings.
  3. This build is currently unsigned, so the first launch needs a one-time manual approval (clear quarantine on macOS, click "Run anyway" on Windows). See the desktop installation guide.

Run the CLI from Source

For users who want to debug the underlying CLI, server, or local development flow:

bun install
cp .env.example .env
./bin/claude-haha

See environment variables and global usage for more configuration options.


Desktop Highlights

  • Multi-session workspace: tabs, project switching, terminal entry, and session history in one place.
  • Branch / Worktree launch: choose a repository branch and decide whether to use the current working tree or an isolated Worktree.
  • Right-side file changes: review changed files, added/removed lines, and current workspace state while chatting.
  • Visual code changes: inspect edits, file writes, and diffs directly in the desktop app.
  • Permission review: approve risky commands, tool calls, and model follow-up questions in the GUI.
  • Multi-provider setup: configure Anthropic-compatible APIs, third-party models, WebSearch fallback, and local options.
  • Computer Use: let the agent take screenshots, click, type, and control desktop apps after authorization.
  • H5 remote access: open the current desktop session from a phone or another device with a one-time token.
  • IM integration: chat, switch projects, and approve actions through Telegram / Feishu / WeChat / DingTalk.
  • Scheduled tasks and usage stats: create planned tasks and track local token usage trends.

More Documentation

Document Description
Environment Variables Full env var reference and configuration methods
Third-Party Models Using OpenAI / DeepSeek / Ollama and other non-Anthropic models
Contributing Local tests, live model baselines, PR gates, and release gates
Memory System Cross-session persistent memory usage and implementation
Multi-Agent System Agent orchestration, parallel tasks and Teams collaboration
Skills System Extensible capability plugins, custom workflows and conditional activation
IM Integration Remote chat, project switching, and permission approval via Telegram / Feishu / WeChat / DingTalk
Computer Use Desktop control (screenshots, mouse, keyboard) — Architecture
Desktop App Electron + React GUI client — Quick Start | Architecture | Installation
Global Usage Run claude-haha from any directory
FAQ Common error troubleshooting
Source Fixes Fixes compared with the original leaked source
Project Structure Code directory structure

Sponsorship & Partnership

This project is maintained in the author's spare time. Corporate or individual sponsorships are welcome to support ongoing development. Custom features, integrations, and business partnerships are also open for discussion.

Sponsor Description
JieKou AI
接口AI
Thanks to JieKou AI for sponsoring this project. JieKou AI provides official model resources with stable, high-performance API access. Subscription bundles are priced at 20% off the official rate; new users who register through this link and bind GitHub can claim a $3 coupon.
ShengSuanYun Thanks to ShengSuanYun for sponsoring this project. ShengSuanYun is an industrial-grade AI task parallel execution platform for AI Native Teams, aggregating Claude, ChatGPT, Gemini, and other LLM, image, and video model capacity through direct, non-reverse-engineered access. Its platform SLA reaches 99.7%, with service status available online. It also supports dedicated enterprise gateways, cost and permission controls, smart routing, security protection, BYOK, usage-based billing, upcoming tokens plans, and invoicing. New users registering through this link can receive 10 yuan in model credits plus a 10% first top-up bonus.

📧 Contact: relakkes@gmail.com


Tech Stack

Category Technology
Language TypeScript
Desktop app Electron
Desktop UI React + Vite
Local runtime Bun
Terminal UI React + Ink
CLI parsing Commander.js
API Anthropic SDK
Protocols MCP, LSP

Thanks

Thanks to the following open-source projects and community practices for reference and inspiration:

  • React: frontend engineering and component-based UI ecosystem.
  • Electron: cross-platform desktop app capabilities and engineering practices.
  • cc-switch: reference for model provider configuration.

Star History

If this project helps you, please support it with a Star so more people can discover Claude Code Haha.

Star History Chart

Disclaimer

This repository is based on the Claude Code source leaked from the Anthropic npm registry on 2026-03-31. All original source code copyrights belong to Anthropic. It is provided for learning and research purposes only.

Description
Claude Code 本地可运行版本 - mirror from GitHub
Readme 537 MiB
Languages
TypeScript 98.7%
CSS 0.3%
Rust 0.2%
Shell 0.2%
Python 0.2%
Other 0.3%