feat(installer): support pi package remove and update

This commit is contained in:
Stefano Fiorini
2026-04-23 22:55:41 -05:00
parent 8ea6d08e77
commit d62899308a
4 changed files with 266 additions and 15 deletions
+17 -2
View File
@@ -11,6 +11,7 @@ import {
detectInstalledClients,
detectInstalledSkills,
executeOperation,
isPiPackageInstalled,
parseReviewerShorthand,
resolveClientScope,
reviewerRuntimeRoot,
@@ -93,6 +94,10 @@ async function buildCliSelection(args) {
const clientId = args.client;
if (!CLIENTS[clientId]) throw new Error(`Unsupported client: ${clientId}`);
const scope = args.scope || (clientId === "pi" && args.piPackage ? "packageGlobal" : "global");
const scopeInfo = resolveClientScope(clientId, scope, process.cwd());
if (clientId === "pi" && scopeInfo.packageMode) {
return { selections: [{ clientId, scope, action: args.action || "install", actions: {} }] };
}
const skills = args.skills.length ? args.skills : Object.keys(SKILLS);
const action = args.action || "install";
const actions = Object.fromEntries(skills.map((skill) => [skill, action]));
@@ -129,7 +134,17 @@ async function interactiveAnswers({ dryRun = false } = {}) {
const scopeInfo = resolveClientScope(clientId, scope, process.cwd());
if (scopeInfo.packageMode) {
console.log(`${clientId}/${scope}: package mode manages the full Pi package bundle; per-skill prompts are skipped.`);
selections.push({ clientId, scope, action: "install", actions: {} });
const installed = await isPiPackageInstalled({ scope, repoRoot: process.cwd() });
const choices = "install/update/reinstall/remove/skip";
const defaultAction = installed ? "skip" : "install";
const answer = await rl.question(`${clientId}/${scope} package is ${installed ? "installed" : "not-installed"}; action (${choices}) [${defaultAction}]: `);
const chosen = answer.trim() || defaultAction;
if (!choices.split("/").includes(chosen)) {
console.log(`Invalid action '${chosen}', using skip.`);
selections.push({ clientId, scope, action: "skip", actions: {} });
} else {
selections.push({ clientId, scope, action: chosen, actions: {} });
}
continue;
}
const installed = await detectInstalledSkills({ clientId, skillsRoot: scopeInfo.skillsRoot });
@@ -261,7 +276,7 @@ async function main() {
client: op.clientId,
scope: op.scope,
item: op.skill || op.helper || op.kind,
action: op.action,
action: op.displayAction || op.action,
status: op.status,
details: op.details || op.target || "",
}));