Skip to content

feat: extensions catalog — skills & plugins marketplace from index sources (N2)#45

Merged
mudler merged 13 commits into
masterfrom
feat/extensions-catalog
Jul 4, 2026
Merged

feat: extensions catalog — skills & plugins marketplace from index sources (N2)#45
mudler merged 13 commits into
masterfrom
feat/extensions-catalog

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

Extensions catalog — a skills + plugins marketplace (N2)

Builds on the import engine (#44). Adds a GUI-free catalog package + CLI so nib can discover and install skills and plugins from index sources — the browse/search/marketplace layer.

What's new

  • catalog package — kind-tagged Meta (skill|plugin) parsed from an agentskills.io-shaped index.json; a Source model with DetectSourceKind (URL → index / wellknown host / github repo).
  • catalog.Client — injectable HTTP + GitHub endpoints; fetches per source kind: a direct index URL, a bare host's /.well-known/skills/index.json, or a GitHub repo index-first with a tree-crawl fallback (synthesizes metas from SKILL.md / nib-plugin.yaml dirs, with subtree pruning to match HarvestPack).
  • Merge — fetches enabled sources concurrently (race-free), stamps provenance, unions + dedupes by (kind, name, source), deterministic order; a per-source failure is non-fatal.
  • Install — routes a catalog entry by kind (git sub-path clone or zip download → N1 InstallDir), recording the real source as provenance, landing DISABLED.
  • Sources — persisted to sources.yaml; DefaultSources() seeds agentskills.io, openclaw/agent-skills, and a go:embed bundled starter index (always-on, offline-safe). Built-in sources can be disabled but not removed.
  • CLInib skill|plugin browse, search <query>, source <list|add|enable|disable|remove>, and install <catalog-name> (a strict fallback: existing git/local/zip/url/--link forms are unchanged; only an unmatched bare name resolves against the catalog).

Invariants / safety

  • Everything installs DISABLED; only the existing interactive consent enables.
  • No test touches the real network — all HTTP goes through the injectable Client; tests use httptest and a stubbed vcs.Clone.
  • Merge is -race clean; bundled/built-in source protections are enforced in depth and tested.

Tests

Full module suite green (go build/vet/test ./..., -race ./catalog/, gofmt clean).

Known follow-ups (tracked, non-blocking)

Host-based source labels can collide on the same host; a transient 5xx during GitHub index probing is treated like a 404 (falls to crawl); .claude-plugin/plugin.json isn't crawled yet; truncated GitHub trees yield a partial catalog silently.

Next

This completes the nib engine (import + catalog). Downstream: Dante Desktop UI (import wizard, guided authoring, catalog Browse) over this API.

Built via subagent-driven development (implementer + independent spec/quality review per task, then a whole-branch review; the review caught and fixed the crawl subtree-prune gap).

🤖 Generated with Claude Code

mudler and others added 13 commits July 3, 2026 23:32
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RemoveSource only rejected the bundled source, so removing another built-in
default (agentskills.io, openclaw/agent-skills) dropped it from sources.yaml
and reported success — but LoadSources re-seeds DefaultSources(), so the
"removed" default silently reappeared enabled on the next load.

Reject any built-in default label (set built from DefaultSources(), single
source of truth) before any write, so a rejected remove never rewrites
sources.yaml. disable remains the supported way to turn a built-in off.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rvestPack)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mudler mudler merged commit ad95ba6 into master Jul 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants