forked from jan-leila/nix-config
		
	
		
			
				
	
	
		
			207 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{
 | 
						|
  lib,
 | 
						|
  pkgs,
 | 
						|
  config,
 | 
						|
  inputs,
 | 
						|
  ...
 | 
						|
}: let
 | 
						|
  pkgsRepositories = pkgs.nix-vscode-extensions.forVSCodeVersion config.programs.vscode.package.version;
 | 
						|
  pkgsRepository = pkgsRepositories.open-vsx;
 | 
						|
 | 
						|
  mcp-nixos = inputs.mcp-nixos.packages.${pkgs.stdenv.hostPlatform.system}.default;
 | 
						|
 | 
						|
  anyProfileHasMcpNixos = lib.any (
 | 
						|
    profile:
 | 
						|
      profile.extraExtensions.claudeDev.enable
 | 
						|
      && profile.extraExtensions.claudeDev.mcp.nixos.enable
 | 
						|
  ) (lib.attrValues config.programs.vscode.profiles);
 | 
						|
 | 
						|
  anyProfileHasMcpEslint = lib.any (
 | 
						|
    profile:
 | 
						|
      profile.extraExtensions.claudeDev.enable
 | 
						|
      && profile.extraExtensions.claudeDev.mcp.eslint.enable
 | 
						|
  ) (lib.attrValues config.programs.vscode.profiles);
 | 
						|
 | 
						|
  anyProfileHasMcpVitest = lib.any (
 | 
						|
    profile:
 | 
						|
      profile.extraExtensions.claudeDev.enable
 | 
						|
      && profile.extraExtensions.claudeDev.mcp.vitest.enable
 | 
						|
  ) (lib.attrValues config.programs.vscode.profiles);
 | 
						|
 | 
						|
  anyProfileHasMcpSleep = lib.any (
 | 
						|
    profile:
 | 
						|
      profile.extraExtensions.claudeDev.enable
 | 
						|
      && profile.extraExtensions.claudeDev.mcp.sleep.enable
 | 
						|
  ) (lib.attrValues config.programs.vscode.profiles);
 | 
						|
 | 
						|
  anyProfileHasMcp = anyProfileHasMcpNixos || anyProfileHasMcpEslint || anyProfileHasMcpVitest || anyProfileHasMcpSleep;
 | 
						|
 | 
						|
  getMcpTimeout = serverName:
 | 
						|
    lib.findFirst (timeout: timeout != null) null (map (
 | 
						|
      profile:
 | 
						|
        if profile.extraExtensions.claudeDev.enable && profile.extraExtensions.claudeDev.mcp.${serverName}.enable
 | 
						|
        then profile.extraExtensions.claudeDev.mcp.${serverName}.timeout
 | 
						|
        else null
 | 
						|
    ) (lib.attrValues config.programs.vscode.profiles));
 | 
						|
 | 
						|
  getMcpAutoApprove = serverName:
 | 
						|
    lib.foldl' (
 | 
						|
      acc: profile:
 | 
						|
        if profile.extraExtensions.claudeDev.enable && profile.extraExtensions.claudeDev.mcp.${serverName}.enable
 | 
						|
        then acc // profile.extraExtensions.claudeDev.mcp.${serverName}.autoApprove
 | 
						|
        else acc
 | 
						|
    ) {} (lib.attrValues config.programs.vscode.profiles);
 | 
						|
 | 
						|
  getMcpPackage = serverName:
 | 
						|
    lib.findFirst (package: package != null) null (map (
 | 
						|
      profile:
 | 
						|
        if profile.extraExtensions.claudeDev.enable && profile.extraExtensions.claudeDev.mcp.${serverName}.enable
 | 
						|
        then profile.extraExtensions.claudeDev.mcp.${serverName}.package
 | 
						|
        else null
 | 
						|
    ) (lib.attrValues config.programs.vscode.profiles));
 | 
						|
