theseus/bundled-addons/pithos/index.js
Local Dev 4ad95b3c7a Theseus: bundle the Pithos add-on
Ships Pithos (the s3d control panel) as a built-in extension: the dock
menu opens it in a tab served from a loopback port, and "Stop s3d"
shuts the gateway down. Generated by Pithos/scripts/build-theseus-addon.mjs.

yaml is vendored under vendor/yaml/lib rather than node_modules/ or
dist/, because Theseus git-ignores both and a clean-worktree release
build would otherwise ship the add-on without its only dependency.
2026-10-03 19:03:05 +02:00

57 lines
2 KiB
JavaScript

// Pithos for Theseus. The add-on runs the same control server as the web
// console and desktop app, in Theseus's main process, and opens its UI in a
// normal tab at a random loopback port. The first URL carries a one-time
// secret that the server swaps for an HttpOnly cookie.
//
// Loaded with require() by the add-on host; core/ is ESM, hence import().
const path = require("node:path");
const { pathToFileURL } = require("node:url");
let pithos = null;
let starting = null;
module.exports = {
activate(api) {
// The pinned s3d release lands in the per-add-on data folder, never in the
// add-on folder itself (that one is replaced on update).
const dataDir = path.join(api.dataDir || path.join(api.folder, "..", "..", "extensions-data"), "pithos");
async function ensureServer() {
if (pithos) return pithos;
if (!starting) {
starting = (async () => {
const { createPithos } = await import(pathToFileURL(path.join(__dirname, "core", "server.js")).href);
pithos = await createPithos({
host: "127.0.0.1",
port: 0,
hostName: "theseus",
binDir: path.join(dataDir, "bin"),
openExternal: (url) => api.openTab(url),
});
api.log(`control server on ${pithos.url}`);
return pithos;
})().finally(() => { starting = null; });
}
return starting;
}
api.onMessage("menu-select", async (payload) => {
const id = payload && payload.id;
if (id === "open") {
const p = await ensureServer();
api.openTab(p.authUrl);
} else if (id === "stop") {
if (pithos) await pithos.daemon.stop();
}
});
// The host has no quit hook for add-ons; without this an s3d we started
// would outlive Theseus.
process.on("exit", () => { try { pithos && pithos.daemon.child && pithos.daemon.child.kill(); } catch {} });
},
async deactivate() {
if (pithos) { const p = pithos; pithos = null; await p.close(); }
},
};