{"id":50216089,"url":"https://github.com/jsleekr/skillpack","last_synced_at":"2026-05-26T09:03:38.678Z","repository":{"id":351517711,"uuid":"1211065533","full_name":"JSLEEKR/skillpack","owner":"JSLEEKR","description":"Package manager and lockfile for agent skills (SKILL.md/AGENT.md/.cursorrules). Resolve, pin, hash, bundle, sign. Single Go binary.","archived":false,"fork":false,"pushed_at":"2026-04-15T11:34:02.000Z","size":105,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-15T11:34:53.913Z","etag":null,"topics":["agent-md","agent-skills","claude-code","cli","cursor","go","lockfile","package-manager","semver","skill-md"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JSLEEKR.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T03:12:42.000Z","updated_at":"2026-04-15T11:34:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/JSLEEKR/skillpack","commit_stats":null,"previous_names":["jsleekr/skillpack"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/JSLEEKR/skillpack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSLEEKR%2Fskillpack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSLEEKR%2Fskillpack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSLEEKR%2Fskillpack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSLEEKR%2Fskillpack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JSLEEKR","download_url":"https://codeload.github.com/JSLEEKR/skillpack/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSLEEKR%2Fskillpack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33512335,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T03:12:49.672Z","status":"ssl_error","status_checked_at":"2026-05-26T03:12:47.976Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-md","agent-skills","claude-code","cli","cursor","go","lockfile","package-manager","semver","skill-md"],"created_at":"2026-05-26T09:03:33.503Z","updated_at":"2026-05-26T09:03:38.661Z","avatar_url":"https://github.com/JSLEEKR.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# skillpack\n\n![Go](https://img.shields.io/badge/Go-1.26+-00ADD8?style=for-the-badge\u0026logo=go\u0026logoColor=white)\n![Tests](https://img.shields.io/badge/tests-221-brightgreen?style=for-the-badge)\n![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)\n![Status](https://img.shields.io/badge/status-stable-success?style=for-the-badge)\n![Binary](https://img.shields.io/badge/binary-%3C5MB-orange?style=for-the-badge)\n![Deps](https://img.shields.io/badge/runtime%20deps-zero-blueviolet?style=for-the-badge)\n\n\u003e **Package manager, lockfile, and bundler for Claude Code / Cursor / AGENT.md agent skills.**\n\u003e Resolve dependencies. Pin sha256 hashes. Bundle and sign. Single Go binary, zero runtime deps.\n\n```bash\nskillpack init\nskillpack add ./skills\nskillpack install   # writes skillpack.lock\nskillpack verify    # CI: exit 1 if anything drifted\nskillpack bundle    # produces a deterministic *.skl tarball\nskillpack sign --key priv.key mypack.skl\n```\n\n---\n\n## Why This Exists\n\nThe agent-skill ecosystem is exploding. In the last six months, vendors and\nthe community have shipped:\n\n- **Anthropic SKILL.md** — the canonical Claude Code skill format with YAML\n  frontmatter\n- **Cursor `.cursorrules`** — Cursor IDE rule files driving the editor's\n  inline assistant\n- **AGENT.md** — the cross-vendor proposal for a portable agent manifest\n  (used by opencli, googleworkspace/cli, and others)\n- **`skill.yaml`** — pure-YAML manifests for tooling-first skill catalogs\n\nThere are at least **six trending GitHub repositories** with combined stars\nabove **100,000** that cluster around this wedge:\n\n- `googleworkspace/cli` (22K stars) — \"40+ agent skills included\"\n- `antigravity-awesome-skills` (28K stars) — curated catalog of skills\n- `awesome-claude-code` (33K stars) — the canonical \"list of skills\" repo\n- `opencli` (8K stars, 632 stars/day) — runtime dispatcher reading AGENT.md\n- `claude-code-ultimate-guide` — docs site for the ecosystem\n- `awesome-openclaw-agents` — community-curated agent registry\n\nAnd yet — **zero of these repositories solve the lifecycle problem**. They\nall answer \"what skills exist?\" but none answer:\n\n- How do I pin the exact version of a skill across machines?\n- How do I detect when a skill on disk has drifted from what my CI expects?\n- How do I bundle 20 skills into a single distributable artifact?\n- How do I sign that artifact so my team can trust it?\n- How do I declare that skill A depends on skill B at version `^1.2.0`?\n\n`opencli` is a runtime dispatcher (different layer). `googleworkspace/cli`\nships its own bundle (vendor-locked). `awesome-claude-code` is a hand-curated\nmarkdown list (no tooling). The lifecycle hole is wide open, and skillpack\nfills it.\n\n**skillpack is the npm/cargo/pip of agent skills** — except it works across\nevery vendor format from day one.\n\n---\n\n## What skillpack Does\n\n| Layer | What it does |\n|---|---|\n| **Parse** | Read `SKILL.md`, `.cursorrules`, `AGENT.md`, and `skill.yaml`; normalize all four into a single canonical record |\n| **Resolve** | Honor `requires:` semver constraints between skills; produce a deterministic install order via topological sort |\n| **Hash** | Compute a content-addressed sha256 fingerprint per skill (LF-normalized, frontmatter-sorted, key-canonicalized) |\n| **Lock** | Write `skillpack.lock` — a deterministic JSON file with no timestamps and stable ordering |\n| **Bundle** | Produce a `*.skl` tarball (gzipped, fixed mtime, sorted file order, PAX format) — byte-identical across two runs |\n| **Sign** | Detached ed25519 signatures over the bundle bytes |\n| **Verify** | CI mode that exits non-zero on hash drift, version drift, or missing skills |\n\nEvery byte of output is deterministic. Two machines parsing the same source\nfiles produce **byte-identical** lockfiles and tarballs. This is what makes\nskillpack a real package manager and not a glorified zip script.\n\n---\n\n## Installation\n\n### From source\n\n```bash\ngo install github.com/JSLEEKR/skillpack/cmd/skillpack@latest\n```\n\n### Build manually\n\n```bash\ngit clone https://github.com/JSLEEKR/skillpack.git\ncd skillpack\ngo build -ldflags=\"-s -w\" -o skillpack ./cmd/skillpack\n```\n\nThe resulting binary is **under 5 MB** with zero runtime dependencies.\nDrop it in your `$PATH` and you're done.\n\n### Pre-built binaries\n\nDownload from the [Releases](https://github.com/JSLEEKR/skillpack/releases) page.\n\n---\n\n## Quick Start\n\n### 1. Initialize a workspace\n\n```bash\nmkdir my-pack \u0026\u0026 cd my-pack\nskillpack init --name my-pack\n```\n\nThis creates a `skillpack.yaml` workspace manifest:\n\n```yaml\nname: my-pack\nversion: 0.1.0\nskills:\n  - ./skills\n```\n\n### 2. Add some skills\n\nDrop a `SKILL.md` (or `.cursorrules`, `AGENT.md`, `skill.yaml`) under `./skills`:\n\n```markdown\n---\nname: code-review\nversion: 1.2.0\ndescription: Carefully review code changes for issues\nlicense: MIT\nauthor: jslee\ntools:\n  - git\n  - bash\nrequires:\n  - base-agent ^1.0.0\n---\n\n# Code Review Skill\n\nWhen asked to review code, follow these steps:\n1. ...\n```\n\n### 3. Resolve and install\n\n```bash\n$ skillpack resolve\nInstall order (2 skills):\n  1. base-agent@1.0.0 [skill.md] — skills/base-agent/SKILL.md\n  2. code-review@1.2.0 [skill.md] — skills/code-review/SKILL.md\n\n$ skillpack install\nskillpack: wrote skillpack.lock (2 skills)\n```\n\nThe resulting `skillpack.lock`:\n\n```json\n{\n  \"version\": 1,\n  \"generated_by\": \"skillpack\",\n  \"skills\": [\n    {\n      \"name\": \"base-agent\",\n      \"version\": \"1.0.0\",\n      \"format\": \"skill.md\",\n      \"hash\": \"sha256:b6a8...\",\n      \"source\": \"skills/base-agent/SKILL.md\"\n    },\n    {\n      \"name\": \"code-review\",\n      \"version\": \"1.2.0\",\n      \"format\": \"skill.md\",\n      \"hash\": \"sha256:f3c0...\",\n      \"source\": \"skills/code-review/SKILL.md\",\n      \"requires\": [\"base-agent ^1.0.0\"]\n    }\n  ]\n}\n```\n\n### 4. Verify in CI\n\n```bash\n$ skillpack verify\nskillpack: verify OK\n```\n\nExit code 0. Wire it into your pipeline:\n\n```yaml\n# .github/workflows/ci.yml\n- name: Verify skill lockfile\n  run: skillpack verify\n```\n\nIf any skill drifts (someone edited a body, bumped a version, deleted a file),\n`verify` exits with code 1 and prints exactly what changed.\n\n### 5. Bundle and sign\n\n```bash\n$ skillpack bundle -o my-pack.skl\nskillpack: wrote my-pack.skl (4218 bytes, 2 skills)\n  hash: sha256:5e9d...\n\n$ skillpack keygen --priv priv.key --pub pub.key\n$ skillpack sign --key priv.key my-pack.skl\nskillpack: wrote signature my-pack.skl.sig\n\n$ skillpack sign --verify --pubkey pub.key my-pack.skl\nskillpack: signature OK for my-pack.skl\n```\n\nDistribute `my-pack.skl` + `my-pack.skl.sig` + `pub.key` and your users can\nverify provenance with one command.\n\n---\n\n## Supported Formats\n\nskillpack speaks all four of the de facto agent-skill manifest formats:\n\n### SKILL.md (Anthropic)\n\n```markdown\n---\nname: my-skill\nversion: 1.0.0\ndescription: What this skill does\nlicense: MIT\nauthor: alice\ntools:\n  - bash\n  - git\nrequires:\n  - other-skill ^1.0.0\n---\n\nThe body of the skill goes here.\n```\n\n### .cursorrules (Cursor)\n\n```markdown\n---\nname: my-cursor-rules\nversion: 0.3.0\ndescription: Code style for our team\nglobs:\n  - \"**/*.ts\"\n  - \"**/*.tsx\"\nalwaysApply: true\n---\n\nAlways use tabs.\nNever use any.\nPrefer named exports.\n```\n\n### AGENT.md (Cross-vendor)\n\n```markdown\n---\nname: portable-bot\nversion: 2.0.0\ndescription: A bot that works in any vendor's runtime\nvendor: anthropic\nmodels:\n  - claude-3.5-sonnet\npermissions:\n  - filesystem\n  - network\ntools:\n  - bash\n---\n\nThis agent helps you...\n```\n\n### skill.yaml (Pure YAML)\n\n```yaml\nname: yaml-only\nversion: 1.0.0\ndescription: A skill defined entirely in YAML\nlicense: Apache-2.0\ntools:\n  - curl\n  - jq\nbody: |\n  This skill talks to APIs.\n```\n\nskillpack normalizes all four into the same canonical record, so you can mix\nand match formats inside a single workspace and the lockfile will treat them\nidentically.\n\n---\n\n## Determinism Guarantees\n\nEvery byte of skillpack's output is deterministic. The following invariants\nare tested:\n\n| Invariant | Test |\n|---|---|\n| `skillpack install` produces byte-identical lockfile across two runs | `lockfile.TestMarshalDeterministic` |\n| `skillpack bundle` produces byte-identical tarball across two runs | `bundle.TestBundleDeterministic` |\n| Tarball is identical regardless of input skill order | `bundle.TestBundleDeterministicRegardlessOfInputOrder` |\n| Hash is identical regardless of frontmatter key order | `hasher.TestHashFrontmatterOrderInsensitive` |\n| Hash is identical regardless of tools/requires order | `hasher.TestHashToolsOrderInsensitive` |\n| Hash is identical regardless of CRLF vs LF line endings | `parser.TestParseSkillMDCRLF` + canonical normalization |\n| Hash is identical regardless of UTF-8 BOM presence | `parser.TestParseSkillMDBOM` |\n| Resolver order is identical across runs (lexicographic tiebreak) | `resolver.TestResolveDeterministic` |\n\nHow we achieve this:\n\n- **Lockfile**: `encoding/json` with sorted struct fields, manually sorted\n  skills slice, manually sorted requires within each entry, LF line endings,\n  trailing newline.\n- **Tarball**: sorted file order, fixed `mtime` (1970-01-02 to dodge zero-mtime\n  quirks), `uid/gid = 0`, `Uname/Gname = \"\"`, `tar.FormatPAX`, gzip with fixed\n  header name.\n- **Hashing**: canonical pre-image is line-oriented `key=value\\n` form with\n  sorted keys, body normalized to LF + single trailing newline.\n- **No timestamps anywhere** in any hashable code path.\n\n---\n\n## Exit Codes\n\nskillpack uses distinct exit codes so CI pipelines can branch on the failure\nmode:\n\n| Code | Meaning | When |\n|---|---|---|\n| `0` | OK | Operation succeeded |\n| `1` | Drift | `verify` found a hash or version mismatch (expected failure mode) |\n| `2` | Parse error | A skill file is malformed (YAML, frontmatter, manifest) |\n| `3` | IO error | Filesystem, permission, or missing-file error |\n| `4` | Internal error | An unexpected bug in skillpack itself |\n| `5` | Usage error | Invalid CLI flags or missing required arguments |\n| `6` | Security | `sign --verify` failed (tampered bundle or wrong key) — treat as a hard-fail, never a routine lock refresh |\n\nCI example:\n\n```bash\nskillpack verify\ncase $? in\n  0) echo \"All skills clean\" ;;\n  1) echo \"Drift detected — open a PR to update skillpack.lock\" ; exit 1 ;;\n  2) echo \"Skill file is broken — block merge\" ; exit 1 ;;\n  6) echo \"SIGNATURE TAMPER — do not merge, investigate\" ; exit 1 ;;\n  *) echo \"skillpack itself failed — investigate\" ; exit 1 ;;\nesac\n```\n\n---\n\n## Architecture\n\nskillpack is intentionally small: ~5,300 lines of Go split across 13 internal\npackages. Each package has a single responsibility and a clean interface.\n\n```\ncmd/skillpack/main.go         entry point (5 lines)\n\ninternal/\n├── cli/                      cobra command tree\n│   ├── root.go               root command + Execute\n│   ├── init.go               skillpack init\n│   ├── add.go                skillpack add\n│   ├── resolve.go            skillpack resolve\n│   ├── install.go            skillpack install\n│   ├── verify.go             skillpack verify\n│   ├── bundle.go             skillpack bundle\n│   ├── sign.go               skillpack sign / keygen\n│   └── lock.go               skillpack lock\n├── workspace/                manifest + parser + resolver glue\n├── manifest/                 skillpack.yaml read/write\n├── parser/                   multi-format parser\n│   ├── skillmd.go            SKILL.md\n│   ├── cursorrules.go        .cursorrules\n│   ├── agentmd.go            AGENT.md\n│   ├── skillyaml.go          skill.yaml\n│   └── helpers.go            normalizeRequires, dedupSorted\n├── skill/                    canonical Skill record\n├── semver/                   constraint matching (^/~/x/...)\n├── resolver/                 topological sort with semver checks\n├── hasher/                   sha256 content addressing\n├── lockfile/                 deterministic JSON lockfile\n├── bundle/                   deterministic tar.gz writer\n├── signer/                   ed25519 detached signatures\n├── verify/                   CI drift detection\n└── exitcode/                 typed errors -\u003e exit codes\n```\n\nDependency direction always flows downward — `cli` depends on `workspace`,\n`workspace` depends on `parser` + `resolver` + `manifest`, and so on. There\nare no cycles, and the leaf packages (`skill`, `semver`, `exitcode`) have no\ninternal dependencies.\n\n---\n\n## Test Coverage\n\n221 tests across all layers:\n\n| Package | Tests | What it covers |\n|---|---|---|\n| `parser` | 32 | All four formats, CRLF, BOM, missing fields, bad YAML, requires (list/map), v-prefix versions |\n| `cli` | 27 | init, add, resolve, install, verify (clean/drift), bundle, sign, keygen, lock, JSON output, error paths |\n| `lockfile` | 19 | Roundtrip, sort order, LF only, trailing newline, missing/negative/future version, atomic write, duplicate-name rejection (Cycle K) |\n| `semver` | 17 | Caret, tilde, comparators, x-ranges, BestMatch, normalize, edge cases |\n| `hasher` | 17 | Determinism, frontmatter order, tools/requires order, body/version/name sensitivity, collision-resistance across comma/pipe/`=`/newline ambiguity |\n| `signer` | 16 | Generate, sign, verify, tampered, wrong key, CRLF in key file, file roundtrip, trailing garbage, multi-line body |\n| `bundle` | 16 | Determinism, multiple formats, header validation, path safety, list mode, tainted-archive hardening |\n| `skill` | 16 | Canonical record validation, name rules (`.`/`..`/leading-dot/whitespace), constraint parsing, sorting |\n| `resolver` | 14 | Linear chain, diamond, cycle, self-cycle, missing dep, version conflict, deterministic ordering, duplicates |\n| `manifest` | 14 | Roundtrip, sort, missing fields, bad YAML, write/read, skills-path validation |\n| `verify` | 12 | Clean, drift hash, drift version, missing, extra, sorted findings, parse error, JSON snake_case schema pin (Cycle J) |\n| `exitcode` | 8 | Wrap/Classify, nil-safe, layered wrap preservation |\n| `workspace` | 8 | Load happy, missing manifest, missing dep, recursive discover, dedup, ignore .git |\n| `docsmeta` | 5 | Doc-accuracy meta-tests: ROUND_LOG/CHANGELOG/README test-count pins + badge pin + per-package table sum + meta-meta self-consistency (Cycle J, L) |\n\nRun them yourself:\n\n```bash\ngo test ./...                 # all green, ~5 seconds\ngo test -race ./...           # race detector clean\ngo vet ./...                  # vet clean\n```\n\n---\n\n## Comparison with Existing Tools\n\n| Tool | Layer | Format support | Lockfile | Hashing | Bundling | Signing | Status |\n|---|---|---|---|---|---|---|---|\n| **skillpack** | Lifecycle | All 4 | ✅ | ✅ sha256 | ✅ deterministic | ✅ ed25519 | This project |\n| `opencli` | Runtime dispatch | AGENT.md | ❌ | ❌ | ❌ | ❌ | Different layer |\n| `googleworkspace/cli` | Vendor bundle | Vendor-specific | ❌ | ❌ | Bundled at build | ❌ | Vendor-locked |\n| `awesome-claude-code` | Curation | Markdown list | ❌ | ❌ | ❌ | ❌ | No tooling |\n| `claude-code-ultimate-guide` | Docs | Docs | ❌ | ❌ | ❌ | ❌ | Docs site |\n| npm/cargo/pip | Code packages | N/A | ✅ | ✅ | ✅ | Sometimes | Wrong domain |\n\nskillpack is the **only** tool that closes the lifecycle loop for agent skills.\n\n---\n\n## Roadmap\n\nThings that are explicitly out of scope for v1.0 (and may land in 1.x):\n\n- **Federated registry** — v1.0 has no centralized registry. Skills come from\n  local paths, file:// URIs, http(s):// URLs, and git URLs only. A federated\n  index is V2 and only if traction warrants.\n- **Skill audit** — security analysis of skill bundles (prompt injection,\n  shell calls, oversized contexts). See the runner-up `skillaudit` proposal.\n- **Skill catalog UI** — local index + search over installed skills.\n- **Schema validation** — strict JSON Schema validation per format.\n- **Lockfile resolution caching** — for very large workspaces.\n\n---\n\n## Contributing\n\nBug reports, feature ideas, and pull requests welcome at\n[github.com/JSLEEKR/skillpack/issues](https://github.com/JSLEEKR/skillpack/issues).\n\nBefore opening a PR:\n\n```bash\ngo test -race ./...    # must be green\ngo vet ./...           # must be clean\n```\n\nThe Generator/Evaluator separation in our build pipeline means every change\ngoes through an independent eval pass before merging.\n\n---\n\n## License\n\nMIT © 2026 JSLEEKR. See [LICENSE](./LICENSE) for the full text.\n\n---\n\n## Acknowledgements\n\n- The Anthropic Claude Code team for shipping `SKILL.md` as a parseable format\n- The Cursor team for `.cursorrules`\n- The opencli, googleworkspace/cli, and awesome-claude-code communities for\n  proving the demand for skill tooling\n- `golang.org/x/mod/semver` for the rock-solid semver primitives\n- `gopkg.in/yaml.v3` for YAML parsing\n- `github.com/spf13/cobra` for the CLI framework\n\nIf skillpack saves your team a single deployment headache, that's payment enough.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsleekr%2Fskillpack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsleekr%2Fskillpack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsleekr%2Fskillpack/lists"}