🚀 skillshare v0.17.5 Release Notes
Release date: 2026-03-18
TL;DR
v0.17.5 adds fail-fast config validation, sync safety, reverse proxy support, a skill design pattern wizard, .skillignore.local override, and metadata.targets:
- Config Save Validation — saving config now validates semantics (source path, sync modes, target paths), returning HTTP 400 for invalid configs instead of silently saving broken configurations
- Sync Safety — No Auto-Create — sync no longer auto-creates missing target directories. A typo like
~/.cusor/skillsnow fails immediately instead of silently creating the wrong directory - Dry-run Path Validation —
sync --dry-runnow detects missing target paths, matching the behavior of a real sync - Config Save → Sync Preview — after saving config, a banner offers to preview what sync will do via a dry-run modal before committing
- Web UI Base Path — serve the Web UI under a sub-path behind a reverse proxy with
--base-pathorSKILLSHARE_UI_BASE_PATH - Skill Design Patterns —
skillshare newnow offers an interactive wizard with five design pattern templates (tool-wrapper, generator, reviewer, inversion, pipeline) and category tagging .skillignore.local— local-only override file that lets you un-ignore skills blocked by a shared.skillignorewithout modifying the shared filemetadata.targets—targetscan now live under ametadata:block in SKILL.md, aligning with the 30+ tool ecosystem convention. Top-leveltargets:still works- Hermes Agent — new built-in target for Nous Research's Hermes Agent CLI (56+ total targets)
Config Save Validation
The problem
PUT /api/config only validated YAML syntax. Users could save a config with a nonexistent source path, an invalid sync mode like "invalid", or a misspelled target path — and get HTTP 200 OK. The error only appeared later when running sync, with a cryptic filesystem error message.
Solution
Config save now performs semantic validation after YAML parsing:
- Source path must exist and be a directory
- Sync mode must be
merge,symlink, orcopy(both global and per-target) - Target paths must exist and be directories
Fatal validation errors return HTTP 400 with a descriptive message. Non-fatal warnings (e.g., project mode source not created yet) return HTTP 200 with { success: true, warnings: [...] }.
The same validation runs in the CLI: skillshare sync validates config before starting, so manually-edited config.yaml files get the same protection.
Design decisions
- Shared validation —
config.ValidateConfig()andconfig.ValidateProjectConfig()are used by both the API handler and CLI sync command, ensuring identical behavior - Warnings vs errors — two-tier severity: errors block the operation (400), warnings let it proceed but surface the issue. This matches the compiler warning/error model
- Project mode leniency — built-in target paths (like
.claude/skills) skip existence checks in project mode because the user can't control whether the tool is installed. Only custom paths with explicitpath:are validated - Path expansion —
ValidateConfighandles~expansion internally, so callers don't need to pre-process paths
Sync Safety — No Auto-Create
The problem
When sync encountered a missing target directory, it silently ran mkdir -p to create it. This was convenient for first-time setup but dangerous for typos — ~/.cusor/skills (missing r) would silently create the wrong directory, and skills would sync there unnoticed.
Solution
Sync now fails fast with a clear error when a target directory doesn't exist:
Error: target directory does not exist: /home/user/.cusor/skills
This applies to:
- All sync modes (merge, copy)
- Symlink-to-merge/copy conversions (the only case where
mkdiris still used — after removing an existing symlink) --dry-runmode (previously skipped existence checks entirely)- Both CLI and API sync endpoints
Design decisions
- Symlink conversion is the exception — when converting from symlink mode to merge/copy, the code removes the directory-level symlink and recreates it as a real directory. This is not auto-creation from scratch — it's a deliberate mode conversion on an already-configured target
- Dry-run must also validate — users run dry-run to check what will happen. If dry-run silently ignores a missing path but real sync fails, the dry-run output was misleading
- Extracted shared helper —
ensureRealTargetDir()handles both symlink conversion and existence verification in a single function, used by both merge and copy modes
Config Save → Sync Preview
The problem
After editing config (adding/removing targets, changing sync mode) or updating .skillignore, users had to manually navigate to the Sync page and click Sync to apply changes. This extra step was friction — but running sync automatically on save felt risky because users might not realize what would change.
Solution
A preview-first flow that gives users visibility before action:
- Save config or skillignore
- A banner appears above the editor: "Config updated — preview what sync will do?"
- Click "Preview Sync" to open a modal that auto-runs
sync --dry-run - The modal shows per-target results: which skills will be linked, updated, or pruned (compact badge-count view)
- Click "Sync Now" to execute, or Cancel to walk away
Design decisions
- Inline banner, not toast — a banner is a better fit because the "save confirmation" and "sync prompt" are different responsibilities. Toasts are for notifications; banners are for suggested follow-up actions
- Banner above editor — positioned between the tab selector and the code editor so it's visible without scrolling, and doesn't get covered by the toast notification at the bottom-right
- Auto-dismiss on edit — if the user starts editing again, the banner disappears (they're making more changes, so previewing now is premature)
- Dry-run first, confirm to execute — two-step confirmation prevents accidental syncs when config isn't quite right
- Warnings in preview — the dry-run modal now shows pre-check warnings (empty source, missing targets) as a yellow banner above the results
Edge cases handled
- No targets configured — shows "No targets configured" (distinct from "everything up to date")
- All targets in sync — shows "Everything is up to date" and hides the Sync Now button
- API errors — shows error message with a Retry button; modal stays open
- Refresh while open — a refresh icon in the modal header re-runs dry-run
- Double-click prevention — Sync Now button shows loading state and disables during execution; backdrop/Escape are blocked during sync
Web UI — Base Path for Reverse Proxy
The problem
Organizations that run multiple internal tools behind a reverse proxy (Nginx, Caddy, Traefik) need to serve each tool under a sub-path like /skillshare/. Without base path support, API routes, static assets, and client-side navigation all break when the UI is not served from the root.
Solution
A --base-path flag and SKILLSHARE_UI_BASE_PATH environment variable let you host the Web UI under any sub-path:
skillshare ui --base-path /skillshareAll API routes, static assets, and React Router navigation automatically adjust to the configured prefix.
Design decisions
- Server-side injection — the base path is injected into the SPA's
index.htmlat serve time via a__BASE_PATH__placeholder, so no frontend rebuild is needed - Environment variable fallback —
SKILLSHARE_UI_BASE_PATHis supported alongside the CLI flag, making it easy to configure in Docker Compose or systemd environments - Trailing slash normalization — the server handles both
/skillshareand/skillshare/consistently
Skill Design Patterns — skillshare new Wizard
The problem
skillshare new generated a single generic SKILL.md template regardless of what kind of skill you were building. A skill that wraps a library API needs a very different structure from one that runs a multi-step pipeline or reviews code against a checklist. Users had to restructure the template manually every time.
Solution
skillshare new now offers five structural design patterns, each producing a tailored SKILL.md body and recommended directory structure:
| Pattern | What it does | Scaffold dirs |
|---|---|---|
tool-wrapper
| Teaches agent library/API conventions | references/
|
generator
| Produces formatted output from templates | assets/, references/
|
reviewer
| Scores/audits against a checklist | references/
|
inversion
| Agent interviews user before acting | assets/
|
pipeline
| Multi-step workflow with checkpoints | references/, assets/, scripts/
|
Without flags, an interactive TUI wizard guides through pattern → category → scaffold directory selection. With -P <pattern>, it skips the wizard and auto-creates scaffold directories.
Usage patterns
# Interactive wizard (Esc = back to previous step)
skillshare new my-skill
# Direct pattern selection
skillshare new my-reviewer -P reviewer
# Plain template (previous behavior)
skillshare new my-skill -P noneDesign decisions
- Patterns and categories are separate concerns — patterns describe how a skill is structured (workflow), categories describe what it's for (domain). Both are optional frontmatter fields (
pattern:,category:) - Wizard back-navigation — Esc at category goes back to pattern, Esc at scaffold goes back to category. Breadcrumbs in the help bar footer show previous selections
-Pauto-scaffolds — when using the flag, scaffold directories are always created (sensible default for non-interactive use). The wizard asks separately- Nine categories from community research — based on Anthropic's skill taxonomy (library, verification, data, automation, scaffold, quality, cicd, runbook, infra)
.skillignore.local — Local Override
The problem
Shared skill repos use .skillignore to hide internal tools from consumers. But the repo author themselves is also blocked — the .skillignore they wrote applies to their own machine too. Root-level negation (!pattern) in the source root can't override a repo-level .skillignore because the two files are evaluated as independent, cascaded filters.
Solution
A .skillignore.local file placed alongside any .skillignore (source root or tracked repo root). Patterns from .local are appended after the base file, so !negation rules naturally override previously-ignored skills:
# _team-repo/.skillignore blocks private-*
# _team-repo/.skillignore.local un-ignores your own:
echo '!private-mine' > _team-repo/.skillignore.local
skillshare sync # private-mine is now discoveredWorks at both levels (source root and repo root). CLI commands (sync, status, doctor) show a .local active indicator when override files are present.
Design decisions
- Transparent merge in
ReadMatcher—.localpatterns are appended to base patterns before compilation. All callers ofReadMatcher(dir)get.localsupport with zero code changes - Last-rule-wins gitignore semantics — by appending
.localafter the base file, the existing pattern engine's "last matching rule wins" behavior naturally handles overrides. No new matching logic needed - Install is unaffected —
installrunsReadMatcheron a temporary cloned directory. Since.skillignore.localshould not be committed (it's in.gitignore), it won't exist in clones HasLocalflag on Matcher — a lightweight boolean tracks whether.localwas merged, enabling CLI reporting without additional filesystem checks during stats collection
metadata.targets — Ecosystem-Aligned Frontmatter
The problem
The agent skill ecosystem (30+ tools including Claude Code, Gemini CLI, Cursor) is converging on a metadata: nested structure in SKILL.md frontmatter for deployment and behavioral fields. Google's ADK documentation and other tool authors use patterns like metadata: { pattern: tool-wrapper, domain: fastapi }. Skillshare's targets field was a top-level field, out of step with this emerging convention.
Solution
targets can now be placed under a metadata: block:
---
name: claude-prompts
description: Prompt patterns for Claude Code
metadata:
targets: [claude]
---The top-level targets: format continues to work unchanged. If both are present, metadata.targets takes priority — letting authors migrate gradually without breaking anything.
Design decisions
- Modify
ParseFrontmatterListonly — aresolveFieldhelper checksmetadata.<field>first, then falls back to the top-level field. All downstream consumers see the same[]stringreturn value with zero code changes metadatawins on conflict — if a SKILL.md has bothtargets:andmetadata.targets:, the metadata version takes priority. This encourages migration toward the ecosystem convention- Other parse functions untouched —
ParseFrontmatterFieldandParseFrontmatterFieldsintentionally do not gain metadata awareness yet. This will be addressed when more fields move tometadata:(e.g.,argument-hint) - No built-in skill changes — the built-in skillshare skill doesn't use
targets, so no migration was needed
New Target: Hermes Agent
Hermes Agent (by Nous Research) is now a built-in target, bringing the total to 56+ supported AI CLIs.
skillshare init # auto-detects ~/.hermes if present
skillshare sync # syncs skills to ~/.hermes/skills| Path | |
|---|---|
| Global | ~/.hermes/skills
|
| Project | .hermes/skills
|
| Alias | hermes-agent
|
Changelog
- 04f65e5 feat(cli): add --base-path flag and SKILLSHARE_UI_BASE_PATH env var to ui command
- ffa5dba feat(new): add TUI prompts and integrate -P flag into new command
- 935752b feat(new): add pattern/category definitions and template generators
- 4f6ae5a feat(new): add wizard back-navigation (Esc returns to previous step)
- 6500653 feat(new): show breadcrumbs of previous selections in wizard steps
- 6e23f11 feat(server): add GET /api/skills/templates endpoint
- 60b4166 feat(server): add POST /api/skills endpoint for skill creation
- 10444ee feat(server): add basePath support for reverse-proxy sub-path hosting (#85)
- 768c9f4 feat(server): inject BASE_PATH into SPA index.html when base path is set
- 6b38586 feat(skillignore): add .skillignore.local for local pattern overrides
- c9624df feat(tui): add header field to checklist for wizard breadcrumbs
- d6be805 feat(ui): add API client types and methods for skill creation
- 87bc3d3 feat(ui): add NewSkillPage wizard for creating skills from templates
- 7b99d0f feat(ui): add SyncPreviewModal with dry-run preview and confirm
- 0335210 feat(ui): add action, persistent, replaceKey to Toast system
- 6bd1314 feat(ui): render Toast action button, hide progress bar when persistent
- 214c8b9 feat(ui): support base path for reverse proxy deployments
- 75f35d2 feat(ui): wire SyncPreviewModal into ConfigPage save handlers
- fa6ad43 feat(ui): wire up NewSkillPage routing and add entry button
- 2dd1742 feat: add Hermes Agent (Nous Research) target support
- 92603f5 feat: add config save validation and sync safety checks
- 3c3974c feat: support metadata.targets in SKILL.md frontmatter
- 6fa73ae fix(new): handle .gitkeep write error instead of ignoring it
- efdd636 fix(new): show wizard breadcrumbs inside TUI title instead of terminal
- 550f398 fix(test): update integration tests for target path validation
- 7b3844b fix(ui): align NewSkillPage layout with dashboard conventions
- 0446711 fix(ui): include pruned in hasChanges for SyncResultList
- a7ecc40 fix(ui): move sync preview banner above editor to avoid toast overlap
- 0ed219b fix(ui): normalize scaffoldDirs in getTemplates response
- 0e2b323 fix(ui): remove icon from NewSkillPage header
- d9acaf2 fix(ui): remove plus icon from NewSkillPage header
- 1d03eea fix(ui): remove subtitle from NewSkillPage header
- 02009b8 fix(ui): use blue accent for active card selection in wizard
- bc4658e fix(ui): use bold border only for active card selection
- bca6c64 fix(ui): use spec-compliant mode label in new skill wizard
- 2eb6a79 fix: address code review findings from simplify pass
- 14cef54 ref: add luongnv89/agent-skill-manager competitor analysis
- 93a3067 refactor(tui): move wizard breadcrumbs to help bar footer
- 2dcd756 refactor(ui): extract SyncResultList component from SyncPage
- f6ec0e9 refactor(ui): extract shared sync helpers to eliminate duplication
- 0ff5963 refactor(ui): replace toast action with inline banner for sync preview
- 22efeea refactor: extract skill templates to internal/skill package
- f0e164c refactor: simplify base path code after review
- 8c67518 test(new): add integration tests for -P flag and scaffold directories
- 7b6cb70 test(server): add tests for create skill and templates endpoints
- 657adcc test+docs: add base path integration tests and reverse proxy guide