← Back to PRs

#17503: feat(dashboard): add Uninstall button for bundled skills

by diegofornalha open 2026-02-15 20:41 View on GitHub →
app: web-ui gateway stale size: S
## Summary - Adds a `skills.uninstall` gateway RPC method that removes a bundled skill directory and appends it to `.gitignore` (preventing it from returning on `git pull`/update) - Adds an "Uninstall" button (danger style) in the Skills dashboard view for bundled skills - Follows the same patterns as the existing `skills.install` flow ## Changes ### Backend - **`src/gateway/protocol/schema/agents-models-skills.ts`** — New `SkillsUninstallParamsSchema` - **`src/gateway/protocol/schema/types.ts`** — New `SkillsUninstallParams` type - **`src/gateway/protocol/index.ts`** — Register validator + exports - **`src/gateway/server-methods/skills.ts`** — `skills.uninstall` handler (validates params, resolves bundled dir, deletes skill folder, appends to `.gitignore`) - **`src/gateway/server-methods.ts`** — Add `skills.uninstall` to admin-scoped methods ### Frontend - **`ui/src/ui/controllers/skills.ts`** — `uninstallSkill()` controller function - **`ui/src/ui/views/skills.ts`** — "Uninstall" button for `openclaw-bundled` skills - **`ui/src/ui/app-render.ts`** — Wire `onUninstall` handler ## Motivation Currently, removing a bundled skill requires manually deleting its folder and editing `.gitignore`. This PR automates the process with a single click from the dashboard. ## Test plan - [ ] Open dashboard → Skills → Built-in Skills - [ ] Click "Uninstall" on a bundled skill - [ ] Verify skill folder is deleted - [ ] Verify `skills/<name>/` is appended to `.gitignore` - [ ] Verify skill disappears from list after refresh - [ ] Verify non-bundled skills do not show the button - [ ] Verify disabled skills do not show the button 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds a `skills.uninstall` RPC endpoint and corresponding dashboard UI to allow one-click removal of bundled skills. The backend handler resolves the bundled skills directory, deletes the skill folder, and attempts to append the path to `.gitignore` to prevent the skill from returning on `git pull`. The frontend adds a "danger"-styled Uninstall button for `openclaw-bundled` skills, following the same controller/view patterns as the existing `skills.install` flow. - Two critical issues were previously flagged and remain unresolved: **path traversal vulnerability** (no validation that the resolved path stays within the bundled directory) and **`.gitignore` update silently never executes** (`resolveOpenClawPackageRootSync({})` is called with empty options, causing it to always return `null`) - Protocol schema, type exports, validator registration, and admin authorization are all wired correctly following existing conventions - Frontend controller and view changes cleanly mirror the existing install flow <h3>Confidence Score: 1/5</h3> - This PR has two unresolved critical issues — a path traversal vulnerability that enables arbitrary directory deletion, and a `.gitignore` update that silently never executes. - Score of 1 reflects two previously-flagged but unresolved critical issues: (1) The `name` parameter is only validated as a non-empty string, allowing values like `../../etc` to escape the bundled directory and trigger recursive deletion of arbitrary directories via `fs.promises.rm`. (2) `resolveOpenClawPackageRootSync({})` is called with an empty options object, which means all candidate resolution paths are empty and it always returns `null`, silently skipping the `.gitignore` update — one of the two stated goals of the feature. The frontend and protocol changes are clean and follow existing patterns. - `src/gateway/server-methods/skills.ts` needs path traversal protection on the resolved skill directory (line 173) and correct options passed to `resolveOpenClawPackageRootSync` (line 185). <sub>Last reviewed commit: b141a6f</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs