feat(dev-env): aiolabs dev environment — options, lib, config, presets

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-06-28 06:48:37 +02:00
commit 7960f82494
6 changed files with 1689 additions and 0 deletions

View file

@ -0,0 +1,564 @@
# aiolabs preset — opinionated project list for the aiolabs ecosystem
#
# Reproduces the current ~/dev tree declaratively. Importing this file
# is opt-in; the dev-env module itself ships no projects by default.
#
# Includes the projects pinned by optimize-deploys/unified/flake.nix
# (which dev-env.deploy.deriveProjectsFromInputs would derive
# automatically when wired up) plus the dev-only worktrees that don't
# have a deploy artifact.
#
# Tmux sessions mirror the layouts in ~/dev/.devenv.d/20-tmux-sessions.sh
# but expressed as a Nix attrset rendered to JSON for dev-tm.
{ config, lib, ... }:
let
mk = config.dev-env.lib.mkProject;
in
{
# Gated: applies only when the aiolabs pack is enabled. Imported (inert)
# via modules/packs/aiolabs.nix. Enabling aiolabs implies lnbits.
config = lib.mkIf config.omni.packs.aiolabs.enable {
omni.packs.lnbits.enable = true;
dev-env = {
forgejo.org = lib.mkDefault "aiolabs";
github.forkUser = lib.mkDefault "your-github-username";
deploy.targets = lib.mkDefault {
host1 = "root@host1.example";
host2 = "root@host2.example";
host3 = "root@host3.example";
host4 = "root@host4.example";
host5 = "root@host5.example";
host6 = "root@host6.example";
host7 = "root@host7.example";
host8 = "root@host8.example";
};
projects = {
# ─── lnbits: shared codebase, dev/main branches ────────────────
lnbits = mk {
name = "lnbits";
category = null;
upstream = "https://github.com/lnbits/lnbits";
deployFlakeInput = "lnbits";
worktrees = {
dev = {
branch = "dev";
};
main = {
branch = "main";
};
};
};
# ─── nsecbunkerd: nostr remote signer daemon (NIP-46) ──────────
nsecbunkerd = mk {
name = "nsecbunkerd";
category = null;
upstream = "https://github.com/kind-0/nsecbunkerd";
worktrees = {
master = {
branch = "master";
};
};
};
# ─── webapp: divergent per-target branches ─────────────────────
webapp = mk {
name = "webapp";
category = null;
upstream = null; # no upstream — original work
deployFlakeInput = "webapp";
isClone = true; # single branch — per-target config lives
# in the deploy flake's services.webapp.*
# options, not in separate branches
};
# ─── boilerplate-website: vue+vite starter, spawn worktrees per site ─
boilerplate-website = mk {
name = "boilerplate-website";
category = null;
upstream = null; # original work
worktrees = {
main = {
branch = "main";
};
};
};
# ─── ATM stack ──────────────────────────────────────────────────
#
# bitspire (active) groups the bitSpire ATM frontend + atm-tui.
# lamassu-next (legacy, retained until the last machines migrate)
# groups the lamassu-next frontend + the lightning-pub fork it
# used. nostr-lightning-wallet is a single clone at top level.
bitspire = mk {
name = "bitspire";
category = "bitspire";
forgejoRepo = "aiolabs/bitspire";
upstream = null; # original
worktrees = {
main = {
branch = "main";
};
dev = {
branch = "dev";
};
};
};
lamassu-next = mk {
name = "lamassu-next";
category = "lamassu-next";
forgejoRepo = "aiolabs/lamassu-next";
upstream = null;
deployFlakeInput = "lamassu-next";
worktrees = {
main = {
branch = "main";
};
dev = {
branch = "dev";
};
};
};
lightning-pub = mk {
name = "lightning-pub";
category = "lamassu-next";
forgejoRepo = "aiolabs/lightning-pub";
upstream = "https://github.com/shocknet/Lightning.Pub";
worktrees = {
master = {
branch = "master";
};
dev = {
branch = "dev";
};
nip05 = {
branch = "feature/nip05";
};
marketplace = {
branch = "feature/marketplace";
};
withdraw = {
branch = "feature/withdraw";
};
extension-loader = {
branch = "feature/extension-loader";
};
};
};
nostr-lightning-wallet = mk {
name = "nostr-lightning-wallet";
category = null;
forgejoRepo = "aiolabs/shockwallet-vue";
upstream = null;
isClone = true; # single clone, has its own flake
deployFlakeInput = "shockwallet-vue";
};
atm-tui = mk {
name = "atm-tui";
category = "bitspire";
forgejoRepo = "aiolabs/atm-tui";
upstream = null; # original
isClone = true;
};
# ─── shared OSS forks ────────────────────────────────────────────
lamassu-server = mk {
name = "lamassu-server";
category = "shared";
forgejoRepo = "aiolabs/lamassu-server";
upstream = "https://github.com/lamassu/lamassu-server";
isClone = true;
};
lamassu-machine = mk {
name = "lamassu-machine";
category = "shared";
forgejoRepo = "aiolabs/lamassu-machine";
upstream = "https://github.com/lamassu/lamassu-machine";
isClone = true;
};
nix-bitcoin = mk {
name = "nix-bitcoin";
category = "shared";
forgejoRepo = "aiolabs/nix-bitcoin";
upstream = "https://github.com/fort-nix/nix-bitcoin";
isClone = true;
};
# ─── lnbits extensions (forked + original) ───────────────────────
ext-nostrrelay = mk {
name = "nostrrelay";
category = "shared/extensions";
forgejoRepo = "aiolabs/nostrrelay";
upstream = "https://github.com/lnbits/nostrrelay";
isClone = true;
};
ext-nostrclient = mk {
name = "nostrclient";
category = "shared/extensions";
forgejoRepo = "aiolabs/nostrclient";
upstream = "https://github.com/lnbits/nostrclient";
isClone = true;
};
ext-nostrmarket = mk {
name = "nostrmarket";
category = "shared/extensions";
forgejoRepo = "aiolabs/nostrmarket";
upstream = "https://github.com/lnbits/nostrmarket";
isClone = true;
};
ext-events = mk {
name = "events";
category = "shared/extensions";
forgejoRepo = "aiolabs/events";
upstream = "https://github.com/lnbits/events";
isClone = true;
};
ext-spirekeeper = mk {
name = "spirekeeper";
category = "shared/extensions";
forgejoRepo = "aiolabs/spirekeeper";
upstream = null; # original — bitSpire operator dashboard
isClone = true;
};
ext-libra = mk {
name = "libra";
category = "shared/extensions";
forgejoRepo = "aiolabs/libra";
upstream = null;
isClone = true;
};
ext-restaurant = mk {
name = "restaurant";
category = "shared/extensions";
forgejoRepo = "aiolabs/restaurant";
upstream = null; # original
isClone = true;
};
ext-withdraw = mk {
name = "withdraw";
category = "shared/extensions";
forgejoRepo = "aiolabs/withdraw";
upstream = "https://github.com/lnbits/withdraw";
isClone = true;
};
ext-lnurlp = mk {
name = "lnurlp";
category = "shared/extensions";
forgejoRepo = "aiolabs/lnurlp";
upstream = "https://github.com/lnbits/lnurlp";
isClone = true;
};
ext-splitpayments = mk {
name = "splitpayments";
category = "shared/extensions";
forgejoRepo = "aiolabs/splitpayments";
upstream = "https://github.com/lnbits/splitpayments";
isClone = true;
};
ext-tasks = mk {
name = "tasks";
category = "shared/extensions";
forgejoRepo = "aiolabs/tasks";
upstream = null; # original
isClone = true;
};
# ─── community-organizer surfaces ───────────────────────────────
#
# Matrix-side bot plugins + the foyer e-ink renderer. Both consume
# the NIP-52/NIP-72 community-organizer protocol defined in
# ~/dev/maubot-plugins/docs/community-organizer-spec.md and feed
# into the wider aiolabs Nostr-native stack (see /etc/nixos/docs/
# system-map.md for the end-to-end picture).
maubot-plugins = mk {
name = "maubot-plugins";
category = null;
forgejoRepo = "aiolabs/maubot-plugins";
upstream = null; # original
isClone = true;
};
inky-impression = mk {
name = "inky-impression";
category = null;
forgejoRepo = "aiolabs/inky-impression";
upstream = null; # original
isClone = true;
};
# ─── auxiliary ──────────────────────────────────────────────────
#
# Note: host5-home and atitlanio-pitch are both auto-derived from
# the server-deploy flake's inputs, so they don't need preset
# entries. See modules/dev-env/config.nix `derivedProjects`.
# The deploy flake itself (also a project so dev-env-bootstrap
# clones it for in-place editing alongside everything else).
# Not derived from the flake because a flake can't list itself
# as an input — this must be hand-authored.
server-deploy = mk {
name = "server-deploy";
category = "deploy";
forgejoRepo = "aiolabs/server-deploy";
upstream = null;
isClone = true;
};
# Regtest environment (Bitcoin/Lightning local dev)
regtest = mk {
name = "regtest";
category = "local/docker";
forgejoRepo = "aiolabs/regtest";
upstream = "https://github.com/lnbits/legend-regtest-enviroment";
isClone = true;
};
# Curated upstream-reference catalogue + weekly digests.
# Bootstrap clones the repo to ~/dev/refs/; bin/refresh
# then materialises repos/<group>/<owner>/<name> from refs.toml.
# The home-manager refs-refresh systemd timer runs that weekly;
# for first-bootstrap immediacy, run `~/dev/refs/bin/refresh`.
refs = mk {
name = "refs";
category = null;
forgejoRepo = "aiolabs/refs";
upstream = null;
isClone = true;
};
# Documentation (Quartz static site)
castle-docs = mk {
name = "castle-docs";
category = "docs";
forgejoRepo = "padreug/castle-docs";
upstream = null;
isClone = true;
};
# ─── reference material ─────────────────────────────────────────
nips = mk {
name = "nips";
category = "nostr-protocol";
originUrl = "https://github.com/nostr-protocol/nips";
upstream = null;
isClone = true;
};
quasar = mk {
name = "quasar";
category = "vue-framework";
originUrl = "https://github.com/quasarframework/quasar";
upstream = null;
isClone = true;
};
# Lightning.Pub + wallet2 upstreams now live as read-only mirrors
# under ~/dev/refs/ (see refs.toml), not as project worktrees.
extension-builder-stub = mk {
name = "extension_builder_stub";
category = "lnbits-reference";
originUrl = "https://github.com/lnbits/extension_builder_stub";
upstream = null;
isClone = true;
};
regtest-upstream = mk {
name = "regtest-upstream";
category = "lnbits-upstream";
originUrl = "https://github.com/lnbits/legend-regtest-enviroment";
upstream = null;
isClone = true;
};
};
# ─── tmux sessions (mirror the existing layouts) ──────────────────
tmux.enable = lib.mkDefault true;
tmux.sessions = {
lnbits = {
cwd = "lnbits";
windows = [
{
name = "dev";
cwd = "lnbits/dev";
cmd = "nvim .";
}
{
name = "main";
cwd = "lnbits/main";
cmd = null;
}
{
name = "extensions";
cwd = "shared/extensions";
cmd = null;
}
{
name = "term";
cwd = "lnbits/dev";
cmd = null;
}
{
name = "git";
cwd = "lnbits/dev";
cmd = "lazygit";
}
];
};
webapp = {
cwd = "webapp";
windows = [
{
name = "edit";
cwd = "webapp";
cmd = "nvim .";
}
{
name = "term";
cwd = "webapp";
cmd = null;
}
{
name = "git";
cwd = "webapp";
cmd = "lazygit";
}
];
};
shared = {
cwd = "shared";
windows = [
{
name = "extensions";
cwd = "shared/extensions";
cmd = null;
}
{
name = "lamassu";
cwd = "shared/lamassu-server";
cmd = null;
}
{
name = "nix-bitcoin";
cwd = "shared/nix-bitcoin";
cmd = null;
}
{
name = "git";
cwd = "shared";
cmd = "wts";
}
];
};
local = {
cwd = "local";
windows = [
{
name = "docker";
cwd = "local/docker";
cmd = null;
}
{
name = "lazydocker";
cwd = "local/docker";
cmd = "lazydocker";
}
{
name = "logs";
cwd = "local";
cmd = null;
}
];
};
bitspire = {
cwd = "bitspire/bitspire";
windows = [
{
name = "dev";
cwd = "bitspire/bitspire/dev";
cmd = "nvim .";
}
{
name = "main";
cwd = "bitspire/bitspire/main";
cmd = null;
}
{
name = "atm-tui";
cwd = "bitspire/atm-tui";
cmd = null;
}
{
name = "git";
cwd = "bitspire/bitspire/dev";
cmd = "lazygit";
}
];
};
lightning-pub = {
cwd = "lamassu-next/lightning-pub";
windows = [
{
name = "dev";
cwd = "lamassu-next/lightning-pub/dev";
cmd = "nvim .";
}
{
name = "master";
cwd = "lamassu-next/lightning-pub/master";
cmd = null;
}
{
name = "extensions";
cwd = "lamassu-next/lightning-pub/extension-loader";
cmd = null;
}
{
name = "git";
cwd = "lamassu-next/lightning-pub/dev";
cmd = "lazygit";
}
];
};
};
};
};
}