Skip to content

Commit 45576f5

Browse files
committed
Installer updated
1 parent 3a19661 commit 45576f5

3 files changed

Lines changed: 69 additions & 41 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@linkedapi/skills",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "One-command installer for Linked API agent skills across Claude Code, Codex, Cursor, and Windsurf.",
55
"type": "module",
66
"bin": {

src/lib/prompts.mjs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ export function spinner() {
3030
return clack.spinner();
3131
}
3232

33-
export async function multiselect(options) {
34-
return unwrap(await clack.multiselect(options));
35-
}
36-
3733
export async function select(options) {
3834
return unwrap(await clack.select(options));
3935
}

src/lib/wizard.mjs

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,62 @@ async function wizard(ctx) {
2929
);
3030

3131
const detectedIds = snap.agents.filter((a) => a.detected).map((a) => a.id);
32-
const agentIds = await prompts.multiselect({
33-
message: 'Install into which agents?',
34-
options: snap.agents.map((a) => ({
35-
value: a.id,
36-
label: a.detected ? a.label : `${a.label} (not detected)`,
37-
hint: a.nativeSkills ? undefined : 'imported as rules',
38-
})),
39-
initialValues: detectedIds.length ? detectedIds : [snap.agents[0].id],
40-
required: true,
41-
});
32+
const allSkillIds = snap.skills.map((s) => s.name);
33+
const defaultScope = snap.git.inRepo ? 'project' : 'global';
4234

43-
const skillIds = await prompts.multiselect({
44-
message: 'Which skills?',
45-
options: snap.skills.map((s) => ({ value: s.name, label: s.label, hint: s.name })),
46-
initialValues: snap.skills.map((s) => s.name),
47-
required: true,
48-
});
35+
let agentIds;
36+
let skillIds;
37+
let scope;
4938

50-
const scope = await prompts.select({
51-
message: 'Install scope?',
52-
options: [
53-
{
54-
value: 'project',
55-
label: 'Project',
56-
hint: snap.git.inRepo ? 'this repository' : 'current directory',
57-
},
58-
{ value: 'global', label: 'Global', hint: 'all your projects (~)' },
59-
],
60-
initialValue: snap.git.inRepo ? 'project' : 'global',
61-
});
39+
// Fast path: pre-pick detected agents + all skills and confirm with one Yes/No, so the common
40+
// case is just Enter — no need to know about the space key. "No" → per-item Yes/No questions.
41+
let chooseManually = detectedIds.length === 0;
42+
if (detectedIds.length > 0) {
43+
const installAll = await prompts.confirm({
44+
message: `Install ${allSkillIds.join(', ')} into ${detectedIds.join(', ')} (${defaultScope} scope)?`,
45+
active: 'Yes, install all',
46+
inactive: 'No, let me choose',
47+
initialValue: true,
48+
});
49+
if (installAll) {
50+
agentIds = detectedIds;
51+
skillIds = allSkillIds;
52+
scope = defaultScope;
53+
} else {
54+
chooseManually = true;
55+
}
56+
} else {
57+
prompts.note('No supported agents detected — choose manually below.', 'Heads up');
58+
}
59+
60+
if (chooseManually) {
61+
skillIds = await pickByConfirm(
62+
snap.skills.map((s) => ({ id: s.name, message: `Install the "${s.name}" skill?`, on: true })),
63+
);
64+
if (skillIds.length === 0) {
65+
prompts.cancel('No skills selected — nothing to do.');
66+
return;
67+
}
68+
agentIds = await pickByConfirm(
69+
snap.agents.map((a) => ({
70+
id: a.id,
71+
message: `Install into ${agentLabel(a)}?`,
72+
on: a.detected,
73+
})),
74+
);
75+
if (agentIds.length === 0) {
76+
prompts.cancel('No agents selected — nothing to do.');
77+
return;
78+
}
79+
scope = await prompts.select({
80+
message: 'Install scope?',
81+
options: [
82+
{ value: 'project', label: 'Project', hint: snap.git.inRepo ? 'this repository' : 'current directory' },
83+
{ value: 'global', label: 'Global', hint: 'all your projects (~)' },
84+
],
85+
initialValue: defaultScope,
86+
});
87+
}
6288

6389
await ensurePrereqs(snap);
6490

@@ -70,14 +96,6 @@ async function wizard(ctx) {
7096
});
7197
}
7298

73-
const proceed = await prompts.confirm({
74-
message: `Install ${skillIds.join(', ')} into ${agentIds.join(', ')} (${scope})?`,
75-
});
76-
if (!proceed) {
77-
prompts.cancel('Aborted — nothing was changed.');
78-
return;
79-
}
80-
8199
const version = packageVersion();
82100
for (const name of skillIds) {
83101
const skill = getSkill(name);
@@ -97,6 +115,20 @@ async function wizard(ctx) {
97115
prompts.outro('Done. Restart your agent — skills load at startup.');
98116
}
99117

118+
function agentLabel(agent) {
119+
if (agent.detected) return `${agent.label} (detected)`;
120+
return agent.nativeSkills ? agent.label : `${agent.label} (imported as rules)`;
121+
}
122+
123+
async function pickByConfirm(items) {
124+
const chosen = [];
125+
for (const item of items) {
126+
const yes = await prompts.confirm({ message: item.message, initialValue: item.on });
127+
if (yes) chosen.push(item.id);
128+
}
129+
return chosen;
130+
}
131+
100132
async function ensurePrereqs(snap) {
101133
if (!snap.linkedinCli.installed) {
102134
const install = await prompts.confirm({

0 commit comments

Comments
 (0)