github runkids/skillshare v0.17.4

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

skillshare v0.17.4 Release Notes

Release date: 2026-03-17

TL;DR

v0.17.4 adds machine-readable health checks and source-level skill filtering:

  1. doctor --json — structured JSON output for CI pipelines, with per-check status and exit code 1 on errors
  2. Web UI Health Check page — visual dashboard for doctor results with filtering, expandable details, and re-check
  3. Root-level .skillignore — hide skills and directories from all commands using a single file at the source root
  4. Full gitignore syntax for .skillignore**, ?, [abc], !negation, anchored /pattern, directory-only pattern/, and escaped \#/\! now all work
  5. .skillignore visibilitystatus and doctor now report active patterns and ignored skills; the web UI Config page has a .skillignore editor tab

Doctor JSON Output

The problem

skillshare doctor was text-only — useful for humans but impossible to integrate into CI pipelines, automation scripts, or the web dashboard. There was no way to programmatically check if a skillshare setup was healthy.

Solution

doctor --json outputs structured JSON with every check result:

skillshare doctor --json
{
  "checks": [
    { "name": "source", "status": "pass", "message": "Source: ~/.config/skillshare/skills (12 skills)" },
    { "name": "sync_drift", "status": "warning", "message": "claude: 1 skill(s) not synced", "details": ["new-skill"] }
  ],
  "summary": { "total": 13, "pass": 12, "warnings": 1, "errors": 0 },
  "version": { "current": "0.17.4", "update_available": false }
}

Design decisions

  • Exit code semantics — errors produce exit 1 (via jsonSilentError), warnings exit 0. This lets CI gate on errors while allowing warnings to pass
  • Flat checks array — each check is an independent entry with name, status, message, and optional details. Same check name can appear multiple times (e.g., one targets entry per configured target)
  • Version info — included as a top-level field, populated from the async update check that already runs during doctor

Usage patterns

# CI gate — fail if any errors
skillshare doctor --json | jq -e '.summary.errors == 0'

# Extract warnings for Slack notification
skillshare doctor --json | jq '[.checks[] | select(.status == "warning") | .message]'

# Quick health summary
skillshare doctor --json | jq '.summary'

Web UI — Health Check Page

The problem

The web dashboard had no equivalent of skillshare doctor. Users had to switch to the terminal to run diagnostics.

Solution

New Health Check page at /doctor in the sidebar under "System":

  • Summary cards — pass/warnings/errors counts with color-coded indicators
  • Filter toggles — show All, Errors, Warnings, or Pass checks
  • Check list — each check shows a human-readable label, status icon, and message. Checks with details (e.g., list of unsynced skills) are expandable
  • Version section — CLI version with update-available badge
  • Re-check button — re-run all checks without leaving the page

Design decisions

  • Server handler shells outGET /api/doctor runs skillshare doctor --json as a subprocess rather than importing check functions directly. The check logic lives in package main and would require a large refactor to extract. Shelling out is zero-refactoring and stays in sync automatically
  • Human-readable labels — check names are mapped from identifiers (sync_drift) to labels ("Sync Status") in the frontend, not the backend, keeping the JSON API stable

Root-Level .skillignore

The problem

.skillignore only worked inside tracked repos (_repo/.skillignore). There was no way to hide skills at the source root level — you couldn't exclude draft skills, archived directories, or test fixtures from discovery without uninstalling them.

Solution

Place a .skillignore at the source root to hide skills from all commands:

# ~/.config/skillshare/skills/.skillignore
draft-*          # Hide all draft skills
_archived/       # Hide entire directory
test-fixture     # Hide specific skill

Both levels now work:

  • Root-level (<source>/.skillignore) — affects all skills in the source
  • Repo-level (<source>/_repo/.skillignore) — scoped to that tracked repo

Design decisions

  • SkipDir optimization — when a directory matches a .skillignore pattern, the walker skips the entire directory tree (returns fastwalk.SkipDir) instead of entering it and filtering individual files. This meaningfully improves discovery time for source trees with large ignored directories
  • Gitignore syntax — uses the same glob patterns as .gitignore for familiarity

