kun

maintainer xmengnet · 0 votes · scanned 2026-08-03 00:08:14.047287
LOW
View on AUR ↗
Why flagged The npx calls run electron-vite and @electron/rebuild, which are standard build tools resolved from the locally installed node_modules (npm install was already run), not fetching arbitrary remote code; the source tarball is from the project's own GitHub with a pinned sha256sum, so this is a normal AUR build with no evidence of malicious behavior, just a low-vote new package.

Triggered rules

LOW AI review downgraded a static finding llm_review

The static rules flagged this MEDIUM, but an AI model (anthropic/claude-4.6-sonnet-20260217) reviewed the full PKGBUILD and judged it LOW (confidence 70%): The npx calls run electron-vite and @electron/rebuild, which are standard build tools resolved from the locally installed node_modules (npm install was already run), not fetching arbitrary remote code; the source tarball is from the project's own GitHub with a pinned sha256sum, so this is a normal AUR build with no evidence of malicious behavior, just a low-vote new package.

1 higher static finding superseded - not the current verdict (shown for transparency)
MEDIUM npx/bunx/deno executes a remote package remote_code_tool

`npx`/`bunx`/`pnpm dlx`/`deno run <url>` downloads AND runs a remote package at build time — the moral equivalent of piping a download into a shell. Severity downgraded: Node.js consumer context.

  • PKGBUILD:38 npx electron-vite build
  • PKGBUILD:44 npx @electron/rebuild -f -v "${_electron_ver}" -m .

PKGBUILD

