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>
2
pkgname=kun
3
pkgver=0.2.20
4
pkgrel=2
5
pkgdesc="AI agent workspace with Code and Write modes - Electron client"
6
arch=('x86_64')
7
url="https://github.com/KunAgent/Kun"
8
license=('custom:PolyForm-Noncommercial-1.0.0')
9
depends=('electron34')
10
makedepends=('npm' 'nodejs>=20' 'python')
11
optdepends=('libxss: screen saver inhibit support'
12
'libappindicator-gtk3: system tray support on GTK-based DEs')
13
replaces=('kun-gui')
14
conflicts=('kun-gui')
15
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/KunAgent/Kun/archive/refs/tags/v${pkgver}.tar.gz")
16
sha256sums=('2615e45f556f99e5756d986bd214838153f021a3bb46d0bcae3a10ff7fb7a53e')
17
options=('!strip')
18
19
prepare() {
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
27
build() {
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
50
package() {
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
116
XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-~/.config}
117
118
if [[ -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[@]}
121
fi
122
123
# Use native Wayland when available, fallback to X11
124
export 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
128
export KUN_LINUX_WAYLAND_IME=${KUN_LINUX_WAYLAND_IME:-1}
129
130
# Set IM environment variables for input method support (fcitx5/ibus)
131
if [[ -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
141
fi
142
143
exec -a kun /bin/electron34 /usr/lib/kun/out/main/index.js \
144
--name=kun \
145
${KUN_USER_FLAGS[@]} "$@"
146
LAUNCHER
147
148
# Install desktop file
149
install -Dm644 /dev/stdin "${pkgdir}/usr/share/applications/${pkgname}.desktop" << 'EOF'
150
[Desktop Entry]
151
Name=Kun
152
Comment=AI agent workspace with Code and Write modes
153
Exec=kun %U
154
Icon=kun
155
Type=Application
156
Categories=Development;
157
StartupWMClass=kun
158
EOF
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'
169
PolyForm Noncommercial License 1.0.0
170
https://polyformproject.org/licenses/noncommercial/1.0.0
171
172
Copyright (c) Kun Contributors
173
EOF
174
}
175
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 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 |