Full Gitignore Syntax for .skillignore

The problem

.skillignore used a naive string matcher that only supported exact names, directory prefixes, and trailing * wildcards. Users expected .gitignore-compatible syntax — patterns like demo/ with trailing slash caused matching failures (#83), and there was no way to use negation (!important), character classes ([Tt]est), or recursive globs (**/temp).

Solution

The matcher was rewritten to support the full gitignore specification:

# .skillignore — all gitignore patterns now work
**/temp              # Ignore "temp" at any depth
test-*               # Wildcard prefix
!test-important      # Negation — keep this one
vendor/              # Directory-only (won't match a file named "vendor")
[Dd]raft*            # Character class
/root-only           # Anchored to .skillignore location
\#not-a-comment      # Escaped literal

Design decisions

  • No external dependencies — uses Go's path.Match for per-segment glob matching (*, ?, [...]), with ** and gitignore semantics (negation, anchoring, dir-only) layered on top
  • Parent directory inheritance — if vendor is ignored, vendor/sub/deep is automatically ignored too. The matcher checks all parent prefixes of every path
  • Safe CanSkipDir with negation — when negation patterns exist, the walker does not skip ignored directories, because a descendant might be un-ignored by !pattern. Without negation, the SkipDir optimization still applies
  • Backward compatible — all existing .skillignore patterns continue to work. The only semantic change is that * no longer crosses / (matching gitignore spec), but this is handled transparently through parent-dir inheritance

Usage patterns

# Ignore everything under vendor/ except vendor/important
vendor/
!vendor/important

# Ignore all test skills except test-critical
test-*
!test-critical

# Ignore temp directories at any depth
**/temp

# Only ignore build at the root, not nested build/ dirs
/build

.skillignore Visibility

The problem

.skillignore filtering was completely invisible. status showed post-filter skill counts with no indication that filtering occurred. doctor didn't mention .skillignore at all. Users had no way to verify which patterns were active or which skills were being excluded — they had to manually inspect the file and cross-reference with list.

Solution

.skillignore status is now surfaced across CLI and web UI:

CLI — status:

Source: ~/.config/skillshare/skills (12 skills)
  .skillignore: 5 patterns, 3 skills ignored

The extra line only appears when a .skillignore file exists. status --json includes a skillignore object in the source field with active, files, patterns, ignored_count, and ignored_skills.

CLI — doctor --json:
A new skillignore check reports pass with pattern/ignored counts, or info when no .skillignore exists. The info status is a new fourth status alongside pass/warning/error for neutral informational checks.

Web UI — Config page:
The Config page now has two tabs (config.yaml / .skillignore) using the same pill toggle as the Skills page. The .skillignore tab provides a CodeMirror editor with live stats showing how many skills are currently ignored, plus an "Ignored Skills" summary card below the editor.

Web UI — Doctor page:
The Health Check page now shows the .skillignore check in its check list. The filter toggles were also unified to use the same SegmentedControl component as the Skills page for visual consistency.

Design decisions

  • info status — informational checks don't inflate error or warning counts. This lets CI pipelines gate on summary.errors == 0 without being tripped by neutral observations
  • Stats from the same discovery walk — ignored skill data is collected during the same filesystem walk that discovers skills, so there's no extra I/O cost
  • Visibility only when activestatus only shows the .skillignore line when the file exists, keeping the default output clean

Usage patterns

# See what .skillignore is doing
skillshare status

# Get full details in JSON
skillshare status --json | jq '.source.skillignore'

# CI: check if .skillignore is active
skillshare doctor --json | jq '.checks[] | select(.name == "skillignore")'

# Edit .skillignore from the web UI
skillshare ui   # → Config page → .skillignore tab

Bug Fixes

  • .skillignore false warningsdoctor reported false "unverifiable (no metadata)" warnings for directories that were supposed to be excluded via .skillignore (e.g., .venv/ inside tracked repos). Source discovery now respects .skillignore patterns consistently across all commands (#83)
  • .skillignore directory-only patterns during install — patterns with trailing slash (e.g., demo/) now correctly match directories during skillshare install discovery, not just during sync
  • Doctor check labels — the web UI Health Check page displays human-readable labels ("Source Directory", "Symlink Support") instead of raw snake_case identifiers

Changelog

  • e04a36d docs(doctor): update integrity check docs to match new behavior
  • df58b74 docs(skill): add .skillignore usage to built-in skill recipes
  • df39eda docs(skill): add doctor --json to built-in skill recipes and fix Quick Lookup table
  • 1c53779 feat(discovery): add SkipDir optimization and root-level .skillignore
  • ce70745 feat(doctor): add --json structured output for CI pipeline consumption
  • 13a82e3 feat(doctor): add info status and skillignore check
  • 81f043c feat(server): add GET /api/doctor handler that proxies CLI --json output
  • 81cb684 feat(server): add GET/PUT /api/skillignore endpoints
  • 8c7b93e feat(server): include ignored skills in sync and diff API responses
  • 2e9547a feat(skillignore): add IgnoreStats struct with Active/PatternCount/IgnoredCount
  • 4214cb1 feat(skillignore): upgrade to full gitignore-compatible syntax
  • f64fffe feat(status): show .skillignore info in text and JSON output
  • cc68453 feat(sync): pass .skillignore source files in API for accurate UI hints
  • 0717314 feat(sync): show .skillignore ignored skills in CLI text and JSON output
  • c1dc988 feat(ui): add .skillignore tab to Config page with CodeMirror editor
  • 8a46e85 feat(ui): add Doctor Health Check page with status dashboard
  • 2b2e119 feat(ui): add ignored skills types to sync and diff API client
  • 6d66823 feat(ui): show ignored skills badge and collapsible section on SyncPage
  • 9d09e52 feat(ui): unify Doctor filter with SegmentedControl, add info status
  • d925bf4 fix(discovery): respect .skillignore in source discovery (#83)
  • af143a3 fix(doctor): add CLI text output for skillignore check
  • 9c0a137 fix(doctor): skip local skills silently, only warn on incomplete meta
  • 8f19fb0 fix(server): force -g flag on doctor subprocess in global mode
  • ad3b600 fix(skillignore): strip trailing slash from patterns to fix directory matching
  • a8dc497 fix(sync): show .skillignore source hint in CLI output
  • 49cd7c8 fix(sync): truncate duplicate skill names to first 5 + count
  • d8b1323 fix(sync): use correct plural for repo-level .skillignore file count
  • ed7722b fix(ui): convert doctor check names to human-readable labels
  • fc1b7aa fix(ui): guard against null ignored_skills in skillignore response
  • 1c15f8b fix(ui): invalidate doctor query after saving .skillignore
  • a46227c fix(ui): remove unused imports in DoctorPage to fix TypeScript build
  • 4857135 fix(ui): render --- separator as visual divider in Doctor check details
  • 9e90b9c fix(ui): show correct .skillignore source hint for repo-level ignores
  • 1fca4ce fix(ui+server): lazy-fetch skillignore tab, use typed response struct
  • 6e89577 refactor(discovery): extract isSkillIgnored helper, unify tracked repo detection
  • b2f5592 refactor(discovery): extract shared walk, add DiscoverSourceSkillsWithStats
  • 63370df refactor(doctor): extract finalizeDoctorJSON helper and add status constants
  • 4d2d540 refactor: simplify ignore payload and deduplicate formatting
  • 33cc974 style(doctor): add blank line after config directory info
  • e54d469 style(doctor): add visual break before skill validation checks
  • 6698b5f style(ui): improve skillignore check details with grouped tag layout
  • f17e5c5 style(ui): redesign ignored skills section on SyncPage
  • a9972fb test(doctor): add integration tests for --json output
  • 78a4abc test(sync): add integration tests for .skillignore ignored skills output

Don't miss a new skillshare release

NewReleases is sending notifications on new releases.