- C++ 91%
- Nix 7%
- Python 2%
Draconis++ Plugin Lab #
A personal repository for external Draconis++ plugins that do not belong in core.
This repo keeps plugin development separate from Draconis++ core while still building cleanly through the core plugin system. It includes:
- a self-contained plugin directory with
plugin.json - local
IInfoProviderPluginimplementations - a Nix flake that exposes plugin-root packages
Layout #
container_info/
container_info.cpp
plugin.json
vpn_info/
vpn_info.cpp
plugin.json
flake.nix
Draconis++ discovers plugins from directories that contain direct children with
a plugin.json manifest. This repository root is therefore a plugin root.
Build With Draconis++ #
From a Draconis++ core checkout:
meson setup build -Dplugin_dirs=/path/to/draconisplusplus-plugin-lab
meson compile -C build
To compile the plugin statically into Draconis++:
meson setup build -Dplugin_dirs=/path/to/draconisplusplus-plugin-lab -Dstatic_plugins=vpn_info
meson compile -C build
Nix #
The flake exposes plugin-root packages:
packages.${system}.defaultpackages.${system}.allpackages.${system}.container_infopackages.${system}.vpn_info
Example plugin-root usage:
programs.draconisplusplus = {
enable = true;
pluginMode = "static";
pluginPackages = [
(inputs.my-draconis-plugin.lib.${pkgs.system}.mkPluginRoot {
plugins = {
vpn_info = true;
container_info = {
enable = true;
settings.backends = ["podman"];
};
};
})
];
};
The generated plugin root contains only enabled plugins. Its passthru metadata
also contains only those plugins' build inputs, so a VPN-only configuration
does not pull in container dependencies. The legacy names, containerInfo,
and explicit staticPlugins interfaces remain available.
container_info needs libcurl available to the Draconis++ build because its
manifest declares libcurl. The flake exposes per-plugin dependency metadata
through lib.${system}.pluginBuildInputsByName; each generated package carries
the selected dependency union in passthru.pluginBuildInputs.
Customizing #
To add another plugin, create a new plugin directory, then update:
<plugin_name>/plugin.json- the C++ class and
DRAC_PLUGIN(...)registration pluginNamesinflake.nix
Manifest notes:
nameshould match the plugin directory and the implicit source file name.classmust match the C++ class passed toDRAC_PLUGIN(...).platformsuses Mesonhost_machine.system()names such aslinux,darwin, andwindows; use["all"]for portable plugins.depslists external dependencies resolved by Meson, for example{ "name": "libcurl", "include_type": "system", "static": true }.
Keep plugin-specific Nix config in this repository. The core Draconis++ module
should only receive plugin roots through pluginPackages or pluginDirs.
Included Plugins #
container_info #
Reports local container runtime availability and counts without invoking container CLI tools. It checks Docker, Podman, WSL Containers, and LXD/LXC exposed through LXD local APIs.
It reports these fields:
active: true when any supported runtime has running containerstotal_running: total running containers across detected runtimestotal_containers: total containers across detected runtimesruntimes: array of runtime objects withid,display_name,kind,available,active,running,total,version, andendpoint
Display output uses the first available runtime in priority order: Docker, Podman, WSL Containers, then LXD.
WSL Containers support uses the same local COM service path as wslc.exe,
based on the open-source WSL service IDL. The public SDK documentation does not
currently expose a container-listing wrapper, but the local service provides
IWSLCSession::ListContainers. The plugin uses that API for active WSLC
sessions and never shells out to wslc.exe.
For precompiled/static builds, configure which backends are checked through the plugin root:
inputs.my-draconis-plugin.lib.${pkgs.system}.mkPluginRoot {
containerInfo.backends = ["podman"];
}
For runtime plugin builds, use
~/.config/draconis++/plugins/container_info.toml:
backends = ["docker", "podman", "wsl", "lxd"]
The same key can also be set under [plugins.container_info] in the main
Draconis++ config.toml. Omit backends, or use ["all"], to check every
supported backend.
Example layout row:
programs.draconisplusplus.layout = [
{
name = "containers";
rows = [
{ key = "plugin.container_info"; }
];
}
];
vpn_info #
Detects VPN-like interfaces on Windows, macOS, Linux, FreeBSD, OpenBSD, NetBSD, and DragonFly BSD.
It reports these fields:
active: true when any detected VPN-like interface is upinterfaces: object keyed by interface ID. Each value containsdisplay_name,kind,active, andprimary.
Example layout row:
programs.draconisplusplus.layout = [
{
name = "network";
rows = [
{ key = "plugin.vpn_info"; }
];
}
];