`
+- Connects to the WebSocket watch server when enabled and reloads the page on `update`
+- Catches unhandled errors and displays them on screen
+
+## Environment Variables
+
+Both `loader-client` and `loader-server` collect environment variables prefixed with `NANOFORGE_` and forward them to the game with the prefix stripped:
+
+```
+NANOFORGE_MY_VAR=hello → { MY_VAR: "hello" }
+```
+
+The browser game receives these via the `/env` endpoint. The server game receives them directly as a plain object passed to `main()`.
+
## Contributing
Please read through our [contribution guidelines][contributing] before starting a pull request. We welcome contributions of all kinds, not just code! If you're stuck for ideas, look for the [good first issue][good-first-issue] label on issues in the repository. If you have any questions about the project, feel free to ask them on [Discussions][discussions]. Before creating your own issue or pull request, always check to see if one already exists! Don't rush contributions, take your time and ensure you're doing it correctly.
diff --git a/apps/client/README.md b/apps/client/README.md
index 98052bd..cb95a29 100644
--- a/apps/client/README.md
+++ b/apps/client/README.md
@@ -16,25 +16,27 @@
## About
-This repository contains the Loader Client of NanoForge. Check [releases][github-releases] to see versions of the Loader. Nanoforge is a powerful game engine for web browser.
+This package contains the Client Loader of NanoForge. It is part of the [NanoForge Loader][loader-source] monorepo. Check [releases][github-releases] to see versions. NanoForge is a powerful game engine for web browsers.
+
+The client loader is a Bun HTTP server that serves the browser-facing side of a NanoForge project. It delivers the loader UI, the compiled game files and the game environment to the browser, and optionally streams live-reload events via WebSocket.
## Usage
-To use Nanoforge Loader, please refer to the [CLI documentation][cli-source] !
+To use the NanoForge Loader, please refer to the [CLI documentation][cli-source]!
-First, install the CLI :
+First, install the CLI:
```bash
npm install -g @nanoforge-dev/cli
```
-Create a new project :
+Create a new project:
```bash
nf new
```
-And then build and start it :
+Then build and start it:
```bash
cd
@@ -42,6 +44,40 @@ nf build
nf start
```
+## Routes
+
+The client loader exposes the following HTTP routes:
+
+| Route | Description |
+| --------------- | --------------------------------------------------------------------- |
+| `GET /` | Serves the `loader-website` HTML application |
+| `GET /*` | Serves static assets bundled with `loader-website` |
+| `GET /manifest` | Returns the list of game files and the current version as JSON |
+| `GET /env` | Returns `NANOFORGE_*` environment variables (prefix stripped) as JSON |
+| `GET /game/*` | Serves compiled game client files from the configured game directory |
+
+## Options
+
+| Option | Default | Description |
+| -------------------------- | ------------------- | ---------------------------------------------- |
+| `-p, --port ` | `3000` | Port the HTTP server listens on |
+| `-d, --dir ` | `.nanoforge/client` | Directory of compiled client game files |
+| `--watch` | `false` | Enable file watcher and browser hot-reload |
+| `--watch-port ` | auto | Port for the WebSocket watch server |
+| `--watch-server-dir ` | — | Also watch a server game directory for changes |
+| `--cert ` | — | TLS certificate file (enables HTTPS) |
+| `--key ` | — | TLS private key file (enables HTTPS) |
+
+## Watch Mode
+
+When `--watch` is enabled, the client loader starts a WebSocket server on `--watch-port` (or a random free port). Any file change in the game directory causes the server to broadcast an `update` message. The `loader-website` frontend listens for this message and reloads the page automatically.
+
+You can also pass `--watch-server-dir` to trigger a reload when the server game directory changes — useful when both sides are compiled simultaneously.
+
+## HTTPS / TLS
+
+Pass `--cert` and `--key` to enable HTTPS. The `loader-website` frontend will detect TLS and communicate this to the game via the `/env` response (`tlsEnabled: true`). HTTPS is required when the browser's secure context is enforced (e.g. to use the Origin Private File System).
+
## Contributing
Please read through our [contribution guidelines][contributing] before starting a pull request. We welcome contributions of all kinds, not just code! If you're stuck for ideas, look for the [good first issue][good-first-issue] label on issues in the repository. If you have any questions about the project, feel free to ask them on [Discussions][discussions]. Before creating your own issue or pull request, always check to see if one already exists! Don't rush contributions, take your time and ensure you're doing it correctly.
@@ -53,5 +89,6 @@ If you don't understand something in the documentation, you are experiencing pro
[contributing]: https://github.com/NanoForge-dev/Loader/blob/main/.github/CONTRIBUTING.md
[discussions]: https://github.com/NanoForge-dev/Loader/discussions
[cli-source]: https://github.com/NanoForge-dev/CLI
+[loader-source]: https://github.com/NanoForge-dev/Loader
[github-releases]: https://github.com/NanoForge-dev/Loader/releases
[good-first-issue]: https://github.com/NanoForge-dev/Loader/contribute
diff --git a/apps/client/package.json b/apps/client/package.json
index 8698b6e..ed0826f 100644
--- a/apps/client/package.json
+++ b/apps/client/package.json
@@ -66,13 +66,18 @@
"prettier": "catalog:lint",
"typescript": "catalog:build"
},
- "packageManager": "pnpm@10.22.0",
+ "packageManager": "pnpm@11.5.1",
"engines": {
"node": "25"
},
"publishConfig": {
"access": "public"
},
+ "pnpm": {
+ "allowBuilds": {
+ "bun": true
+ }
+ },
"lint-staged": {
"**": [
"prettier --ignore-unknown --write"
diff --git a/apps/client/tsconfig.json b/apps/client/tsconfig.json
index 9e6d724..33abe00 100644
--- a/apps/client/tsconfig.json
+++ b/apps/client/tsconfig.json
@@ -1,6 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig.json",
"extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "types": ["bun"]
+ },
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
diff --git a/apps/server/README.md b/apps/server/README.md
index e24a66f..8d572fb 100644
--- a/apps/server/README.md
+++ b/apps/server/README.md
@@ -16,25 +16,27 @@
## About
-This repository contains the Loader Server of NanoForge. Check [releases][github-releases] to see versions of the Loader. Nanoforge is a powerful game engine for web browser.
+This package contains the Server Loader of NanoForge. It is part of the [NanoForge Loader][loader-source] monorepo. Check [releases][github-releases] to see versions. NanoForge is a powerful game engine for web browsers.
+
+The server loader is a Node.js process that runs the server-side game code of a NanoForge project. It scans a compiled game directory, then forks an isolated worker process that loads `main.js` and calls its exported `main()` function.
## Usage
-To use Nanoforge Loader, please refer to the [CLI documentation][cli-source] !
+To use the NanoForge Loader, please refer to the [CLI documentation][cli-source]!
-First, install the CLI :
+First, install the CLI:
```bash
npm install -g @nanoforge-dev/cli
```
-Create a new project :
+Create a new project:
```bash
nf new
```
-And then build and start it :
+Then build and start it:
```bash
cd
@@ -42,6 +44,34 @@ nf build
nf start
```
+## How It Works
+
+The server loader runs in two processes:
+
+1. **Server** (`server.js`) — the entry point. It scans the game directory, locates `/main.js`, and forks the worker. In `--watch` mode it restarts the worker whenever a file changes.
+2. **Worker** (`worker.js`) — the isolated child process. It requires the game's `main.js` and calls `main({ files, env })`, where `files` is a map of all game file paths and `env` contains the forwarded environment variables.
+
+## Options
+
+| Option | Default | Description |
+| ----------------- | ------------------- | ------------------------------------------------ |
+| `-d, --dir ` | `.nanoforge/server` | Directory of compiled server game files |
+| `--watch` | `false` | Enable file watcher and worker restart on change |
+
+## Watch Mode
+
+When `--watch` is enabled, the loader watches the game directory recursively. On any file change, the running worker is killed and a new worker is immediately forked with a fresh state. Changes are debounced to 100 ms to avoid redundant restarts during bulk builds.
+
+## Environment Variables
+
+The server loader reads all environment variables prefixed with `NANOFORGE_`, strips the prefix, and passes them to the game as a plain object:
+
+```
+NANOFORGE_MY_VAR=hello → { MY_VAR: "hello" }
+```
+
+These variables are available inside the game via the `env` field of the `main()` options.
+
## Contributing
Please read through our [contribution guidelines][contributing] before starting a pull request. We welcome contributions of all kinds, not just code! If you're stuck for ideas, look for the [good first issue][good-first-issue] label on issues in the repository. If you have any questions about the project, feel free to ask them on [Discussions][discussions]. Before creating your own issue or pull request, always check to see if one already exists! Don't rush contributions, take your time and ensure you're doing it correctly.
@@ -53,5 +83,6 @@ If you don't understand something in the documentation, you are experiencing pro
[contributing]: https://github.com/NanoForge-dev/Loader/blob/main/.github/CONTRIBUTING.md
[discussions]: https://github.com/NanoForge-dev/Loader/discussions
[cli-source]: https://github.com/NanoForge-dev/CLI
+[loader-source]: https://github.com/NanoForge-dev/Loader
[github-releases]: https://github.com/NanoForge-dev/Loader/releases
[good-first-issue]: https://github.com/NanoForge-dev/Loader/contribute
diff --git a/apps/server/package.json b/apps/server/package.json
index 73bd199..8359d7e 100644
--- a/apps/server/package.json
+++ b/apps/server/package.json
@@ -66,7 +66,7 @@
"prettier": "catalog:lint",
"typescript": "catalog:build"
},
- "packageManager": "pnpm@10.22.0",
+ "packageManager": "pnpm@11.5.1",
"engines": {
"node": "25"
},
diff --git a/apps/website/README.md b/apps/website/README.md
index 3f57e2c..098ae31 100644
--- a/apps/website/README.md
+++ b/apps/website/README.md
@@ -16,25 +16,27 @@
## About
-This repository contains the Loader Website of NanoForge. Check [releases][github-releases] to see versions of the Loader. Nanoforge is a powerful game engine for web browser.
+This package contains the Website Loader of NanoForge. It is part of the [NanoForge Loader][loader-source] monorepo. Check [releases][github-releases] to see versions. NanoForge is a powerful game engine for web browsers.
+
+The website loader is a browser application (HTML + TypeScript) bundled as static assets and served by `loader-client`. It is the loading screen the player sees before the game starts: it downloads the game files, caches them locally in the browser and then bootstraps the game.
## Usage
-To use Nanoforge Loader, please refer to the [CLI documentation][cli-source] !
+To use the NanoForge Loader, please refer to the [CLI documentation][cli-source]!
-First, install the CLI :
+First, install the CLI:
```bash
npm install -g @nanoforge-dev/cli
```
-Create a new project :
+Create a new project:
```bash
nf new
```
-And then build and start it :
+Then build and start it:
```bash
cd
@@ -42,6 +44,26 @@ nf build
nf start
```
+## Loading Sequence
+
+When the browser opens the loader URL, the following steps happen in order:
+
+1. **Fetch manifest** — requests `/manifest` to get the game version and the list of files.
+2. **Verify cache** — checks whether the game files from the previous session are still present in the browser's Origin Private File System (OPFS).
+3. **Download files** — if the cache is stale or missing, downloads each game file from `/game/*` and writes it into OPFS, showing a progress bar and the current file name.
+4. **Fetch environment** — requests `/env` to get the `NANOFORGE_*` variables forwarded by the server.
+5. **Bootstrap game** — dynamically imports `/main.js` from the local cache, calls its exported `main({ files, env, container })` and hides the loading screen.
+
+If any step fails, the error message is displayed on screen instead of a blank page.
+
+## Watch Mode
+
+When the server enables watch mode, the manifest includes a WebSocket URL. The website loader connects to this URL and reloads the page automatically whenever it receives an `update` message — enabling live-reload during development.
+
+## Requirements
+
+The loader requires a **secure context** (HTTPS or `localhost`) because it uses the browser's Origin Private File System API to cache game files locally. Starting the client loader with `--cert` and `--key` satisfies this requirement in production.
+
## Contributing
Please read through our [contribution guidelines][contributing] before starting a pull request. We welcome contributions of all kinds, not just code! If you're stuck for ideas, look for the [good first issue][good-first-issue] label on issues in the repository. If you have any questions about the project, feel free to ask them on [Discussions][discussions]. Before creating your own issue or pull request, always check to see if one already exists! Don't rush contributions, take your time and ensure you're doing it correctly.
@@ -53,5 +75,6 @@ If you don't understand something in the documentation, you are experiencing pro
[contributing]: https://github.com/NanoForge-dev/Loader/blob/main/.github/CONTRIBUTING.md
[discussions]: https://github.com/NanoForge-dev/Loader/discussions
[cli-source]: https://github.com/NanoForge-dev/CLI
+[loader-source]: https://github.com/NanoForge-dev/Loader
[github-releases]: https://github.com/NanoForge-dev/Loader/releases
[good-first-issue]: https://github.com/NanoForge-dev/Loader/contribute
diff --git a/apps/website/package.json b/apps/website/package.json
index b93ca9b..1575272 100644
--- a/apps/website/package.json
+++ b/apps/website/package.json
@@ -51,7 +51,7 @@
"prettier": "catalog:lint",
"typescript": "catalog:build"
},
- "packageManager": "pnpm@10.22.0",
+ "packageManager": "pnpm@11.5.1",
"engines": {
"node": "25"
},
diff --git a/docs/docs/architecture.mdx b/docs/docs/architecture.mdx
deleted file mode 100644
index df7d46a..0000000
--- a/docs/docs/architecture.mdx
+++ /dev/null
@@ -1,157 +0,0 @@
----
-title: "Architecture"
-description: "How NanoForge Loader works — runtime modes, package structure, and data flows."
----
-
-## Overview
-
-NanoForge Loader is a runtime system that serves and executes NanoForge game
-engine projects. It provides two execution modes:
-
-- **Client mode**: Serves a web interface where users can load and play games directly in the browser using WebGL.
-- **Server mode**: Executes game server logic in a Node.js worker thread, suitable for multiplayer game backends.
-
-Both loaders share a common architecture: they read game files from a directory,
-generate a manifest of assets, and execute the game's `main.js` entry point.
-
-## Technology Stack
-
-| Component | Technology |
-| --------------- | ----------------------------------- |
-| Language | TypeScript (strict mode) |
-| Runtime | Bun (bundler and runtime) |
-| Module Formats | ESM + CJS (dual package) |
-| Target | Browser (client) / Node.js (server) |
-| Package Manager | pnpm 10.x |
-| Node Version | 25 |
-| Linter | ESLint 9.x |
-| Formatter | Prettier 3.x |
-| CI/CD | GitHub Actions |
-
-## Package Architecture
-
-The loader is organized as a monorepo with three packages:
-
-```
-loader/
-+-- apps/
-| +-- client/ # Browser loader server
-| | +-- src/
-| | | +-- server.ts # HTTP server entry point
-| | | +-- env.ts # Environment configuration
-| | | +-- files.ts # File utilities
-| | | +-- manifest.ts # Manifest generation
-| | | +-- watch.ts # File watcher for hot reload
-| | +-- package.json
-| +-- server/ # Node.js server loader
-| | +-- src/
-| | | +-- server.ts # Bootstrap entry point
-| | | +-- worker.ts # Worker thread implementation
-| | | +-- env.ts # Environment configuration
-| | | +-- files.ts # File utilities
-| | | +-- watch.ts # File watcher for hot reload
-| | +-- package.json
-| +-- website/ # Web interface
-| +-- src/
-| | +-- index.ts # Main entry point
-| | +-- cache/ # Caching logic
-| | +-- file-system/ # File system abstraction
-| | +-- game/ # Game runner
-| | +-- loader/ # Game file loader
-| | +-- types/ # TypeScript types
-| | +-- utils/ # Utility functions
-| | +-- version/ # Version management
-| +-- package.json
-+-- package.json # Root workspace config
-+-- pnpm-workspace.yaml # pnpm workspace definition
-+-- turbo.json # Turbo build configuration
-```
-
-## Client Loader Flow
-
-The client loader implements an HTTP server using Bun:
-
-1. **Server Initialization**: Starts an HTTP server on the configured port.
-
-2. **Route Handling**:
- - `/` — Serves the website `index.html`
- - `/*` — Serves static website assets
- - `/manifest` — Returns the game file manifest (JSON)
- - `/env` — Returns public environment variables
- - `/game/*` — Serves game files from the game directory
-
-3. **Manifest Generation**: On each `/manifest` request, scans the game directory and builds a list of all game files with their paths.
-
-4. **Hot Reload** (optional): When `WATCH=true`, starts a WebSocket server that notifies the browser when game files change.
-
-```
-Browser Client Loader Game Directory
- | | |
- |----GET /manifest-------->| |
- | |---scan directory--------->|
- | |<--file list---------------|
- |<---JSON manifest---------| |
- | | |
- |----GET /game/main.js---->| |
- | |---read file-------------->|
- |<---JavaScript file-------| |
- | | |
- |====WebSocket (watch)=====| |
- |<---file changed----------|<--fsnotify---------------|
-```
-
-## Server Loader Flow
-
-The server loader executes game logic in a Node.js worker thread:
-
-1. **Bootstrap**: Reads the game directory and locates `main.js`.
-2. **Worker Fork**: Spawns a child process that runs the worker script.
-3. **Game Execution**: The worker imports `main.js` and calls its `main()` function with a file map containing all game assets.
-4. **Hot Reload** (optional): When watch mode is enabled, the worker process is killed and restarted when files change.
-
-```
-Server Loader Worker Thread Game Code
- | | |
- |---fork(worker.js)--------->| |
- | |---import main.js-------->|
- | |<--main function----------|
- | |---call main()----------->|
- | | |
-[file change detected] | |
- |---kill worker------------->| |
- |---fork new worker--------->| |
-```
-
-## Website Architecture
-
-The website package provides the browser-side game loader:
-
-1. **Manifest Fetching**: Requests `/manifest` from the client server.
-2. **File Caching**: Downloads game files and stores them in browser storage (IndexedDB via the file-system abstraction).
-3. **Version Checking**: Compares the manifest version with cached version to determine if files need updating.
-4. **Game Loading**: Imports the main module and creates a file map for the game to access assets.
-5. **Game Execution**: Calls the game's `main()` function with container and file references.
-6. **Watch Integration**: Subscribes to the WebSocket for hot reload notifications during development.
-
-## Build Pipeline
-
-The project uses Bun for building and bundling:
-
-```bash
-# Build all packages
-pnpm run build
-
-# What happens internally:
-# 1. website: bun build -> dist/index.html + assets
-# 2. client: bun build -> dist/server.js
-# 3. server: bun build -> dist/server.js + dist/worker.js
-```
-
-Each package produces optimized bundles for its target environment:
-
-- **Website**: Browser bundle with HTML entry point
-- **Client**: Bun-targeted server bundle
-- **Server**: Node.js-targeted bundles for server and worker
-
-Turbo is used to orchestrate builds across packages with proper dependency
-ordering (website must build before client).
diff --git a/docs/docs/client.mdx b/docs/docs/client.mdx
deleted file mode 100644
index 1c4847c..0000000
--- a/docs/docs/client.mdx
+++ /dev/null
@@ -1,102 +0,0 @@
----
-title: "Client Loader"
-description: "HTTP server that serves the web interface and game files for browser-based NanoForge games."
----
-
-**Package**: `@nanoforge-dev/loader-client`
-
-The client loader is a Bun-based HTTP server that:
-
-- Serves the loader website interface
-- Provides a manifest endpoint listing all game files
-- Serves game files from a configured directory
-- Optionally enables hot reload via WebSocket
-
-## Environment Variables
-
-| Variable | Required | Description |
-| ----------------------- | -------- | ------------------------------------------------------------- |
-| `PORT` | Yes | Port number for the HTTP server |
-| `GAME_DIR` | Yes | Absolute path to the game directory |
-| `WATCH` | No | Set to `"true"` to enable hot reload |
-| `WATCH_PORT` | No | Port for the WebSocket watch server |
-| `WATCH_SERVER_GAME_DIR` | No | Game directory for server-side watch |
-| `PUBLIC_*` | No | Any variable prefixed with `PUBLIC_` is exposed to the client |
-
-## API Endpoints
-
-| Endpoint | Description |
-| --------------- | -------------------------------------------- |
-| `GET /` | Serves the main `index.html` page |
-| `GET /*` | Serves static website assets |
-| `GET /manifest` | Returns the game manifest as JSON |
-| `GET /env` | Returns public environment variables as JSON |
-| `GET /game/*` | Serves files from the game directory |
-
-## Manifest Format
-
-The `/manifest` endpoint returns a JSON object:
-
-```typescript
-interface IManifest {
- version: string;
- files: { path: string }[];
- watch: { enable: false } | { enable: true; url: string };
-}
-```
-
-## Source Modules
-
-### server.ts
-
-Main entry point that creates and configures the Bun HTTP server with all route handlers.
-
-### env.ts
-
-Environment variable accessors:
-
-```typescript
-function getPort(): string;
-function getGameDir(): string;
-function getWatch(): string | undefined;
-function getWatchPort(): string | undefined;
-function getWatchServerGameDir(): string | undefined;
-function getPublicEnv(): Record;
-```
-
-### manifest.ts
-
-Manifest generation:
-
-```typescript
-const MANIFEST: IManifest;
-function updateManifest(gameDir: string): Promise;
-```
-
-### watch.ts
-
-File watching for hot reload:
-
-```typescript
-function startWatch(
- gameDir: string,
- watchPort: string | undefined,
- watchServerGameDir: string | undefined,
-): void;
-```
-
-## Usage
-
-```bash
-# Set required environment variables
-export PORT=3000
-export GAME_DIR=/path/to/game
-
-# Start the client loader
-pnpm --filter @nanoforge-dev/loader-client start
-
-# With hot reload
-export WATCH=true
-export WATCH_PORT=3001
-pnpm --filter @nanoforge-dev/loader-client start
-```
diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx
deleted file mode 100644
index d4c5e50..0000000
--- a/docs/docs/index.mdx
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: "Technical Documentation"
-description: "Architecture, package APIs, and module references for NanoForge Loader."
----
-
-
-
- Runtime modes, package structure, data flows, and the build pipeline.
-
-
- HTTP server that serves the web interface and game files for browser-based games.
-
-
- Worker-thread-based loader for executing game server logic in Node.js.
-
-
- Browser-side module handling manifest fetching, file caching, and game initialization.
-
-
diff --git a/docs/docs/loader/1-overview.mdx b/docs/docs/loader/1-overview.mdx
new file mode 100644
index 0000000..ca34b33
--- /dev/null
+++ b/docs/docs/loader/1-overview.mdx
@@ -0,0 +1,57 @@
+---
+title: Loader
+description: Overview of the @nanoforge-dev/loader packages
+---
+
+import { Card, CardGroup } from "mintlify/components";
+
+## What is the Loader?
+
+The NanoForge Loader is the runtime layer that starts a NanoForge project. It is invoked by the [NanoForge CLI](https://github.com/NanoForge-dev/CLI) when you run `nf start`, and handles both sides of a game simultaneously: the **client side** delivered to the browser and the **server side** running in Node.js.
+
+The Loader is a monorepo of three packages, each with a distinct responsibility at runtime:
+
+- **`loader-client`** — the Bun HTTP server that serves the browser with the loader UI and the compiled game files.
+- **`loader-server`** — the Node.js process that runs the compiled server game code in an isolated worker.
+- **`loader-website`** — the browser application that displays the loading screen, caches game files locally, and bootstraps the game.
+
+The NanoForge CLI orchestrates all three; as a game developer you never interact with these packages directly.
+
+## Installation
+
+```bash
+npm install -g @nanoforge-dev/cli
+```
+
+The loader packages are dependencies of the CLI and do not need to be installed separately. If you want to invoke the loaders directly outside of the CLI:
+
+```bash
+npm install @nanoforge-dev/loader-client
+npm install @nanoforge-dev/loader-server
+```
+
+Then run them with:
+
+```bash
+npx loader-client --dir .nanoforge/client
+npx loader-server --dir .nanoforge/server
+```
+
+## Packages
+
+
+
+ Bun HTTP server that serves the loader website and the compiled client game files. Exposes the
+ manifest, environment variables, and game assets. Supports HTTPS and hot-reload.
+
+
+ Browser application bundled as static assets. Displays the loading screen, downloads and caches
+ game files via the browser Origin Private File System, then bootstraps the game.
+
+
+ Node.js process that runs the server-side game code in an isolated worker process. Supports
+ live-reload by restarting the worker on file changes.
+
+
+
+see the [changelog](https://github.com/NanoForge-dev/Loader/blob/main/CHANGELOG.md) for the full release history.
diff --git a/docs/docs/loader/2-client.mdx b/docs/docs/loader/2-client.mdx
new file mode 100644
index 0000000..7a9c4ed
--- /dev/null
+++ b/docs/docs/loader/2-client.mdx
@@ -0,0 +1,82 @@
+---
+title: Client
+description: Bun HTTP server that serves the browser-side of a NanoForge project
+---
+
+import { Tooltip } from "mintlify/components";
+
+## Overview
+
+`loader-client` is a Bun HTTP server that bridges the browser and the compiled game client. It serves the `loader-website` frontend, exposes the game file manifest, delivers the compiled game assets, and forwards environment variables to the browser. It is the single entry point for everything the player's browser contacts.
+
+## Usage
+
+```bash
+nf start
+```
+
+Or invoke directly after building the loader packages:
+
+```bash
+npx loader-client --dir .nanoforge/client --port 3000
+```
+
+## Routes
+
+| Route | Description |
+| --------------- | --------------------------------------------------------------------- |
+| `GET /` | Serves the `loader-website` HTML application |
+| `GET /*` | Serves static assets bundled with `loader-website` |
+| `GET /manifest` | Returns the list of game files and the current version as JSON |
+| `GET /env` | Returns `NANOFORGE_*` environment variables (prefix stripped) as JSON |
+| `GET /game/*` | Serves compiled game client files from the configured game directory |
+
+## Options
+
+| Option | Type | Default | Description |
+| -------------------------- | --------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `-p, --port ` | `string` | `3000` | Port the HTTP server listens on |
+| `-d, --dir ` | `string` | `.nanoforge/client` | Directory of compiled client game files |
+| `--watch` | `boolean` | `false` | Enable file watcher and browser hot-reload |
+| `--watch-port ` | `string` | auto | Port for the WebSocket watch server |
+| `--watch-server-dir ` | `string` | — | Also watch a server game directory for changes |
+| `--cert ` | `string` | — | TLS certificate file (enables HTTPS) |
+| `--key ` | `string` | — | TLS private key file (enables HTTPS) |
+
+## Watch mode
+
+When `--watch` is enabled, `loader-client` starts a WebSocket server on `--watch-port` (or a random free port) and sets the `watch.url` field in the manifest response. Any file change in the game directory causes the server to broadcast an `update` message. The `loader-website` frontend connects to that WebSocket and reloads the page on receipt.
+
+Pass `--watch-server-dir` to also reload when the server game directory changes — useful when client and server are compiled in one step.
+
+## HTTPS / TLS
+
+Pass `--cert` and `--key` to enable HTTPS. The server reads both files with Bun's native TLS support. The `/env` response will include `tlsEnabled: true` so the game can detect the protocol at runtime.
+
+HTTPS is required when the browser enforces a secure context — for example when using the Origin Private File System API used by `loader-website` to cache game files.
+
+## Examples
+
+**Start on port 8080:**
+
+```bash
+npx loader-client --port 8080
+```
+
+**Start with watch mode:**
+
+```bash
+npx loader-client --watch --watch-server-dir .nanoforge/server
+```
+
+**Start with HTTPS:**
+
+```bash
+npx loader-client --cert ./certs/server.crt --key ./certs/server.key
+```
+
+**Point to a custom game directory:**
+
+```bash
+npx loader-client --dir ./dist/client
+```
diff --git a/docs/docs/loader/3-website.mdx b/docs/docs/loader/3-website.mdx
new file mode 100644
index 0000000..1d0827c
--- /dev/null
+++ b/docs/docs/loader/3-website.mdx
@@ -0,0 +1,64 @@
+---
+title: Website
+description: Browser application that loads and bootstraps a NanoForge game
+---
+
+import { Tooltip } from "mintlify/components";
+
+## Overview
+
+`loader-website` is a browser application (HTML + TypeScript) bundled as static assets and served by `loader-client`. It is the loading screen the player sees before the game starts. It fetches the game's file list from the server, downloads and caches each file locally in the browser, then dynamically imports the game entry point and starts it.
+
+This package is a dependency of `loader-client` and is not consumed directly.
+
+## Loading sequence
+
+When the browser opens the loader URL, the following steps happen in order:
+
+1. **Fetch manifest** — requests `/manifest` to get the game version and the list of files to download.
+2. **Verify cache** — checks whether the game files from the previous session are still present in the browser's Origin Private File System (OPFS). The loading screen shows _"Verifying application integrity"_.
+3. **Download files** — if the cache is stale or missing, downloads each game file from `/game/*` and writes it into OPFS. The loading screen shows a progress bar and the name of the current file.
+4. **Fetch environment** — requests `/env` to get the `NANOFORGE_*` variables forwarded by `loader-client`.
+5. **Bootstrap game** — dynamically imports `/main.js` from the local OPFS cache, calls its exported `main({ files, env, container })`, and fades out the loading screen.
+
+If any step fails, the error message is displayed on screen instead of a blank page or an unhandled rejection.
+
+## Game interface
+
+`loader-website` calls the game's `main` export with the following shape:
+
+| Field | Type | Description |
+| ----------- | ------------------------------------- | ------------------------------------------------------------------------------ |
+| `files` | `Map` | Map of logical game paths (`/assets/sprite.png`, etc.) to their OPFS blob URLs |
+| `env` | `Record` | Environment variables fetched from `/env` (prefix stripped) |
+| `container` | `HTMLDivElement` | The DOM element the game should render into |
+
+## Watch mode
+
+When `loader-client` starts with `--watch`, the manifest response includes a `watch.url` WebSocket URL. `loader-website` connects to that URL and listens for messages. When it receives an `update` message it reloads the page, giving the developer an automatic live-reload experience.
+
+## Error display
+
+`loader-website` installs global handlers for `error` and `unhandledrejection` window events. If the game throws or rejects after starting, the error message is surfaced on the loading screen instead of failing silently.
+
+## Requirements
+
+`loader-website` uses the browser's [Origin Private File System](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system) (OPFS) API to cache game files locally. This API is only available in a **secure context** — either `localhost` or a page served over HTTPS.
+
+Start `loader-client` with `--cert` and `--key` to enable HTTPS when running on a non-localhost address.
+
+## Examples
+
+The website loader is not invoked directly. Start it via the CLI or `loader-client`:
+
+```bash
+nf start
+```
+
+Or:
+
+```bash
+npx loader-client --port 3000 --cert ./certs/server.crt --key ./certs/server.key
+```
+
+Then open the printed URL in a browser. The loader screen will appear, followed by the game.
diff --git a/docs/docs/loader/4-server.mdx b/docs/docs/loader/4-server.mdx
new file mode 100644
index 0000000..5387d07
--- /dev/null
+++ b/docs/docs/loader/4-server.mdx
@@ -0,0 +1,93 @@
+---
+title: Server
+description: Node.js process that runs the server-side game code of a NanoForge project
+---
+
+import { Tooltip } from "mintlify/components";
+
+## Overview
+
+`loader-server` is a Node.js process that runs the compiled server-side game code. It scans a built game directory, locates `/main.js`, then forks an isolated child process — the worker — that loads the game and calls its exported `main()` function. The parent process manages the worker lifecycle and restarts it when files change in watch mode.
+
+## Usage
+
+```bash
+nf start
+```
+
+Or invoke directly after building the loader packages:
+
+```bash
+npx loader-server --dir .nanoforge/server
+```
+
+## How it works
+
+The server loader runs as two processes:
+
+1. **Server** (`server.js`) — the entry point. Scans the game directory, finds `/main.js`, and forks the worker. In `--watch` mode it restarts the worker on any file change.
+2. **Worker** (`worker.js`) — an isolated child process forked by the server. It requires the game's `main.js` via `createRequire` and calls `main({ files, env })` to start the game.
+
+This two-process split ensures that a game crash or `process.exit()` call in the game code does not terminate the loader itself.
+
+## Options
+
+| Option | Type | Default | Description |
+| ----------------- | --------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
+| `-d, --dir ` | `string` | `.nanoforge/server` | Directory of compiled server game files |
+| `--watch` | `boolean` | `false` | Enable file watcher and worker restart on change |
+
+## Watch mode
+
+When `--watch` is enabled, the loader watches the game directory recursively. On any file change the running worker is killed and a new worker is immediately forked with a clean state. Changes are debounced to 100 ms to avoid redundant restarts during bulk builds.
+
+## Environment variables
+
+The server loader collects all environment variables whose name starts with `NANOFORGE_`, strips the prefix, and passes the resulting object to the game via the `env` field of `main()`:
+
+```
+NANOFORGE_MY_VAR=hello → { MY_VAR: "hello" }
+```
+
+The game receives these inside the worker:
+
+```ts
+export const main = async ({
+ files,
+ env,
+}: {
+ files: Map;
+ env: Record;
+}) => {
+ console.log(env.MY_VAR); // "hello"
+};
+```
+
+## Game interface
+
+The worker calls the game's `main` export with the following shape:
+
+| Field | Type | Description |
+| ------- | ------------------------------------- | --------------------------------------------------------------------------- |
+| `files` | `Map` | Map of logical game paths (`/main.js`, etc.) to their full filesystem paths |
+| `env` | `Record` | Environment variables forwarded from the host (prefix stripped) |
+
+## Examples
+
+**Start with a custom game directory:**
+
+```bash
+npx loader-server --dir ./dist/server
+```
+
+**Start in watch mode:**
+
+```bash
+npx loader-server --watch
+```
+
+**Pass environment variables to the game:**
+
+```bash
+NANOFORGE_PORT=4000 NANOFORGE_DEBUG=true npx loader-server
+```
diff --git a/docs/docs/server.mdx b/docs/docs/server.mdx
deleted file mode 100644
index 505484d..0000000
--- a/docs/docs/server.mdx
+++ /dev/null
@@ -1,141 +0,0 @@
----
-title: "Server Loader"
-description: "Executes NanoForge game server logic in an isolated Node.js worker thread with optional hot reload."
----
-
-**Package**: `@nanoforge-dev/loader-server`
-
-The server loader:
-
-- Scans the game directory for files
-- Locates the `main.js` entry point
-- Forks a worker process to execute game code
-- Provides file paths to the game via a Map
-- Optionally restarts on file changes
-
-## Environment Variables
-
-| Variable | Required | Description |
-| ---------- | -------- | ------------------------------------- |
-| `GAME_DIR` | Yes | Absolute path to the game directory |
-| `WATCH` | No | Set to any value to enable hot reload |
-
-## Game Entry Point
-
-The server loader expects a `main.js` file in the game directory that exports a `main` function:
-
-```typescript
-interface RunOptions {
- files: Map;
-}
-
-export async function main(options: RunOptions): Promise {
- // Game server logic
- const files = options.files;
- // files.get("/assets/config.json") -> absolute path to file
-}
-```
-
-The `files` map contains all game files with their relative paths as keys and absolute file system paths as values.
-
-## Worker Thread
-
-The game code runs in a separate worker thread (child process), which:
-
-- Isolates game code from the loader process
-- Enables clean restarts during hot reload
-- Prevents game crashes from affecting the loader
-
-## Source Modules
-
-### server.ts
-
-Bootstrap entry point that:
-
-1. Reads the game directory
-2. Locates `main.js`
-3. Forks the worker process
-4. Sets up file watching if enabled
-
-```typescript
-async function bootstrap(): Promise;
-```
-
-### worker.ts
-
-Worker thread implementation that:
-
-1. Receives the main path and file list via process arguments
-2. Imports the game's main module using `createRequire`
-3. Calls the `main()` function with the files map
-
-```typescript
-interface MainFunction {
- main: (options: { files: Map }) => Promise;
-}
-```
-
-### env.ts
-
-Environment variable accessors:
-
-```typescript
-function getGameDir(): string;
-function getWatch(): string | undefined;
-```
-
-### files.ts
-
-File system utilities:
-
-```typescript
-function getFiles(gameDir: string): [string, string][];
-```
-
-Returns an array of tuples containing `[relativePath, absolutePath]` for all files in the game directory.
-
-### watch.ts
-
-File watching for hot reload:
-
-```typescript
-function startWatch(gameDir: string, callback: () => Promise): void;
-```
-
-Calls the callback function when files change, allowing the server to restart the worker process.
-
-## Usage
-
-```bash
-# Set required environment variables
-export GAME_DIR=/path/to/game
-
-# Start the server loader
-pnpm --filter @nanoforge-dev/loader-server start
-
-# With hot reload
-export WATCH=1
-pnpm --filter @nanoforge-dev/loader-server start
-```
-
-## Example Game Server
-
-```javascript
-// main.js
-export async function main(options) {
- const { files } = options;
-
- console.log("Server starting...");
- console.log("Available files:", [...files.keys()]);
-
- // Read a config file
- const configPath = files.get("/config.json");
- if (configPath) {
- const config = await import(configPath, { with: { type: "json" } });
- console.log("Config loaded:", config);
- }
-
- // Your game server logic here
- // e.g., start a WebSocket server, initialize game state, etc.
-}
-```
diff --git a/docs/docs/website.mdx b/docs/docs/website.mdx
deleted file mode 100644
index cb3a480..0000000
--- a/docs/docs/website.mdx
+++ /dev/null
@@ -1,209 +0,0 @@
----
-title: "Website"
-description: "Browser-side interface for loading, caching, and running NanoForge games."
----
-
-**Package**: `@nanoforge-dev/loader-website`
-
-The website is a client-side application that:
-
-- Fetches the game manifest from the loader server
-- Caches game files in browser storage
-- Loads and executes the game's main module
-- Provides a container and file access to the game
-- Supports hot reload via WebSocket
-
-## Modules
-
-### loader
-
-**Path**: `src/loader/`
-
-Loads game files from the manifest and prepares them for execution.
-
-```typescript
-async function loadGameFiles(manifest: IExtendedManifest): Promise<[Map, any]>;
-```
-
-Returns a tuple containing:
-
-1. A map of file paths to local (cached) paths
-2. The imported main module
-
-The loader iterates through manifest files, caches each file locally, dynamically imports `main.js`, and returns the main module's exports.
-
-### game
-
-**Path**: `src/game/`
-
-Handles game execution and window management.
-
-```typescript
-function runGame(mainModule: any, options: Omit): void;
-```
-
-Switches the UI to game mode, gets the container element, and calls the game's `main()` function with options.
-
-### cache
-
-**Path**: `src/cache/`
-
-Manages browser-side caching of game files for offline support and faster subsequent loads.
-
-### file-system
-
-**Path**: `src/file-system/`
-
-Provides a file system abstraction over browser storage APIs (IndexedDB):
-
-```typescript
-class FileSystemManager {
- async getDirectory(path: string): Promise;
- async getFile(path: string): Promise;
-}
-
-class FileSystemDirectory {
- async list(): Promise;
- async create(): Promise;
-}
-
-class FileSystemFile {
- async read(): Promise;
- async write(data: Blob): Promise;
- async exists(): Promise;
-}
-
-class FileSystemHandler {
- // Low-level storage interface
-}
-```
-
-### manifest
-
-**Path**: `src/manifest.ts`
-
-Manifest fetching and validation:
-
-```typescript
-async function getManifest(): Promise;
-function isManifestUpToDate(manifest: IManifest): boolean;
-```
-
-### version
-
-**Path**: `src/version/`
-
-Manages version tracking for cache invalidation:
-
-```typescript
-function getVersion(): string | null;
-function setVersion(version: string): void;
-```
-
-### watch
-
-**Path**: `src/watch.ts`
-
-WebSocket connection for hot reload notifications.
-
-### window
-
-**Path**: `src/window.ts`
-
-UI state management:
-
-```typescript
-function setLoadingStatus(status: string): void;
-function changeWindowToGame(): void;
-```
-
-### utils
-
-**Path**: `src/utils/`
-
-
-
- ```typescript
- class Logger {
- constructor(prefix: string)
- info(...args: any[]): void
- warn(...args: any[]): void
- error(...args: any[]): void
- }
- ```
-
-
- ```typescript
- function getElementById(id: string): HTMLElement
- function addScript(src: string): void
- ```
-
-
- ```typescript
- function delay(ms: number): Promise
- ```
-
-
-
-## Types
-
-### IManifest
-
-```typescript
-interface IManifest {
- version: string;
- files: IManifestFile[];
- watch: { enable: false } | { enable: true; url: string };
-}
-```
-
-### IManifestFile
-
-```typescript
-interface IManifestFile {
- path: string;
-}
-```
-
-### IExtendedManifest
-
-Extended manifest with local file paths after caching:
-
-```typescript
-interface IExtendedManifest {
- files: IExtendedManifestFile[];
-}
-```
-
-### IExtendedManifestFile
-
-```typescript
-interface IExtendedManifestFile extends IManifestFile {
- localPath: string; // Local cached path (blob URL or IndexedDB path)
-}
-```
-
-### IGameOptions
-
-Options passed to the game's main function:
-
-```typescript
-interface IGameOptions {
- container: HTMLDivElement;
- files: Map;
-}
-```
-
-## Build Output
-
-The website builds to static assets:
-
-```
-dist/
-+-- index.html # Main HTML entry point
-+-- index.js # Bundled JavaScript
-+-- style.css # Styles
-+-- assets/ # Static assets
-```
-
-These files are served by the client loader and consumed by the browser.
diff --git a/docs/guides/contributing.mdx b/docs/guides/contributing.mdx
deleted file mode 100644
index 74fecf5..0000000
--- a/docs/guides/contributing.mdx
+++ /dev/null
@@ -1,210 +0,0 @@
----
-title: "Contributing"
-description: "How to contribute to the NanoForge Loader project."
----
-
-## Prerequisites
-
-- [Node.js](https://nodejs.org/) version 25
-- [pnpm](https://pnpm.io/installation) 10.x
-- [Bun](https://bun.sh/) runtime
-
-## Setup
-
-
-
- ```bash
- git clone https://github.com//Loader.git
- cd Loader
- ```
-
-
- ```bash
- git checkout main
- ```
-
-
- ```bash
- pnpm install --frozen-lockfile
- ```
-
- This also sets up Husky git hooks via the `prepare` script.
-
-
-
- ```bash
- git checkout -b feat/my-feature
- ```
-
-
-
-## Development Workflow
-
-1. Make your changes in the appropriate `apps/` package:
- - `apps/client/` — Client loader server
- - `apps/server/` — Server loader
- - `apps/website/` — Browser interface
-
-2. Run formatting and lint fixes:
-
- ```bash
- pnpm format
- ```
-
-3. Build all packages to verify there are no errors:
-
- ```bash
- pnpm build
- ```
-
-4. Run the full lint check:
-
- ```bash
- pnpm lint
- ```
-
-## Building Individual Packages
-
-```bash
-# Build website
-pnpm --filter @nanoforge-dev/loader-website build
-
-# Build client
-pnpm --filter @nanoforge-dev/loader-client build
-
-# Build server
-pnpm --filter @nanoforge-dev/loader-server build
-```
-
-
- The client package depends on the website package. Build website first when making changes to
- both.
-
-
-## Commit Convention
-
-This project uses [Conventional Commits](https://www.conventionalcommits.org/).
-Every commit message must follow this format:
-
-```
-():
-
-[optional body]
-
-[optional footer(s)]
-```
-
-### Types
-
-| Type | Purpose |
-| ---------- | ------------------------------------------- |
-| `feat` | A new feature |
-| `fix` | A bug fix |
-| `docs` | Documentation changes |
-| `chore` | Maintenance tasks (deps, CI, tooling) |
-| `refactor` | Code restructuring without behavior change |
-| `perf` | Performance improvements |
-| `test` | Adding or updating tests |
-| `style` | Code style changes (formatting, whitespace) |
-
-### Scopes
-
-| Scope | Package |
-| ---------------- | --------------------- |
-| `loader-client` | Client loader package |
-| `loader-server` | Server loader package |
-| `loader-website` | Website package |
-
-### Examples
-
-```text
-feat(loader-client): add WebSocket reconnection logic
-fix(loader-server): correct worker restart on file change
-docs: update getting started guide
-chore(deps): update bun to v1.2
-```
-
-Commit messages are validated by `commitlint` via a git hook. Commits that do not follow the convention are rejected.
-
-## Pull Request Process
-
-
- ```bash git push origin feat/my-feature ```
-
- [Open a pull request](https://github.com/NanoForge-dev/Loader/compare) against the `main`
- branch.
-
- Ensure the CI pipeline passes (lint checks, builds).
- Request a review from a maintainer.
- Once approved, the PR is merged into `main`.
-
-
-## Code Style
-
-The project enforces consistent code style through ESLint and Prettier.
-
-**Naming conventions:**
-
-- **Files**: kebab-case (`file-system-manager.ts`)
-- **Classes**: PascalCase (`FileSystemManager`)
-- **Functions**: camelCase (`loadGameFiles`)
-- **Constants**: SCREAMING_SNAKE_CASE (`MANIFEST`)
-- **Interfaces**: PascalCase with `I` prefix (`IManifest`)
-
-**Import ordering** (enforced by Prettier plugin):
-
-1. Node.js built-in modules (`node:path`, `node:fs`)
-2. External packages
-3. Internal modules (relative imports)
-
-## Project Structure
-
-When adding code, follow the existing structure:
-
-- **Client**: HTTP server logic in `apps/client/src/`
-- **Server**: Bootstrap and worker in `apps/server/src/`
-- **Website**: Browser modules in `apps/website/src/`
-
-Each package has its own:
-
-- `src/` directory for source code
-- `package.json` with package-specific scripts
-- `CHANGELOG.md` for release notes
-
-## Dependencies
-
-Dependencies are managed through pnpm workspace version catalogs defined in
-`pnpm-workspace.yaml`. When adding or updating a dependency, use the catalog
-reference rather than a direct version:
-
-```json
-{
- "devDependencies": {
- "typescript": "catalog:build",
- "eslint": "catalog:lint"
- }
-}
-```
-
-## Release Process
-
-Releases are managed using `cliff-jumper`:
-
-```bash
-# Generate changelog and bump version
-pnpm --filter @nanoforge-dev/loader-client release
-pnpm --filter @nanoforge-dev/loader-server release
-pnpm --filter @nanoforge-dev/loader-website release
-```
-
-Each package maintains its own version and changelog.
-
-## Reporting Issues
-
-Report bugs and request features on the
-[GitHub Issues](https://github.com/NanoForge-dev/Loader/issues) page.
-
-## Security
-
-For security vulnerabilities, refer to the `SECURITY.md` file in the
-repository root for the responsible disclosure process.
diff --git a/docs/guides/getting-started.mdx b/docs/guides/getting-started.mdx
deleted file mode 100644
index 22964db..0000000
--- a/docs/guides/getting-started.mdx
+++ /dev/null
@@ -1,196 +0,0 @@
----
-title: "Getting Started"
-description: "How to use the NanoForge Loader packages to run NanoForge game engine projects."
----
-
-## Prerequisites
-
-- [Node.js](https://nodejs.org/) version 25 or later
-- [Bun](https://bun.sh/) runtime (for client loader)
-- A package manager: npm, yarn, pnpm, or bun
-
-## Installation
-
-Install the loader packages as dependencies in your project:
-
-
-
-```bash npm
-npm install @nanoforge-dev/loader-client @nanoforge-dev/loader-server
-```
-
-```bash pnpm
-pnpm add @nanoforge-dev/loader-client @nanoforge-dev/loader-server
-```
-
-```bash yarn
-yarn add @nanoforge-dev/loader-client @nanoforge-dev/loader-server
-```
-
-```bash bun
-bun add @nanoforge-dev/loader-client @nanoforge-dev/loader-server
-```
-
-
-
-## Running the Client Loader
-
-The client loader serves your game in a browser environment.
-
-### Basic Usage
-
-Set the required environment variables and start the loader:
-
-```bash
-export PORT=3000
-export GAME_DIR=/path/to/your/game
-pnpm --filter @nanoforge-dev/loader-client start
-```
-
-Open `http://localhost:3000` in your browser to load and play the game.
-
-### With Hot Reload
-
-Enable hot reload for development:
-
-```bash
-export PORT=3000
-export GAME_DIR=/path/to/your/game
-export WATCH=true
-export WATCH_PORT=3001
-pnpm --filter @nanoforge-dev/loader-client start
-```
-
-The browser will automatically reload when game files change.
-
-### Environment Variables
-
-| Variable | Description |
-| ----------------------- | -------------------------------------------------------- |
-| `PORT` | HTTP server port (required) |
-| `GAME_DIR` | Path to game directory (required) |
-| `WATCH` | Set to `"true"` to enable hot reload |
-| `WATCH_PORT` | WebSocket port for hot reload notifications |
-| `WATCH_SERVER_GAME_DIR` | Server game directory for watch coordination |
-| `PUBLIC_*` | Any `PUBLIC_` prefixed variable is exposed to the client |
-
-## Running the Server Loader
-
-The server loader executes your game's server-side logic.
-
-### Basic Usage
-
-Set the game directory and start the loader:
-
-```bash
-export GAME_DIR=/path/to/your/game
-pnpm --filter @nanoforge-dev/loader-server start
-```
-
-The server will locate `main.js` in your game directory and execute it in a worker thread.
-
-### With Hot Reload
-
-Enable hot reload for development:
-
-```bash
-export GAME_DIR=/path/to/your/game
-export WATCH=1
-pnpm --filter @nanoforge-dev/loader-server start
-```
-
-The worker will restart when game files change.
-
-### Game Entry Point
-
-Your game must have a `main.js` file that exports a `main` function:
-
-```javascript
-// main.js
-export async function main(options) {
- const files = options.files;
- console.log("Server started with files:", [...files.keys()]);
-
- // Your game server logic here
-}
-```
-
-The `options.files` map contains all game files with their paths.
-
-## Project Structure
-
-A typical NanoForge game project structure:
-
-```
-my-game/
-+-- main.js # Entry point (exports main function)
-+-- assets/
-| +-- sprites/
-| +-- sounds/
-| +-- config.json
-+-- components/
-+-- systems/
-+-- package.json
-```
-
-The loader will include all files in the manifest and make them available to your game code.
-
-## Using with NanoForge CLI
-
-The loader is typically invoked through the NanoForge CLI rather than directly:
-
-```bash
-# Run client (browser) game
-nanoforge run --part client
-
-# Run server game
-nanoforge run --part server
-
-# Development mode with hot reload
-nanoforge dev
-```
-
-The CLI handles environment variable setup and loader invocation.
-
-## Typical Development Workflow
-
-
-
- ```bash schematics @nanoforge-dev/schematics:application my-game ```
-
- ```bash cd my-game pnpm install ```
-
- ```bash schematics @nanoforge-dev/schematics:part-base my-game --part=client ```
-
-
- ```bash schematics @nanoforge-dev/schematics:part-main my-game --part=client ```
-
- ```bash pnpm build ```
-
- ```bash export PORT=3000 export GAME_DIR=$(pwd)/dist/client export WATCH=true pnpm --filter
- @nanoforge-dev/loader-client start ```
-
- Navigate to `http://localhost:3000` to play your game.
-
-
-## Troubleshooting
-
-
-
- Set the `PORT` environment variable before starting the client loader.
-
-
- Set the `GAME_DIR` environment variable to your game's build output directory.
-
-
- Ensure your game directory contains a `main.js` file that exports a `main` function.
-
-
- Check the browser console for errors. Ensure the game was built correctly and all assets are
- present in the game directory.
-
-
- Verify `WATCH=true` is set and the `WATCH_PORT` is available. Check that no firewall is blocking
- WebSocket connections.
-
-
diff --git a/docs/guides/index.mdx b/docs/guides/index.mdx
deleted file mode 100644
index de53b74..0000000
--- a/docs/guides/index.mdx
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Guides"
-description: "Step-by-step guides for using and contributing to NanoForge Loader."
----
-
-
-
- Install the loader packages and run your first NanoForge game in browser or server mode.
-
-
- Set up a local dev environment, follow the commit convention, and open a pull request.
-
-
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6841b22..32c7dfa 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -20,11 +20,11 @@ catalogs:
specifier: ^21.0.2
version: 21.0.2
'@favware/cliff-jumper':
- specifier: ^6.0.0
+ specifier: ^6.1.0
version: 6.1.0
'@nanoforge-dev/actions':
- specifier: ^2.1.2
- version: 2.1.2
+ specifier: ^2.1.3
+ version: 2.1.3
husky:
specifier: ^9.1.7
version: 9.1.7
@@ -36,14 +36,14 @@ catalogs:
specifier: ^1.3.14
version: 1.3.14
'@types/node':
- specifier: ^25.9.1
- version: 25.9.1
+ specifier: ^25.9.2
+ version: 25.9.2
bun:
- specifier: ^1.3.13
+ specifier: ^1.3.14
version: 1.3.14
commander:
- specifier: ^14.0.3
- version: 14.0.3
+ specifier: ^15.0.0
+ version: 15.0.0
lint:
'@nanoforge-dev/utils-eslint-config':
specifier: ^1.0.2
@@ -67,13 +67,13 @@ importers:
devDependencies:
'@commitlint/cli':
specifier: catalog:ci
- version: 21.0.2(@types/node@25.9.1)(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)(typescript@6.0.3)
+ version: 21.0.2(@types/node@25.9.2)(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)(typescript@6.0.3)
'@commitlint/config-conventional':
specifier: catalog:ci
version: 21.0.2
'@nanoforge-dev/actions':
specifier: catalog:ci
- version: 2.1.2
+ version: 2.1.3
'@nanoforge-dev/utils-eslint-config':
specifier: catalog:lint
version: 1.0.2(@types/eslint@9.6.1)(eslint@10.4.1(jiti@2.6.1))(prettier@3.8.3)(typescript@6.0.3)
@@ -88,7 +88,7 @@ importers:
version: 1.3.14
'@types/node':
specifier: catalog:core
- version: 25.9.1
+ version: 25.9.2
eslint:
specifier: catalog:lint
version: 10.4.1(jiti@2.6.1)
@@ -118,7 +118,7 @@ importers:
version: 1.3.14
commander:
specifier: catalog:core
- version: 14.0.3
+ version: 15.0.0
devDependencies:
'@favware/cliff-jumper':
specifier: catalog:ci
@@ -149,7 +149,7 @@ importers:
dependencies:
commander:
specifier: catalog:core
- version: 14.0.3
+ version: 15.0.0
devDependencies:
'@favware/cliff-jumper':
specifier: catalog:ci
@@ -263,140 +263,71 @@ packages:
resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
engines: {node: '>=6.9.0'}
- '@commitlint/cli@20.5.3':
- resolution: {integrity: sha512-OJdL0EXWD5y9LPa0nr/geOwzaS8BsdaybKkcloB0JgsguGxNv2R+hC2FTPqrAcprg35zF33KOQerY0x8W1aesA==}
- engines: {node: '>=v18'}
- hasBin: true
-
'@commitlint/cli@21.0.2':
resolution: {integrity: sha512-YMmfLbqBg+ZRvvmPhc+cilSQFrh/AgzVgCT1U/OifmUZEwPbvCtA8rN//YNaF9d5eoZphxVMGYtmwA2QgQORgg==}
engines: {node: '>=22.12.0'}
hasBin: true
- '@commitlint/config-conventional@20.5.3':
- resolution: {integrity: sha512-j34Qqeaa152chJgz2ysyk0BCpHenJn1lV0Rx0VXf8k3ccQcED+48EZrzMvo9jLmJUyBrrBwvu89I+2er4gW7QQ==}
- engines: {node: '>=v18'}
-
'@commitlint/config-conventional@21.0.2':
resolution: {integrity: sha512-P/ZRhryQmkj0Z0dY9FOoRwe3xkwJyyAdtXwt01NT2kuZttcG2CNYp1q5Ci3u+nDT2jcbJRw2kt13Czl1qKNPfg==}
engines: {node: '>=22.12.0'}
- '@commitlint/config-validator@20.5.0':
- resolution: {integrity: sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==}
- engines: {node: '>=v18'}
-
'@commitlint/config-validator@21.0.1':
resolution: {integrity: sha512-Zd2UFdndeMMaW2O96HK0tdfT4gOImUvidMpAd/pws2zZ4m1nrAZ/9b/v2JYuE8fs86GpXv9F7LNaIuCIWhY+pA==}
engines: {node: '>=22.12.0'}
- '@commitlint/ensure@20.5.3':
- resolution: {integrity: sha512-4i4AgNvH62owG9MwSiWKrle7HGNpBHHdLnWFIp5fTsHUYe5kRuh15t08L/0pdbbrRk8JKXQxxN4hZQcn+szkrw==}
- engines: {node: '>=v18'}
-
'@commitlint/ensure@21.0.1':
resolution: {integrity: sha512-jJ1037967wU7YN/xkv+iRlOBlmaOXPhPO5KQSqya6GyXzBlwuLzELBFao16DVg9dZyqmNrhewzwZ3SAibetHBQ==}
engines: {node: '>=22.12.0'}
- '@commitlint/execute-rule@20.0.0':
- resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==}
- engines: {node: '>=v18'}
-
'@commitlint/execute-rule@21.0.1':
resolution: {integrity: sha512-RifH+FmImozKBE6mozhF4K3r2RRKP7SMi/Q/zLCmExtp5e05lhHOUYqGBlFBAGNHaZxU/WYw1XuugYK9jQzqnA==}
engines: {node: '>=22.12.0'}
- '@commitlint/format@20.5.0':
- resolution: {integrity: sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==}
- engines: {node: '>=v18'}
-
'@commitlint/format@21.0.1':
resolution: {integrity: sha512-ksmG2+cHGtuDPQQbhBbC4unwm444+6TiPw0d1bKf67hntgZqZ8E0g1MuYKUuyT5IH4IMmXZhKq22/Z3jBvtQIw==}
engines: {node: '>=22.12.0'}
- '@commitlint/is-ignored@20.5.0':
- resolution: {integrity: sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==}
- engines: {node: '>=v18'}
-
'@commitlint/is-ignored@21.0.2':
resolution: {integrity: sha512-H5z4t8PC9tUsmZ/o+EptM3Nq8sTFtskAShdcqxCoyzklW5eaVT5xbrDAET2uypzir9Vsj4ZZmBtyKjYe2XqgeQ==}
engines: {node: '>=22.12.0'}
- '@commitlint/lint@20.5.3':
- resolution: {integrity: sha512-M7JbWBNr2gXKaPc4i/KipsuW1gkDHpj35KPjWtKy3Z+2AQw5wu1gBi1LIO0uoaij67CqY4K8PxPZSGens4evCw==}
- engines: {node: '>=v18'}
-
'@commitlint/lint@21.0.2':
resolution: {integrity: sha512-PnUmLYGeGLfW8oVatR9KpNxSHYAnJOEWlMZzfdeFOUq6WUrFx1fGQaWCWJqMoIll/xPM+GdfJV+tKHZVHhl0Fg==}
engines: {node: '>=22.12.0'}
- '@commitlint/load@20.5.3':
- resolution: {integrity: sha512-1FDZWuKyu98Myb8i7Tp31jPU2rZpOwAdYRyJcy2KoGg7Xk2A+bgHN8smhMaaNSNkmE8fwt53BokywZq8Gv/5XQ==}
- engines: {node: '>=v18'}
-
'@commitlint/load@21.0.2':
resolution: {integrity: sha512-lwUE70hN0/qE/ZRROhbaX65ly/FF12DrqfReLCESo37M0OQCFAf2jRS+2tSCSORq+bm4Kdju7qNDj46uc1QzTA==}
engines: {node: '>=22.12.0'}
- '@commitlint/message@20.4.3':
- resolution: {integrity: sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==}
- engines: {node: '>=v18'}
-
'@commitlint/message@21.0.2':
resolution: {integrity: sha512-5n4aqHGD/FNnom/D5L8i7cYtV+xjuXcBL832C3w9VglEsZzIsoHpJsvxzJ7cgiOsOdc/2jU4t5+7qMHh7GBX3g==}
engines: {node: '>=22.12.0'}
- '@commitlint/parse@20.5.0':
- resolution: {integrity: sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==}
- engines: {node: '>=v18'}
-
'@commitlint/parse@21.0.2':
resolution: {integrity: sha512-QVZJhGHTm+oiuWyEKOCTQ0ZM3mfJ0eGWFeHuj7WzSKEth+UukcCHac9GD8pgdFlg/qGkFWOtyaNd1T8REgagaw==}
engines: {node: '>=22.12.0'}
- '@commitlint/read@20.5.0':
- resolution: {integrity: sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==}
- engines: {node: '>=v18'}
-
'@commitlint/read@21.0.2':
resolution: {integrity: sha512-BtsrnLVycSSKf4Q0gMch4giCj5NNlmcbhc8ra5vONgGtP2IjRDo33bEFtr5Pm+2N+5fXGWb2MksWPrspPfdhdw==}
engines: {node: '>=22.12.0'}
- '@commitlint/resolve-extends@20.5.3':
- resolution: {integrity: sha512-+ogW9v/u9JqpvAgTrLra/YTFo0KkjU6iNblF89pPsj4NebNc+DAWctsludwezI8YnsjBmfHpApSwcXprN/f/ew==}
- engines: {node: '>=v18'}
-
'@commitlint/resolve-extends@21.0.1':
resolution: {integrity: sha512-0DhjYWL6uYrY16Efa032fYk3woGJDU4AGWiG1XXltT9AMUNYKyb5cIZU2ivbaMZ3+kKFqUjikD2cjh66Sbh/Sg==}
engines: {node: '>=22.12.0'}
- '@commitlint/rules@20.5.3':
- resolution: {integrity: sha512-MPlMnb9D3wbszYMp+1hPtuhtPJndRo6I6yfkZVA4+jR8w7Kqp0u2u/Y+gzbaItx5Lltq5rw7FSZQWJMoXUC4NQ==}
- engines: {node: '>=v18'}
-
'@commitlint/rules@21.0.2':
resolution: {integrity: sha512-k6tQ69Td7t2qUSIbik8D3TL1q3ZJpkEbV+yLogDzCRAdOxJm4ndhtBNREsLA1/puRfWvzS9eioF2w43WT+hHgQ==}
engines: {node: '>=22.12.0'}
- '@commitlint/to-lines@20.0.0':
- resolution: {integrity: sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==}
- engines: {node: '>=v18'}
-
'@commitlint/to-lines@21.0.1':
resolution: {integrity: sha512-bd1BFII7p1EQZre9Kaj+kKaMFP3cFCdt21K7DItVux9XP5WjLgJ0/Uy1pJJh9aPwVJ6SKg62PxqlZaHI8hQAXw==}
engines: {node: '>=22.12.0'}
- '@commitlint/top-level@20.4.3':
- resolution: {integrity: sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==}
- engines: {node: '>=v18'}
-
'@commitlint/top-level@21.0.2':
resolution: {integrity: sha512-s9KKM+e+mXgFeIh4n7KmOGAVT3mkJ3Fp1bBYHIK5pjeUwlEMzp/tZfb5u0Poa680AsQTXMEMRxZi1vQ9m2X5ug==}
engines: {node: '>=22.12.0'}
- '@commitlint/types@20.5.0':
- resolution: {integrity: sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==}
- engines: {node: '>=v18'}
-
'@commitlint/types@21.0.1':
resolution: {integrity: sha512-4u7w8jcoCUFWhjWnASYzZHAP34OqOtuFBN87nQmFvqda03YU0T6z+yB4w0gSAMpekiRqqGk5rt+qSlW+a2vSEg==}
engines: {node: '>=22.12.0'}
@@ -498,8 +429,8 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
- '@nanoforge-dev/actions@2.1.2':
- resolution: {integrity: sha512-s1HdWoy92eLztffboUnKzmjIpMLWHhCKzQM/+FPR+eZgxuULDT3uUUvKeRxxobdljFuD0e14gxnbQZZRTrG1Dg==}
+ '@nanoforge-dev/actions@2.1.3':
+ resolution: {integrity: sha512-eOuQ5q0gFylFrj//77c7PWCKAcX0GRKM7fAQiiExOnUxnuYWQGu4DIL3LMXsjDNAVMRgK3BMk0C1QivEPUN5Dg==}
engines: {node: '25'}
'@nanoforge-dev/utils-eslint-config@1.0.2':
@@ -851,8 +782,8 @@ packages:
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
- '@types/node@25.9.1':
- resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==}
+ '@types/node@25.9.2':
+ resolution: {integrity: sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==}
'@typescript-eslint/eslint-plugin@8.60.1':
resolution: {integrity: sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==}
@@ -933,18 +864,10 @@ packages:
resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==}
engines: {node: '>=18'}
- ansi-regex@5.0.1:
- resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
- engines: {node: '>=8'}
-
ansi-regex@6.2.2:
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
engines: {node: '>=12'}
- ansi-styles@4.3.0:
- resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
- engines: {node: '>=8'}
-
ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
@@ -1000,21 +923,10 @@ packages:
resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==}
engines: {node: '>=20'}
- cliui@8.0.1:
- resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
- engines: {node: '>=12'}
-
cliui@9.0.1:
resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==}
engines: {node: '>=20'}
- color-convert@2.0.1:
- resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
- engines: {node: '>=7.0.0'}
-
- color-name@1.1.4:
- resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
-
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
@@ -1022,6 +934,10 @@ packages:
resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
engines: {node: '>=20'}
+ commander@15.0.0:
+ resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==}
+ engines: {node: '>=22.12.0'}
+
compare-func@2.0.0:
resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
@@ -1095,9 +1011,6 @@ packages:
emoji-regex@10.6.0:
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
- emoji-regex@8.0.0:
- resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
-
env-paths@2.2.1:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'}
@@ -1341,9 +1254,6 @@ packages:
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
engines: {node: '>=6'}
- import-meta-resolve@4.2.0:
- resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==}
-
imurmurhash@0.1.4:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
@@ -1363,10 +1273,6 @@ packages:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
- is-fullwidth-code-point@3.0.0:
- resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
- engines: {node: '>=8'}
-
is-fullwidth-code-point@5.1.0:
resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==}
engines: {node: '>=18'}
@@ -1441,11 +1347,6 @@ packages:
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
- lint-staged@16.4.0:
- resolution: {integrity: sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==}
- engines: {node: '>=20.17'}
- hasBin: true
-
lint-staged@17.0.7:
resolution: {integrity: sha512-JrSobt+tW3rH8IOMi8tDZd3foorM5yPEkLD/V2NxobgHrFfHWGee4MOLVuZeScgxftEwbHrPHIFA/ZL+nUJeuA==}
engines: {node: '>=22.22.1'}
@@ -1455,10 +1356,6 @@ packages:
resolution: {integrity: sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==}
engines: {node: '>=22.13.0'}
- listr2@9.0.5:
- resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==}
- engines: {node: '>=20.0.0'}
-
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
@@ -1490,9 +1387,6 @@ packages:
resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
engines: {node: '>=16 || 14 >=14.17'}
- minimist@1.2.8:
- resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
-
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -1589,10 +1483,6 @@ packages:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
- require-directory@2.1.1:
- resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
- engines: {node: '>=0.10.0'}
-
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
@@ -1612,8 +1502,8 @@ packages:
rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
- semver@7.8.1:
- resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==}
+ semver@7.8.2:
+ resolution: {integrity: sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==}
engines: {node: '>=10'}
hasBin: true
@@ -1645,10 +1535,6 @@ packages:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
- string-width@4.2.3:
- resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
- engines: {node: '>=8'}
-
string-width@7.2.0:
resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
engines: {node: '>=18'}
@@ -1657,10 +1543,6 @@ packages:
resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==}
engines: {node: '>=20'}
- strip-ansi@6.0.1:
- resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
- engines: {node: '>=8'}
-
strip-ansi@7.2.0:
resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
engines: {node: '>=12'}
@@ -1753,10 +1635,6 @@ packages:
resolution: {integrity: sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==}
engines: {node: '>=20'}
- wrap-ansi@7.0.0:
- resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
- engines: {node: '>=10'}
-
wrap-ansi@9.0.2:
resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
engines: {node: '>=18'}
@@ -1770,18 +1648,10 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
- yargs-parser@21.1.1:
- resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
- engines: {node: '>=12'}
-
yargs-parser@22.0.0:
resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==}
engines: {node: ^20.19.0 || ^22.12.0 || >=23}
- yargs@17.7.2:
- resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
- engines: {node: '>=12'}
-
yargs@18.0.0:
resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=23}
@@ -1874,26 +1744,11 @@ snapshots:
'@babel/helper-string-parser': 7.29.7
'@babel/helper-validator-identifier': 7.29.7
- '@commitlint/cli@20.5.3(@types/node@25.9.1)(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)(typescript@6.0.3)':
- dependencies:
- '@commitlint/format': 20.5.0
- '@commitlint/lint': 20.5.3
- '@commitlint/load': 20.5.3(@types/node@25.9.1)(typescript@6.0.3)
- '@commitlint/read': 20.5.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)
- '@commitlint/types': 20.5.0
- tinyexec: 1.2.4
- yargs: 17.7.2
- transitivePeerDependencies:
- - '@types/node'
- - conventional-commits-filter
- - conventional-commits-parser
- - typescript
-
- '@commitlint/cli@21.0.2(@types/node@25.9.1)(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)(typescript@6.0.3)':
+ '@commitlint/cli@21.0.2(@types/node@25.9.2)(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)(typescript@6.0.3)':
dependencies:
'@commitlint/format': 21.0.1
'@commitlint/lint': 21.0.2
- '@commitlint/load': 21.0.2(@types/node@25.9.1)(typescript@6.0.3)
+ '@commitlint/load': 21.0.2(@types/node@25.9.2)(typescript@6.0.3)
'@commitlint/read': 21.0.2(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)
'@commitlint/types': 21.0.1
tinyexec: 1.2.4
@@ -1904,66 +1759,32 @@ snapshots:
- conventional-commits-parser
- typescript
- '@commitlint/config-conventional@20.5.3':
- dependencies:
- '@commitlint/types': 20.5.0
- conventional-changelog-conventionalcommits: 9.3.1
-
'@commitlint/config-conventional@21.0.2':
dependencies:
'@commitlint/types': 21.0.1
conventional-changelog-conventionalcommits: 9.3.1
- '@commitlint/config-validator@20.5.0':
- dependencies:
- '@commitlint/types': 20.5.0
- ajv: 8.20.0
-
'@commitlint/config-validator@21.0.1':
dependencies:
'@commitlint/types': 21.0.1
ajv: 8.20.0
- '@commitlint/ensure@20.5.3':
- dependencies:
- '@commitlint/types': 20.5.0
- es-toolkit: 1.47.0
-
'@commitlint/ensure@21.0.1':
dependencies:
'@commitlint/types': 21.0.1
es-toolkit: 1.47.0
- '@commitlint/execute-rule@20.0.0': {}
-
'@commitlint/execute-rule@21.0.1': {}
- '@commitlint/format@20.5.0':
- dependencies:
- '@commitlint/types': 20.5.0
- picocolors: 1.1.1
-
'@commitlint/format@21.0.1':
dependencies:
'@commitlint/types': 21.0.1
picocolors: 1.1.1
- '@commitlint/is-ignored@20.5.0':
- dependencies:
- '@commitlint/types': 20.5.0
- semver: 7.8.1
-
'@commitlint/is-ignored@21.0.2':
dependencies:
'@commitlint/types': 21.0.1
- semver: 7.8.1
-
- '@commitlint/lint@20.5.3':
- dependencies:
- '@commitlint/is-ignored': 20.5.0
- '@commitlint/parse': 20.5.0
- '@commitlint/rules': 20.5.3
- '@commitlint/types': 20.5.0
+ semver: 7.8.2
'@commitlint/lint@21.0.2':
dependencies:
@@ -1972,29 +1793,14 @@ snapshots:
'@commitlint/rules': 21.0.2
'@commitlint/types': 21.0.1
- '@commitlint/load@20.5.3(@types/node@25.9.1)(typescript@6.0.3)':
- dependencies:
- '@commitlint/config-validator': 20.5.0
- '@commitlint/execute-rule': 20.0.0
- '@commitlint/resolve-extends': 20.5.3
- '@commitlint/types': 20.5.0
- cosmiconfig: 9.0.1(typescript@6.0.3)
- cosmiconfig-typescript-loader: 6.3.0(@types/node@25.9.1)(cosmiconfig@9.0.1(typescript@6.0.3))(typescript@6.0.3)
- es-toolkit: 1.47.0
- is-plain-obj: 4.1.0
- picocolors: 1.1.1
- transitivePeerDependencies:
- - '@types/node'
- - typescript
-
- '@commitlint/load@21.0.2(@types/node@25.9.1)(typescript@6.0.3)':
+ '@commitlint/load@21.0.2(@types/node@25.9.2)(typescript@6.0.3)':
dependencies:
'@commitlint/config-validator': 21.0.1
'@commitlint/execute-rule': 21.0.1
'@commitlint/resolve-extends': 21.0.1
'@commitlint/types': 21.0.1
cosmiconfig: 9.0.1(typescript@6.0.3)
- cosmiconfig-typescript-loader: 6.3.0(@types/node@25.9.1)(cosmiconfig@9.0.1(typescript@6.0.3))(typescript@6.0.3)
+ cosmiconfig-typescript-loader: 6.3.0(@types/node@25.9.2)(cosmiconfig@9.0.1(typescript@6.0.3))(typescript@6.0.3)
es-toolkit: 1.47.0
is-plain-obj: 4.1.0
picocolors: 1.1.1
@@ -2002,33 +1808,14 @@ snapshots:
- '@types/node'
- typescript
- '@commitlint/message@20.4.3': {}
-
'@commitlint/message@21.0.2': {}
- '@commitlint/parse@20.5.0':
- dependencies:
- '@commitlint/types': 20.5.0
- conventional-changelog-angular: 8.3.1
- conventional-commits-parser: 6.4.0
-
'@commitlint/parse@21.0.2':
dependencies:
'@commitlint/types': 21.0.1
conventional-changelog-angular: 8.3.1
conventional-commits-parser: 6.4.0
- '@commitlint/read@20.5.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)':
- dependencies:
- '@commitlint/top-level': 20.4.3
- '@commitlint/types': 20.5.0
- git-raw-commits: 5.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)
- minimist: 1.2.8
- tinyexec: 1.2.4
- transitivePeerDependencies:
- - conventional-commits-filter
- - conventional-commits-parser
-
'@commitlint/read@21.0.2(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)':
dependencies:
'@commitlint/top-level': 21.0.2
@@ -2039,15 +1826,6 @@ snapshots:
- conventional-commits-filter
- conventional-commits-parser
- '@commitlint/resolve-extends@20.5.3':
- dependencies:
- '@commitlint/config-validator': 20.5.0
- '@commitlint/types': 20.5.0
- es-toolkit: 1.47.0
- global-directory: 5.0.0
- import-meta-resolve: 4.2.0
- resolve-from: 5.0.0
-
'@commitlint/resolve-extends@21.0.1':
dependencies:
'@commitlint/config-validator': 21.0.1
@@ -2056,13 +1834,6 @@ snapshots:
global-directory: 5.0.0
resolve-from: 5.0.0
- '@commitlint/rules@20.5.3':
- dependencies:
- '@commitlint/ensure': 20.5.3
- '@commitlint/message': 20.4.3
- '@commitlint/to-lines': 20.0.0
- '@commitlint/types': 20.5.0
-
'@commitlint/rules@21.0.2':
dependencies:
'@commitlint/ensure': 21.0.1
@@ -2070,23 +1841,12 @@ snapshots:
'@commitlint/to-lines': 21.0.1
'@commitlint/types': 21.0.1
- '@commitlint/to-lines@20.0.0': {}
-
'@commitlint/to-lines@21.0.1': {}
- '@commitlint/top-level@20.4.3':
- dependencies:
- escalade: 3.2.0
-
'@commitlint/top-level@21.0.2':
dependencies:
escalade: 3.2.0
- '@commitlint/types@20.5.0':
- dependencies:
- conventional-commits-parser: 6.4.0
- picocolors: 1.1.1
-
'@commitlint/types@21.0.1':
dependencies:
conventional-commits-parser: 6.4.0
@@ -2096,7 +1856,7 @@ snapshots:
dependencies:
'@simple-libs/child-process-utils': 1.0.2
'@simple-libs/stream-utils': 1.2.0
- semver: 7.8.1
+ semver: 7.8.2
optionalDependencies:
conventional-commits-filter: 5.0.0
conventional-commits-parser: 6.4.0
@@ -2153,7 +1913,7 @@ snapshots:
execa: 9.6.1
git-cliff: 2.13.1
js-yaml: 4.2.0
- semver: 7.8.1
+ semver: 7.8.2
smol-toml: 1.6.1
'@favware/colorette-spinner@1.0.1':
@@ -2190,12 +1950,12 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
- '@nanoforge-dev/actions@2.1.2':
+ '@nanoforge-dev/actions@2.1.3':
dependencies:
'@actions/core': 3.0.1
'@actions/github': 9.1.1
- commander: 14.0.3
- semver: 7.8.1
+ commander: 15.0.0
+ semver: 7.8.2
'@nanoforge-dev/utils-eslint-config@1.0.2(@types/eslint@9.6.1)(eslint@10.4.1(jiti@2.6.1))(prettier@3.8.3)(typescript@6.0.3)':
dependencies:
@@ -2443,7 +2203,7 @@ snapshots:
'@types/json-schema@7.0.15': {}
- '@types/node@25.9.1':
+ '@types/node@25.9.2':
dependencies:
undici-types: 7.24.6
@@ -2515,7 +2275,7 @@ snapshots:
'@typescript-eslint/visitor-keys': 8.60.1
debug: 4.4.3
minimatch: 10.2.5
- semver: 7.8.1
+ semver: 7.8.2
tinyglobby: 0.2.17
ts-api-utils: 2.5.0(typescript@6.0.3)
typescript: 6.0.3
@@ -2562,14 +2322,8 @@ snapshots:
dependencies:
environment: 1.1.0
- ansi-regex@5.0.1: {}
-
ansi-regex@6.2.2: {}
- ansi-styles@4.3.0:
- dependencies:
- color-convert: 2.0.1
-
ansi-styles@6.2.3: {}
argparse@2.0.1: {}
@@ -2594,7 +2348,7 @@ snapshots:
bun-types@1.3.14:
dependencies:
- '@types/node': 25.9.1
+ '@types/node': 25.9.2
bun@1.3.14:
optionalDependencies:
@@ -2628,28 +2382,18 @@ snapshots:
slice-ansi: 8.0.0
string-width: 8.2.1
- cliui@8.0.1:
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 7.0.0
-
cliui@9.0.1:
dependencies:
string-width: 7.2.0
strip-ansi: 7.2.0
wrap-ansi: 9.0.2
- color-convert@2.0.1:
- dependencies:
- color-name: 1.1.4
-
- color-name@1.1.4: {}
-
colorette@2.0.20: {}
commander@14.0.3: {}
+ commander@15.0.0: {}
+
compare-func@2.0.0:
dependencies:
array-ify: 1.0.0
@@ -2682,9 +2426,9 @@ snapshots:
conventional-commits-parser: 6.4.0
meow: 13.2.0
- cosmiconfig-typescript-loader@6.3.0(@types/node@25.9.1)(cosmiconfig@9.0.1(typescript@6.0.3))(typescript@6.0.3):
+ cosmiconfig-typescript-loader@6.3.0(@types/node@25.9.2)(cosmiconfig@9.0.1(typescript@6.0.3))(typescript@6.0.3):
dependencies:
- '@types/node': 25.9.1
+ '@types/node': 25.9.2
cosmiconfig: 9.0.1(typescript@6.0.3)
jiti: 2.6.1
typescript: 6.0.3
@@ -2716,8 +2460,6 @@ snapshots:
emoji-regex@10.6.0: {}
- emoji-regex@8.0.0: {}
-
env-paths@2.2.1: {}
environment@1.1.0: {}
@@ -2967,8 +2709,6 @@ snapshots:
parent-module: 1.0.1
resolve-from: 4.0.0
- import-meta-resolve@4.2.0: {}
-
imurmurhash@0.1.4: {}
ini@6.0.0: {}
@@ -2979,8 +2719,6 @@ snapshots:
is-extglob@2.1.1: {}
- is-fullwidth-code-point@3.0.0: {}
-
is-fullwidth-code-point@5.1.0:
dependencies:
get-east-asian-width: 1.6.0
@@ -3034,15 +2772,6 @@ snapshots:
lines-and-columns@1.2.4: {}
- lint-staged@16.4.0:
- dependencies:
- commander: 14.0.3
- listr2: 9.0.5
- picomatch: 4.0.4
- string-argv: 0.3.2
- tinyexec: 1.2.4
- yaml: 2.9.0
-
lint-staged@17.0.7:
dependencies:
listr2: 10.2.1
@@ -3060,15 +2789,6 @@ snapshots:
rfdc: 1.4.1
wrap-ansi: 10.0.0
- listr2@9.0.5:
- dependencies:
- cli-truncate: 5.2.0
- colorette: 2.0.20
- eventemitter3: 5.0.4
- log-update: 6.1.0
- rfdc: 1.4.1
- wrap-ansi: 9.0.2
-
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
@@ -3100,8 +2820,6 @@ snapshots:
dependencies:
brace-expansion: 2.1.1
- minimist@1.2.8: {}
-
ms@2.1.3: {}
natural-compare@1.4.0: {}
@@ -3205,8 +2923,6 @@ snapshots:
punycode@2.3.1: {}
- require-directory@2.1.1: {}
-
require-from-string@2.0.2: {}
resolve-from@4.0.0: {}
@@ -3220,7 +2936,7 @@ snapshots:
rfdc@1.4.1: {}
- semver@7.8.1: {}
+ semver@7.8.2: {}
shebang-command@2.0.0:
dependencies:
@@ -3244,12 +2960,6 @@ snapshots:
string-argv@0.3.2: {}
- string-width@4.2.3:
- dependencies:
- emoji-regex: 8.0.0
- is-fullwidth-code-point: 3.0.0
- strip-ansi: 6.0.1
-
string-width@7.2.0:
dependencies:
emoji-regex: 10.6.0
@@ -3261,10 +2971,6 @@ snapshots:
get-east-asian-width: 1.6.0
strip-ansi: 7.2.0
- strip-ansi@6.0.1:
- dependencies:
- ansi-regex: 5.0.1
-
strip-ansi@7.2.0:
dependencies:
ansi-regex: 6.2.2
@@ -3347,12 +3053,6 @@ snapshots:
string-width: 8.2.1
strip-ansi: 7.2.0
- wrap-ansi@7.0.0:
- dependencies:
- ansi-styles: 4.3.0
- string-width: 4.2.3
- strip-ansi: 6.0.1
-
wrap-ansi@9.0.2:
dependencies:
ansi-styles: 6.2.3
@@ -3361,22 +3061,11 @@ snapshots:
y18n@5.0.8: {}
- yaml@2.9.0: {}
-
- yargs-parser@21.1.1: {}
+ yaml@2.9.0:
+ optional: true
yargs-parser@22.0.0: {}
- yargs@17.7.2:
- dependencies:
- cliui: 8.0.1
- escalade: 3.2.0
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- string-width: 4.2.3
- y18n: 5.0.8
- yargs-parser: 21.1.1
-
yargs@18.0.0:
dependencies:
cliui: 9.0.1
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index cd7d004..8ecbdcc 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -6,30 +6,23 @@ allowBuilds:
catalogs:
build:
- tsup: ^8.5.1
turbo: ^2.9.16
typescript: ^6.0.3
ci:
'@commitlint/cli': ^21.0.2
'@commitlint/config-conventional': ^21.0.2
- '@favware/cliff-jumper': ^6.0.0
- '@nanoforge-dev/actions': ^2.1.2
+ '@favware/cliff-jumper': ^6.1.0
+ '@nanoforge-dev/actions': ^2.1.3
husky: ^9.1.7
lint-staged: ^17.0.7
core:
'@types/bun': ^1.3.14
- '@types/node': ^25.9.1
- bun: ^1.3.13
- commander: ^14.0.3
+ '@types/node': ^25.9.2
+ bun: ^1.3.14
+ commander: ^15.0.0
lint:
'@nanoforge-dev/utils-eslint-config': ^1.0.2
'@nanoforge-dev/utils-prettier-config': ^1.0.2
'@trivago/prettier-plugin-sort-imports': ^6.0.2
eslint: ^10.4.1
prettier: ^3.8.3
- schematics:
- '@angular-devkit/core': ^21.1.1
- '@angular-devkit/schematics': ^21.1.1
-
-minimumReleaseAgeExclude:
- - '@nanoforge-dev/actions@2.1.2'