in {
 | 
						|
  options.programs.vscode.profiles = lib.mkOption {
 | 
						|
    type = lib.types.attrsOf (lib.types.submodule ({config, ...}: {
 | 
						|
      options = {
 | 
						|
        extraExtensions.claudeDev = {
 | 
						|
          enable = lib.mkEnableOption "should the claude-dev extension for vscode be enabled";
 | 
						|
          extension = lib.mkPackageOption pkgsRepository "claude-dev" {
 | 
						|
            default = ["saoudrizwan" "claude-dev"];
 | 
						|
          };
 | 
						|
 | 
						|
          mcp = {
 | 
						|
            nixos = {
 | 
						|
              enable = lib.mkEnableOption "enable NixOS MCP server for Claude Dev";
 | 
						|
              autoApprove = {
 | 
						|
                nixos_search = lib.mkEnableOption "should the nixos_search tool be auto approved for the nixos MCP server";
 | 
						|
                nixos_info = lib.mkEnableOption "should the nixos_info tool be auto approved for the nixos MCP server";
 | 
						|
                home_manager_search = lib.mkEnableOption "should the home_manager_search tool be auto approved for the nixos MCP server";
 | 
						|
                home_manager_info = lib.mkEnableOption "should the home_manager_info tool be auto approved for the nixos MCP server";
 | 
						|
                darwin_search = lib.mkEnableOption "should the darwin_search tool be auto approved for the nixos MCP server";
 | 
						|
                darwin_info = lib.mkEnableOption "should the darwin_info tool be auto approved for the nixos MCP server";
 | 
						|
                nixos_flakes_search = lib.mkEnableOption "should the nixos_flakes_search tool be auto approved for the nixos MCP server";
 | 
						|
              };
 | 
						|
            };
 | 
						|
            eslint = {
 | 
						|
              enable = lib.mkEnableOption "enable ESLint MCP server for Claude Dev";
 | 
						|
              package = lib.mkOption {
 | 
						|
                type = lib.types.str;
 | 
						|
                default = "@eslint/mcp@latest";
 | 
						|
                description = "NPM package to use for ESLint MCP server";
 | 
						|
              };
 | 
						|
              timeout = lib.mkOption {
 | 
						|
                type = lib.types.nullOr lib.types.int;
 | 
						|
                default = null;
 | 
						|
                description = "Timeout in seconds for ESLint MCP server operations";
 | 
						|
              };
 | 
						|
              autoApprove = {
 | 
						|
                lint-files = lib.mkEnableOption "Should the lint-files tool be auto approved for ESLint MCP server";
 | 
						|
              };
 | 
						|
            };
 | 
						|
            vitest = {
 | 
						|
              enable = lib.mkEnableOption "enable Vitest MCP server for Claude Dev";
 | 
						|
              package = lib.mkOption {
 | 
						|
                type = lib.types.str;
 | 
						|
                default = "@djankies/vitest-mcp";
 | 
						|
                description = "NPM package to use for Vitest MCP server";
 | 
						|
              };
 | 
						|
              timeout = lib.mkOption {
 | 
						|
                type = lib.types.nullOr lib.types.int;
 | 
						|
                default = null;
 | 
						|
                description = "Timeout in seconds for Vitest MCP server operations";
 | 
						|
              };
 | 
						|
              autoApprove = {
 | 
						|
                list_tests = lib.mkEnableOption "Should the list_tests tool be auto approved for Vitest MCP server";
 | 
						|
                run_tests = lib.mkEnableOption "Should the run_tests tool be auto approved for Vitest MCP server";
 | 
						|
                analyze_coverage = lib.mkEnableOption "Should the analyze_coverage tool be auto approved for Vitest MCP server";
 | 
						|
                set_project_root = lib.mkEnableOption "Should the set_project_root tool be auto approved for Vitest MCP server";
 | 
						|
              };
 | 
						|
            };
 | 
						|
            sleep = {
 | 
						|
              enable = lib.mkEnableOption "enable Sleep MCP server for Claude Dev";
 | 
						|
              package = lib.mkOption {
 | 
						|
                type = lib.types.str;
 | 
						|
                default = "sleep-mcp";
 | 
						|
                description = "NPM package to use for Sleep MCP server";
 | 
						|
              };
 | 
						|
              timeout = lib.mkOption {
 | 
						|
                type = lib.types.nullOr lib.types.int;
 | 
						|
                default = null;
 | 
						|
                description = "Timeout in seconds for Sleep MCP server operations";
 | 
						|
              };
 | 
						|
              autoApprove = {
 | 
						|
                sleep = lib.mkEnableOption "Should the sleep tool be auto approved for Sleep MCP server";
 | 
						|
              };
 | 
						|
            };
 | 
						|
          };
 | 
						|
        };
 | 
						|
      };
 | 
						|
      config = lib.mkIf config.extraExtensions.claudeDev.enable {
 | 
						|
        extensions = [
 | 
						|
          config.extraExtensions.claudeDev.extension
 | 
						|
        ];
 | 
						|
      };
 | 
						|
    }));
 | 
						|
  };
 | 
						|
 | 
						|
  config = lib.mkMerge [
 | 
						|
    (lib.mkIf anyProfileHasMcpNixos {
 | 
						|
      home.packages = [
 | 
						|
        mcp-nixos
 | 
						|
      ];
 | 
						|
    })
 | 
						|
 | 
						|
    (lib.mkIf anyProfileHasMcp {
 | 
						|
      home.file."${config.xdg.configHome}/VSCodium/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json" = {
 | 
						|
        text = builtins.toJSON {
 | 
						|
          mcpServers =
 | 
						|
            (lib.optionalAttrs anyProfileHasMcpNixos {
 | 
						|
              nixos = {
 | 
						|
                command = "${mcp-nixos}/bin/mcp-nixos";
 | 
						|
              };
 | 
						|
            })
 | 
						|
            // (lib.optionalAttrs anyProfileHasMcpEslint {
 | 
						|
              eslint =
 | 
						|
                {
 | 
						|
                  command = "${pkgs.nodejs}/bin/npx";
 | 
						|
                  args = ["-y" (getMcpPackage "eslint")];
 | 
						|
                }
 | 
						|
                // (lib.optionalAttrs ((getMcpTimeout "eslint") != null) {
 | 
						|
                  timeout = getMcpTimeout "eslint";
 | 
						|
                })
 | 
						|
                // (lib.optionalAttrs ((getMcpAutoApprove "eslint") != {}) {
 | 
						|
                  autoApprove = builtins.attrNames (lib.filterAttrs (_: v: v) (getMcpAutoApprove "eslint"));
 | 
						|
                });
 | 
						|
            })
 | 
						|
            // (lib.optionalAttrs anyProfileHasMcpVitest {
 | 
						|
              vitest =
 | 
						|
                {
 | 
						|
                  command = "${pkgs.nodejs}/bin/npx";
 | 
						|
                  args = ["-y" (getMcpPackage "vitest")];
 | 
						|
                }
 | 
						|
                // (lib.optionalAttrs ((getMcpTimeout "vitest") != null) {
 | 
						|
                  timeout = getMcpTimeout "vitest";
 | 
						|
                })
 | 
						|
                // (lib.optionalAttrs ((getMcpAutoApprove "vitest") != {}) {
 | 
						|
                  autoApprove = builtins.attrNames (lib.filterAttrs (_: v: v) (getMcpAutoApprove "vitest"));
 | 
						|
                });
 | 
						|
            })
 | 
						|
            // (lib.optionalAttrs anyProfileHasMcpSleep {
 | 
						|
              sleep-mcp =
 | 
						|
                {
 | 
						|
                  command = "${pkgs.nodejs}/bin/npx";
 | 
						|
                  args = ["-y" (getMcpPackage "sleep")];
 | 
						|
                }
 | 
						|
                // (lib.optionalAttrs ((getMcpTimeout "sleep") != null) {
 | 
						|
                  timeout = getMcpTimeout "sleep";
 | 
						|
                })
 | 
						|
                // (lib.optionalAttrs ((getMcpAutoApprove "sleep") != {}) {
 | 
						|
                  autoApprove = builtins.attrNames (lib.filterAttrs (_: v: v) (getMcpAutoApprove "sleep"));
 | 
						|
                });
 | 
						|
            });
 | 
						|
        };
 | 
						|
        force = true;
 | 
						|
      };
 | 
						|
    })
 | 
						|
  ];
 | 
						|
}
 |