SkillEx Logo

SkillEx – Claude Skill Aggregator

Hex.pm Documentation License

SkillEx is our hub for collecting .claude/skills directories from every Elixir repo, validating them, and packaging a single skills-pack-<date>.zip that Claude can load in one go. Each application owns the content of its skill, while SkillEx keeps the packs fresh and consistent.


Why SkillEx Exists

  • One-stop distribution – No more hunting through repos; the pack contains every published skill.
  • Consistent validation – Every skill runs through the same packaging/validation script before inclusion.
  • Repeatable automation – The CLI emits JSON so CI pipelines can publish artifacts or fail fast on issues.
  • Change tracking – The manifest captures checksums and timestamps so we know what shipped and when.

Quick Start

# Install deps and run the test suite
mix deps.get
mix test

# Review or edit the manifest
cat manifest.json

# Run a sync using the script (dry run shown)
elixir scripts/sync_skills.exs \
  --manifest manifest.json \
  --target skills \
  --dry-run

The script reports a JSON summary and (when not in dry-run) copies every discovered skill into skills/<repo>/<skill-name>/, runs validation, updates manifest.json, and emits a packaged zip under dist/.


Repository Layout

skill_ex/
 lib/
    skill_ex/aggregator.ex      # Sync, validation, packaging logic
    skill_ex/manifest.ex        # Manifest load/save helpers
 scripts/sync_skills.exs         # CLI that drives the aggregator
 skills/                         # Output directory populated by sync
 dist/                           # Final zipped packs (created on demand)
 manifest.json                   # Declares upstream repos and tracks sync metadata
 docs/                           # Extended documentation (workflow, manifest, CI)
 test/                           # ExUnit suites & helpers (pure TDD coverage)
 logo/skill_ex.svg               # Project badge for docs/dashboards

Core Components

ComponentResponsibility
SkillEx.ManifestLoad/save JSON manifest, manage skills entries, timestamp updates.
SkillEx.AggregatorCopy skills out of repos, call validators, compute checksums, package archives, and refresh the manifest.
scripts/sync_skills.exsThin CLI wrapper. Parses flags, loads repos from the manifest, invokes the aggregator, prints JSON for CI usage.
test/support/test_helpers.exsFixture helpers (temp dirs, fake repos, stub validators) used across tests.

Implementation details and extension ideas live in the docs directory—start with docs/WORKFLOW.md.


Running the Sync Script

elixir scripts/sync_skills.exs \
  --manifest path/to/manifest.json \
  --target path/to/output/skills \
  --package-script path/to/scripts/package_skill.py \
  [--dry-run] \
  [--clock 2025-10-08T12:00:00Z] \
  [--version 2025.10.08]

Flags

FlagRequiredDescription
--manifestManifest file to read/write. Determines which repos export skills.
--targetDirectory that should contain synced skills. Created if missing.
--package-script✅ (unless validator provided)External validator/packager (typically scripts/package_skill.py).
--dry-runOptionalReports what would happen without copying or packaging.
--clockOptionalISO8601 timestamp used for deterministic runs/tests. Defaults to DateTime.utc_now/0.
--versionOptionalOverrides the archive suffix (skills-pack-<version>.zip). Useful in CI.

The script exits with 0 for success and 1 when sync/validation encounters errors. Output is always JSON so downstream steps can parse it reliably.


Manifest Overview

The manifest ties everything together. It tracks which repos export skills and stores metadata about the last successful sync.

{
  "version": 1,
  "generated_at": "2025-10-08T12:00:00Z",
  "repositories": [
    {
      "name": "supertester",
      "path": "../supertester",
      "skills_dir": ".claude/skills"
    }
  ],
  "skills": [
    {
      "name": "supertester-otp-testing",
      "source_repo": "supertester",
      "target_path": "supertester/supertester-otp-testing",
      "checksum": "01ab...ff",
      "packaged_at": "2025-10-08T12:00:00Z"
    }
  ]
}

Every field is documented in docs/MANIFEST_REFERENCE.md, including optional keys and gotchas (network paths, symlinks, etc.).


Typical Workflow

  1. Prepare source repos
    • Each repo houses its skill under .claude/skills/<repo-skill>/SKILL.md.
    • Ensure the repo’s own validator (usually scripts/package_skill.py) succeeds locally.
  2. Update manifest.json
    • Add repo entries (absolute or relative paths).
    • Commit the manifest change back to SkillEx.
  3. Run the CLI
    • Dry-run first to audit the operations (planned count).
    • Run without --dry-run to copy, validate, and write the bundle.
  4. Inspect outputs
    • Check skills/<repo>/<skill>/ to confirm the expected files.
    • Review the JSON summary and updated manifest for checksum/timestamp changes.
    • Find the zipped artifact under dist/skills-pack-<date>.zip.
  5. Automate
    • CI can invoke the script, parse JSON, and upload the archive as a build artifact.
    • See docs/CI_PLAYBOOK.md for ideas.

The ExUnit suite mirrors this flow with deterministic temp repos so regressions are caught quickly.


Development & Testing

TaskCommand
Run entire test suitemix test
Format stubs or generated manifestsmix format
Execute only aggregator testsmix test test/skill_ex/aggregator_test.exs
Run script tests (integration style)mix test test/scripts/sync_skills_script_test.exs

All tests are written first (true TDD). When expanding the system:

  • Add tests before implementation for new behaviours (new validator modes, multi-root targets, etc.).
  • Use test helpers to keep fixtures tidy.
  • Prefer pure functions (clock injection, custom validator) to keep tests deterministic.

Roadmap & Ideas

  • Surface git metadata (repo SHA, branch) in manifest skill entries.
  • Allow repo-specific validator overrides instead of one global --package-script.
  • Support incremental packaging (skip unchanged skills based on checksum).
  • Publish checksum diff reports to highlight what changed between packs.
  • Add optional references/ ingestion to capture documentation bundles.

If you explore any of these, drop a note in the docs so future developers know the plan.


Learn More

📄 License

This project is licensed under the MIT License – see the LICENSE file for details.

Questions? Share findings or improvements in the repo so the next engineer has an even smoother ride.