Skip to content

feat(skills): manage skills for every agent from Settings - #15

Merged
figassis merged 2 commits into
mainfrom
feat/skills-manager
Oct 2, 2026
Merged

figassis merged 2 commits into
mainfrom
feat/skills-manager

Conversation

@figassis

@figassis figassis commented Oct 2, 2026

Copy link
Copy Markdown

Why

Every CLI backend reads skills from a different directory, so installing one skill meant copying the same SKILL.md into up to eight places by hand. Jean only ever read skills — there was no UI to add one.

What

Settings → Tools → Skills (new pane):

  • Paste a SKILL.md, pick the agents (all selected by default), hit Install. Jean writes the file into each backend's skill root.
  • Installed skills list with a badge per agent that has it, plus Edit and Remove. Remove clears it from every agent.
  • Reference table showing each agent's skill directory.

Frontmatter is normalized on save: name and description come from the form fields (falling back to whatever the paste carried), while any other keys — disable-model-invocation, allowed-tools, … — are preserved. A bare paste with no frontmatter still produces a valid skill. Renaming cleans up the old directory in every backend.

Write targets mirror the read paths in projects::list_*_skills, so a saved skill appears in Jean's slash-command picker as well as in the CLI:

Agent Directory
Claude ~/.claude/skills
Codex ~/.agents/skills
OpenCode $XDG_CONFIG_HOME/opencode/skills
Cursor ~/.cursor/skills-cursor
Grok ~/.grok/skills
Pi / Command Code / Kimi ~/.jean/skills/<backend>

Project-level skills (.claude/skills, .agents/skills) are still discovered automatically and are deliberately not managed here.

Drive-by fix

collect_skills_from_dir read a skill's description from a leading # Heading only. Real skills put it in YAML frontmatter, so the slash-command picker showed no description for essentially every installed skill. It now reads frontmatter first and keeps the heading as a fallback.

Notes

  • Partial failures are reported per agent rather than aborting the whole install; the save only errors if no agent could be written.
  • Slugs are validated against path traversal before any write or delete, and deletes are scoped to the known skill roots.
  • Skill writes invalidate the cli-skills query so the picker refreshes without a restart.

Testing

  • cargo test -p jean-core: 1133 passed, 0 failed — 10 new skills tests (slugify, slug validation/traversal, frontmatter parse incl. broken YAML, frontmatter injection/preservation/clearing, backend resolution, dir coverage, atomic write round-trip) and 2 for the description fix.
  • bunx vitest run SkillsPane: 5 new tests (list rendering with agent badges, paste → install payload, install blocked with no agents selected, edit loads the file, remove).
  • bun run typecheck, bun run lint, cargo fmt --check, cargo clippy -- -D warnings: clean.
  • bun run test:run: 2136 passed. The failures in DesktopBackendModelPicker / BackendModelPickerContent reproduce unchanged on origin/main — pre-existing, unrelated.
  • make docker-build → jean:dev succeeds.

How to test manually

  1. Restart Jean on the fresh jean:dev.
  2. Settings → Tools → Skills. Existing skills are listed with agent badges.
  3. Add skill → paste any SKILL.md → Install. Verify the file lands in each selected directory: ls ~/.claude/skills/<slug>/ ~/.agents/skills/<slug>/ ~/.grok/skills/<slug>/.
  4. Paste a body with no frontmatter, fill in Name + Description, install — the written file should have a generated frontmatter block.
  5. Open a chat, type / — the new skill appears, now with its description.
  6. Edit the skill, rename it, save — the old slug directory should be gone from every agent.
  7. Remove it — gone everywhere.

Related

PR #14 (output styles) is open against the same base. This branch is cut from main and is independent of it; say the word if you'd rather I fold them together.

🤖 Generated with Claude Code

figassis and others added 2 commits October 2, 2026 15:37
Claude Code output styles set Claude's role, tone, and response format for
a whole session. Jean drives the CLI non-interactively, so `/output-style`
and `/config` were unreachable — there was no way to pick one.

Adds a per-session output style picker (global preference as the default),
discovery of custom styles from ~/.claude/output-styles and the worktree's
.claude/output-styles chain, an authoring UI under Settings > Providers, and
20 presets vendored from smixs/awesome-claude-output-styles (MIT).

Also fixes a pre-existing bug this would have widened: `build_claude_args`
emitted `--settings` twice (custom CLI profile file, then Jean's inline
JSON). The CLI's `--settings` is non-variadic, so the last flag won and the
profile's env — including API keys and base URLs — was silently discarded
whenever a thinking/effort/fast setting was active. The two sources are now
merged into a single value, written to a per-session file when a profile
contributes so secrets stay out of the process arguments.

