summarylogtreecommitdiffstats
path: root/PKGBUILD
blob: 79b7b3643a5e204c114b745ae176d4b77c44a142 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# Maintainer: AstroSteveO <stevengmjr at gmail dot com>

pkgname=claude-desktop-native
pkgver=0.14.10
pkgrel=2
pkgdesc="Unofficial Claude Desktop for Linux"
arch=('x86_64')
url="https://github.com/jkoelker/claude-desktop-native"
license=('MIT' 'Apache')
depends=('electron')
makedepends=('p7zip' 'npm' 'nodejs' 'rust' 'cargo' 'imagemagick' 'icoutils' 'tar')
optdepends=('docker: for running MCP servers')
source=("Claude-Setup-x64-${pkgver}-${pkgrel}.exe::https://storage.googleapis.com/osprey-downloads-c02f6a0d-347c-492b-a752-3e0651722e97/nest-win-x64/Claude-Setup-x64.exe"
  "patchy-cnb::git+https://github.com/k3d3/claude-desktop-linux-flake.git")
sha256sums=('4a7fe5bcc95f29dedbfeeb45bc2c6b916343253ba0e0e392038968f5857c6aa9'
            'SKIP')

prepare() {
  cd "${srcdir}"

  # Extract installer exe and nupkg
  7z x -y "Claude-Setup-x64-${pkgver}-${pkgrel}.exe"
  7z x -y "AnthropicClaude-${pkgver}-full.nupkg"

  # Verify version matches what's in the nuspec file
  if [ -f "AnthropicClaude.nuspec" ]; then
    NUSPEC_VERSION=$(grep -oP '<version>\K[^<]+' "AnthropicClaude.nuspec")
    if [ "$NUSPEC_VERSION" != "$pkgver" ]; then
      echo "WARNING: PKGBUILD version ($pkgver) does not match nuspec version ($NUSPEC_VERSION)"
      echo "Please update pkgver in PKGBUILD to: $NUSPEC_VERSION"
    fi
  fi

  # Extract icons from claude.exe
  wrestool -x -t 14 lib/net45/claude.exe -o claude.ico
  icotool -x claude.ico

  mkdir -p icons/hicolor
  for size in 16 24 32 48 64 256; do
    mkdir -p "icons/hicolor/${size}x${size}/apps"
    install -Dm 644 claude_*"${size}x${size}x32.png" \
      "icons/hicolor/${size}x${size}/apps/claude.png"
  done
}

build() {
  # Build patchy-cnb (assuming patchy-cnb folder exists at same level as PKGBUILD)
  cd "${srcdir}/patchy-cnb/patchy-cnb"
  npm install
  npm run build
  cd "${srcdir}"

  # Process app.asar files
  mkdir -p electron-app
  cp "lib/net45/resources/app.asar" electron-app/
  cp -r "lib/net45/resources/app.asar.unpacked" electron-app/

  cd electron-app
  npx asar extract app.asar app.asar.contents
  # Fix resource paths - handle different variable names for app object
  sed -i 's|return[[:space:]]\+[a-zA-Z_][a-zA-Z0-9_]*\.app\.isPackaged[[:space:]]*?[^:]*:[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*\.resolve([^,]*,[[:space:]]*"\.\.","\.\.","resources")|return "/usr/lib/'"${pkgname}"'/resources"|g' app.asar.contents/.vite/build/index*.js
  # Fix i18n resource paths specifically
  sed -i 's|return[[:space:]]\+[a-zA-Z_][a-zA-Z0-9_]*\.app\.isPackaged[[:space:]]*?[^:]*:[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*\.resolve([^,]*,[[:space:]]*"\.\.","\.\.","resources","i18n")|return "/usr/lib/'"${pkgname}"'/resources"|g' app.asar.contents/.vite/build/index*.js
  # fix negation operator to show menubar
  sed -i -E 's/if\(!([a-zA-Z]+)[[:space:]]*&&[[:space:]]*([a-zA-Z]+)\)/if(\1 \&\& \2)/g' app.asar.contents/.vite/renderer/main_window/assets/MainWindowPage-*.js

  # Replace native bindings with patchy-cnb
  pwd
  local PATCHY_CNB_NODE=$(find ../patchy-cnb/patchy-cnb -name "patchy-cnb.*.node")
  cp "${PATCHY_CNB_NODE}" app.asar.contents/node_modules/claude-native/claude-native-binding.node
  cp "${PATCHY_CNB_NODE}" app.asar.unpacked/node_modules/claude-native/claude-native-binding.node

  # Add Tray icons to app resources
  mkdir -p app.asar.contents/resources
  cp ../lib/net45/resources/Tray* app.asar.contents/resources/

  # Copy i18n json files
  mkdir -p app.asar.contents/resources/i18n
  cp ../lib/net45/resources/*.json app.asar.contents/resources/i18n/

  # Repackage app.asar
  npx asar pack app.asar.contents app.asar
}

package() {
  cd "${srcdir}"

  # Install app files
  install -d "${pkgdir}/usr/lib/${pkgname}"
  cp -r electron-app/app.asar "${pkgdir}/usr/lib/${pkgname}/"
  cp -r electron-app/app.asar.unpacked "${pkgdir}/usr/lib/${pkgname}/"

  # Install resources directory with tray icons
  install -d "${pkgdir}/usr/lib/${pkgname}/resources"
  cp electron-app/app.asar.contents/resources/Tray* "${pkgdir}/usr/lib/${pkgname}/resources/"

  # Copy language JSON files to resources directory
  cp lib/net45/resources/*.json "${pkgdir}/usr/lib/${pkgname}/resources/"

  # Install icons
  install -d "${pkgdir}/usr/share/icons"
  cp -r icons/* "${pkgdir}/usr/share/icons/"

  # Create desktop file
  install -Dm644 /dev/stdin "${pkgdir}/usr/share/applications/${pkgname}.desktop" <<EOF
[Desktop Entry]
Name=Claude
GenericName=Claude Desktop
Exec=${pkgname} %u
Icon=claude
Type=Application
Terminal=false
Categories=Office;Utility;
MimeType=x-scheme-handler/claude;
StartupWMClass=Claude
EOF

  # Create launcher script
  install -Dm755 /dev/stdin "${pkgdir}/usr/bin/${pkgname}" <<EOF
#!/bin/sh
exec electron /usr/lib/${pkgname}/app.asar --gtk-version=3 "\$@"
EOF
}