# Copyright 2026 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 EAPI=8 inherit desktop pax-utils xdg DESCRIPTION="Agentic Development Environment desktop app from Z.ai (GLM harness)" HOMEPAGE="https://zcode.z.ai/" SRC_URI=" amd64? ( https://cdn-zcode.z.ai/zcode/electron/releases/${PV}/linux-x64/ZCode-${PV}-linux-x64.deb -> ${P}_amd64.deb ) " S="${WORKDIR}" LICENSE="ZCode-EULA" SLOT="0" KEYWORDS="-* ~amd64" # The deb's internal Version: is 3.8.1-5310 (upstream build number, # not encoded in the CDN path or filename). If a same-PV re-spin ever # changes the archive, the Manifest digest mismatch is the symptom; # re-pin by re-hashing the new artifact. # Proprietary binary blob: the terms forbid redistribution, and the .deb # ships prebuilt ELFs (the Electron app, its bundled Chromium libs, # ffmpeg, Vulkan/SwiftShader, plus vendored ripgrep/bfs/ugrep tools) # that must NOT be stripped. RESTRICT="bindist mirror strip" # Runtime deps. ZCode bundles its own Electron under /opt/ZCode, so this # list is the set of host libraries those prebuilt ELFs actually link # against, derived from DT_NEEDED across every ELF in the archive plus # the extra libraries upstream's own .deb `Depends:` field and the # Electron runtime dlopen() at launch (libnotify, libsecret, libXtst, # libXScrnSaver). libudev is consumed via the systemd/eudev split. RDEPEND=" app-accessibility/at-spi2-core app-crypt/libsecret dev-libs/expat dev-libs/glib:2 dev-libs/nspr dev-libs/nss media-libs/alsa-lib media-libs/mesa net-print/cups sys-apps/dbus sys-apps/util-linux virtual/libudev x11-libs/cairo x11-libs/gtk+:3 x11-libs/libnotify x11-libs/libX11 x11-libs/libxcb x11-libs/libXcomposite x11-libs/libXdamage x11-libs/libXext x11-libs/libXfixes x11-libs/libxkbcommon x11-libs/libXrandr x11-libs/libXScrnSaver x11-libs/libXtst x11-libs/pango x11-misc/xdg-utils " BDEPEND=" app-arch/xz-utils " # The whole application tree is prebuilt; skip QA on it. QA_PREBUILT="opt/ZCode/*" src_unpack() { local deb="${DISTDIR}/${P}_amd64.deb" mkdir -p "${S}" || die cd "${S}" || die # .deb is an ar archive of {debian-binary, control.tar.*, data.tar.xz}. ar x "${deb}" || die "ar x failed on ${deb}" unpack ./data.tar.xz } src_install() { # Application tree -> /opt/ZCode (upstream's own install prefix, as # referenced by the shipped .desktop Exec= and the /usr/bin/zcode # symlink in the .deb postinst). cp -a preserves the executable bits # on the bundled ELFs (zcode, chrome-sandbox, chrome_crashpad_handler, # the *.so blobs, and the vendored ripgrep/bfs/ugrep tools). mkdir -p "${ED}/opt" || die cp -a "${S}/opt/ZCode" "${ED}/opt/" || die "Failed to install /opt/ZCode tree" # Electron's setuid sandbox helper: upstream's .deb postinst chmods # it 4755 only when unprivileged user namespaces are unavailable; # on a kernel with working user namespaces Chromium does not need # the helper at all. Install it setuid anyway (tightened to 4711 as # ::gentoo's Electron packages do) so the sandbox also works under # hardened kernels with user namespaces disabled. fperms 4711 /opt/ZCode/chrome-sandbox # The main binary is a V8/JIT engine: mark it so a PaX/hardened kernel # permits RWX/mprotect. No-op on a vanilla kernel. pax-mark m "${ED}/opt/ZCode/zcode" # Convenience launcher on PATH (mirrors the .deb postinst symlink). dosym ../../opt/ZCode/zcode /usr/bin/zcode # Desktop file. Upstream's copy is already valid; normalise Exec= to # the PATH name so the menu entry and the CLI agree. local desktop="${S}/usr/share/applications/zcode.desktop" [[ -f "${desktop}" ]] || die "expected desktop file missing: ${desktop}" sed -i \ -e 's|^Exec=/opt/ZCode/zcode |Exec=zcode |' \ "${desktop}" \ || die "sed on desktop file failed" domenu "${desktop}" # Icons. Upstream ships a full set of sized hicolor PNGs; install # each into its matching bucket so icon themes resolve `Icon=zcode`. local icon size for icon in "${S}"/usr/share/icons/hicolor/*/apps/zcode.png; do size=$(basename "$(dirname "$(dirname "${icon}")")") newicon -s "${size%x*}" "${icon}" zcode.png done } pkg_postinst() { xdg_pkg_postinst elog "" elog "ZCode stores its configuration, plugins, and workspaces under" elog "~/.zcode. Launch it from your menu or by running: zcode" elog "" elog "Signing in with a Z.ai account is required to use the bundled" elog "GLM models. See https://zcode.z.ai/en/docs/install for setup." elog "" elog "Updates arrive as new ebuild versions: the in-app auto-updater" elog "cannot write to /opt/ZCode under the package manager." elog "" elog "Per the ZCode terms, use of the service and its output without" elog "a paid subscription is limited to non-commercial, personal" elog "research and study purposes." elog "" }