seabox 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,310 +1,310 @@
1
- # seabox
2
-
3
- A reusable tool for building Node.js Single Executable Applications (SEA) with native-module support and binary extraction.
4
-
5
- ## Features
6
-
7
- - Bundle Node.js applications into standalone executables
8
- - **Automatic asset detection** from `path.join(__dirname, ...)` patterns
9
- - **Automatic native module detection** (.node files) with pattern transforms
10
- - Platform-specific library extraction (DLLs, shared libraries)
11
- - Asset encryption with obfuscated keys
12
- - Multi-platform targeting (Windows, Linux, macOS)
13
- - V8 snapshot support for faster startup
14
- - Integrity checking for extracted binaries
15
- - Automatic code signature removal before injection
16
-
17
- ## Use case
18
- This tooling was created as an alternative to pkg, which is unfortunatly deprecated, and where forks were running foul of virus checkers. By using node's SEA, the executables are directly downloaded from nodejs's distribution source, and built using node's native Single Executable Application solution. Unfortunatly this does mean native modules embedded within the exe cannot run directly and must be extracted to a location on the disk on first run - This tooling automates that process for you, while providing arbitrary asset embedding. Embedded assets are _not_ extracted and access to them is handled by intercepting require and fs.
19
-
20
- Note: **V8 snapshot includes and embedds the original source**, this is currently a limitation of Node's SEA tooling as far as I can tell; thus the snapshot is only useful for faster startup. Its possible to get around this by using bytenode's vm.script hack (embed the bytenode code as an asset and run another vm snapshot with the faux script input) and I'll look into supporting it in the future.
21
-
22
- ## Installation
23
-
24
- ```bash
25
- npm install --save-dev seabox
26
- ```
27
-
28
- ### Optional: Windows Executable Metadata
29
-
30
- If you want to customize Windows executable metadata (icon, version info), install `rcedit`:
31
-
32
- ```bash
33
- npm install --save-dev rcedit
34
- ```
35
-
36
- This is only needed if you use the `rcedit` configuration option.
37
-
38
- ## Configuration
39
-
40
- Create a `seabox.config.json` file in your project root:
41
-
42
- ```json
43
- {
44
- "entry": "./src/index.js",
45
- "outputs": [
46
- {
47
- "path": "./dist/win",
48
- "target": "node24.11.0-win32-x64",
49
- "output": "myapp.exe"
50
- }
51
- ],
52
- "bundler": {
53
- "external": []
54
- },
55
- "encryptAssets": false,
56
- "useSnapshot": true,
57
- "verbose": false
58
- }
59
- ```
60
-
61
- ## Configuration Options
62
-
63
- | Option | Type | Required | Description |
64
- |--------|------|----------|-------------|
65
- | `entry` | `string` | Yes | Path to your application's entry point |
66
- | `outputs` | `array` | Yes | Array of build targets |
67
- | `outputs[].path` | `string` | Yes | Output directory for this target |
68
- | `outputs[].target` | `string` | Yes | Build target (format: `nodeX.Y.Z-platform-arch`) |
69
- | `outputs[].output` | `string` | Yes | Output filename |
70
- | `outputs[].libraries` | `array` | No | Explicit glob patterns for shared libraries (DLLs/SOs) requiring filesystem extraction. Libraries referenced in code via `, ...)` are automatically detected. |
71
- | `outputs[].rcedit` | `object` | No | Windows executable metadata (icon, version info) |
72
- | `assets` | `array` | No | Glob patterns for assets to embed (merged with auto-detected assets) |
73
- | `bundler` | `object` | No | Rolldown Bundler options |
74
- | `bundler.external` | `array` | No | Modules to exclude from bundling |
75
- | `bundler.plugins` | `array` | No | Additional Rolldown plugins |
76
- | `bundler.minify` | `boolean` | No | Minify bundled code |
77
- | `bundler.sourcemap` | `boolean` | No | Generate source maps |
78
- | `encryptAssets` | `boolean` | No | Enable asset encryption (default: false) |
79
- | `encryptExclude` | `array` | No | Glob patterns to exclude from encryption |
80
- | `useSnapshot` | `boolean` | No | Enable V8 startup snapshots (default: true) |
81
- | `useCodeCache` | `boolean` | No | Enable V8 code cache (default: false) |
82
- | `cacheLocation` | `string` | No | Path for code cache storage |
83
- | `sign` | `string` | No | Path to custom signing script (.mjs/.cjs) |
84
- | `verbose` | `boolean` | No | Enable verbose logging (default: false) |
85
-
86
- ## Usage
87
-
88
- ### CLI Commands
89
-
90
- ```bash
91
- # Build executable(s)
92
- npx seabox build
93
-
94
- # Build with verbose output
95
- npx seabox build --verbose
96
-
97
- # Specify custom config file
98
- npx seabox build --config custom-config.json
99
-
100
- # Initialize a new config file
101
- npx seabox init
102
-
103
- # Show help
104
- npx seabox help
105
- ```
106
-
107
- ### npm Scripts (Recommended)
108
-
109
- Add to your `package.json`:
110
-
111
- ```json
112
- {
113
- "scripts": {
114
- "build": "seabox build",
115
- "build:verbose": "seabox build --verbose"
116
- }
117
- }
118
- ```
119
-
120
- Then run:
121
-
122
- ```bash
123
- npm run build
124
- ```
125
-
126
- ### Programmatic API
127
-
128
- ```javascript
129
- import { build } from 'seabox';
130
-
131
- await build({
132
- projectRoot: process.cwd(),
133
- verbose: true
134
- });
135
- ```
136
-
137
- ## How It Works
138
-
139
- seabox automates the entire SEA build process:
140
-
141
- 1. **Bundling** - Automatically bundles your app with Rolldown, detecting:
142
- - Native module patterns (`bindings`, `node-gyp-build`, direct `.node` requires)
143
- - Asset references via `path.join(__dirname, 'relative/path')`
144
- - Additional
145
-
146
- 2. **Asset Collection** - Gathers assets from three sources:
147
- - **Auto-detected**: Files referenced via `path.join(__dirname, ...)` patterns
148
- - **Config globs**: Patterns specified in `assets` array
149
- - **Libraries**: Platform-specific shared libraries (DLLs/SOs)
150
-
151
- 3. **Native Module Rebuilding** - Rebuilds native modules for target platform
152
-
153
- 4. **Bootstrap Injection** - Adds runtime code for asset loading and native module extraction
154
-
155
- 5. **SEA Blob Creation** - Packages everything using Node.js SEA tooling
156
-
157
- 6. **Binary Preparation** - Downloads target Node.js binary and removes code signature
158
-
159
- 7. **Injection** - Uses `postject` to inject the blob into the Node.js binary
160
-
161
- 8. **Output** - Produces standalone executable(s) ready for distribution
162
-
163
- ### Automatic Asset Detection
164
-
165
- **Like pkg**, seabox automatically detects and embeds assets referenced in your code:
166
-
167
- ```javascript
168
- import path from 'path';
169
- import { fileURLToPath } from 'url';
170
-
171
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
172
-
173
- // This asset will be automatically detected and embedded
174
- const configPath = path.join(__dirname, '../config/app.json');
175
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
176
- ```
177
-
178
- **Asset sources (merged and deduplicated):**
179
- 1. **Auto-detected** from code analysis during bundling
180
- 2. **Config globs** from `assets: ["./data/**/*", "./public/**/*"]`
181
- 3. **Platform libraries** from `outputs[].libraries` (e.g., DLLs for Windows)
182
-
183
- ### Native Module Support
184
-
185
- seabox automatically handles native modules without any configuration:
186
-
187
- **Supported patterns:**
188
- - `require('bindings')('module')` - Standard bindings package
189
- - `require('./build/Release/addon.node')` - Direct requires
190
- - `require('node-gyp-build')(__dirname)` - Prebuild binaries
191
- - `require('node-pre-gyp')` patterns - Pre-compiled binaries
192
-
193
- **At runtime:**
194
- - Native modules are extracted to a cache directory on first run
195
- - Modules are integrity-checked with SHA-256 hashes
196
- - Custom `require()` shim loads modules from cache
197
-
198
- ### Platform-Specific Libraries
199
-
200
- Libraries that require filesystem access (like DLLs loaded via `dlopen`) can be included in two ways:
201
-
202
- **1. Automatic Detection (Recommended)**
203
-
204
- If your code references a DLL using `path.join(__dirname, ...)`, it will be automatically detected and included:
205
-
206
- ```javascript
207
- // This will be automatically detected during bundling
208
- const dllPath = path.join(__dirname, './lib/RGDevice.dll');
209
- ```
210
-
211
- **2. Explicit Glob Patterns**
212
-
213
- You can also explicitly specify library patterns in your config:
214
-
215
- ```json
216
- {
217
- "outputs": [
218
- {
219
- "target": "node24.11.0-win32-x64",
220
- "libraries": ["lib/*.dll"] // Manually specify DLLs to include
221
- }
222
- ]
223
- }
224
- ```
225
-
226
-
227
- These files are extracted on first run (like `.node` files) since they need to be loaded from the filesystem.
228
-
229
- ### Code Signature Removal
230
- If you have sign tools available, the seabox will attempt to unsign the node exe before modifying it. This is to reduce issues afterward when you try to resign it.
231
- - **Windows**: `signtool.exe` (from Windows SDK)
232
- - **macOS**: `codesign` (included with Xcode)
233
- - **Linux**: Not required
234
-
235
- ### Custom Signing
236
-
237
- You can apply code signing after the build completes by specifying a custom signing script:
238
-
239
- ```json
240
- {
241
- "sign": "./scripts/sign.mjs"
242
- }
243
- ```
244
-
245
- The signing script must export a default function that receives a config object:
246
-
247
- ```javascript
248
- // scripts/sign.mjs
249
- export default async function sign(config) {
250
- const { exePath, target, platform, arch, nodeVersion, projectRoot } = config;
251
-
252
- // Example: Windows code signing with signtool
253
- if (platform === 'win32') {
254
- execSync(`signtool sign /fd SHA256 /a "${exePath}"`);
255
- }
256
-
257
- // Example: macOS code signing
258
- if (platform === 'darwin') {
259
- execSync(`codesign --force --sign "Developer ID" "${exePath}"`);
260
- }
261
- }
262
- ```
263
-
264
- **Config parameters:**
265
- - `exePath` - Absolute path to the built executable
266
- - `target` - Full target string (e.g., "node24.11.0-win32-x64")
267
- - `platform` - Platform name (win32, linux, darwin)
268
- - `arch` - Architecture (x64, arm64)
269
- - `nodeVersion` - Node.js version
270
- - `projectRoot` - Absolute path to project root
271
-
272
- ## Asset Encryption
273
-
274
- seabox supports optional AES-256-GCM encryption of embedded assets to protect your application code and data:
275
-
276
- ```json
277
- {
278
- "sea": {
279
- "encryptAssets": true,
280
- "encryptExclude": ["*.txt", "public/*"],
281
- "useSnapshot": true
282
- }
283
- }
284
- ```
285
-
286
- ### How Encryption Works
287
-
288
- 1. **Build Time**: A random 256-bit encryption key is generated
289
- 2. **Asset Encryption**: Non-binary assets are encrypted using AES-256-GCM
290
- 3. **Key Embedding**: The encryption key is obfuscated and embedded in the bootstrap code
291
- 4. **Key Obfuscation**: the bootstrap and key code are obfuscated
292
- 5. **Runtime Decryption**: Assets are transparently decrypted when accessed
293
-
294
- ### Considerations
295
-
296
- - **Binary files** (`.node`, `.dll`, `.so`, `.dylib`) are **never encrypted** as they must be extracted as-is
297
- - The manifest (`sea-manifest.json`) is **not encrypted** to allow bootstrap initialization
298
- - **V8 snapshot includes the original source**, this is currently a limitation of Node's SEA tooling.
299
- - Encryption provides **obfuscation**, not cryptographic security against determined attackers
300
- - The bootloader code, that includes the encryption key, is obfuscated in the source embedded by Node's SEA
301
-
302
- ## Contributing
303
-
304
- Contributions welcome! Please open an issue or PR on [GitHub](https://github.com/MeirionHughes/seabox).
305
-
306
- ## License
307
-
308
- MIT
309
-
310
- Copyright © 2025 Meirion Hughes
1
+ # seabox
2
+
3
+ A reusable tool for building Node.js Single Executable Applications (SEA) with native-module support and binary extraction.
4
+
5
+ ## Features
6
+
7
+ - Bundle Node.js applications into standalone executables
8
+ - **Automatic asset detection** from `path.join(__dirname, ...)` patterns
9
+ - **Automatic native module detection** (.node files) with pattern transforms
10
+ - Platform-specific library extraction (DLLs, shared libraries)
11
+ - Asset encryption with obfuscated keys
12
+ - Multi-platform targeting (Windows, Linux, macOS)
13
+ - V8 snapshot support for faster startup
14
+ - Integrity checking for extracted binaries
15
+ - Automatic code signature removal before injection
16
+
17
+ ## Use case
18
+ This tooling was created as an alternative to pkg, which is unfortunatly deprecated, and where forks were running foul of virus checkers. By using node's SEA, the executables are directly downloaded from nodejs's distribution source, and built using node's native Single Executable Application solution. Unfortunatly this does mean native modules embedded within the exe cannot run directly and must be extracted to a location on the disk on first run - This tooling automates that process for you, while providing arbitrary asset embedding. Embedded assets are _not_ extracted and access to them is handled by intercepting require and fs.
19
+
20
+ Note: **V8 snapshot includes and embedds the original source**, this is currently a limitation of Node's SEA tooling as far as I can tell; thus the snapshot is only useful for faster startup. Its possible to get around this by using bytenode's vm.script hack (embed the bytenode code as an asset and run another vm snapshot with the faux script input) and I'll look into supporting it in the future.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install --save-dev seabox
26
+ ```
27
+
28
+ ### Optional: Windows Executable Metadata
29
+
30
+ If you want to customize Windows executable metadata (icon, version info), install `rcedit`:
31
+
32
+ ```bash
33
+ npm install --save-dev rcedit
34
+ ```
35
+
36
+ This is only needed if you use the `rcedit` configuration option.
37
+
38
+ ## Configuration
39
+
40
+ Create a `seabox.config.json` file in your project root:
41
+
42
+ ```json
43
+ {
44
+ "entry": "./src/index.js",
45
+ "outputs": [
46
+ {
47
+ "path": "./dist/win",
48
+ "target": "node24.11.0-win32-x64",
49
+ "output": "myapp.exe"
50
+ }
51
+ ],
52
+ "bundler": {
53
+ "external": []
54
+ },
55
+ "encryptAssets": false,
56
+ "useSnapshot": true,
57
+ "verbose": false
58
+ }
59
+ ```
60
+
61
+ ## Configuration Options
62
+
63
+ | Option | Type | Required | Description |
64
+ |--------|------|----------|-------------|
65
+ | `entry` | `string` | Yes | Path to your application's entry point |
66
+ | `outputs` | `array` | Yes | Array of build targets |
67
+ | `outputs[].path` | `string` | Yes | Output directory for this target |
68
+ | `outputs[].target` | `string` | Yes | Build target (format: `nodeX.Y.Z-platform-arch`) |
69
+ | `outputs[].output` | `string` | Yes | Output filename |
70
+ | `outputs[].libraries` | `array` | No | Explicit glob patterns for shared libraries (DLLs/SOs) requiring filesystem extraction. Libraries referenced in code via `, ...)` are automatically detected. |
71
+ | `outputs[].rcedit` | `object` | No | Windows executable metadata (icon, version info) |
72
+ | `assets` | `array` | No | Glob patterns for assets to embed (merged with auto-detected assets) |
73
+ | `bundler` | `object` | No | Rolldown Bundler options |
74
+ | `bundler.external` | `array` | No | Modules to exclude from bundling |
75
+ | `bundler.plugins` | `array` | No | Additional Rolldown plugins |
76
+ | `bundler.minify` | `boolean` | No | Minify bundled code |
77
+ | `bundler.sourcemap` | `boolean` | No | Generate source maps |
78
+ | `encryptAssets` | `boolean` | No | Enable asset encryption (default: false) |
79
+ | `encryptExclude` | `array` | No | Glob patterns to exclude from encryption |
80
+ | `useSnapshot` | `boolean` | No | Enable V8 startup snapshots (default: true) |
81
+ | `useCodeCache` | `boolean` | No | Enable V8 code cache (default: false) |
82
+ | `cacheLocation` | `string` | No | Path for code cache storage |
83
+ | `sign` | `string` | No | Path to custom signing script (.mjs/.cjs) |
84
+ | `verbose` | `boolean` | No | Enable verbose logging (default: false) |
85
+
86
+ ## Usage
87
+
88
+ ### CLI Commands
89
+
90
+ ```bash
91
+ # Build executable(s)
92
+ npx seabox build
93
+
94
+ # Build with verbose output
95
+ npx seabox build --verbose
96
+
97
+ # Specify custom config file
98
+ npx seabox build --config custom-config.json
99
+
100
+ # Initialize a new config file
101
+ npx seabox init
102
+
103
+ # Show help
104
+ npx seabox help
105
+ ```
106
+
107
+ ### npm Scripts (Recommended)
108
+
109
+ Add to your `package.json`:
110
+
111
+ ```json
112
+ {
113
+ "scripts": {
114
+ "build": "seabox build",
115
+ "build:verbose": "seabox build --verbose"
116
+ }
117
+ }
118
+ ```
119
+
120
+ Then run:
121
+
122
+ ```bash
123
+ npm run build
124
+ ```
125
+
126
+ ### Programmatic API
127
+
128
+ ```javascript
129
+ import { build } from 'seabox';
130
+
131
+ await build({
132
+ projectRoot: process.cwd(),
133
+ verbose: true
134
+ });
135
+ ```
136
+
137
+ ## How It Works
138
+
139
+ seabox automates the entire SEA build process:
140
+
141
+ 1. **Bundling** - Automatically bundles your app with Rolldown, detecting:
142
+ - Native module patterns (`bindings`, `node-gyp-build`, direct `.node` requires)
143
+ - Asset references via `path.join(__dirname, 'relative/path')`
144
+ - Additional
145
+
146
+ 2. **Asset Collection** - Gathers assets from three sources:
147
+ - **Auto-detected**: Files referenced via `path.join(__dirname, ...)` patterns
148
+ - **Config globs**: Patterns specified in `assets` array
149
+ - **Libraries**: Platform-specific shared libraries (DLLs/SOs)
150
+
151
+ 3. **Native Module Rebuilding** - Rebuilds native modules for target platform
152
+
153
+ 4. **Bootstrap Injection** - Adds runtime code for asset loading and native module extraction
154
+
155
+ 5. **SEA Blob Creation** - Packages everything using Node.js SEA tooling
156
+
157
+ 6. **Binary Preparation** - Downloads target Node.js binary and removes code signature
158
+
159
+ 7. **Injection** - Uses `postject` to inject the blob into the Node.js binary
160
+
161
+ 8. **Output** - Produces standalone executable(s) ready for distribution
162
+
163
+ ### Automatic Asset Detection
164
+
165
+ **Like pkg**, seabox automatically detects and embeds assets referenced in your code:
166
+
167
+ ```javascript
168
+ import path from 'path';
169
+ import { fileURLToPath } from 'url';
170
+
171
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
172
+
173
+ // This asset will be automatically detected and embedded
174
+ const configPath = path.join(__dirname, '../config/app.json');
175
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
176
+ ```
177
+
178
+ **Asset sources (merged and deduplicated):**
179
+ 1. **Auto-detected** from code analysis during bundling
180
+ 2. **Config globs** from `assets: ["./data/**/*", "./public/**/*"]`
181
+ 3. **Platform libraries** from `outputs[].libraries` (e.g., DLLs for Windows)
182
+
183
+ ### Native Module Support
184
+
185
+ seabox automatically handles native modules without any configuration:
186
+
187
+ **Supported patterns:**
188
+ - `require('bindings')('module')` - Standard bindings package
189
+ - `require('./build/Release/addon.node')` - Direct requires
190
+ - `require('node-gyp-build')(__dirname)` - Prebuild binaries
191
+ - `require('node-pre-gyp')` patterns - Pre-compiled binaries
192
+
193
+ **At runtime:**
194
+ - Native modules are extracted to a cache directory on first run
195
+ - Modules are integrity-checked with SHA-256 hashes
196
+ - Custom `require()` shim loads modules from cache
197
+
198
+ ### Platform-Specific Libraries
199
+
200
+ Libraries that require filesystem access (like DLLs loaded via `dlopen`) can be included in two ways:
201
+
202
+ **1. Automatic Detection (Recommended)**
203
+
204
+ If your code references a DLL using `path.join(__dirname, ...)`, it will be automatically detected and included:
205
+
206
+ ```javascript
207
+ // This will be automatically detected during bundling
208
+ const dllPath = path.join(__dirname, './lib/RGDevice.dll');
209
+ ```
210
+
211
+ **2. Explicit Glob Patterns**
212
+
213
+ You can also explicitly specify library patterns in your config:
214
+
215
+ ```json
216
+ {
217
+ "outputs": [
218
+ {
219
+ "target": "node24.11.0-win32-x64",
220
+ "libraries": ["lib/*.dll"] // Manually specify DLLs to include
221
+ }
222
+ ]
223
+ }
224
+ ```
225
+
226
+
227
+ These files are extracted on first run (like `.node` files) since they need to be loaded from the filesystem.
228
+
229
+ ### Code Signature Removal
230
+ If you have sign tools available, the seabox will attempt to unsign the node exe before modifying it. This is to reduce issues afterward when you try to resign it.
231
+ - **Windows**: `signtool.exe` (from Windows SDK)
232
+ - **macOS**: `codesign` (included with Xcode)
233
+ - **Linux**: Not required
234
+
235
+ ### Custom Signing
236
+
237
+ You can apply code signing after the build completes by specifying a custom signing script:
238
+
239
+ ```json
240
+ {
241
+ "sign": "./scripts/sign.mjs"
242
+ }
243
+ ```
244
+
245
+ The signing script must export a default function that receives a config object:
246
+
247
+ ```javascript
248
+ // scripts/sign.mjs
249
+ export default async function sign(config) {
250
+ const { exePath, target, platform, arch, nodeVersion, projectRoot } = config;
251
+
252
+ // Example: Windows code signing with signtool
253
+ if (platform === 'win32') {
254
+ execSync(`signtool sign /fd SHA256 /a "${exePath}"`);
255
+ }
256
+
257
+ // Example: macOS code signing
258
+ if (platform === 'darwin') {
259
+ execSync(`codesign --force --sign "Developer ID" "${exePath}"`);
260
+ }
261
+ }
262
+ ```
263
+
264
+ **Config parameters:**
265
+ - `exePath` - Absolute path to the built executable
266
+ - `target` - Full target string (e.g., "node24.11.0-win32-x64")
267
+ - `platform` - Platform name (win32, linux, darwin)
268
+ - `arch` - Architecture (x64, arm64)
269
+ - `nodeVersion` - Node.js version
270
+ - `projectRoot` - Absolute path to project root
271
+
272
+ ## Asset Encryption
273
+
274
+ seabox supports optional AES-256-GCM encryption of embedded assets to protect your application code and data:
275
+
276
+ ```json
277
+ {
278
+ "sea": {
279
+ "encryptAssets": true,
280
+ "encryptExclude": ["*.txt", "public/*"],
281
+ "useSnapshot": true
282
+ }
283
+ }
284
+ ```
285
+
286
+ ### How Encryption Works
287
+
288
+ 1. **Build Time**: A random 256-bit encryption key is generated
289
+ 2. **Asset Encryption**: Non-binary assets are encrypted using AES-256-GCM
290
+ 3. **Key Embedding**: The encryption key is obfuscated and embedded in the bootstrap code
291
+ 4. **Key Obfuscation**: the bootstrap and key code are obfuscated
292
+ 5. **Runtime Decryption**: Assets are transparently decrypted when accessed
293
+
294
+ ### Considerations
295
+
296
+ - **Binary files** (`.node`, `.dll`, `.so`, `.dylib`) are **never encrypted** as they must be extracted as-is
297
+ - The manifest (`sea-manifest.json`) is **not encrypted** to allow bootstrap initialization
298
+ - **V8 snapshot includes the original source**, this is currently a limitation of Node's SEA tooling.
299
+ - Encryption provides **obfuscation**, not cryptographic security against determined attackers
300
+ - The bootloader code, that includes the encryption key, is obfuscated in the source embedded by Node's SEA
301
+
302
+ ## Contributing
303
+
304
+ Contributions welcome! Please open an issue or PR on [GitHub](https://github.com/MeirionHughes/seabox).
305
+
306
+ ## License
307
+
308
+ MIT
309
+
310
+ Copyright © 2025 Meirion Hughes