Bumps FALLBACK_CODEX_VERSION from 0.116.0-alpha.12 to 0.160.0.

Co-Authored-By: Claude <noreply@anthropic.com>
Each CLI backend reads skills from its own directory, so installing one
meant copying the same SKILL.md into up to eight places by hand. Jean only
ever read skills — there was no UI to add them.

Adds Settings > Tools > Skills: paste a SKILL.md, pick the agents (all by
default), and Jean writes it to each backend's skill root. The list shows
every installed skill with badges for the agents that have it, plus edit and
remove, and a reference table of the directories involved.

Frontmatter is normalized on save: name and description are injected or
overwritten from the form fields while any other keys the paste carried are
preserved, so a bare paste with no frontmatter still produces a valid skill.
Renaming a skill cleans up the old directory in every backend.

Also fixes skill descriptions in the slash-command picker, which only read a
leading `# Heading` and so showed nothing for the YAML-frontmatter skills
every CLI actually ships.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 23 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 2fa8e2bb-bc0b-4857-8c0b-56e0c770197f

📥 Commits

Reviewing files that changed from the base of the PR and between 24ed062 and bc80c84.

📒 Files selected for processing (59)
  • jean-core/assets/output-styles/CREDITS.md
  • jean-core/assets/output-styles/LICENSE
  • jean-core/assets/output-styles/adhd.md
  • jean-core/assets/output-styles/analogy-engine.md
  • jean-core/assets/output-styles/bedtime-story.md
  • jean-core/assets/output-styles/caveman.md
  • jean-core/assets/output-styles/coach.md
  • jean-core/assets/output-styles/eli15.md
  • jean-core/assets/output-styles/executive.md
  • jean-core/assets/output-styles/feynman.md
  • jean-core/assets/output-styles/gen-z.md
  • jean-core/assets/output-styles/ladder.md
  • jean-core/assets/output-styles/no-ai-slop.md
  • jean-core/assets/output-styles/no-slop.md
  • jean-core/assets/output-styles/plain-english.md
  • jean-core/assets/output-styles/smart-brevity.md
  • jean-core/assets/output-styles/sportscaster.md
  • jean-core/assets/output-styles/street.md
  • jean-core/assets/output-styles/thing-explainer.md
  • jean-core/assets/output-styles/unslop.md
  • jean-core/assets/output-styles/wait-what.md
  • jean-core/assets/output-styles/yoda.md
  • jean-core/src/chat/claude.rs
  • jean-core/src/chat/commands.rs
  • jean-core/src/chat/storage.rs
  • jean-core/src/chat/types.rs
  • jean-core/src/claude_cli/mod.rs
  • jean-core/src/claude_cli/output_styles.rs
  • jean-core/src/codex_cli/commands.rs
  • jean-core/src/http_server/dispatch.rs
  • jean-core/src/lib.rs
  • jean-core/src/projects/commands.rs
  • jean-core/src/skills/mod.rs
  • src/components/chat/ChatToolbar.tsx
  • src/components/chat/ChatWindow.tsx
  • src/components/chat/hooks/session-setting-sync.ts
  • src/components/chat/hooks/useToolbarHandlers.test.tsx
  • src/components/chat/hooks/useToolbarHandlers.ts
  • src/components/chat/toolbar/DesktopToolbarControls.tsx
  • src/components/chat/toolbar/MobileSettingsMenu.tsx
  • src/components/chat/toolbar/OutputStyleDropdown.test.tsx
  • src/components/chat/toolbar/OutputStyleDropdown.tsx
  • src/components/chat/toolbar/types.ts
  • src/components/preferences/PreferencesDialog.test.tsx
  • src/components/preferences/PreferencesDialog.tsx
  • src/components/preferences/panes/OutputStylesEditor.tsx
  • src/components/preferences/panes/ProvidersPane.tsx
  • src/components/preferences/panes/SkillsPane.test.tsx
  • src/components/preferences/panes/SkillsPane.tsx
  • src/components/preferences/preferences-search.ts
  • src/services/chat.ts
  • src/services/jean-skills.ts
  • src/services/output-styles.ts
  • src/store/chat-store.ts
  • src/store/ui-store.ts
  • src/types/chat.ts
  • src/types/jean-skills.ts
  • src/types/output-styles.ts
  • src/types/preferences.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@figassis
figassis merged commit 514b134 into main Oct 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant