Initial plugin registry: unreal + hello-exbyte
This commit is contained in:
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");
|
||||
}
|
||||
Reference in New Issue
Block a user