Archive Steam docs; add itch.io upload guide
Move legacy Steam-related docs into documentation/archived and add a new UPLOAD-ITCH.md describing how to publish builds to itch.io with Butler. Update top-level README to state official releases will be on itch.io. Remove Steam-specific UI/features: drop steamCloudOptIn from first-run preferences, remove the Steam Cloud teaser and summary from the setup flow, and adjust settings/setup copy to reference handheld devices and non‑Steam distribution. Also make a small wording tweak in the plugins doc about rendererPreload.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# Nebula Plugins (Early Preview)
|
||||
|
||||
This document explains how to build simple plugins for Nebula. The initial API is intentionally small and will grow with feedback.
|
||||
|
||||
## Overview
|
||||
|
||||
- Plugins live under either of these folders:
|
||||
- App folder: `<app>/plugins/<plugin-id>/`
|
||||
- User folder: `%APPDATA%/Nebula/plugins/<plugin-id>/` (Windows) – preferred for user-installed plugins.
|
||||
- Each plugin has a `plugin.json` manifest. Optional `main.js` runs in the main process. Optional `renderer-preload.js` runs in the renderer preload context and can expose safe APIs via `contextBridge`.
|
||||
- Plugins are loaded on app start. Toggle a plugin by setting `"enabled": false` in its manifest.
|
||||
|
||||
## Manifest (plugin.json)
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "my-plugin",
|
||||
"name": "My Plugin",
|
||||
"version": "0.1.0",
|
||||
"description": "What it does",
|
||||
"main": "main.js",
|
||||
"rendererPreload": "renderer-preload.js",
|
||||
"categories": ["Search", "Productivity"],
|
||||
"authors": ["Jane Doe", { "name": "Acme Labs", "email": "oss@acme.example" }],
|
||||
"enabled": true
|
||||
}
|
||||
```
|
||||
|
||||
Fields:
|
||||
- id: Unique id. Defaults to folder name if omitted.
|
||||
- main: Optional entry for main process integration.
|
||||
- rendererPreload: Optional file injected into the preload. Use it to expose a safe surface to the page.
|
||||
- categories: Optional string or array of strings used for organizing/filtering plugins in UI and APIs. Example: ["AI", "Utilities"].
|
||||
- authors: Optional string or array of strings/objects describing authors. Objects support { name, email, url }. In APIs/UI, names are displayed.
|
||||
- enabled: Defaults to true.
|
||||
|
||||
## Main process API (activate)
|
||||
|
||||
If `main` is present, export an `activate(ctx)` function. The `ctx` contains:
|
||||
- Electron: `app`, `BrowserWindow`, `ipcMain`, `session`, `Menu`, `dialog`, `shell`
|
||||
- paths: `{ appPath, userData, pluginDir }`
|
||||
- log/warn/error: prefix logs with your plugin id
|
||||
- on(event, cb): subscribe to lifecycle events (experimental)
|
||||
- registerIPC(channel, handler): quickly expose an `ipcMain.handle`
|
||||
- registerWebRequest(filter, listener): attach `session.webRequest.onBeforeRequest`
|
||||
|
||||
Example:
|
||||
|
||||
module.exports.activate = (ctx) => {
|
||||
ctx.log('hello');
|
||||
ctx.registerIPC('my-plugin:do', async (_evt, payload) => ({ ok: true }));
|
||||
ctx.registerWebRequest({ urls: ['*://*/*'] }, (details) => ({ cancel: false }));
|
||||
};
|
||||
|
||||
## Renderer preload API
|
||||
|
||||
If `rendererPreload` is present, it will be `require()`-d from the app preload. You can use `contextBridge` to expose a safe surface to the page:
|
||||
|
||||
const { contextBridge, ipcRenderer } = require('electron');
|
||||
contextBridge.exposeInMainWorld('myPlugin', {
|
||||
hello: () => ipcRenderer.invoke('my-plugin:do'),
|
||||
});
|
||||
|
||||
Your exposed API will be available on `window.myPlugin` in `renderer/` code (e.g., `script.js`).
|
||||
|
||||
## Sample plugin
|
||||
|
||||
A working sample is included at `plugins/sample-hello/`:
|
||||
- Adds menu item "Say Hello (Sample Plugin)" under Help.
|
||||
- Exposes `window.sampleHello.ping()` and `window.sampleHello.onHello(cb)`.
|
||||
|
||||
Try it from the DevTools console:
|
||||
|
||||
await window.sampleHello.ping();
|
||||
window.sampleHello.onHello((m) => console.log('got hello', m));
|
||||
|
||||
Click Help -> Say Hello (Sample Plugin) to see the message delivered to the page.
|
||||
|
||||
## Loading order and safety
|
||||
|
||||
- Plugins load after the app is ready. Renderer preloads run after Nebula's own preload has exposed its APIs.
|
||||
- Context isolation stays enabled. Only data explicitly exposed via `contextBridge` is available to pages.
|
||||
- Avoid long blocking work in plugin activation.
|
||||
|
||||
## Debugging
|
||||
|
||||
- See logs with a `[Plugin:<id>]` prefix in the app console.
|
||||
- Temporarily disable a plugin by setting `enabled: false` in `plugin.json`.
|
||||
|
||||
## Roadmap
|
||||
|
||||
This is a first pass. Planned next:
|
||||
- Enable plugin settings UI
|
||||
- Hot reload/reload button
|
||||
- More lifecycle hooks (tab events, context menu contributions)
|
||||
- Theming hooks
|
||||
Reference in New Issue
Block a user