docs: README for the blueprint structure; drop standalone-UI sections
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,7 @@ even uses the same art source (SteamGridDB) when you give it an API key.
|
||||
|
||||
- A Punktfunk host (Linux or Windows) with the **scripting runner** (`punktfunk-scripting`) enabled.
|
||||
- [Bun](https://bun.sh) (the runner is Bun).
|
||||
- `@punktfunk/host` **≥ 0.1.1** — it provides the plugin-UI surface (`servePluginUi`) and discovers
|
||||
- `@punktfunk/host` **≥ 0.1.2** + `@punktfunk/plugin-kit` **≥ 0.1.1** — it provides the plugin-UI surface (`servePluginUi`) and discovers
|
||||
scoped `@punktfunk/plugin-*` packages.
|
||||
|
||||
## Install
|
||||
@@ -39,12 +39,12 @@ Enable-ScheduledTask PunktfunkScripting # Windows
|
||||
|
||||
Open the Punktfunk console — a **ROM Manager** entry appears in the nav. That's it.
|
||||
|
||||
> **Headless / host-only boxes** without the console can use the [standalone UI](#standalone-ui) or
|
||||
> just drop a `config.json` (below) — the sync engine is fully functional from the file alone.
|
||||
> **Headless / host-only boxes** without the console can just drop a `config.json` (below) and use
|
||||
> the CLI — the sync engine is fully functional from the file alone.
|
||||
|
||||
## Quick start (config file)
|
||||
|
||||
The plugin owns `<config_dir>/rom-manager/config.json`. A minimal example:
|
||||
The plugin owns `<config_dir>/plugin-state/rom-manager/config.json`. A minimal example:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
@@ -56,7 +56,8 @@ The plugin owns `<config_dir>/rom-manager/config.json`. A minimal example:
|
||||
}
|
||||
```
|
||||
|
||||
See [`config.example.json`](./config.example.json) for every option. Then, from the plugin dir:
|
||||
Only the keys you author are stored — defaults live in the schema (`contract/src/config.ts`) and are
|
||||
never baked into your file. Then, from the plugin dir:
|
||||
|
||||
```sh
|
||||
bunx punktfunk-plugin-rom-manager scan # what the scanner finds
|
||||
@@ -95,27 +96,12 @@ sheets hide their tracks, `.chd` stands alone.
|
||||
|
||||
## The UI
|
||||
|
||||
### Console-hosted (default)
|
||||
|
||||
`servePluginUi` serves the SPA on a loopback ephemeral port behind a per-boot secret and registers it
|
||||
with the host; the console reverse-proxies it and gates it with your existing console sign-in. Four
|
||||
pages: **Setup** (ROM roots), **Emulators** (detected + per-platform overrides), **Games** (scan
|
||||
preview with covers + per-title include toggles), **Sync** (status, art settings, sync options).
|
||||
|
||||
### Standalone UI
|
||||
|
||||
For host-only installs, set `ui.standalone: true` (config). It serves the same SPA on a fixed port:
|
||||
|
||||
```jsonc
|
||||
"ui": { "standalone": true, "port": 47993, "bind": "127.0.0.1" }
|
||||
```
|
||||
|
||||
A **non-loopback bind requires a password** (fail-closed — the UI can edit launch commands, i.e.
|
||||
host-user code):
|
||||
|
||||
```sh
|
||||
bunx punktfunk-plugin-rom-manager set-password 'your-password'
|
||||
```
|
||||
with the host; the console reverse-proxies it and gates it with your existing console sign-in. Five
|
||||
pages: **Overview** (health, stats, live sync activity), **Library** (scan preview with covers
|
||||
+ include toggles), **Sources** (ROM roots), **Emulators** (detection + per-platform overrides),
|
||||
**Settings** (art, sync, file paths). The console surface is the only UI — the old standalone
|
||||
password server was removed in 0.3.0 (headless boxes drive the plugin via the CLI).
|
||||
|
||||
## Security
|
||||
|
||||
@@ -125,24 +111,33 @@ bunx punktfunk-plugin-rom-manager set-password 'your-password'
|
||||
- `config.json` lives in the hardened `<config_dir>`; the plugin refuses a group/world-writable one.
|
||||
- Outbound network in v1: SteamGridDB (if keyed) and libretro-thumbnails only. No telemetry.
|
||||
|
||||
## Development
|
||||
## Development — this repo is the plugin blueprint
|
||||
|
||||
rom-manager is the reference consumer of
|
||||
[`@punktfunk/plugin-kit`](https://git.unom.io/unom/punktfunk/src/branch/main/plugin-kit) — copy this
|
||||
repo's structure to start a new plugin. Three bun workspaces:
|
||||
|
||||
| Workspace | What it is |
|
||||
|---|---|
|
||||
| `contract/` | **The single source of truth**: Effect Schemas for the config (raw↔resolved in one schema), domain DTOs, the `HttpApi` contract, API errors. Never published — bundled into the plugin, imported source-level by the UI. No hand-mirrored types anywhere. |
|
||||
| `plugin/` | The published package. `src/domain` + `src/art` are the pure, injectable, unit-tested core; `src/services` wires them into the kit (ConfigService, CacheStore, SyncEngine, ProviderClient, HttpApi handlers + SSE); `src/index.ts` is the `definePluginKit` entry (async at the runner boundary, Effect inside). |
|
||||
| `ui/` | The SPA: React 19 + `@unom/ui` + `@unom/app-ui` + the kit's `/react` helpers + `/theme.css`, with an Effect-native data layer (`AtomHttpApi` atoms derived from the contract). Builds into `plugin/dist/ui`. |
|
||||
|
||||
```sh
|
||||
bun install # backend deps (@punktfunk/host + effect) from the Gitea registry
|
||||
bun test # engine unit tests (pure core: quoting, scanner, reconcile, art)
|
||||
bun run typecheck
|
||||
bun run build:all # backend → dist/ (tsc), SPA → dist/ui/ (Vite)
|
||||
cd ui && bun run dev # SPA dev server (point it at a running standalone instance)
|
||||
bun install # one workspace install (Gitea registry for @punktfunk/@unom scopes)
|
||||
bun test # domain + service tests (plugin/)
|
||||
bun run typecheck # contract → plugin → ui
|
||||
bun run build # backend bundle + SPA → plugin/dist
|
||||
|
||||
cd ui && bun run dev # UI with ZERO host running (in-browser mock layer + scenarios)
|
||||
cd ui && bun run storybook # per-page stories on the same fixtures (port 6013)
|
||||
cd plugin && bun run dev # auth-free dev API on :5885 …
|
||||
cd ui && bun run dev:live # … and the UI proxied against it
|
||||
```
|
||||
|
||||
- The backend is plain `tsc` output — it depends on `@punktfunk/host` + `effect` at runtime (shared
|
||||
with the runner and other plugins, not bundled).
|
||||
- The **SPA** (`ui/`) uses the console's design system (`@unom/ui` + `@unom/style` + Tailwind v4) so it
|
||||
reads as family. Those are **build-time only** — the SPA compiles to static assets in `dist/ui`, so
|
||||
the published plugin carries no `@unom` runtime dependency. Installing them needs the `@unom` scope in
|
||||
your `~/.npmrc` (with the Gitea token); CI needs the same token as a secret.
|
||||
|
||||
Requires `@punktfunk/host` ≥ 0.1.1.
|
||||
Requires `@punktfunk/host` ≥ 0.1.2 and `@punktfunk/plugin-kit` ≥ 0.1.1 at runtime (shared with the
|
||||
runner, not bundled). `@unom/*` + `@effect/atom-react` are build-time only — the SPA ships as static
|
||||
assets, so the published plugin carries no UI runtime dependencies.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Reference in New Issue
Block a user