# Babysitter user profile for Pi/agent workflows. { config, lib, ... }: let cfg = config.coding.agents.babysitter; defaultTimestamp = "2026-05-29T00:00:00.000Z"; defaultUserProfile = { name = config.home.username; specialties = [ { domain = "declarative-system-configuration"; subdomains = ["nix" "home-manager" "agents"]; } ]; expertiseLevels = {}; goals = [ { id = "goal-agents-declarative-profile"; description = "Keep Babysitter user preferences declarative and reproducible across systems."; category = "agents"; priority = "medium"; status = "active"; } ]; preferences = { verbosity = "concise"; autonomyLevel = "semi-autonomous"; riskTolerance = "conservative"; }; toolPreferences = { packageManagers = ["nix"]; languages = ["nix"]; operatingSystem = "nixos"; }; breakpointTolerance = { global = "moderate"; skipBreakpointsForKnownPatterns = false; alwaysBreakOn = ["destructive-operations" "secrets" "external-publication"]; }; communicationStyle = { tone = "technical"; language = "en"; useEmojis = false; explanationDepth = "brief"; preferredResponseFormat = "markdown"; }; experience = {}; installedPlugins = ["babysitter-pi"]; installedSkills = ["babysit" "call" "plan" "resume" "doctor" "yolo"]; installedAgents = []; createdAt = defaultTimestamp; updatedAt = defaultTimestamp; version = 1; }; effectiveProfile = lib.recursiveUpdate cfg.profile cfg.profileOverrides; profileJsonTarget = "${cfg.profileDirectory}/user-profile.json"; profileMarkdownTarget = "${cfg.profileDirectory}/user-profile.md"; profilePreferences = effectiveProfile.preferences or {}; profileBreakpointTolerance = effectiveProfile.breakpointTolerance or {}; listMarkdown = values: lib.concatMapStringsSep "\n" (value: "- ${toString value}") values; specialtyDomains = map (specialty: specialty.domain or "unspecified") (effectiveProfile.specialties or []); profileMarkdown = '' # Babysitter User Profile This file is generated by Home Manager from `coding.agents.babysitter`. - Name: ${effectiveProfile.name or "unspecified"} - Breakpoint tolerance: ${profileBreakpointTolerance.global or "unspecified"} - Autonomy level: ${profilePreferences.autonomyLevel or "unspecified"} - Risk tolerance: ${profilePreferences.riskTolerance or "unspecified"} ## Specialties ${listMarkdown specialtyDomains} ## Installed Babysitter Pi Skills ${listMarkdown (effectiveProfile.installedSkills or [])} ''; in { options.coding.agents.babysitter = { enable = lib.mkEnableOption "Babysitter user profile for Pi/agent workflows"; profileDirectory = lib.mkOption { type = lib.types.str; default = ".a5c"; description = '' Home-relative directory where Babysitter reads the user profile. Babysitter Pi documents the user profile at ~/.a5c/user-profile.json. ''; }; profile = lib.mkOption { type = lib.types.attrsOf lib.types.anything; default = defaultUserProfile; description = "Complete non-secret Babysitter user profile JSON."; }; profileOverrides = lib.mkOption { type = lib.types.attrsOf lib.types.anything; default = {}; description = '' Recursive overrides merged into the default Babysitter user profile. Keep this non-secret; the result is written into the Nix store. ''; }; }; config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.profileDirectory != "" && !lib.hasPrefix "/" cfg.profileDirectory; message = "coding.agents.babysitter.profileDirectory must be a non-empty home-relative path."; } { assertion = effectiveProfile ? name && builtins.isString effectiveProfile.name; message = "coding.agents.babysitter profile must include a string name."; } { assertion = effectiveProfile ? specialties && builtins.isList effectiveProfile.specialties; message = "coding.agents.babysitter profile must include a specialties list."; } { assertion = effectiveProfile ? breakpointTolerance && effectiveProfile.breakpointTolerance ? global; message = "coding.agents.babysitter profile must include breakpointTolerance.global."; } ]; home.file = { "${profileJsonTarget}".text = builtins.toJSON effectiveProfile + "\n"; "${profileMarkdownTarget}".text = profileMarkdown; }; }; }