github runkids/skillshare v0.17.5

latest releases: v0.19.5, v0.19.4, v0.19.3...
one month ago

🚀 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:

  1. 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
  2. Sync Safety — No Auto-Create — sync no longer auto-creates missing target directories. A typo like ~/.cusor/skills now fails immediately instead of silently creating the wrong directory
  3. Dry-run Path Validationsync --dry-run now detects missing target paths, matching the behavior of a real sync
  4. Config Save → Sync Preview — after saving config, a banner offers to preview what sync will do via a dry-run modal before committing
  5. Web UI Base Path — serve the Web UI under a sub-path behind a reverse proxy with --base-path or SKILLSHARE_UI_BASE_PATH
  6. Skill Design Patternsskillshare new now offers an interactive wizard with five design pattern templates (tool-wrapper, generator, reviewer, inversion, pipeline) and category tagging
  7. .skillignore.local — local-only override file that lets you un-ignore skills blocked by a shared .skillignore without modifying the shared file
  8. metadata.targetstargets can now live under a metadata: block in SKILL.md, aligning with the 30+ tool ecosystem convention. Top-level targets: still works
  9. 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, or copy (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 validationconfig.ValidateConfig() and config.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 explicit path: are validated
  • Path expansionValidateConfig handles ~ 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 mkdir is still used — after removing an existing symlink)
  • --dry-run mode (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 helperensureRealTargetDir() 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:

  1. Save config or skillignore
  2. A banner appears above the editor: "Config updated — preview what sync will do?"
  3. Click "Preview Sync" to open a modal that auto-runs sync --dry-run
  4. The modal shows per-target results: which skills will be linked, updated, or pruned (compact badge-count view)
  5. 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 /skillshare

All 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.html at serve time via a __BASE_PATH__ placeholder, so no frontend rebuild is needed
  • Environment variable fallbackSKILLSHARE_UI_BASE_PATH is supported alongside the CLI flag, making it easy to configure in Docker Compose or systemd environments
  • Trailing slash normalization — the server handles both /skillshare and /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 none

Design 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
  • -P auto-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 discovered

Works 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.local patterns are appended to base patterns before compilation. All callers of ReadMatcher(dir) get .local support with zero code changes
  • Last-rule-wins gitignore semantics — by appending .local after the base file, the existing pattern engine's "last matching rule wins" behavior naturally handles overrides. No new matching logic needed
  • Install is unaffectedinstall runs ReadMatcher on a temporary cloned directory. Since .skillignore.local should not be committed (it's in .gitignore), it won't exist in clones
  • HasLocal flag on Matcher — a lightweight boolean tracks whether .local was 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 ParseFrontmatterList only — a resolveField helper checks metadata.<field> first, then falls back to the top-level field. All downstream consumers see the same []string return value with zero code changes
  • metadata wins on conflict — if a SKILL.md has both targets: and metadata.targets:, the metadata version takes priority. This encourages migration toward the ecosystem convention
  • Other parse functions untouchedParseFrontmatterField and ParseFrontmatterFields intentionally do not gain metadata awareness yet. This will be addressed when more fields move to metadata: (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

Don't miss a new skillshare release

NewReleases is sending notifications on new releases.