diff --git a/configurations/home-manager/leyla/packages/vscode/default.nix b/configurations/home-manager/leyla/packages/vscode/default.nix index a651265..583f440 100644 --- a/configurations/home-manager/leyla/packages/vscode/default.nix +++ b/configurations/home-manager/leyla/packages/vscode/default.nix @@ -72,9 +72,27 @@ in { enable = true; mcp = { nixos.enable = true; - eslint.enable = true; - vitest.enable = true; - sleep.enable = true; + eslint = { + enable = true; + autoApprove = { + lint-files = true; + }; + }; + vitest = { + enable = true; + autoApprove = { + list_tests = true; + run_tests = true; + analyze_coverage = true; + }; + }; + sleep = { + enable = true; + timeout = 18000; # 5 hours to match claude codes timeout + autoApprove = { + sleep = true; + }; + }; }; }; diff --git a/modules/home-manager-modules/programs/vscode/claudeDev.nix b/modules/home-manager-modules/programs/vscode/claudeDev.nix index 9c067e8..0e34f97 100644 --- a/modules/home-manager-modules/programs/vscode/claudeDev.nix +++ b/modules/home-manager-modules/programs/vscode/claudeDev.nix @@ -35,6 +35,30 @@ ) (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, ...}: { @@ -51,12 +75,53 @@ in { }; 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"; + }; }; 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"; + }; }; }; }; @@ -86,22 +151,43 @@ in { }; }) // (lib.optionalAttrs anyProfileHasMcpEslint { - eslint = { - command = "${pkgs.nodejs}/bin/npx"; - args = ["-y" "@eslint/mcp@latest"]; - }; + 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" "@djankies/vitest-mcp"]; - }; + 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" "sleep-mcp"]; - }; + 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;