Skip to content

feat: extensions import engine — zip/URL install for skills & plugins (N1)#44

Merged
mudler merged 10 commits into
masterfrom
feat/extensions-import-engine
Jul 3, 2026
Merged

feat: extensions import engine — zip/URL install for skills & plugins (N1)#44
mudler merged 10 commits into
masterfrom
feat/extensions-import-engine

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

Extensions import engine (N1)

Lets nib install a skill or plugin from a .zip archive or a bare SKILL.md URL — from the library and the CLI. Folder and git installs already worked; this fills the remaining import forms and lays the reusable foundation for the upcoming catalog/marketplace (N2) and the Dante Desktop UI.

What's new

  • extsource packageExtractZip (safe unzip with zip-slip guards: rejects path-escape, absolute, and symlink entries; bounded reads) and FetchSKILLURL (downloads a bare SKILL.md into a pack dir, the agentskills.io well-known form).
  • InstallDir on both managersskill.Manager.InstallDir(dir, name, sourceURL) and plugin.Manager.InstallDir(dir, nibVersion, sourceURL) install an already-prepared local directory. Each is a behaviour-preserving refactor that extracts a shared place tail out of the existing Install.
  • HarvestPack precedence — a root-level SKILL.md now counts as the single skill only when the pack has no subdirectory skills (supports the bare-file / agentskills.io form; multi-skill packs are unchanged). Proven additive against existing installed packs.
  • CLInib skill install <zip|SKILL.md-url> and nib plugin install <zip>; git/local-dir/--link paths unchanged. Imports land DISABLED; the only enable path remains the existing interactive consent.

Safety / invariants

  • Every install path lands DISABLED (place records Enabled: false).
  • Zip-slip guards are enforced and mutation-verified (each guard has a test that fails if the guard line is removed).
  • The two Install refactors are behaviour-preserving; the real source (zip path / URL) is recorded as SourceURL for honest list provenance.

Tests

Full module suite green (go build/vet/test ./..., gofmt clean). New coverage in extsource, skill, plugin, and cmd.

Follow-ups (separate work)

  • N2: catalog package + nib skill/plugin browse|search|source (skills+plugins marketplace from indexes).
  • Dante Desktop: import wizard, guided authoring, and catalog Browse UI over this engine.

Built via subagent-driven development (implementer + independent spec/quality review per task, then a whole-branch review).

🤖 Generated with Claude Code

mudler and others added 10 commits July 3, 2026 22:40
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the tail of Install into a private place() helper and add the
public InstallDir(dir, name) entrypoint that copies a prepared dir into
a temp under the skills dir and calls place. Installed packs land
DISABLED. Also teach HarvestPack to recognize a root-level SKILL.md as a
single skill (the bare fetched-SKILL.md case), which InstallDir relies on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Commit 528a3b5 made a root-level SKILL.md the single skill
unconditionally, regressing multi-skill packs that ship both a root
overview SKILL.md and real skills in subdirectories. Restructure
HarvestPack so the subdirectory walk runs first and wins: a root
SKILL.md is the single skill only as a fallback when the walk yields
zero skills (supporting a bare fetched SKILL.md / single-file form).

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

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mudler mudler merged commit 3286a57 into master Jul 3, 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