2 offending line(s) highlighted
1# Maintainer: liyp <my@liyp.cc>
2pkgname=kun
3pkgver=0.2.20
4pkgrel=2
5pkgdesc="AI agent workspace with Code and Write modes - Electron client"
6arch=('x86_64')
7url="https://github.com/KunAgent/Kun"
8license=('custom:PolyForm-Noncommercial-1.0.0')
9depends=('electron34')
10makedepends=('npm' 'nodejs>=20' 'python')
11optdepends=('libxss: screen saver inhibit support'
12 'libappindicator-gtk3: system tray support on GTK-based DEs')
13replaces=('kun-gui')
14conflicts=('kun-gui')
15source=("${pkgname}-${pkgver}.tar.gz::https://github.com/KunAgent/Kun/archive/refs/tags/v${pkgver}.tar.gz")
16sha256sums=('2615e45f556f99e5756d986bd214838153f021a3bb46d0bcae3a10ff7fb7a53e')
17options=('!strip')
18
19prepare() {
20 cd "${srcdir}/Kun-${pkgver}"
21 # Install main project, skip postinstall (it auto-builds kun and tries electron prebuild)
22 npm install --ignore-scripts
23 # Install kun runtime dependencies
24 npm --prefix kun install
25}
26
27build() {
28 cd "${srcdir}/Kun-${pkgver}"
29 # Build kun runtime (was skipped by --ignore-scripts above)
30 npm --prefix kun run build
31 # Verify kun runtime was built
32 if [ ! -f "kun/dist/cli/serve-entry.js" ]; then
33 echo "ERROR: kun runtime build failed - kun/dist/cli/serve-entry.js not found"
34 return 1
35 fi
36 echo "==> kun runtime built successfully"
37 # Build Electron app (tsc + vite)
38 npx electron-vite build
39 # Rebuild native modules (node-pty, etc.) against Electron's ABI
40 # node-pty has no linux-x64 prebuild, so node-gyp compilation is required
41 local _electron_ver
42 _electron_ver=$(electron34 --version | sed 's/^v//')
43 echo "==> Rebuilding native modules for Electron ${_electron_ver}..."
44 npx @electron/rebuild -f -v "${_electron_ver}" -m .
45 # Prune to production dependencies only (must be after vite build and electron-rebuild)
46 npm prune --production
47 npm --prefix kun prune --production
48}
49
50package() {
51 cd "${srcdir}/Kun-${pkgver}"
52
53 # Install application to /usr/lib/kun
54 install -d "${pkgdir}/usr/lib/${pkgname}"
55
56 # Copy built output
57 cp -r out "${pkgdir}/usr/lib/${pkgname}/out"
58 # Patch compiled JS: fix app identity and inject correct version
59 # (upstream uses electron-builder extraMetadata to set these at CI build time,
60 # but we don't run electron-builder, so we patch the compiled output directly)
61 local _js="${pkgdir}/usr/lib/${pkgname}/out/main/index.js"
62 # 1. APP_PRODUCT_NAME: source has "Kun" (uppercase), .desktop is kun (lowercase)
63 sed -i 's/APP_PRODUCT_NAME = "Kun"/APP_PRODUCT_NAME = "kun"/' "$_js"
64 # 2. Version: app.getVersion() returns "0.0" (not from our package.json),
65 # so we inject app.setVersion() right after app.setName()
66 sed -i 's/app\.setName(APP_PRODUCT_NAME);/app.setName(APP_PRODUCT_NAME); app.setVersion("'"${pkgver}"'");/' "$_js"
67 # Fix version in package.json as well
68 sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"${pkgver}\"/" package.json
69 install -Dm644 package.json "${pkgdir}/usr/lib/${pkgname}/package.json"
70
71 # Copy production node_modules
72 cp -r node_modules "${pkgdir}/usr/lib/${pkgname}/node_modules"
73
74 # Copy kun runtime + dependencies — only into out/main/
75 # The app resolves kun path relative to __dirname (out/main/), root-level copy is unused
76 mkdir -p "${pkgdir}/usr/lib/${pkgname}/out/main"
77 cp -r kun "${pkgdir}/usr/lib/${pkgname}/out/main/kun"
78
79 # Copy vendor dependencies
80 if [ -d "vendor" ]; then
81 cp -r vendor "${pkgdir}/usr/lib/${pkgname}/vendor"
82 fi
83
84 # Aggressively clean up to reduce package size
85 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -name "*.map" -delete
86 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -name "*.ts" -not -name "*.d.ts" -delete
87 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -name "README*" -delete 2>/dev/null || true
88 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -name "CHANGELOG*" -delete 2>/dev/null || true
89 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -name ".package-lock.json" -delete
90 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -type d -name "test" -exec rm -rf {} + 2>/dev/null || true
91 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -type d -name "tests" -exec rm -rf {} + 2>/dev/null || true
92 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -type d -name "example" -exec rm -rf {} + 2>/dev/null || true
93 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -type d -name "examples" -exec rm -rf {} + 2>/dev/null || true
94 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -type d -name "doc" -exec rm -rf {} + 2>/dev/null || true
95 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -type d -name "docs" -exec rm -rf {} + 2>/dev/null || true
96 # Remove .d.ts type definitions (not needed at runtime) — saves ~10M+
97 find "${pkgdir}/usr/lib/${pkgname}/node_modules" -name "*.d.ts" -delete
98 # Remove TypeScript compiler (devDependency that survived prune) — saves ~23M
99 rm -rf "${pkgdir}/usr/lib/${pkgname}/node_modules/typescript"
100 # Remove @types packages (type-only, not needed at runtime) — saves ~4M
101 rm -rf "${pkgdir}/usr/lib/${pkgname}/node_modules/@types"
102 # Remove @napi-rs/canvas native binary (mermaid server-side canvas; Electron uses browser canvas) — saves ~32M
103 rm -rf "${pkgdir}/usr/lib/${pkgname}/node_modules/@napi-rs/canvas-linux-x64-gnu"
104 # Clean up out/main/kun/ — remove source, tests, build scripts, and type definitions
105 rm -rf "${pkgdir}/usr/lib/${pkgname}/out/main/kun/src"
106 rm -rf "${pkgdir}/usr/lib/${pkgname}/out/main/kun/tests"
107 rm -rf "${pkgdir}/usr/lib/${pkgname}/out/main/kun/scripts"
108 find "${pkgdir}/usr/lib/${pkgname}/out/main/kun" -name "*.d.ts" -delete
109 find "${pkgdir}/usr/lib/${pkgname}/out/main/kun" -name "*.d.ts.map" -delete
110 find "${pkgdir}/usr/lib/${pkgname}/out/main/kun" -name "*.map" -delete
111
112 # Create launch script
113 install -Dm755 /dev/stdin "${pkgdir}/usr/bin/${pkgname}" << 'LAUNCHER'
114#!/bin/bash
115
116XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-~/.config}
117
118if [[ -f "${XDG_CONFIG_HOME}/kun-flags.conf" ]]; then
119 mapfile -t KUN_USER_FLAGS <<<"$(grep -v '^#' "${XDG_CONFIG_HOME}/kun-flags.conf")"
120 echo "User flags:" ${KUN_USER_FLAGS[@]}
121fi
122
123# Use native Wayland when available, fallback to X11
124export ELECTRON_OZONE_PLATFORM_HINT=${ELECTRON_OZONE_PLATFORM_HINT:-auto}
125
126# Enable Wayland IME switches even when XWayland is active (DISPLAY is set)
127# Without this, the source code's condition (WAYLAND_DISPLAY && !DISPLAY) fails
128export KUN_LINUX_WAYLAND_IME=${KUN_LINUX_WAYLAND_IME:-1}
129
130# Set IM environment variables for input method support (fcitx5/ibus)
131if [[ -z "${GTK_IM_MODULE}" ]]; then
132 if [[ -n "${XMODIFIERS}" && "${XMODIFIERS}" == *"fcitx"* ]]; then
133 export GTK_IM_MODULE=fcitx
134 elif command -v fcitx5 &>/dev/null; then
135 export GTK_IM_MODULE=fcitx
136 export XMODIFIERS=${XMODIFIERS:-@im=fcitx}
137 elif command -v ibus-daemon &>/dev/null; then
138 export GTK_IM_MODULE=ibus
139 export XMODIFIERS=${XMODIFIERS:-@im=ibus}
140 fi
141fi
142
143exec -a kun /bin/electron34 /usr/lib/kun/out/main/index.js \
144 --name=kun \
145 ${KUN_USER_FLAGS[@]} "$@"
146LAUNCHER
147
148 # Install desktop file
149 install -Dm644 /dev/stdin "${pkgdir}/usr/share/applications/${pkgname}.desktop" << 'EOF'
150[Desktop Entry]
151Name=Kun
152Comment=AI agent workspace with Code and Write modes
153Exec=kun %U
154Icon=kun
155Type=Application
156Categories=Development;
157StartupWMClass=kun
158EOF
159
160 # Install icon to hicolor theme (required for KDE Wayland dock icon matching)
161 install -Dm644 "src/asset/img/kun.png" \
162 "${pkgdir}/usr/share/icons/hicolor/256x256/apps/kun.png"
163 # Also keep in pixmaps as fallback
164 install -Dm644 "src/asset/img/kun.png" "${pkgdir}/usr/share/pixmaps/kun.png"
165
166 # Install license
167 install -d "${pkgdir}/usr/share/licenses/${pkgname}"
168 cat > "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" << 'EOF'
169PolyForm Noncommercial License 1.0.0
170https://polyformproject.org/licenses/noncommercial/1.0.0
171
172Copyright (c) Kun Contributors
173EOF
174}
175

Scan history

Scanned at (UTC)SeverityRules
2026-08-03 00:08:14 LOW 2
2026-08-02 00:16:08 LOW 2
2026-08-01 00:11:18 LOW 2
2026-07-31 00:14:10 LOW 2
2026-07-30 00:17:23 LOW 2
2026-07-29 00:25:53 LOW 2
2026-07-28 00:07:28 LOW 2
2026-07-27 00:24:32 LOW 2
2026-07-26 00:07:32 LOW 2
2026-07-25 00:13:44 LOW 2
2026-07-24 00:02:28 LOW 2
2026-07-23 00:14:47 LOW 2
2026-07-22 00:29:32 LOW 2
2026-07-21 00:24:15 LOW 2
2026-07-20 00:19:49 LOW 2
2026-07-19 00:17:08 LOW 2
2026-07-18 00:14:48 LOW 2
2026-07-17 00:06:16 LOW 2
2026-07-16 00:05:41 LOW 2
2026-07-15 00:09:25 LOW 2

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion