WikifitaGitHub live67e8de5
projeto · claude_desktop/claude-desktop-bundles

Claude Desktop — Bundle Architecture

Documentation: Claude Desktop — Bundle Architecture

Baixar raw

Claude Desktop — Bundle Architecture

Claude Desktop Electron app structure, extracted from ASAR (/Applications/Claude.app/Contents/Resources/app.asar).

Build System

  • Version: 1.14271.0
  • Build tool: Electron Forge + Vite 6.4.2
  • Renderer: React 18.3.1 + Tailwind CSS 3.4.19
  • Minifier: Terser (local variables mangled, properties preserved)
  • Package: @ant/desktop

ASAR Structure

app.asar/
├── package.json                   # @ant/desktop, deps
├── harness-bootstrap.js           # Bezetacil runtime (added via repack)
├── .vite/
│   ├── build/
│   │   ├── index.js              # 14 MB — Electron Main Process (ALL logic)
│   │   ├── index.pre.js          # 811 KB — Preload script
│   │   ├── mainWindow.js         # 165 KB
│   │   ├── mainView.js           # 194 KB
│   │   └── ...
│   └── renderer/
│       ├── main_window/
│       │   ├── assets/
│       │   │   ├── main-Bh0l-09t.js      # 291 KB — React shell (react, react-dom, react-intl)
│       │   │   └── MainWindowPage-1yenKknx.js  # 13 KB — UI components
│       ├── about_window/         # About window bundle
│       ├── find_in_page/         # Find-in-page bundle
│       └── quick_window/         # Quick entry window
├── node_modules/
│   ├── @ant/claude-native/       # Native addons (.node, .dylib)
│   ├── ws/                       # WebSocket library
│   └── node-pty/                 # Terminal PTY
└── resources/
    └── office365-mcp/            # Office 365 MCP server

1p vs 3p — The Real Difference

Not two separate bundles. Same code with compile-time switches:

Mechanism3p (prod)1p (internal)
buildType"prod""dev" or "staging"
isNestBuildfalsetrue
dzA() (staging detect)no-op stub () => {}real function
uF() (URL base)hardcoded "https://claude.ai"CLAUDE_AI_URL env var
hardcodedMainGrowthBookFeatures()return nullreturn V3i
_vt() (voice module)return Promise.resolve({})real module
y4n (Echo MCP)Object.freeze({}) emptyreal module

URL Override (Dev)

function uF() {
  if (buildType === "dev")
    return process.env.CLAUDE_AI_URL || config.claudeAiUrl || "https://claude.ai"
  if (isDeveloperApprovedDevUrlOverrideEnabled && process.env.CLAUDE_AI_URL)
    return process.env.CLAUDE_AI_URL
  return "https://claude.ai"
}

isDeveloperApprovedDevUrlOverrideEnabled requires Ed25519 signature via CLAUDE_CDP_AUTH.

Remote Bundle (1p)

Loaded from assets-proxy.anthropic.com/claude-ai/v2/assets/v1/:

FileSizeContent
index-BW29VlNm.js7.2 MBComplete React webapp (voice, UI, GrowthBook)
c6a992d55-CvsZ6KID.css758 KBDesign system @ant-cds + Tailwind
vendor-ant-cds-D6IJ1PR1.css204 BCDS loader

Extracted to ~/.bezetacil/workdir/claude-desktop/ion-dist/ via CDP.

Voice Components in Remote Bundle

buildVoiceWebSocket, getVoice, setVoice, selectedVoice,
voiceContentBlocks, voiceSessionId

SFX: /audio/voice/sfx/enter_voice_mode.mp3, exit_voice_mode.mp3, disconnected.mp3

AudioWorklet: audioSinkWorklet with 5.76 MB ring buffer

Persistent Workdir

~/.bezetacil/workdir/claude-desktop/
├── package.json              # From original ASAR
├── harness-bootstrap.js      # Bezetacil runtime
├── jsconfig.json             # Config for LSP (tsserver)
├── .vite/                    # ASAR bundles (main + renderer)
├── ion-dist/                 # Remote bundles extracted from 1p
│   ├── index-BW29VlNm.js     # 7.2 MB — webapp React
│   └── *.css                 # Design system
├── remote-scripts.json       # Remote script URLs
├── 1p-boot-features.json     # 1p desktopBootFeatures
├── 1p-features.json          # 1p scope scan
└── feature-flags.csv         # 226 analyzed features

Design System

  • Framework: Tailwind CSS 3.4.19 with custom HSL tokens
  • Components: @ant-cds (Anthropic Design System) + @radix-ui
  • Icons: @phosphor-icons/react
  • Fonts: AnthropicSans, AnthropicSerif (variables)
  • Button variants: primary, secondary, danger, ghost, flat, unstyled

ASAR Repack

Tools used: @electron/asar (Node.js API), Python for Info.plist

Integrity hash: SHA256 of headerString (JSON), stored in ElectronAsarIntegrity in Info.plist (9 copies).

References