boxlang-runtime-desktop-electron — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited boxlang-runtime-desktop-electron (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill applies to desktop applications that embed BoxLang using Electron and run a local BoxLang MiniServer process.
Core model:
This pattern gives a desktop UX without replacing BoxLang with another backend stack.
Expected module boundaries:
app/electron/Main.js: app bootstrap and module wiring.app/electron/BoxLang.js: MiniServer process manager (start/stop/restart/readiness).app/electron/AppMenu.js: application menu.app/electron/TrayMenu.js: tray behavior and status.app/electron/Shortcuts.js: global keyboard shortcuts.runtime/Package.bx: MiniServer runtime packager using .bvmrc.miniserver.json: local server runtime controls..boxlang-dev.json: development BoxLang runtime defaults..boxlang.json: production BoxLang runtime defaults.Preserve modular boundaries in app/electron/* instead of collapsing logic into a single file.
Package the MiniServer runtime, not Java:
runtime/binruntime/lib.bvmrcruntime/Package.bxruntime/bin/boxlang-miniserver first, global boxlang-miniserver fallback.Important runtime constraint:
miniserver.json (development server control)Use this as the primary local server control file for desktop development:
Example:
{
"port": 59700,
"host": "127.0.0.1",
"webRoot": "public",
"serverHome": ".boxlang",
"rewrites": true,
"debug": false,
"envFile": ".env"
}.boxlang-dev.json vs .boxlang.jsonUse split runtime config for predictable behavior:
.boxlang-dev.json: development-focused runtime behavior (debugMode, cache toggles, testing mappings)..boxlang.json: production defaults for packaged desktop execution.Both should include baseline mappings so classes/templates resolve predictably:
"/app": {
"path": "${user-dir}/app",
"external": false
},
"/public": "${user-dir}/public"Recommended process flow in BoxLang.js:
miniserver.json.Checklist for robust lifecycle handling:
Common script set for this runtime style:
npm run dev: Vite + Electron development loop.npm run build: build frontend assets to public/includes/resources.npm run package:miniserver: download/extract runtime from .bvmrc.npm run package: build assets and package desktop app.npm run package:full: package MiniServer, then package app.Use package:full for distributable builds.
This project uses Electron Forge as the packaging and distribution tool (forge.config.cjs).
forge.config.cjs) — Forge does not support ESM config files.electron-forge make (wrapped in the package / package:mac / package:win / package:linux npm scripts).asar must always be falsepackagerConfig: {
asar: false,
...
}BoxLang.js spawns runtime/bin/boxlang-miniserver as a real OS process. If asar: true, Forge archives the app directory into a single .asar file and the spawned path no longer exists on the filesystem, breaking MiniServer startup entirely.
Forge resolves icons from the base name in packagerConfig.icon:
icon: "./public/includes/icon",It then appends the platform-appropriate extension automatically:
| Platform | Extension | Source |
|---|---|---|
| macOS | .icns | public/includes/icon.icns (from iconset via iconutil) |
| Windows | .ico | public/includes/icon.ico (generated by npm run generate:icons) |
| Linux | .png | public/includes/icon.iconset/icon.png |
All three files must exist at package time. Missing any one causes a fatal Forge error on that platform.
| Platform | Maker | Output |
|---|---|---|
| macOS | @electron-forge/maker-dmg, @electron-forge/maker-zip | .dmg, .zip |
| Windows | @electron-forge/maker-squirrel, @electron-forge/maker-zip | .exe (Squirrel), .zip |
| Linux | @electron-forge/maker-deb, @electron-forge/maker-rpm | .deb, .rpm |
Windows installer uses Squirrel, not NSIS.
The config includes a postMake hook that copies unsigned-build helper scripts (mac-open.sh, win-unblock.ps1, UNSIGNED-BUILD.md) into every ZIP artifact so end users have bypass instructions without hunting for docs.
bx:http {}, bx:zip {}), never new bx:....CliGetArgs().expandPath() and check file/directory existence before destructive operations.path.join().runtime/bin and runtime/lib exist (run npm run package:miniserver).boxlang-miniserver is on PATH.miniserver.json host/port/webRoot values.npm run package:miniserver:force.runtime/bin/boxlang-miniserver.npm run build and confirm manifest exists in public/includes/resources/.vite/manifest.json.Pin the Windows runner to Node 20 LTS. cross-zip (a transitive dependency of @electron-forge/maker-zip) calls fs.rmdir(path, { recursive: true }), which was removed in Node.js 22+. Running Node 25 on windows-latest causes a hard failure during the Squirrel make step:
TypeError [ERR_INVALID_ARG_VALUE]: The property 'options.recursive' is no longer supported. Received trueWorkaround in .github/workflows/build.yml:
- name: Set up Node.js
uses: actions/setup-node@v6
with:
# Pin to Node 20 LTS — cross-zip uses fs.rmdir({recursive:true}) removed in Node 22+
node-version: "20"
cache: "npm"Revisit when cross-zip or @electron-forge/maker-zip ships a patched release.
.ico Icon RequirementThe Squirrel installer (@electron-forge/maker-squirrel) requires a real .ico file on Windows. Forge auto-resolves icons from the base name configured in packagerConfig.icon. A missing .ico produces:
Fatal error: Unable to set iconThe scripts/generate-icons.js script generates public/includes/icon.ico from the PNG iconset. Run it in CI before packaging:
- name: Generate Windows icon
run: npm run generate:icons
- name: Package Electron app (Windows)
run: npm run package:winAlternatively, commit public/includes/icon.ico to the repository to skip the generation step in CI entirely (recommended for faster, more predictable builds).
For repositories using this starter, adopt the two-file instruction pattern for maximum agent compatibility:
AGENTS.md and repeats critical safety guardrails.Template for .github/copilot-instructions.md:
# Project — Copilot Bridge Instructions
Use AGENTS.md at repository root as the canonical instruction source.
## Canonical Source
- Primary instructions: AGENTS.md
- If any conflict exists, AGENTS.md wins.
## Critical Guardrails
- Keep modular boundaries in app/electron/* — do not collapse into a single file.
- Preserve process lifecycle safety in MiniServer startup and shutdown paths.
- Preserve cross-platform behavior (macOS, Windows, Linux).
- Do not remove packaged-runtime-first fallback to global boxlang-miniserver.
- Never enable asar in forge.config.cjs — MiniServer spawning requires real filesystem paths.miniserver.json as developer-facing runtime control..boxlang-dev.json and .boxlang.json under source control./app and /public mappings stable unless there is a deliberate architecture change.public/includes/icon.ico to avoid Windows icon generation in CI.cross-zip is updated for Node 22+.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.