Replace the stub dev-env with the real, working implementation that grew
in the reference machine config — de-identified for the public scaffold.
Nix layer:
- options.nix: full project schema (url/upstream/fork/category/
worktreeRoot/worktrees{branch,path,remote}/isClone/deployFlakeInput),
deploy.targets, github.forkUser, writeDirenvHints. Drops the
forgejo-URL block + deploy-flake auto-derivation (incoherent in a
scaffold that uses explicit per-project urls).
- lib.nix: mkProject + worktreePath/bareRepoPath/projectRemotes,
generalized to the explicit-url model (origin falls back to upstream).
- config.nix: renders /etc/dev-env/{config.sh,projects.json,
tmux-sessions.json}, installs helpers via writeShellScriptBin, loads
shell functions into interactive shells, wires the git pre-commit hook.
Scripts (config-driven, read /etc/dev-env at runtime):
- bootstrap.sh, nav.sh, worktree.sh, pr-helpers.sh, rebase.sh,
status.sh, deploy.sh, regtest.sh, tmux-launch.sh.
- Stripped aiolabs/forgejo/bitspire/lamassu/webapp hardcoding; the
github-fork remote is renamed 'fork' to match git.remotes vocabulary.
- Removes the dev.sh stub (the matured impl uses discrete commands +
shell functions, not a unified 'dev' CLI).
presets/example.nix: a worked, generic project list replacing the
identity-specific aiolabs preset. tests/smoke.nix + flake checks
exercise the schema; 'nix flake check' is green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.2 KiB
modules/dev-env
Declarative NixOS module for managing a multi-project dev environment around an LNbits stack — bare repos, worktrees, navigation helpers, tmux sessions, the regtest docker env, and the upstream-PR workflow.
Design principles
-
Nix owns the configuration, bash owns the runtime. Nix renders
/etc/dev-env/config.sh+projects.json; installed bash scripts source those at call time. Navigation helpers walk the filesystem at runtime — adding a new branch isgit worktree add, nevernixos-rebuild. -
Projects are explicit, git-host-agnostic. Each project declares its
originurldirectly (any forgejo / gitea / codeberg / github URL). The only github-specific knob isgithub.forkUser, used to derive a personalforkremote for upstream PRs. -
Bootstrap is user-invoked, not an activation hook.
dev-env-bootstrapmaterializes bare repos + worktrees. It is never run duringnixos-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 + path/remote helpers. |
config.nix |
Renders config files, installs scripts, wires git hooks. |
presets/example.nix |
A worked, generic project list — copy and edit. |
scripts/*.sh |
Bash helpers loaded via builtins.readFile. |
scripts/git-hooks/pre-commit |
Shared secret-scanner hook (via core.hooksPath). |
tests/smoke.nix |
nix flake check evaluation test for the schema. |
Using it
# configuration.nix
imports = [
./modules/dev-env
./modules/dev-env/presets/example.nix # opt-in; copy and edit
];
lnbits-sensei.devEnv = {
enable = true;
scaffoldPath = "/home/you/dev/lnbits-sensei";
github.forkUser = "octocat";
deploy.targets = {
prod = "root@prod-host";
staging = "root@staging-host";
};
};
Bootstrap workflow
# 1. Rebuild with dev-env enabled
sudo nixos-rebuild switch --flake .#<host>
# 2. Dry-run to see what will be created
dev-env-bootstrap --dry-run
# 3. Materialize bare repos + worktrees
dev-env-bootstrap
# 4. Navigate (shell functions, sourced into interactive shells)
lb dev # → ~/dev/lnbits/dev
g extensions myext # → ~/dev/extensions/myext
ext <name> # → ~/dev/shared/extensions/<name>
prb lnbits fix-x # → ~/dev/upstream-prs/lnbits-fix-x on upstream/main
# 5. Inspect / sync
dev-status # dirty + ahead/behind for every worktree
wts # fetch all bare repos, summarize worktree status
rebase status # which forks need rebasing onto upstream
lnbits-status # lnbits dev/main divergence vs upstream
# 6. Regtest (when devEnv.regtest.enable = true; needs docker)
regtest-start dev # build lnbits from ~/dev/lnbits/dev, bring stack up
regtest-stop
# 7. Deploy
dev-deploy prod # uses the locked deploy-flake input
dev-deploy --local staging # overrides inputs with local worktrees
Command summary
| Command | What |
|---|---|
dev-env-bootstrap |
Materialize bare repos + worktrees from projects.json. |
dev-status |
Dirty/ahead/behind report across all worktrees. |
dev-tm <session> |
Launch a declarative tmux session. |
dev-deploy <host> |
nixos-rebuild against your deploy flake. |
rebase [status|all|<path>] |
Safe fork-onto-upstream rebase with backups. |
regtest-start / -stop / -status |
Bitcoin/Lightning regtest stack. |
lb / g / ext / dep / prs / shared / repos |
Navigation (shell functions). |
wt / wts / wtu / wtn |
Worktree list / sync / upstream-fetch / spawn. |
prb / prc / prl |
Upstream-PR worktree branch / cleanup / list. |
lnbits-status / lnbits-sync-dev / lnbits-sync-main |
lnbits fork workflow. |
What this module does NOT do
- Run
git fetch/git pullautomatically — usewts/wtuor a manualgit fetch --all. - Manage per-worktree
.envrcbeyond writing a defaultuse flakehint on bootstrap (never clobbers an existing file). - Install docker for you —
devEnv.regtest.enableinstalls theregtest-*helpers, but you must provide the container engine.