Skip to content

Commit cb79649

Browse files
committed
Fix: no agents selected when installing find-skills
1 parent 668546a commit cb79649

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

src/add-prompt.test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ describe('promptForAgents', () => {
2626
vi.clearAllMocks();
2727
});
2828

29-
it('should use empty initial selection when no history exists', async () => {
29+
it('should use default agents (claude-code, opencode, codex) when no history exists', async () => {
3030
vi.mocked(skillLock.getLastSelectedAgents).mockResolvedValue(undefined);
3131
vi.mocked(searchMultiselectModule.searchMultiselect).mockResolvedValue(['opencode']);
3232

3333
await promptForAgents('Select agents', choices);
3434

35+
// Should default to claude-code, opencode, codex (filtered by available choices)
3536
expect(searchMultiselectModule.searchMultiselect).toHaveBeenCalledWith(
3637
expect.objectContaining({
37-
initialSelected: [],
38+
initialSelected: ['claude-code', 'opencode'],
3839
})
3940
);
4041
});
@@ -65,15 +66,17 @@ describe('promptForAgents', () => {
6566
);
6667
});
6768

68-
it('should use empty list if all history agents are invalid', async () => {
69+
it('should use default agents if all history agents are invalid', async () => {
6970
vi.mocked(skillLock.getLastSelectedAgents).mockResolvedValue(['invalid-agent']);
7071
vi.mocked(searchMultiselectModule.searchMultiselect).mockResolvedValue(['opencode']);
7172

7273
await promptForAgents('Select agents', choices);
7374

75+
// When history is invalid, should fall back to defaults (claude-code, opencode, codex)
76+
// filtered by available choices
7477
expect(searchMultiselectModule.searchMultiselect).toHaveBeenCalledWith(
7578
expect.objectContaining({
76-
initialSelected: [],
79+
initialSelected: ['claude-code', 'opencode'],
7780
})
7881
);
7982
});

src/add.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,27 @@ export async function promptForAgents(
115115

116116
const validAgents = choices.map((c) => c.value);
117117

118+
// Default agents to pre-select when no valid history exists
119+
const defaultAgents: AgentType[] = ['claude-code', 'opencode', 'codex'];
120+
const defaultValues = defaultAgents.filter((a) => validAgents.includes(a));
121+
118122
let initialValues: AgentType[] = [];
119123

120124
if (lastSelected && lastSelected.length > 0) {
121125
// Filter stored agents against currently valid agents
122126
initialValues = lastSelected.filter((a) => validAgents.includes(a as AgentType)) as AgentType[];
123127
}
124128

129+
// If no valid selection from history, use defaults
130+
if (initialValues.length === 0) {
131+
initialValues = defaultValues;
132+
}
133+
125134
const selected = await searchMultiselect({
126135
message,
127136
items: choices,
128137
initialSelected: initialValues,
138+
required: true,
129139
});
130140

131141
if (!isCancelled(selected)) {

src/prompts/search-multiselect.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export interface SearchMultiselectOptions<T> {
2020
items: SearchItem<T>[];
2121
maxVisible?: number;
2222
initialSelected?: T[];
23+
/** If true, require at least one item to be selected before submitting */
24+
required?: boolean;
2325
}
2426

2527
const S_STEP_ACTIVE = pc.green('◆');
@@ -38,7 +40,7 @@ export const cancelSymbol = Symbol('cancel');
3840
export async function searchMultiselect<T>(
3941
options: SearchMultiselectOptions<T>
4042
): Promise<T[] | symbol> {
41-
const { message, items, maxVisible = 8, initialSelected = [] } = options;
43+
const { message, items, maxVisible = 8, initialSelected = [], required = false } = options;
4244

4345
return new Promise((resolve) => {
4446
const rl = readline.createInterface({
@@ -177,6 +179,10 @@ export async function searchMultiselect<T>(
177179
};
178180

179181
const submit = (): void => {
182+
// If required, don't allow submitting with no selection
183+
if (required && selected.size === 0) {
184+
return;
185+
}
180186
render('submit');
181187
cleanup();
182188
resolve(Array.from(selected));

0 commit comments

Comments
 (0)