feat(installer): improve cursor and opencode skill handling
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
CLIENTS,
|
||||
SKILLS,
|
||||
buildOperationPlan,
|
||||
detectHelperInstallState,
|
||||
detectInstalledClients,
|
||||
detectInstalledSkills,
|
||||
executeOperation,
|
||||
@@ -42,7 +43,8 @@ Answers JSON example:
|
||||
{
|
||||
"clientId": "codex",
|
||||
"scope": "global",
|
||||
"actions": { "create-plan": "install", "web-automation": "skip" }
|
||||
"actions": { "create-plan": "install", "web-automation": "skip" },
|
||||
"helperActions": { "reviewer-runtime": "skip" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -168,7 +170,32 @@ async function interactiveAnswers({ dryRun = false } = {}) {
|
||||
actions[skill] = chosen;
|
||||
}
|
||||
}
|
||||
selections.push({ clientId, scope, actions });
|
||||
const helperActions = {};
|
||||
const workflowNeedsReviewerRuntime = Object.entries(actions).some(([skill, action]) => (
|
||||
["install", "update", "reinstall"].includes(action) && SKILLS[skill]?.requiresReviewerRuntime
|
||||
));
|
||||
const helperTarget = reviewerRuntimeRoot(clientId, scopeInfo.skillsRoot, process.cwd());
|
||||
const helperState = await detectHelperInstallState({
|
||||
source: path.join(process.cwd(), CLIENTS[clientId].reviewerRuntime.source),
|
||||
target: helperTarget,
|
||||
files: CLIENTS[clientId].reviewerRuntime.files,
|
||||
});
|
||||
if (workflowNeedsReviewerRuntime || helperState !== "not-installed") {
|
||||
const choices = helperState === "not-installed" ? "install/skip" : "update/reinstall/remove/skip";
|
||||
let defaultAction = "skip";
|
||||
if (workflowNeedsReviewerRuntime && helperState === "not-installed") defaultAction = "install";
|
||||
if (workflowNeedsReviewerRuntime && ["stale", "unknown"].includes(helperState)) defaultAction = "update";
|
||||
const answer = await rl.question(`${clientId}/${scope}/reviewer-runtime is ${helperState}; action (${choices}) [${defaultAction}]: `);
|
||||
const chosen = answer.trim() || defaultAction;
|
||||
const allowed = choices.split("/");
|
||||
if (!allowed.includes(chosen)) {
|
||||
console.log(`Invalid action '${chosen}', using skip.`);
|
||||
helperActions["reviewer-runtime"] = "skip";
|
||||
} else {
|
||||
helperActions["reviewer-runtime"] = chosen;
|
||||
}
|
||||
}
|
||||
selections.push({ clientId, scope, actions, helperActions });
|
||||
}
|
||||
return { selections };
|
||||
} finally {
|
||||
@@ -212,6 +239,8 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
if (plan.operations.length === 0) return;
|
||||
|
||||
if (args.dryRun) {
|
||||
console.log("\nDry-run mode: no filesystem changes performed.");
|
||||
return;
|
||||
@@ -275,7 +304,7 @@ async function main() {
|
||||
const rows = results.map((op) => ({
|
||||
client: op.clientId,
|
||||
scope: op.scope,
|
||||
item: op.skill || op.helper || op.kind,
|
||||
item: op.item || op.skill || op.helper || op.kind,
|
||||
action: op.displayAction || op.action,
|
||||
status: op.status,
|
||||
details: op.details || op.target || "",
|
||||
|
||||
Reference in New Issue
Block a user