-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathjustfile
More file actions
433 lines (368 loc) · 16 KB
/
justfile
File metadata and controls
433 lines (368 loc) · 16 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# AionUI Development Justfile
# Usage: just <recipe>
# Use PowerShell on all platforms for consistency
set shell := ["pwsh", "-NoProfile", "-Command"]
set windows-shell := ["powershell.exe", "-NoProfile", "-Command"]
# Default recipe: show available commands
default:
@just --list --unsorted
# ============================================================
# Development
# ============================================================
# Start development server (Electron + Vite HMR)
dev:
bun run start
# Start WebUI development mode
webui:
bun run webui
# Start WebUI with remote access
webui-remote:
bun run webui:remote
# Start WebUI production mode
webui-prod:
bun run webui:prod
# Run CLI mode
cli:
bun run cli
# ============================================================
# Environment Checks (from CI experience)
# ============================================================
# Check all build prerequisites are met
[no-exit-message]
preflight:
$ErrorActionPreference = 'Continue'; \
$failed = $false; \
Write-Host "=========================================="; \
Write-Host " AionUI Build Preflight Check"; \
Write-Host "=========================================="; \
Write-Host ""; \
Write-Host "[1/6] Node.js..."; \
try { \
$nodeVer = (node --version 2>&1).Trim(); \
$major = [int]($nodeVer -replace '^v','').Split('.')[0]; \
if ($major -ge 22) { Write-Host " OK Node.js $nodeVer" } \
else { Write-Host " WARN Node.js $nodeVer (recommend >= 22)" } \
} catch { Write-Host " FAIL Node.js not found"; $failed = $true }; \
Write-Host "[2/6] bun..."; \
try { \
$bunVer = (bun --version 2>&1).Trim(); \
Write-Host " OK bun $bunVer" \
} catch { Write-Host " FAIL bun not found"; $failed = $true }; \
Write-Host "[3/6] Python (for native modules)..."; \
try { \
$pyVer = (python --version 2>&1).Trim(); \
Write-Host " OK $pyVer" \
} catch { Write-Host " WARN Python not found (needed for native module compilation)" }; \
Write-Host "[4/6] Dependencies (node_modules)..."; \
if ((Test-Path "node_modules") -and ((Test-Path "bun.lock") -or (Test-Path "package-lock.json"))) { \
Write-Host " OK node_modules exists" \
} else { \
Write-Host " WARN node_modules missing - running: just install"; \
just install; \
if (Test-Path "node_modules") { Write-Host " OK node_modules installed" } \
else { Write-Host " FAIL Failed to install dependencies"; $failed = $true } \
}; \
Write-Host "[5/6] Native modules (better-sqlite3)..."; \
$nativeOk = (Test-Path "node_modules/better-sqlite3/build/Release/better_sqlite3.node") -or (Test-Path "node_modules/better-sqlite3/prebuilds"); \
if ($nativeOk) { Write-Host " OK better-sqlite3 native module found" } \
else { Write-Host " WARN better-sqlite3 native binary missing - run: just rebuild-native" }; \
Write-Host "[6/6] Electron version..."; \
try { \
$electronVer = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
Write-Host " OK Electron $electronVer" \
} catch { Write-Host " FAIL Cannot read Electron version"; $failed = $true }; \
Write-Host ""; \
Write-Host "=========================================="; \
if ($failed) { Write-Host " PREFLIGHT FAILED"; exit 1 } \
else { Write-Host " PREFLIGHT PASSED" }; \
Write-Host "=========================================="
# Show current build environment info
info:
Write-Host "AionUI Build Environment"; \
Write-Host "========================"; \
Write-Host "Node: $((node --version 2>&1).Trim())"; \
Write-Host "bun: $((bun --version 2>&1).Trim())"; \
$electronVer = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
$appVer = (node -p "require('./package.json').version" 2>&1).Trim(); \
Write-Host "App: v$appVer"; \
Write-Host "Electron: $electronVer"; \
Write-Host "Branch: $((git branch --show-current 2>&1).Trim())"; \
Write-Host "Commit: $((git rev-parse --short HEAD 2>&1).Trim())"
# ============================================================
# Dependencies & Native Modules
# ============================================================
# Install dependencies (clean install)
install:
bun install
# Install dependencies (with lockfile update)
install-update:
bun install
# Full setup: install deps + rebuild native modules
setup: install rebuild-native
# Rebuild native modules for Electron (critical step!)
# On Windows, ensure MSVC build tools are installed via:
# choco install visualstudio2022buildtools --package-parameters "--add Microsoft.VisualStudio.Workload.VCTools"
# or install Visual Studio 2022 with "Desktop development with C++" workload.
[no-exit-message]
rebuild-native:
$ErrorActionPreference = 'Stop'; \
$electronVer = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
Write-Host "=========================================="; \
Write-Host "Rebuilding native modules for Electron $electronVer"; \
Write-Host "=========================================="; \
Write-Host ""; \
Write-Host "[Step 1] electron-rebuild..."; \
bunx electron-rebuild -f -w better-sqlite3; \
Write-Host " OK electron-rebuild completed"; \
Write-Host ""; \
Write-Host "[Verify] Checking native modules..."; \
$verified = $true; \
$sqliteNode = "node_modules/better-sqlite3/build/Release/better_sqlite3.node"; \
if (Test-Path $sqliteNode) { \
$size = [math]::Round((Get-Item $sqliteNode).Length / 1MB, 1); \
Write-Host " OK better-sqlite3 ($size MB)" \
} elseif (Test-Path "node_modules/better-sqlite3/prebuilds") { \
Write-Host " OK better-sqlite3 (prebuilds)" \
} else { \
Write-Host " FAIL better-sqlite3 native module not found"; \
$verified = $false \
}; \
Write-Host ""; \
if ($verified) { \
Write-Host " All native modules verified" \
} else { \
Write-Host " NATIVE MODULE VERIFICATION FAILED"; \
exit 1 \
}
# Verify native modules can actually be loaded by Node.js
[no-exit-message]
verify-native:
Write-Host "Verifying native modules can be loaded..."; \
$result = node -e "try { require('better-sqlite3'); console.log('OK'); } catch(e) { console.log('FAIL: ' + e.message); process.exit(1); }" 2>&1; \
if ($result -match "OK") { \
Write-Host " OK better-sqlite3 loads correctly" \
} else { \
Write-Host " FAIL better-sqlite3: $result"; \
Write-Host " Run: just rebuild-native"; \
exit 1 \
}; \
Write-Host "All native modules verified and loadable."
# ============================================================
# Build (mirrors CI workflow environment setup)
# ============================================================
# Build for current platform (preflight → build)
build: preflight
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
bun run build
# Quick build - uses cached Vite output if available
build-quick: preflight
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
node scripts/build-with-builder.js auto --skip-native
# Build package only (no installer) - fastest iteration
build-package: preflight
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
node scripts/build-with-builder.js auto --pack-only --skip-native
# Force full rebuild (clears cache)
build-force: preflight clean
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
node scripts/build-with-builder.js auto --force
# Build for Windows x64
build-win-x64: preflight
Write-Host "Ensuring npm dependencies..."; \
if (-not (Test-Path "node_modules")) { npm install } else { npm install --prefer-offline }; \
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
$env:npm_config_runtime = "electron"; \
$env:npm_config_target = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
$env:npm_config_arch = "x64"; \
$env:npm_config_target_arch = "x64"; \
$env:npm_config_disturl = "https://electronjs.org/headers"; \
$env:npm_config_build_from_source = "true"; \
$env:MSVS_VERSION = "2022"; \
$env:GYP_MSVS_VERSION = "2022"; \
node scripts/build-with-builder.js x64 --win --x64
# Build for Windows arm64
build-win-arm64: preflight
Write-Host "Ensuring npm dependencies..."; \
if (-not (Test-Path "node_modules")) { npm install } else { npm install --prefer-offline }; \
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
$env:npm_config_runtime = "electron"; \
$env:npm_config_target = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
$env:npm_config_arch = "arm64"; \
$env:npm_config_target_arch = "arm64"; \
$env:npm_config_disturl = "https://electronjs.org/headers"; \
$env:npm_config_build_from_source = "true"; \
$env:MSVS_VERSION = "2022"; \
$env:GYP_MSVS_VERSION = "2022"; \
node scripts/build-with-builder.js arm64 --win --arm64
# Build for Windows (auto-detect arch)
build-win: preflight
Write-Host "Cleaning output directory..."; \
Get-Process -Name "AionUI","electron" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue; \
if (Test-Path "out") { Remove-Item -Recurse -Force "out" -ErrorAction SilentlyContinue }; \
npm install; \
npm run postinstall; if ($LASTEXITCODE -ne 0) { Write-Host "postinstall failed (continuing)"; $LASTEXITCODE = 0 }; \
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
$env:MSVS_VERSION = "2022"; \
$env:GYP_MSVS_VERSION = "2022"; \
bun run build-win
# Build for macOS ARM64
build-mac-arm64: preflight
Write-Host "Ensuring npm dependencies..."; \
if (-not (Test-Path "node_modules")) { npm install } else { npm install --prefer-offline }; \
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
$env:npm_config_runtime = "electron"; \
$env:npm_config_target = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
$env:npm_config_disturl = "https://electronjs.org/headers"; \
node scripts/build-with-builder.js arm64 --mac --arm64
# Build for macOS x64
build-mac-x64: preflight
Write-Host "Ensuring npm dependencies..."; \
if (-not (Test-Path "node_modules")) { npm install } else { npm install --prefer-offline }; \
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
$env:npm_config_runtime = "electron"; \
$env:npm_config_target = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
$env:npm_config_disturl = "https://electronjs.org/headers"; \
node scripts/build-with-builder.js x64 --mac --x64
# Build for macOS (arm64 + x64)
build-mac: preflight
Write-Host "Ensuring npm dependencies..."; \
if (-not (Test-Path "node_modules")) { npm install } else { npm install --prefer-offline }; \
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
$env:npm_config_runtime = "electron"; \
$env:npm_config_target = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
$env:npm_config_disturl = "https://electronjs.org/headers"; \
bun run build-mac
# Build for Linux
build-linux: preflight
Write-Host "Ensuring npm dependencies..."; \
if (-not (Test-Path "node_modules")) { npm install } else { npm install --prefer-offline }; \
$env:NODE_OPTIONS = "--max-old-space-size=8192"; \
$env:npm_config_runtime = "electron"; \
$env:npm_config_target = (node -p "require('./package.json').devDependencies.electron.replace(/[\^~]/g, '')" 2>&1).Trim(); \
$env:npm_config_disturl = "https://electronjs.org/headers"; \
bun run build-deb
# Package only (electron-vite build, no installer)
package:
bun run package
# Distribute (shortcut)
dist:
bun run dist
# ============================================================
# Code Quality
# ============================================================
# Run linter
lint:
bun run lint
# Run linter with auto-fix
lint-fix:
bun run lint:fix
# Format code
fmt:
bun run format
# Check formatting
fmt-check:
bun run format:check
# Type check
typecheck:
bunx tsc --noEmit
# Run all checks (lint + format + typecheck) — mirrors CI code-quality job
check: lint fmt-check typecheck
# ============================================================
# Testing
# ============================================================
# Run all tests
test:
bun run test
# Run tests in watch mode
test-watch:
bun run test:watch
# Run tests with coverage
test-coverage:
bun run test:coverage
# Run contract tests
test-contract:
bun run test:contract
# Run integration tests
test-integration:
bun run test:integration
# Verify packaged artifact contains complete renderer assets (i18n safety)
test-packaged-i18n:
bun run test:packaged:i18n
# Run E2E tests (Playwright + Electron — auto-launches app)
# Builds main+preload+renderer into out/ first to ensure fresh artifacts.
e2e-test:
bun run package
bunx playwright test --config playwright.config.ts
# Run only extension-related E2E tests (faster iteration)
e2e-test-ext:
bun run package
bunx playwright test --config playwright.config.ts tests/e2e/specs/ext-*.e2e.ts
# Run E2E tests with headed browser (for debugging)
e2e-test-headed:
bun run package
bunx playwright test --config playwright.config.ts --headed
# Open Playwright HTML report after test run
e2e-report:
bunx playwright show-report tests/e2e/report
# ============================================================
# Extension System (RFC-001)
# ============================================================
# Start dev server with example extensions loaded
# CDP remote debugging is enabled by default on port 9222 in dev mode
dev-ext:
node scripts/dev-bootstrap.mjs launch start --extensions
# Start WebUI with example extensions loaded
webui-ext:
node scripts/dev-bootstrap.mjs launch webui --extensions
# Start CLI with example extensions loaded
cli-ext:
node scripts/dev-bootstrap.mjs launch cli --extensions
# Cross-platform diagnosis for dev extension startup
dev-ext-doctor:
node scripts/dev-bootstrap.mjs doctor
# Launch packaged (unpacked) app with example extensions for one-click debugging
# Requires out/*-unpacked artifacts
packaged-ext:
node scripts/packaged-launch.mjs
# Build package first, then launch with example extensions
packaged-ext-build: build-package
node scripts/packaged-launch.mjs
# Validate extension system types compile correctly
ext-typecheck:
bunx tsc --noEmit --project tsconfig.json
# Run extension system tests
ext-test:
bunx vitest run tests/extensions/ --passWithNoTests
# Run extension system tests in watch mode
ext-test-watch:
bunx vitest tests/extensions/
# ============================================================
# Utilities
# ============================================================
# Reset WebUI password
reset-password:
bun run resetpass
# Clean build artifacts
clean:
if (Test-Path "out") { Remove-Item -Recurse -Force "out" }; \
if (Test-Path "dist") { Remove-Item -Recurse -Force "dist" }; \
Write-Host "Build artifacts cleaned."
# Deep clean (build artifacts + node_modules)
clean-all: clean
if (Test-Path "node_modules") { \
Write-Host "Removing node_modules..."; \
Remove-Item -Recurse -Force "node_modules" \
}; \
Write-Host "Full clean complete. Run: just setup"
# List build output artifacts
list-artifacts:
if (Test-Path "out") { \
Get-ChildItem out -Recurse -Include *.exe,*.msi,*.dmg,*.deb,*.AppImage,*.zip | \
ForEach-Object { \
$size = [math]::Round($_.Length / 1MB, 1); \
Write-Host " $($_.Name) ($size MB)" \
} \
} else { Write-Host "No build output found. Run: just build" }
# CI-like full build validation (mirrors GitHub Actions workflow)
ci-local: check test build
Write-Host "CI-local pipeline passed!"