diff --git a/AGENTS.md b/AGENTS.md index 48b3acc..7fe98f7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,12 +22,12 @@ This repo uses Bun as the package manager and `bun2nix` for reproducible Nix bui - `bun.lock` is the source of truth for JS dependencies. - `bun.nix` is generated from `bun.lock` with `bun run update:bun-nix`. - `flake.nix` imports the `bun2nix` overlay and exposes `packages..default` plus `nixosModules.default`. -- `nix/package.nix` uses `bun2nix.fetchBunDeps` with `bun.nix`, runs `bun run build`, and installs the bundled `server.js` plus frontend assets as the `leo-ed` executable. +- `nix/package.nix` uses `bun2nix.fetchBunDeps` with `bun.nix`, runs `bun run build`, and installs the bundled `server.js` plus frontend assets as the `kotsukotsu` executable. Whenever dependencies change, update both `bun.lock` and `bun.nix` in the same commit. CI checks that `bun.nix` matches the lockfile by regenerating it and failing on diff. ## Server and Deployment Model -This repo is the application source, not the full server configuration. Production is intended to be managed from a separate NixOS infra repo that imports this flake and sets `services.leo-ed.package = inputs.leo-ed.packages.${pkgs.system}.default;`. The included module in `nix/module.nix` defines the systemd service, runtime env (`APP_ORIGIN`, `PORT`, `SQLITE_PATH`, `SESSION_COOKIE_SECURE`), and persistent state directory. +This repo is the application source, not the full server configuration. Production is intended to be managed from a separate NixOS infra repo that imports this flake and sets `services.kotsukotsu.package = inputs.kotsukotsu.packages.${pkgs.system}.default;`. The included module in `nix/module.nix` defines the systemd service, runtime env (`APP_ORIGIN`, `PORT`, `SQLITE_PATH`, `SESSION_COOKIE_SECURE`), and persistent state directory. `server/config.ts` exists so production behavior is explicit: WebAuthn origin/RP ID, SQLite path, bind host, and secure cookies should come from NixOS service configuration, not reverse-proxy accident. diff --git a/flake.nix b/flake.nix index 70e4954..9a27f0f 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,5 @@ { - description = "leo-ed typing app"; + description = "kotsukotsu typing app"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; @@ -7,52 +7,39 @@ bun2nix.inputs.nixpkgs.follows = "nixpkgs"; }; - nixConfig = { - extra-substituters = [ - "https://cache.nixos.org" - "https://nix-community.cachix.org" - ]; - extra-trusted-public-keys = [ - "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - ]; + outputs = { + self, + nixpkgs, + bun2nix, + }: let + systems = ["x86_64-linux" "aarch64-linux"]; + forAllSystems = nixpkgs.lib.genAttrs systems; + in { + packages = forAllSystems (system: let + pkgs = import nixpkgs { + inherit system; + overlays = [bun2nix.overlays.default]; + }; + in rec { + kotsukotsu = pkgs.callPackage ./nix/package.nix {}; + default = kotsukotsu; + }); + + devShells = forAllSystems (system: let + pkgs = import nixpkgs { + inherit system; + overlays = [bun2nix.overlays.default]; + }; + in { + default = pkgs.mkShell { + packages = with pkgs; [ + bun + bun2nix + nodejs + ]; + }; + }); + + nixosModules.default = import ./nix/module.nix; }; - - outputs = { self, nixpkgs, bun2nix }: - let - systems = [ "x86_64-linux" "aarch64-linux" ]; - forAllSystems = nixpkgs.lib.genAttrs systems; - in - { - packages = forAllSystems (system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ bun2nix.overlays.default ]; - }; - in - rec { - leo-ed = pkgs.callPackage ./nix/package.nix { }; - default = leo-ed; - }); - - devShells = forAllSystems (system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ bun2nix.overlays.default ]; - }; - in - { - default = pkgs.mkShell { - packages = with pkgs; [ - bun - bun2nix - nodejs - ]; - }; - }); - - nixosModules.default = import ./nix/module.nix; - }; } diff --git a/nix/module.nix b/nix/module.nix index 41e21bf..90e2bb1 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -1,16 +1,16 @@ { config, lib, pkgs, ... }: let - cfg = config.services.leo-ed; + cfg = config.services.kotsukotsu; in { - options.services.leo-ed = { - enable = lib.mkEnableOption "leo-ed typing app"; + options.services.kotsukotsu = { + enable = lib.mkEnableOption "kotsukotsu typing app"; package = lib.mkOption { type = lib.types.nullOr lib.types.package; default = null; - description = "The leo-ed package to run, typically inputs.leo-ed.packages.${pkgs.system}.default."; + description = "The kotsukotsu package to run, typically inputs.kotsukotsu.packages.${pkgs.system}.default."; }; host = lib.mkOption { @@ -34,19 +34,19 @@ in dataDir = lib.mkOption { type = lib.types.str; - default = "/var/lib/leo-ed"; + default = "/var/lib/kotsukotsu"; description = "Directory for the persistent SQLite database."; }; user = lib.mkOption { type = lib.types.str; - default = "leo-ed"; + default = "kotsukotsu"; description = "User account for the service."; }; group = lib.mkOption { type = lib.types.str; - default = "leo-ed"; + default = "kotsukotsu"; description = "Group for the service."; }; @@ -61,24 +61,24 @@ in assertions = [ { assertion = cfg.package != null; - message = "services.leo-ed.package must be set, usually from this flake input."; + message = "services.kotsukotsu.package must be set, usually from this flake input."; } { assertion = cfg.domain != null && cfg.domain != ""; - message = "services.leo-ed.domain must be set."; + message = "services.kotsukotsu.domain must be set."; } { assertion = lib.hasPrefix "/" cfg.dataDir; - message = "services.leo-ed.dataDir must be an absolute path."; + message = "services.kotsukotsu.dataDir must be an absolute path."; } ]; - users.groups = lib.mkIf (cfg.group == "leo-ed") { - leo-ed = { }; + users.groups = lib.mkIf (cfg.group == "kotsukotsu") { + kotsukotsu = { }; }; - users.users = lib.mkIf (cfg.user == "leo-ed") { - leo-ed = { + users.users = lib.mkIf (cfg.user == "kotsukotsu") { + kotsukotsu = { isSystemUser = true; group = cfg.group; home = toString cfg.dataDir; @@ -90,8 +90,8 @@ in "d ${toString cfg.dataDir} 0750 ${cfg.user} ${cfg.group} -" ]; - systemd.services.leo-ed = { - description = "leo-ed typing app"; + systemd.services.kotsukotsu = { + description = "kotsukotsu typing app"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; diff --git a/nix/package.nix b/nix/package.nix index 874f926..f9819c4 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -9,7 +9,7 @@ let packageJson = lib.importJSON ../package.json; in stdenvNoCC.mkDerivation { - pname = "leo-ed"; + pname = "kotsukotsu"; version = packageJson.version; src = lib.cleanSource ../.; @@ -35,12 +35,12 @@ stdenvNoCC.mkDerivation { installPhase = '' runHook preInstall - mkdir -p $out/share/leo-ed $out/bin - cp -r build/. $out/share/leo-ed/ + mkdir -p $out/share/kotsukotsu $out/bin + cp -r build/. $out/share/kotsukotsu/ - makeWrapper ${lib.getExe bun} $out/bin/leo-ed \ - --run "cd $out/share/leo-ed" \ - --add-flags "$out/share/leo-ed/server.js" + makeWrapper ${lib.getExe bun} $out/bin/kotsukotsu \ + --run "cd $out/share/kotsukotsu" \ + --add-flags "$out/share/kotsukotsu/server.js" runHook postInstall ''; @@ -48,7 +48,7 @@ stdenvNoCC.mkDerivation { meta = { description = "Typing practice app with passkey auth"; homepage = "https://example.invalid"; - mainProgram = "leo-ed"; + mainProgram = "kotsukotsu"; platforms = lib.platforms.linux; }; }