Vectrum
Sign In

Add build.sh to package the app as a binary and AppImage

Builds a release binary and an AppImage into ./build, using the Vectrum
mark from vectrum.cc as the app icon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JjohannSocommitted 1 parent 466f3c7commit8d0805a

Showing 3 changed files with 93 additions and 0 deletions.

+1−0.gitignoreView File
@@ -1,2 +1,3 @@
11 /target
22 /dist
3+ /build
+6−0assets/icons/vectrum-code.svgaddedView File
@@ -0,0 +1,6 @@
1+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
2+ <!-- The Vectrum mark from vectrum.cc, on the site's dark app-icon plate. -->
3+ <rect width="256" height="256" rx="56" fill="#0d0d0d"/>
4+ <path fill="#dcdcdc" fill-rule="evenodd" transform="translate(50 50) scale(5)"
5+ d="M2 13a8.5 8.5 0 1 0 17 0a8.5 8.5 0 1 0-17 0ZM11.54 7.69Q10 4 14 4H26Q30 4 28.46 7.69L21.54 24.31Q20 28 18.46 24.31Z"/>
6+ </svg>
+86−0build.shaddedView File
@@ -0,0 +1,86 @@
1+ #!/usr/bin/env bash
2+ # Builds Vectrum Code in release mode and writes two artifacts to ./build:
3+ # build/vectrum-code plain binary
4+ # build/Vectrum_Code-<version>-<arch>.AppImage
5+ #
6+ # appimagetool is used from $PATH if present, otherwise downloaded once into
7+ # build/.tools. Set APPIMAGETOOL=/path/to/appimagetool to use a specific one.
8+ set -euo pipefail
9+
10+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11+ BUILD="$ROOT/build"
12+ TOOLS="$BUILD/.tools"
13+ APPDIR="$BUILD/AppDir"
14+
15+ NAME="vectrum-code"
16+ PRETTY="Vectrum Code"
17+ VERSION="$(sed -n 's/^version *= *"\(.*\)"/\1/p' "$ROOT/Cargo.toml" | head -n1)"
18+ ARCH="$(uname -m)"
19+
20+ log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
21+
22+ # ── 1. Binary ────────────────────────────────────────────────────────────────
23+ log "Building $NAME $VERSION (release, $ARCH)"
24+ cargo build --release --manifest-path "$ROOT/Cargo.toml"
25+
26+ TARGET_DIR="$(cargo metadata --format-version 1 --no-deps --manifest-path "$ROOT/Cargo.toml" |
27+ sed -n 's/.*"target_directory":"\([^"]*\)".*/\1/p')"
28+ mkdir -p "$BUILD"
29+ install -m755 "$TARGET_DIR/release/$NAME" "$BUILD/$NAME"
30+ log "Binary: build/$NAME"
31+
32+ # ── 2. AppDir ────────────────────────────────────────────────────────────────
33+ rm -rf "$APPDIR"
34+ mkdir -p "$APPDIR/usr/bin" \
35+ "$APPDIR/usr/share/applications" \
36+ "$APPDIR/usr/share/icons/hicolor/scalable/apps"
37+
38+ install -m755 "$BUILD/$NAME" "$APPDIR/usr/bin/$NAME"
39+
40+ cat > "$APPDIR/usr/share/applications/$NAME.desktop" <<EOF
41+ [Desktop Entry]
42+ Type=Application
43+ Name=$PRETTY
44+ Comment=A T3 Code-style GUI for Claude Code
45+ Exec=$NAME
46+ Icon=$NAME
47+ Terminal=false
48+ Categories=Development;IDE;
49+ StartupWMClass=$NAME
50+ EOF
51+
52+ install -m644 "$ROOT/assets/icons/$NAME.svg" "$APPDIR/usr/share/icons/hicolor/scalable/apps/$NAME.svg"
53+
54+ cat > "$APPDIR/AppRun" <<'EOF'
55+ #!/bin/sh
56+ HERE="$(dirname "$(readlink -f "$0")")"
57+ exec "$HERE/usr/bin/vectrum-code" "$@"
58+ EOF
59+ chmod +x "$APPDIR/AppRun"
60+
61+ ln -sf "usr/share/applications/$NAME.desktop" "$APPDIR/$NAME.desktop"
62+ ln -sf "usr/share/icons/hicolor/scalable/apps/$NAME.svg" "$APPDIR/$NAME.svg"
63+ ln -sf "$NAME.svg" "$APPDIR/.DirIcon"
64+
65+ # ── 3. appimagetool ──────────────────────────────────────────────────────────
66+ APPIMAGETOOL="${APPIMAGETOOL:-$(command -v appimagetool || true)}"
67+ if [[ -z "$APPIMAGETOOL" ]]; then
68+ APPIMAGETOOL="$TOOLS/appimagetool-$ARCH.AppImage"
69+ if [[ ! -x "$APPIMAGETOOL" ]]; then
70+ log "Downloading appimagetool"
71+ mkdir -p "$TOOLS"
72+ curl -fL --progress-bar -o "$APPIMAGETOOL.part" \
73+ "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$ARCH.AppImage"
74+ chmod +x "$APPIMAGETOOL.part"
75+ mv "$APPIMAGETOOL.part" "$APPIMAGETOOL"
76+ fi
77+ fi
78+
79+ # ── 4. AppImage ──────────────────────────────────────────────────────────────
80+ OUT="$BUILD/${PRETTY// /_}-$VERSION-$ARCH.AppImage"
81+ log "Packaging AppImage"
82+ # Extract-and-run so this works on systems without FUSE (containers, CI).
83+ APPIMAGE_EXTRACT_AND_RUN=1 ARCH="$ARCH" "$APPIMAGETOOL" --no-appstream "$APPDIR" "$OUT"
84+ rm -rf "$APPDIR"
85+
86+ log "AppImage: ${OUT#"$ROOT"/}"