feat(skills): create, edit, and delete user and repo skills#2605
Merged
Conversation
Contributor
Author
This was referenced Jun 11, 2026
|
React Doctor could not complete this scan.
Reviewed by React Doctor for commit |
Contributor
Prompt To Fix All With AIFix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
packages/ui/src/features/skills/SkillDetailPanel.tsx:166
**Edit button enabled while body content is unavailable**
When the `SKILL.md` fetch has settled (e.g. a query error) `isLoading` is `false` but `fileContent` is still `null`, so `body` is `null`. Clicking "Edit" opens `SkillManifestEditor` with `initialBody=""`, and saving immediately overwrites whatever the real body contained with an empty string.
```suggestion
disabled={isLoading || (isSkillMd && !fileContent)}
```
### Issue 2 of 3
packages/ui/src/features/skills/NewSkillDialog.tsx:68
**Hint text omits dots and underscores that the validator allows**
`SKILL_DIR_NAME_PATTERN` (`/^[a-z0-9][a-z0-9._-]*$/`) accepts dots and underscores, and the server error message even mentions them explicitly. A user who types `my_skill` will be surprised if the hint told them only dashes were allowed.
```suggestion
Lowercase letters, numbers, dashes, dots, and underscores
```
### Issue 3 of 3
packages/ui/src/features/skills/useSkillMutations.ts:59
**`useRenameSkill` hook missing — router endpoint is unreachable from the UI**
`skills.ts` implements `renameSkill` and the tRPC router exposes a `rename` procedure, but there is no corresponding hook here and no UI that calls it. If this is intentional (planned for a follow-up), consider either removing the router endpoint from this PR to keep the surface consistent, or adding the hook now so the feature is at least reachable.
Reviews (1): Last reviewed commit: "feat(skills): create, edit, and delete u..." | Re-trigger Greptile |
jonathanlab
approved these changes
Jun 11, 2026
0b5ff98 to
34baff5
Compare
d3d7209 to
abb385b
Compare
34baff5 to
83a4081
Compare
Contributor
Author
Merge activity
|
- SkillsService mutations: createSkill (scaffolds directory + templated SKILL.md), saveSkillManifest (frontmatter writer + body), saveSkillFile, renameSkillFile, deleteSkillFile, deleteSkill, renameSkill. Every mutation resolves its target against the writable roots (~/.claude/skills and each workspace folder's .claude/skills); bundled and plugin-marketplace paths are rejected server-side. SKILL.md itself cannot be renamed or deleted. - serializeSkillMarkdown writes frontmatter that round-trips through parseSkillFrontmatter and stays valid YAML (plain -> quoted -> literal block as values get more hostile). The parser now tolerates blank lines inside block scalars so multi-paragraph descriptions survive. - host-router skills.* mutation routes as one-line forwards. - UI: "New skill" button with scope picker (Your skills / repository), edit mode in the detail panel (form for frontmatter name/description, CodeMirror for the body), add/rename/delete companion files, and delete-skill confirmation. Non-editable sources show no affordances. - Unit tests cover the write-path guard directly (bundled paths, arbitrary dirs, traversal), name validation, SKILL.md protection, and the frontmatter round-trip. Generated-By: PostHog Code Task-Id: f4e84f1a-19c9-490c-9b98-47787a7dddcf
Review feedback on #2605: disable Edit until file content has actually loaded (prevents wiping SKILL.md with an empty body after a failed fetch), mention dots and underscores in the name hint, and drop the unreachable skills.rename endpoint until there is UI for it. Generated-By: PostHog Code Task-Id: f4e84f1a-19c9-490c-9b98-47787a7dddcf
83a4081 to
fc872b6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Problem
Users had no way to create, edit, or delete skills from the UI — the skills panel was read-only. This adds full CRUD support for skills, including creating new skills, editing the manifest and companion files, renaming/deleting files within a skill, and deleting or renaming entire skills.
Changes
Backend (
workspace-server)createSkill,saveSkillManifest,saveSkillFile,renameSkillFile,deleteSkillFile,deleteSkill, andrenameSkillmethods toSkillsService.resolveWritableSkillDir, which enforces that the target skill lives directly under a writable root (~/.claude/skillsor a workspace folder's.claude/skills). Bundled/plugin skills are rejected server-side.validateSkillDirName(lowercase letters, numbers, dots, dashes, underscores; max 64 chars) andresolveSkillFilePath(prevents path traversal out of the skill directory) as shared helpers.write-skill-frontmatter.tswithserializeSkillMarkdown, which serializes name/description/body back to a valid SKILL.md. Scalars fall back from plain → double-quoted → YAML literal block to handle colons, quotes, backslashes, and multi-line values.collectIndentedLinesinparse-skill-frontmatter.tswhere blank lines inside a multi-line YAML value were being dropped instead of preserved.schemas.tswith Zod schemas and TypeScript types for all new operations.Host router (
host-router)create,saveManifest,saveFile,renameFile,deleteFile,delete, andrenametRPC mutations on theskillsRouter.UI (
ui)useSkillMutations.ts— new hooks (useCreateSkill,useSaveSkillManifest,useSaveSkillFile,useRenameSkillFile,useDeleteSkillFile,useDeleteSkill) that each invalidate all skills queries on success.NewSkillDialog.tsx— dialog for creating a skill with a name and a scope selector (user skills or a specific open repository).SkillCodeEditor.tsx— uncontrolled CodeMirror wrapper that reports document changes viaonDocChanged.SkillManifestEditor.tsx— edit mode forSKILL.md: a small form for name/description frontmatter fields plus a CodeMirror body editor.SkillFileEditor.tsx— edit mode for companion files inside a skill directory.SkillDetailPanel.tsx— added edit, add-file, delete-skill toolbar buttons (visible only for editable skills), wired upSkillManifestEditorandSkillFileEditorfor the active file, and added dialogs for adding a file, renaming a file, confirming file deletion, and confirming skill deletion.SkillFileTree.tsx— added optionalonRenameFile/onDeleteFilecallbacks; when present, non-SKILL.mdfile rows show inline rename and delete icon buttons.SkillsView.tsx— added a "New skill" button next to the search field that opensNewSkillDialogand selects the newly created skill.How did you test this?
skills.test.tscoveringcreateSkill(happy path, invalid names, non-open repo, duplicate names), the write-path guard (bundled skills, arbitrary directories, traversal attacks, file-path escapes), and all mutation methods (manifest round-trip, companion file lifecycle, SKILL.md protection, full skill delete, skill rename).write-skill-frontmatter.test.tscovering round-trip fidelity for plain values, empty descriptions, colons, special leading characters, double quotes, backslashes, multi-line descriptions, multi-paragraph descriptions, and body sections that contain fake frontmatter fences.Automatic notifications