consortium
Version:
Remote control and session sharing CLI for AI coding agents
110 lines (104 loc) • 3.97 kB
JavaScript
;
var fs = require('node:fs/promises');
var os = require('node:os');
var path = require('node:path');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os);
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
const EXTENSION_DIRNAME = "consortium-permission";
const FILES_TO_COPY_DEV = ["package.json", "index.ts"];
const FILES_TO_COPY_DIST = ["package.json", "index.js", "index.cjs", "index.mjs"];
async function pathExists(p) {
try {
await fs__namespace.access(p);
return true;
} catch {
return false;
}
}
async function readJson(p) {
try {
const raw = await fs__namespace.readFile(p, "utf8");
return JSON.parse(raw);
} catch {
return null;
}
}
function compareVersions(a, b) {
const pa = a.split(".").map((s) => parseInt(s, 10));
const pb = b.split(".").map((s) => parseInt(s, 10));
const len = Math.max(pa.length, pb.length);
for (let i = 0; i < len; i++) {
const na = pa[i];
const nb = pb[i];
if (Number.isNaN(na) || Number.isNaN(nb)) return a < b ? -1 : a > b ? 1 : 0;
if ((na ?? 0) !== (nb ?? 0)) return (na ?? 0) - (nb ?? 0);
}
return 0;
}
async function resolveSourceDir() {
const candidates = [
path__namespace.resolve(__dirname, "../ext/consortium-permission"),
path__namespace.resolve(__dirname, "./pi/ext/consortium-permission"),
path__namespace.resolve(__dirname, "./ext/consortium-permission"),
path__namespace.resolve(__dirname, "../../pi-ext")
];
for (const dir of candidates) {
if (!await pathExists(path__namespace.join(dir, "package.json"))) continue;
const hasJs = await pathExists(path__namespace.join(dir, "index.js")) || await pathExists(path__namespace.join(dir, "index.cjs"));
return { dir, files: hasJs ? FILES_TO_COPY_DIST : FILES_TO_COPY_DEV };
}
return null;
}
function resolveTargetDir(piConfigDir) {
const base = piConfigDir ?? process.env.PI_CODING_AGENT_DIR ?? path__namespace.join(os__namespace.homedir(), ".pi", "agent");
return path__namespace.join(base, "extensions", EXTENSION_DIRNAME);
}
async function atomicCopy(src, dest) {
const tmp = `${dest}.tmp`;
await fs__namespace.unlink(tmp).catch(() => void 0);
await fs__namespace.copyFile(src, tmp);
await fs__namespace.rename(tmp, dest);
}
async function ensurePiExtensionInstalled(opts = {}) {
const targetDir = resolveTargetDir(opts.piConfigDir);
if (process.env.CONSORTIUM_PI_NO_EXTENSION === "1") {
return { installed: false, targetDir, skipped: "env-disabled" };
}
const source = await resolveSourceDir();
if (!source) {
return { installed: false, targetDir };
}
const shippedPkg = await readJson(path__namespace.join(source.dir, "package.json"));
const installedPkg = await readJson(path__namespace.join(targetDir, "package.json"));
if (!opts.force && shippedPkg?.version && installedPkg?.version) {
if (compareVersions(installedPkg.version, shippedPkg.version) >= 0) {
return { installed: false, targetDir, skipped: "up-to-date" };
}
}
await fs__namespace.mkdir(targetDir, { recursive: true });
for (const file of source.files) {
const src = path__namespace.join(source.dir, file);
if (!await pathExists(src)) continue;
const dest = path__namespace.join(targetDir, file);
await atomicCopy(src, dest);
}
return { installed: true, targetDir };
}
exports.ensurePiExtensionInstalled = ensurePiExtensionInstalled;