Initial plugin registry: unreal + hello-exbyte
This commit is contained in:
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Exbyte Depot — official plugin registry
|
||||
|
||||
`registry.json` lists official plugins for **Exbyte Depot**. The client fetches it,
|
||||
shows available plugins, and installs them into the user's local plugins folder.
|
||||
Plugins marked `"autoInstall": true` are installed automatically on first run
|
||||
(e.g. **Unreal Engine Tools**).
|
||||
|
||||
Each plugin lives under `plugins/<id>/` (a `plugin.json` manifest + a JS entry).
|
||||
See the app's `PLUGINS.md` for the SDK.
|
||||
57
plugins/hello-exbyte/index.js
Normal file
57
plugins/hello-exbyte/index.js
Normal file
@ -0,0 +1,57 @@
|
||||
// Hello Exbyte — example plugin.
|
||||
// A plugin is a plain ES module that exports `activate(host)`. The host is the
|
||||
// only way the plugin touches the app; what it can reach is gated by the
|
||||
// "permissions" in plugin.json.
|
||||
|
||||
export function activate(host) {
|
||||
host.log("activating", host.plugin.id, "v", host.version);
|
||||
|
||||
// 1) A menu action (appears under the Actions menu).
|
||||
host.ui.addMenuItem("Say hello 👋", () => {
|
||||
const me = host.info()?.userName || "there";
|
||||
host.flash(`Hello, ${me}! (from the Hello Exbyte plugin)`);
|
||||
host.notify("Hello Exbyte", "The example plugin says hi.");
|
||||
});
|
||||
|
||||
// 2) A file context-menu item (right-click a file in Changes).
|
||||
host.ui.addFileContextItem("Copy depot path (plugin)", (file) => {
|
||||
if (file.depotFile) {
|
||||
host.clipboard.write(file.depotFile);
|
||||
host.flash("Copied: " + file.depotFile);
|
||||
}
|
||||
});
|
||||
|
||||
// 3) A view — a per-workspace notepad, persisted with host.storage.
|
||||
// Opens from the Actions menu (listed by its title).
|
||||
host.ui.addView({
|
||||
id: "notes",
|
||||
title: "Workspace Notes",
|
||||
render: (el) => {
|
||||
const key = "notes:" + (host.info()?.clientName || "default");
|
||||
const ta = document.createElement("textarea");
|
||||
ta.value = host.storage.get(key) || "";
|
||||
ta.placeholder = "Jot notes for this workspace… (saved locally, per workspace)";
|
||||
ta.style.cssText =
|
||||
"width:100%;height:320px;box-sizing:border-box;resize:vertical;" +
|
||||
"background:var(--input-bg,#111);color:var(--txt,#eee);" +
|
||||
"border:1px solid var(--border,#333);border-radius:10px;padding:12px;" +
|
||||
"font:13px/1.6 system-ui;outline:none";
|
||||
ta.addEventListener("input", () => host.storage.set(key, ta.value));
|
||||
el.appendChild(ta);
|
||||
// optional cleanup returned to the host:
|
||||
return () => host.storage.set(key, ta.value);
|
||||
},
|
||||
});
|
||||
|
||||
// 4) A submit guard — blocks (with a confirm) files that look like WIP.
|
||||
// This is the same hook point a reference-integrity guard would use.
|
||||
host.ui.addSubmitHook((files) => {
|
||||
const wip = files.filter((f) => /(^|\/)(wip|temp|scratch)[^/]*$/i.test(f.depotFile || ""));
|
||||
if (wip.length) {
|
||||
return { ok: false, message: `${wip.length} file(s) look like work-in-progress (wip / temp / scratch).` };
|
||||
}
|
||||
return { ok: true };
|
||||
});
|
||||
|
||||
host.log("activated");
|
||||
}
|
||||
11
plugins/hello-exbyte/plugin.json
Normal file
11
plugins/hello-exbyte/plugin.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "hello-exbyte",
|
||||
"name": "Hello Exbyte",
|
||||
"version": "1.0.0",
|
||||
"author": "Exbyte Studios",
|
||||
"description": "Example plugin — a menu action, a per-workspace notes panel, a file context item, and a submit guard. Copy it as a starting point.",
|
||||
"entry": "index.js",
|
||||
"minAppVersion": "0.3.5",
|
||||
"permissions": ["p4:read", "notify"],
|
||||
"contributes": { "menu": true, "views": ["notes"], "fileContext": true, "submitHooks": true }
|
||||
}
|
||||
46
plugins/unreal/index.js
Normal file
46
plugins/unreal/index.js
Normal file
@ -0,0 +1,46 @@
|
||||
// Unreal Engine Tools — official plugin.
|
||||
// The core app keeps the build engine (UnrealBuildTool / MSBuild), the build
|
||||
// overlay and the log reader; this plugin is just the Unreal-facing surface:
|
||||
// a "Build Solution" action and a live Unreal-log view. Reached through the
|
||||
// permission-gated `host.ue` bridge.
|
||||
|
||||
export function activate(host) {
|
||||
const ue = host.ue;
|
||||
if (!ue) { host.log("no ue bridge — plugin.json needs the \"ue\" permission"); return; }
|
||||
|
||||
// Build the game target (UnrealBuildTool for the game module, MSBuild for plain C++).
|
||||
host.ui.addMenuItem("🔨 Build Solution (Unreal)", () => {
|
||||
if (!ue.hasProject()) { host.flash("No Unreal project in the current working folder.", true); return; }
|
||||
ue.build(); // triggers the core build flow + overlay
|
||||
});
|
||||
|
||||
// Live Unreal editor log (tails Saved/Logs). Opens from the Actions menu.
|
||||
host.ui.addView({
|
||||
id: "unreal-log",
|
||||
title: "Unreal Log",
|
||||
render: (el) => {
|
||||
el.style.cssText = "display:flex;flex-direction:column;height:100%;min-height:340px";
|
||||
const pre = document.createElement("pre");
|
||||
pre.style.cssText =
|
||||
"flex:1;margin:0;overflow:auto;white-space:pre-wrap;word-break:break-word;" +
|
||||
"font:11.5px/1.6 var(--mono,ui-monospace,monospace);color:var(--muted,#9a9aa8)";
|
||||
el.appendChild(pre);
|
||||
let alive = true;
|
||||
async function tick() {
|
||||
if (!alive) return;
|
||||
try {
|
||||
if (!ue.hasProject()) { pre.textContent = "No Unreal project in the current working folder."; return; }
|
||||
const atBottom = pre.scrollTop + pre.clientHeight >= pre.scrollHeight - 30;
|
||||
const txt = await ue.readLog(200000);
|
||||
pre.textContent = txt || "No Unreal log yet. It appears when the editor writes to Saved/Logs (i.e. while Unreal is running).";
|
||||
if (atBottom) pre.scrollTop = pre.scrollHeight;
|
||||
} catch (e) { pre.textContent = String(e); }
|
||||
}
|
||||
tick();
|
||||
const id = setInterval(tick, 1500);
|
||||
return () => { alive = false; clearInterval(id); };
|
||||
},
|
||||
});
|
||||
|
||||
host.log("Unreal Engine Tools activated");
|
||||
}
|
||||
12
plugins/unreal/plugin.json
Normal file
12
plugins/unreal/plugin.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "unreal",
|
||||
"name": "Unreal Engine Tools",
|
||||
"version": "1.0.0",
|
||||
"author": "Exbyte Studios",
|
||||
"description": "Build the game (.sln / UnrealBuildTool) and tail the Unreal editor log. Enable this on Unreal Engine projects.",
|
||||
"entry": "index.js",
|
||||
"minAppVersion": "0.3.6",
|
||||
"permissions": ["ue"],
|
||||
"defaultEnabled": true,
|
||||
"contributes": { "menu": true, "views": ["unreal-log"] }
|
||||
}
|
||||
32
registry.json
Normal file
32
registry.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"schema": "exbyte-depot-plugin-registry/1",
|
||||
"updated": "2026-07-09",
|
||||
"plugins": [
|
||||
{
|
||||
"id": "unreal",
|
||||
"name": "Unreal Engine Tools",
|
||||
"version": "1.0.0",
|
||||
"author": "Exbyte Studios",
|
||||
"description": "Build the game (.sln / UnrealBuildTool) and tail the Unreal editor log. For Unreal Engine projects.",
|
||||
"permissions": ["ue"],
|
||||
"minAppVersion": "0.3.6",
|
||||
"official": true,
|
||||
"autoInstall": true,
|
||||
"files": ["plugin.json", "index.js"],
|
||||
"baseUrl": "https://gitea.exbytestudios.com/ExbytePublicServices/exbyte-depot-plugins/raw/branch/main/plugins/unreal/"
|
||||
},
|
||||
{
|
||||
"id": "hello-exbyte",
|
||||
"name": "Hello Exbyte",
|
||||
"version": "1.0.0",
|
||||
"author": "Exbyte Studios",
|
||||
"description": "Example plugin — menu action, per-workspace notes, file context item, submit guard. A starting point for your own.",
|
||||
"permissions": ["p4:read", "notify"],
|
||||
"minAppVersion": "0.3.5",
|
||||
"official": true,
|
||||
"autoInstall": false,
|
||||
"files": ["plugin.json", "index.js"],
|
||||
"baseUrl": "https://gitea.exbytestudios.com/ExbytePublicServices/exbyte-depot-plugins/raw/branch/main/plugins/hello-exbyte/"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user