omnixient/modules/dev-env/README.md
Padreug 7960f82494 feat(dev-env): aiolabs dev environment — options, lib, config, presets
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 09:59:05 +02:00

5.2 KiB

modules/dev-env

Declarative NixOS module for managing a multi-project dev environment.

Design principles

  1. Nix owns the configuration, bash owns the runtime. Nix renders /etc/dev-env/config.sh and projects.json; installed bash scripts source those at call time. Navigation helpers walk the filesystem at runtime — adding a new branch is git worktree add, never nixos-rebuild.

  2. The deploy flake is the single source of truth for deployed refs. Set dev-env.deploy.flakeInput = "deploy-flake" and projects will be derived from inputs.deploy-flake.inputs whose URLs live under the configured forgejo host. Hand-authored extras go in dev-env.projects.

  3. Bootstrap is user-invoked, not an activation hook. dev-env-bootstrap materializes bare repos + worktrees. It is never run during nixos-rebuild — rebuilds stay fast and offline.

Files

File Purpose
default.nix Imports options, lib, config. Module entry point.
options.nix mkOption declarations for every knob.
lib.nix mkProject constructor + deriveFromFlakeInput parser.
config.nix Renders config files, installs scripts, wires git hooks.
presets/aiolabs.nix Hand-authored project list for the aiolabs ecosystem.
scripts/*.sh Ported + new bash helpers loaded via builtins.readFile.
scripts/git-hooks/pre-commit Shared secret-scanner hook (via core.hooksPath).
docs/*.md Runbooks shipped to the user's ~/Documents/dev-env/.

Using from omni

# omni/flake.nix
inputs.deploy-flake = {
  url = "git+ssh://forgejo@git.atitlan.io/padreug/deploy-unified";
};

# omni/configuration.nix
imports = [
  ./modules/dev-env
  ./modules/dev-env/presets/aiolabs.nix  # opt-in to aiolabs defaults
];

dev-env = {
  enable = true;
  forgejo.org = "aiolabs";
  github.forkUser = "your-github-username";
  deploy.flakeInput = "deploy-flake";
  deploy.targets = {
    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";
  };
};

Bootstrap workflow

# 1. Rebuild with dev-env enabled
sudo nixos-rebuild switch --flake .#omni

# 2. Dry-run to see what will be created
dev-env-bootstrap --dry-run

# 3. Materialize bare repos + worktrees
dev-env-bootstrap

# 4. Navigate
lb dev            # → ~/dev/lnbits/dev
bs                # → ~/dev/bitspire/bitspire/dev
lam lightning-pub # → ~/dev/lamassu-next/lightning-pub/dev
prb lnbits fix-x  # → ~/dev/upstream-prs/lnbits-fix-x on upstream/main

# 5. Deploy
dev-deploy host5              # uses locked deploy-flake input
dev-deploy --local host1     # overrides inputs with local worktrees

Extending

Add a new project in presets/aiolabs.nix (or a new preset):

dev-env.projects.my-new-project = lib.mkProject {
  category = "shared";
  upstream = "https://github.com/example/my-project";
  worktrees.main.branch = "main";
};

Then rebuild and dev-env-bootstrap. Existing worktrees are never clobbered — the bootstrap script refuses to touch a worktree whose current branch differs from the declared one.

What this module does NOT do

  • Manage bitSpire's internal flake.nix/devenv.nix — that project has its own dev environment.
  • Run git fetch/git pull automatically — use wts/wtu helpers or a manual git fetch --all.
  • Replace direnv per-worktree .envrc files — it just makes sure nix-direnv is enabled (omni's home.nix already does this).

Reference docs (docs/)

LNbits-domain guides that travel with this module — so the lnbits pack is a self-contained dev environment whether used on omni or imported standalone (nixosModules.lnbits). These were consolidated here from the former standalone lnbits-sensei scaffold, which this pack supersedes.

  • lnbits-workspace-notes.md — practical day-to-day gotchas: ports, LNBITS_SRC build-context traps, extension-folder-upgrade wiping forks, settings precedence (.env vs DB), Nostr keys, CLINK scope, fork versioning.
  • lnbits-extension-dev.md — building extensions: auth-decorator distinctions, FakeWallet vs regtest testing, the migrations_fork.py pattern.
  • lnbits-frontend-gotchas.md — Vue/Quasar UMD traps (no self-closing tags, CSS specificity vs Quasar !important, cache busting, dark-mode discipline).
  • lnbits-upstream-flow.md — how lnbits/lnbits itself moves (dev/main branch model, squash-merge, release tagging).
  • upstream-prs.md — sending a PR upstream via the ~/dev/upstream-prs/ worktree flow (with a fork/PR primer).
  • remotes.md — the three remote-topology patterns (upstream-only / github-fork / multi-remote with a private host).
  • secrets-management.md — getting secrets out of .env into sops-encrypted YAML.
  • stack-overview.md — the aiolabs stack map (which repo is what, how the pieces fit).