atagen

roundabout

public
Star0
Watch0
ecc1cf8df0f5b88c6bf2cd07254c98d13827cd26
1
ssh://brewery@pls.lobotomise.me:33/atagen/roundabout.git

Blame: nix/nixos-module.nix

052a1a49371catagen2026-09-27 03:59 UTC1
self:
052a1a49371catagen2026-09-27 03:59 UTC2
{
052a1a49371catagen2026-09-27 03:59 UTC3
  config,
052a1a49371catagen2026-09-27 03:59 UTC4
  lib,
052a1a49371catagen2026-09-27 03:59 UTC5
  pkgs,
052a1a49371catagen2026-09-27 03:59 UTC6
  ...
052a1a49371catagen2026-09-27 03:59 UTC7
}:
052a1a49371catagen2026-09-27 03:59 UTC8
052a1a49371catagen2026-09-27 03:59 UTC9
let
052a1a49371catagen2026-09-27 03:59 UTC10
  cfg = config.programs.roundabout;
052a1a49371catagen2026-09-27 03:59 UTC11
  toml = pkgs.formats.toml { };
052a1a49371catagen2026-09-27 03:59 UTC12
  plugin = pkgs.callPackage ./plugin.nix { roundabout = cfg.package; };
052a1a49371catagen2026-09-27 03:59 UTC13
in
052a1a49371catagen2026-09-27 03:59 UTC14
{
052a1a49371catagen2026-09-27 03:59 UTC15
  options.programs.roundabout = {
052a1a49371catagen2026-09-27 03:59 UTC16
    enable = lib.mkEnableOption "roundabout, build admission for agents";
052a1a49371catagen2026-09-27 03:59 UTC17
052a1a49371catagen2026-09-27 03:59 UTC18
    package = lib.mkOption {
052a1a49371catagen2026-09-27 03:59 UTC19
      type = lib.types.package;
052a1a49371catagen2026-09-27 03:59 UTC20
      default = self.packages.${pkgs.stdenv.hostPlatform.system}.roundabout;
052a1a49371catagen2026-09-27 03:59 UTC21
      defaultText = lib.literalExpression "roundabout.packages.\${system}.roundabout";
052a1a49371catagen2026-09-27 03:59 UTC22
      description = "the roundabout package";
052a1a49371catagen2026-09-27 03:59 UTC23
    };
052a1a49371catagen2026-09-27 03:59 UTC24
052a1a49371catagen2026-09-27 03:59 UTC25
    socketActivation = lib.mkOption {
052a1a49371catagen2026-09-27 03:59 UTC26
      type = lib.types.bool;
052a1a49371catagen2026-09-27 03:59 UTC27
      default = true;
052a1a49371catagen2026-09-27 03:59 UTC28
      description = ''
052a1a49371catagen2026-09-27 03:59 UTC29
        let a systemd user socket own `$XDG_RUNTIME_DIR/roundabout.sock` and start the
052a1a49371catagen2026-09-27 03:59 UTC30
        daemon on demand. when disabled, the first client spawns daemon instead
052a1a49371catagen2026-09-27 03:59 UTC31
      '';
052a1a49371catagen2026-09-27 03:59 UTC32
    };
052a1a49371catagen2026-09-27 03:59 UTC33
052a1a49371catagen2026-09-27 03:59 UTC34
    settings = lib.mkOption {
052a1a49371catagen2026-09-27 03:59 UTC35
      inherit (toml) type;
052a1a49371catagen2026-09-27 03:59 UTC36
      default = { };
052a1a49371catagen2026-09-27 03:59 UTC37
      example = lib.literalExpression ''
052a1a49371catagen2026-09-27 03:59 UTC38
        {
052a1a49371catagen2026-09-27 03:59 UTC39
          budget.ram = "16GiB";
052a1a49371catagen2026-09-27 03:59 UTC40
          enforce.unwrapped = "wrap";
052a1a49371catagen2026-09-27 03:59 UTC41
          artifacts.stop = "block";
052a1a49371catagen2026-09-27 03:59 UTC42
        }
052a1a49371catagen2026-09-27 03:59 UTC43
      '';
052a1a49371catagen2026-09-27 03:59 UTC44
      description = ''
052a1a49371catagen2026-09-27 03:59 UTC45
        written to `/etc/roundabout/config.toml`, which anyone without a
052a1a49371catagen2026-09-27 03:59 UTC46
        `~/.config/roundabout/config.toml` of their own gets. see readme
052a1a49371catagen2026-09-27 03:59 UTC47
      '';
052a1a49371catagen2026-09-27 03:59 UTC48
    };
052a1a49371catagen2026-09-27 03:59 UTC49
052a1a49371catagen2026-09-27 03:59 UTC50
    claude = {
052a1a49371catagen2026-09-27 03:59 UTC51
      hooks = lib.mkOption {
052a1a49371catagen2026-09-27 03:59 UTC52
        type = lib.types.attrs;
052a1a49371catagen2026-09-27 03:59 UTC53
        readOnly = true;
052a1a49371catagen2026-09-27 03:59 UTC54
        default = import ./hooks.nix {
052a1a49371catagen2026-09-27 03:59 UTC55
          inherit lib;
052a1a49371catagen2026-09-27 03:59 UTC56
          roundabout = cfg.package;
052a1a49371catagen2026-09-27 03:59 UTC57
        };
052a1a49371catagen2026-09-27 03:59 UTC58
        defaultText = lib.literalMD "roundabout's hooks, keyed by event";
052a1a49371catagen2026-09-27 03:59 UTC59
        description = ''
052a1a49371catagen2026-09-27 03:59 UTC60
          hooks in `settings.json` shape, for whatever writes your claude config.
052a1a49371catagen2026-09-27 03:59 UTC61
          lists concatenate under the json format type, so they sit alongside
052a1a49371catagen2026-09-27 03:59 UTC62
          hooks you already have
052a1a49371catagen2026-09-27 03:59 UTC63
        '';
052a1a49371catagen2026-09-27 03:59 UTC64
      };
052a1a49371catagen2026-09-27 03:59 UTC65
052a1a49371catagen2026-09-27 03:59 UTC66
      skill = lib.mkOption {
052a1a49371catagen2026-09-27 03:59 UTC67
        type = lib.types.path;
052a1a49371catagen2026-09-27 03:59 UTC68
        readOnly = true;
052a1a49371catagen2026-09-27 03:59 UTC69
        default = "${plugin}/plugins/roundabout/skills/roundabout";
052a1a49371catagen2026-09-27 03:59 UTC70
        defaultText = lib.literalMD "the roundabout skill directory";
052a1a49371catagen2026-09-27 03:59 UTC71
        description = "the skill directory, for configs that manage `~/.claude/skills` themselves";
052a1a49371catagen2026-09-27 03:59 UTC72
      };
052a1a49371catagen2026-09-27 03:59 UTC73
052a1a49371catagen2026-09-27 03:59 UTC74
      plugin = lib.mkOption {
052a1a49371catagen2026-09-27 03:59 UTC75
        type = lib.types.package;
052a1a49371catagen2026-09-27 03:59 UTC76
        readOnly = true;
052a1a49371catagen2026-09-27 03:59 UTC77
        default = plugin;
052a1a49371catagen2026-09-27 03:59 UTC78
        defaultText = lib.literalMD "the roundabout plugin marketplace";
052a1a49371catagen2026-09-27 03:59 UTC79
        description = "hooks and skill as a marketplace, for `claude plugin marketplace add`";
052a1a49371catagen2026-09-27 03:59 UTC80
      };
052a1a49371catagen2026-09-27 03:59 UTC81
    };
052a1a49371catagen2026-09-27 03:59 UTC82
  };
052a1a49371catagen2026-09-27 03:59 UTC83
052a1a49371catagen2026-09-27 03:59 UTC84
  config = lib.mkIf cfg.enable {
052a1a49371catagen2026-09-27 03:59 UTC85
    environment.systemPackages = [ cfg.package ];
052a1a49371catagen2026-09-27 03:59 UTC86
052a1a49371catagen2026-09-27 03:59 UTC87
    # a real file rather than the usual /etc/static symlink, so a rebuild
052a1a49371catagen2026-09-27 03:59 UTC88
    # renames over it where the daemon's inotify watch can see
052a1a49371catagen2026-09-27 03:59 UTC89
    environment.etc."roundabout/config.toml" = lib.mkIf (cfg.settings != { }) {
052a1a49371catagen2026-09-27 03:59 UTC90
      source = toml.generate "roundabout-config.toml" cfg.settings;
052a1a49371catagen2026-09-27 03:59 UTC91
      mode = "0444";
052a1a49371catagen2026-09-27 03:59 UTC92
    };
052a1a49371catagen2026-09-27 03:59 UTC93
052a1a49371catagen2026-09-27 03:59 UTC94
    systemd.user.sockets.roundabout = lib.mkIf cfg.socketActivation {
052a1a49371catagen2026-09-27 03:59 UTC95
      description = "roundabout build admission socket";
052a1a49371catagen2026-09-27 03:59 UTC96
      wantedBy = [ "sockets.target" ];
052a1a49371catagen2026-09-27 03:59 UTC97
      listenStreams = [ "%t/roundabout.sock" ];
052a1a49371catagen2026-09-27 03:59 UTC98
      socketConfig.SocketMode = "0600";
052a1a49371catagen2026-09-27 03:59 UTC99
    };
052a1a49371catagen2026-09-27 03:59 UTC100
052a1a49371catagen2026-09-27 03:59 UTC101
    systemd.user.services.roundabout = lib.mkIf cfg.socketActivation {
052a1a49371catagen2026-09-27 03:59 UTC102
      description = "roundabout build admission daemon";
052a1a49371catagen2026-09-27 03:59 UTC103
      serviceConfig.ExecStart = "${lib.getExe cfg.package} daemon";
052a1a49371catagen2026-09-27 03:59 UTC104
    };
052a1a49371catagen2026-09-27 03:59 UTC105
  };
052a1a49371catagen2026-09-27 03:59 UTC106
}