No description
  • Luau 86.3%
  • Shell 12.4%
  • Lua 1.3%
Find a file
2026-09-27 15:42:38 +00:00
.github
.nvim/lsp
.tools
.vscode
.zed
niello-startup-manager Run: nohup-style background with >/dev/null 2>&1 & 2026-09-27 15:38:22 +00:00
spraypaint
.gitignore
.luaurc
.nvim.lua
bump.txt
catalog.toml chore: update plugin catalog [skip ci] 2026-09-27 15:42:38 +00:00
LICENSE
README.md
README_TEMPLATE.md

Akinus's Noctalia plugins

Noctalia Logo


A personal plugin source for Noctalia. Add this repo as a source in Noctalia v5 and any plugin under akinus/ becomes installable from the plugin store.

noctalia msg plugins source add akinus https://forge.akinus21.com/akinus/noctalia-plugins.git

Layout

Each plugin is one top-level directory, named after the part of its id that follows the /, so akinus/example lives in example/:

akinus/<plugin>/
  plugin.toml             # manifest: id, metadata, entries, settings
  *.luau                  # entry scripts
  README.md               # rendered as the plugin's page on noctalia.dev
  thumbnail.webp          # the plugin's card image (960x540)
  translations/
    en.json               # every label_key / description_key the manifest references

catalog.toml at the repo root indexes every plugin. It is generated by CI; do not edit it manually or include it in a commit.

A plugin id is <author>/<plugin>. The author segment is akinus. The plugin segment (and the directory it lives in) must be lowercase and match [a-z0-9][a-z0-9._-]*. The directory name is first-come within this repo.

What a plugin is allowed to be

Noctalia plugins are trusted, unsandboxed Luau. Installing a plugin is equivalent to running a script the user owns: it can read files, write files, spawn processes, and talk to the network as that user. Review your own work with that in mind — never ship obfuscated, minified, or generated code; never download and execute remote code; declare every external command in dependencies in plugin.toml; account for every network call, filesystem write, and spawned process.

Writing a plugin

The plugin development docs are the reference: the manifest, the entry types, the declarative UI vocabulary, the runtime API, and the workflow for developing and testing locally. The fastest start is to read noctalia/example in the official repo.

To work on a plugin locally while pointing Noctalia at this checkout:

noctalia msg plugins source add dev path ~/dev/noctalia-plugins
noctalia msg plugins enable akinus/<plugin>

.luau edits hot-reload; manifest changes are picked up on the next config reload.

Editor setup

noctalia.d.luau declares the whole plugin API so luau-lsp gives you autocomplete and typo diagnostics. It lives in the official-plugins repo, which is its single source of truth. Fetch a snapshot into the repo root (where it is gitignored):

curl -O https://raw.githubusercontent.com/noctalia-dev/official-plugins/main/noctalia.d.luau

Re-run that whenever the plugin API changes.

.vscode/settings.json already points luau-lsp at it; for other editors, add the same path to luau-lsp's types.definitionFiles. .luaurc sets nonstrict mode, matching the --!nonstrict directive every plugin script starts with.

Thumbnail

Every plugin ships a thumbnail.webp. It is the card image in the plugin store and on the website. Generate one with the thumbnail generator: drop in a screenshot of your plugin, set the title, category tag, and accent color, then export the 960x540 WebP and commit it as akinus/<plugin>/thumbnail.webp.

README

README.md is the plugin's public page. Follow README_TEMPLATE.md: start with a title and one-paragraph explanation, then a ## Plugin table that documents the manifest id and every entry id exactly as they appear in plugin.toml. For a panel, include the exact command noctalia msg panel-toggle <id>:<panel-id>. For a launcher provider, document its /<prefix> and give an example query. Mention every manifest dependency under ## Requirements, using the exact dependency name. Document declared settings under ## Settings, including units or non-obvious effects.

CI validates that the README documents every entry id and that any declared dependencies, settings, and launcher prefixes are mentioned.

Translations

Write translations/en.json only. Every label_key and description_key in your manifest must resolve to a key in it, and CI checks this. Do not add machine-translated locales; other languages are handled separately.

To pull the latest translated locales from Noctalia Translate into a working checkout:

./.tools/i18n-pull.sh

The command asks for confirmation and overwrites only the locale files returned by the translation service. Review the resulting diff before committing anything.

Tags

The tags in plugin.toml are used for catalog search. Tags must be lowercase and selected from the community-plugins tag list. If your plugin does not fit any existing tag, propose a new one in your pull request rather than inventing a tag in the manifest.

CI

Two workflows, both portable to Forgejo Actions:

  • .github/workflows/validate-plugins.yml runs on every push and PR to main. It runs validate-plugins.py over every */plugin.toml, including the unit tests, and fails the run if a manifest is malformed, a translation key is missing, a thumbnail is the wrong size, the README doesn't document an entry, or a .luau file references a removed entry-specific getConfig alias.
  • .github/workflows/on-push.yml regenerates catalog.toml from the manifests on every push to main and commits the result with [skip ci] so the catalog can never be ahead of the manifests it indexes.

Help