An unparseable entry dropped out of the wanted set, so clean deleted the directory and lock entry of a plugin the user still has configured. Add tests/init_spec.lua covering setup, sync, clean and list.
arti-pack
A Neovim plugin manager that installs plugins from an artifact store instead of
git. It downloads tagged upstream source archives through
artifactapi and unpacks them into
Neovim's native package path — see :h packages.
No git, no submodules, no network access to GitHub from the editor: every plugin arrives as a cached, immutable, tagged artifact from the same proxy that serves RPMs, containers and Terraform providers.
Requirements
- Neovim 0.10+
curl, andunzip(ortarwhen usingext = 'tar.gz')
Install
arti-pack manages itself least awkwardly as a plain clone into the package path:
git clone https://git.unkin.net/unkin/arti-pack \
"${XDG_DATA_HOME:-$HOME/.local/share}/nvim/site/pack/arti-pack/start/arti-pack"
Usage
require('arti-pack').setup({
registry = 'https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/github',
plugins = {
{ 'nvim-lua/plenary.nvim', tag = 'v0.1.4' },
{ 'folke/which-key.nvim', tag = 'v3.13.3', opt = true },
{ 'folke/tokyonight.nvim', tag = 'v4.10.0', as = 'tokyonight' },
{ 'tpope/vim-fugitive', tag = 'v3.7', ext = 'tar.gz' },
},
})
Every plugin needs an explicit tag — that is the point. Plugins install to
stdpath('data')/site/pack/arti-pack/start/<name>, or .../opt/<name> when
opt = true.
Spec fields
| Field | Default | Meaning |
|---|---|---|
[1] |
required | owner/repo |
tag |
required | Upstream tag, used verbatim in the archive path |
opt |
false |
Install under opt/ for :packadd instead of start/ |
as |
repo name | Directory name to install as |
ext |
'zip' |
zip or tar.gz |
url |
— | Full archive URL, bypassing the registry |
Options
| Option | Default | Meaning |
|---|---|---|
registry |
the estate artifactapi github remote | Proxy prefix placed in front of owner/repo |
auto_sync |
true |
Sync missing and changed plugins on startup |
concurrency |
4 |
Plugins downloaded in parallel |
timeout |
120 |
Per-download timeout in seconds |
Commands
| Command | Effect |
|---|---|
:ArtiPackSync |
Install missing plugins and update ones whose tag changed |
:ArtiPackSync! |
Reinstall everything, ignoring recorded state |
:ArtiPackClean |
Remove installed plugins no longer in the spec |
:ArtiPackList |
Show every configured plugin and its state |
How it resolves an archive
<registry>/<owner>/<repo>/archive/refs/tags/<tag>.<ext>
which for the defaults is
https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/github/nvim-lua/plenary.nvim/archive/refs/tags/v0.1.4.zip
Archives are cached under stdpath('cache')/arti-pack, checked for a real zip
or gzip magic header before being trusted, and unpacked into a staging
directory. Tag archives wrap their contents in a single <repo>-<version>
directory, which is stripped on the way in. Installed tags are recorded in
stdpath('data')/arti-pack/lock.json, so a sync with nothing to do costs
nothing. Helptags are regenerated per plugin after install.
A failed plugin is reported and skipped; the rest of the run continues.
Tests
make test