feat(skills): add per-agent checkbox preferences#28422
Conversation
|
Thank you for your contribution! 🎉 🔔 @keito4 @raulgg @DaleSeo @pernielsentikaer @kayotimoteo @alexibuild you might want to have a look. You can use this guide to learn how to check out the Pull Request locally in order to test it. 📋 Quick checkout commandsBRANCH="feat/28377-skills-default-agents-picker"
FORK_URL="https://github.com/alastairsounds/raycast-extensions.git"
EXTENSION_NAME="skills"
REPO_NAME="raycast-extensions"
git clone -n --depth=1 --filter=tree:0 -b $BRANCH $FORK_URL
cd $REPO_NAME
git sparse-checkout set --no-cone "extensions/$EXTENSION_NAME"
git checkout
cd "extensions/$EXTENSION_NAME"
npm install && npm run devWe're currently experiencing a high volume of incoming requests. As a result, the initial review may take up to 10-15 business days. |
Greptile SummaryThis PR adds 54 per-agent checkbox preferences under the "Search Skills" command, allowing users to pre-select their preferred coding agents (Claude Code, Windsurf, Cursor, etc.) so they are checked by default when the install agent picker opens.
Confidence Score: 4/5Safe to merge; the only finding is a minor render-efficiency improvement in the useState initializer. The feature is straightforward: preferences seed an initial Set that users can still override before submitting. The normalization logic correctly maps all 54 current agent names to their preference keys. The one issue is that getPreferenceValues() and the Set constructor are evaluated on every render rather than once, because a direct value is passed to useState instead of a lazy initializer callback. extensions/skills/src/components/actions/InstallSkillAction.tsx — the useState initializer Important Files Changed
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
extensions/skills/src/components/actions/InstallSkillAction.tsx:177-193
The `agentPrefs` object and the `Set` constructor for the initial state are both recomputed on every render, even though they're only consumed by `useState` on the first render. Using a lazy initializer avoids the redundant work on re-renders triggered by `setSelected`.
```suggestion
const [selected, setSelected] = useState<Set<string>>(() => {
const agentPrefs: Record<string, boolean> = {};
for (const [key, value] of Object.entries(getPreferenceValues<Preferences>())) {
if (key.startsWith("agent_") && typeof value === "boolean") {
agentPrefs[key] = value;
}
}
return new Set(
selectableAgents.filter((a) => {
const key = `agent_${a
.toLowerCase()
.replace(/\s+/g, "_")
.replace(/[^a-z0-9_]/g, "")}`;
return agentPrefs[key] === true;
}),
);
});
```
Reviews (1): Last reviewed commit: "feat(skills): add per-agent checkbox pre..." | Re-trigger Greptile |
| const agentPrefs: Record<string, boolean> = {}; | ||
| for (const [key, value] of Object.entries(getPreferenceValues<Preferences>())) { | ||
| if (key.startsWith("agent_") && typeof value === "boolean") { | ||
| agentPrefs[key] = value; | ||
| } | ||
| } | ||
| const [selected, setSelected] = useState<Set<string>>( | ||
| new Set( | ||
| selectableAgents.filter((a) => { | ||
| const key = `agent_${a | ||
| .toLowerCase() | ||
| .replace(/\s+/g, "_") | ||
| .replace(/[^a-z0-9_]/g, "")}`; | ||
| return agentPrefs[key] === true; | ||
| }), | ||
| ), | ||
| ); |
There was a problem hiding this comment.
The
agentPrefs object and the Set constructor for the initial state are both recomputed on every render, even though they're only consumed by useState on the first render. Using a lazy initializer avoids the redundant work on re-renders triggered by setSelected.
| const agentPrefs: Record<string, boolean> = {}; | |
| for (const [key, value] of Object.entries(getPreferenceValues<Preferences>())) { | |
| if (key.startsWith("agent_") && typeof value === "boolean") { | |
| agentPrefs[key] = value; | |
| } | |
| } | |
| const [selected, setSelected] = useState<Set<string>>( | |
| new Set( | |
| selectableAgents.filter((a) => { | |
| const key = `agent_${a | |
| .toLowerCase() | |
| .replace(/\s+/g, "_") | |
| .replace(/[^a-z0-9_]/g, "")}`; | |
| return agentPrefs[key] === true; | |
| }), | |
| ), | |
| ); | |
| const [selected, setSelected] = useState<Set<string>>(() => { | |
| const agentPrefs: Record<string, boolean> = {}; | |
| for (const [key, value] of Object.entries(getPreferenceValues<Preferences>())) { | |
| if (key.startsWith("agent_") && typeof value === "boolean") { | |
| agentPrefs[key] = value; | |
| } | |
| } | |
| return new Set( | |
| selectableAgents.filter((a) => { | |
| const key = `agent_${a | |
| .toLowerCase() | |
| .replace(/\s+/g, "_") | |
| .replace(/[^a-z0-9_]/g, "")}`; | |
| return agentPrefs[key] === true; | |
| }), | |
| ); | |
| }); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/skills/src/components/actions/InstallSkillAction.tsx
Line: 177-193
Comment:
The `agentPrefs` object and the `Set` constructor for the initial state are both recomputed on every render, even though they're only consumed by `useState` on the first render. Using a lazy initializer avoids the redundant work on re-renders triggered by `setSelected`.
```suggestion
const [selected, setSelected] = useState<Set<string>>(() => {
const agentPrefs: Record<string, boolean> = {};
for (const [key, value] of Object.entries(getPreferenceValues<Preferences>())) {
if (key.startsWith("agent_") && typeof value === "boolean") {
agentPrefs[key] = value;
}
}
return new Set(
selectableAgents.filter((a) => {
const key = `agent_${a
.toLowerCase()
.replace(/\s+/g, "_")
.replace(/[^a-z0-9_]/g, "")}`;
return agentPrefs[key] === true;
}),
);
});
```
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Description
This feature adds preference checkboxes to pre-select non-standard coding agents (Claude Code, Windsurf, etc..) The checkboxes are nested under the "Search Skills" command in preferences for the following reasons: 1.) "Search Skills" is the only command that utilizes the agent picker, and 2.) it allows the 54 checkboxes to be kept in a dropdown, rather than muddying up the entire preferences area.
Note:
ray lintrequires adescriptionfield per checkbox. I opted for each description to follow the pattern"Pre-select [Agent] in the install agent picker", but can adjust if we want to make it less verbose.Possible README/store update: This feature might be worth updating in the README so users can see it on the Store page. Something like
"Search for agent skills (pre-select default agents in Settings → Extensions → Skills → Search Skills)". If not, users may still naturally find it via the preferences menu.Screencast
Checklist
npm run buildand tested this distribution build in Raycastassetsfolder are used by the extension itselfREADMEare located outside the metadata folder if they were not generated with our metadata tool