mirror of
https://github.com/nix-community/home-manager.git
synced 2025-12-06 09:01:04 +01:00
claude-code: init module (#7685)
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
This commit is contained in:
parent
567312006a
commit
8b4ac14968
14 changed files with 589 additions and 0 deletions
17
modules/misc/news/2025/08/2025-08-15_15-51-02.nix
Normal file
17
modules/misc/news/2025/08/2025-08-15_15-51-02.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
time = "2025-08-15T20:51:02+00:00";
|
||||||
|
condition = true;
|
||||||
|
message = ''
|
||||||
|
A new module is available: 'programs.claude-code'.
|
||||||
|
|
||||||
|
Claude Code is Anthropic's official CLI for Claude, providing an
|
||||||
|
interactive command-line interface for AI-assisted development.
|
||||||
|
|
||||||
|
The module supports:
|
||||||
|
- Configuration through 'programs.claude-code.settings'
|
||||||
|
- Custom agents via 'programs.claude-code.agents'
|
||||||
|
- Custom commands via 'programs.claude-code.commands'
|
||||||
|
- MCP (Model Context Protocol) servers via 'programs.claude-code.mcpServers'
|
||||||
|
- Package installation control via 'programs.claude-code.package'
|
||||||
|
'';
|
||||||
|
}
|
||||||
261
modules/programs/claude-code.nix
Normal file
261
modules/programs/claude-code.nix
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.programs.claude-code;
|
||||||
|
jsonFormat = pkgs.formats.json { };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
meta.maintainers = [ lib.maintainers.khaneliman ];
|
||||||
|
|
||||||
|
options.programs.claude-code = {
|
||||||
|
enable = lib.mkEnableOption "Claude Code, Anthropic's official CLI";
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "claude-code" { nullable = true; };
|
||||||
|
|
||||||
|
finalPackage = lib.mkOption {
|
||||||
|
type = lib.types.package;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = "Resulting customized claude-code package.";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
inherit (jsonFormat) type;
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
theme = "dark";
|
||||||
|
permissions = {
|
||||||
|
allow = [
|
||||||
|
"Bash(git diff:*)"
|
||||||
|
"Edit"
|
||||||
|
];
|
||||||
|
ask = [ "Bash(git push:*)" ];
|
||||||
|
deny = [
|
||||||
|
"WebFetch"
|
||||||
|
"Bash(curl:*)"
|
||||||
|
"Read(./.env)"
|
||||||
|
"Read(./secrets/**)"
|
||||||
|
];
|
||||||
|
additionalDirectories = [ "../docs/" ];
|
||||||
|
defaultMode = "acceptEdits";
|
||||||
|
disableBypassPermissionsMode = "disable";
|
||||||
|
};
|
||||||
|
model = "claude-3-5-sonnet-20241022";
|
||||||
|
hooks = {
|
||||||
|
PreToolUse = [
|
||||||
|
{
|
||||||
|
matcher = "Bash";
|
||||||
|
hooks = [
|
||||||
|
{
|
||||||
|
type = "command";
|
||||||
|
command = "echo 'Running command: $CLAUDE_TOOL_INPUT'";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
PostToolUse = [
|
||||||
|
{
|
||||||
|
matcher = "Edit|MultiEdit|Write";
|
||||||
|
hooks = [
|
||||||
|
{
|
||||||
|
type = "command";
|
||||||
|
command = "nix fmt $(jq -r '.tool_input.file_path' <<< '$CLAUDE_TOOL_INPUT')";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
statusLine = {
|
||||||
|
type = "command";
|
||||||
|
command = "input=$(cat); echo \"[$(echo \"$input\" | jq -r '.model.display_name')] 📁 $(basename \"$(echo \"$input\" | jq -r '.workspace.current_dir')\")\"";
|
||||||
|
padding = 0;
|
||||||
|
};
|
||||||
|
includeCoAuthoredBy = false;
|
||||||
|
};
|
||||||
|
description = "JSON configuration for Claude Code settings.json";
|
||||||
|
};
|
||||||
|
|
||||||
|
agents = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.lines;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Custom agents for Claude Code.
|
||||||
|
The attribute name becomes the agent filename, and the value is the file content with frontmatter.
|
||||||
|
Agents are stored in .claude/agents/ directory.
|
||||||
|
'';
|
||||||
|
example = {
|
||||||
|
code-reviewer = ''
|
||||||
|
---
|
||||||
|
name: code-reviewer
|
||||||
|
description: Specialized code review agent
|
||||||
|
tools: Read, Edit, Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a senior software engineer specializing in code reviews.
|
||||||
|
Focus on code quality, security, and maintainability.
|
||||||
|
'';
|
||||||
|
documentation = ''
|
||||||
|
---
|
||||||
|
name: documentation
|
||||||
|
description: Documentation writing assistant
|
||||||
|
model: claude-3-5-sonnet-20241022
|
||||||
|
tools: Read, Write, Edit
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a technical writer who creates clear, comprehensive documentation.
|
||||||
|
Focus on user-friendly explanations and examples.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
commands = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.lines;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Custom commands for Claude Code.
|
||||||
|
The attribute name becomes the command filename, and the value is the file content.
|
||||||
|
Commands are stored in .claude/commands/ directory.
|
||||||
|
'';
|
||||||
|
example = {
|
||||||
|
changelog = ''
|
||||||
|
---
|
||||||
|
allowed-tools: Bash(git log:*), Bash(git diff:*)
|
||||||
|
argument-hint: [version] [change-type] [message]
|
||||||
|
description: Update CHANGELOG.md with new entry
|
||||||
|
---
|
||||||
|
Parse the version, change type, and message from the input
|
||||||
|
and update the CHANGELOG.md file accordingly.
|
||||||
|
'';
|
||||||
|
fix-issue = ''
|
||||||
|
---
|
||||||
|
allowed-tools: Bash(git status:*), Read
|
||||||
|
argument-hint: [issue-number]
|
||||||
|
description: Fix GitHub issue following coding standards
|
||||||
|
---
|
||||||
|
Fix issue #$ARGUMENTS following our coding standards and best practices.
|
||||||
|
'';
|
||||||
|
commit = ''
|
||||||
|
---
|
||||||
|
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
|
||||||
|
description: Create a git commit with proper message
|
||||||
|
---
|
||||||
|
## Context
|
||||||
|
|
||||||
|
- Current git status: !`git status`
|
||||||
|
- Current git diff: !`git diff HEAD`
|
||||||
|
- Recent commits: !`git log --oneline -5`
|
||||||
|
|
||||||
|
## Task
|
||||||
|
|
||||||
|
Based on the changes above, create a single atomic git commit with a descriptive message.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mcpServers = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf jsonFormat.type;
|
||||||
|
default = { };
|
||||||
|
description = "MCP (Model Context Protocol) servers configuration";
|
||||||
|
example = {
|
||||||
|
github = {
|
||||||
|
type = "http";
|
||||||
|
url = "https://api.githubcopilot.com/mcp/";
|
||||||
|
};
|
||||||
|
filesystem = {
|
||||||
|
type = "stdio";
|
||||||
|
command = "npx";
|
||||||
|
args = [
|
||||||
|
"-y"
|
||||||
|
"@modelcontextprotocol/server-filesystem"
|
||||||
|
"/tmp"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
database = {
|
||||||
|
type = "stdio";
|
||||||
|
command = "npx";
|
||||||
|
args = [
|
||||||
|
"-y"
|
||||||
|
"@bytebase/dbhub"
|
||||||
|
"--dsn"
|
||||||
|
"postgresql://user:pass@localhost:5432/db"
|
||||||
|
];
|
||||||
|
env = {
|
||||||
|
DATABASE_URL = "postgresql://user:pass@localhost:5432/db";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
customTransport = {
|
||||||
|
type = "websocket";
|
||||||
|
url = "wss://example.com/mcp";
|
||||||
|
customOption = "value";
|
||||||
|
timeout = 5000;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.mcpServers == { } || cfg.package != null;
|
||||||
|
message = "`programs.claude-code.package` cannot be null when `mcpServers` is configured";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.claude-code.finalPackage =
|
||||||
|
let
|
||||||
|
makeWrapperArgs = lib.flatten (
|
||||||
|
lib.filter (x: x != [ ]) [
|
||||||
|
(lib.optional (cfg.mcpServers != { }) [
|
||||||
|
"--add-flags"
|
||||||
|
"--mcp-config ${jsonFormat.generate "claude-code-mcp-config.json" { inherit (cfg) mcpServers; }}"
|
||||||
|
])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
hasWrapperArgs = makeWrapperArgs != [ ];
|
||||||
|
in
|
||||||
|
if hasWrapperArgs then
|
||||||
|
pkgs.symlinkJoin {
|
||||||
|
name = "claude-code";
|
||||||
|
paths = [ cfg.package ];
|
||||||
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
postBuild = ''
|
||||||
|
wrapProgram $out/bin/claude ${lib.escapeShellArgs makeWrapperArgs}
|
||||||
|
'';
|
||||||
|
inherit (cfg.package) meta;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cfg.package;
|
||||||
|
|
||||||
|
home = {
|
||||||
|
packages = lib.mkIf (cfg.package != null) [ cfg.finalPackage ];
|
||||||
|
|
||||||
|
file = {
|
||||||
|
".claude/settings.json" = lib.mkIf (cfg.settings != { }) {
|
||||||
|
source = jsonFormat.generate "claude-code-settings.json" (
|
||||||
|
cfg.settings
|
||||||
|
// {
|
||||||
|
"$schema" = "https://json.schemastore.org/claude-code-settings.json";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// lib.mapAttrs' (
|
||||||
|
name: content:
|
||||||
|
lib.nameValuePair ".claude/agents/${name}.md" {
|
||||||
|
text = content;
|
||||||
|
}
|
||||||
|
) cfg.agents
|
||||||
|
// lib.mapAttrs' (
|
||||||
|
name: content:
|
||||||
|
lib.nameValuePair ".claude/commands/${name}.md" {
|
||||||
|
text = content;
|
||||||
|
}
|
||||||
|
) cfg.commands;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,7 @@ let
|
||||||
"btop"
|
"btop"
|
||||||
"carapace"
|
"carapace"
|
||||||
"cava"
|
"cava"
|
||||||
|
"claude-code"
|
||||||
"clock-rs"
|
"clock-rs"
|
||||||
"cmus"
|
"cmus"
|
||||||
"codex"
|
"codex"
|
||||||
|
|
|
||||||
22
tests/modules/programs/claude-code/assertion.nix
Normal file
22
tests/modules/programs/claude-code/assertion.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
programs.claude-code = {
|
||||||
|
enable = true;
|
||||||
|
package = null;
|
||||||
|
|
||||||
|
mcpServers = {
|
||||||
|
filesystem = {
|
||||||
|
type = "stdio";
|
||||||
|
command = "npx";
|
||||||
|
args = [
|
||||||
|
"-y"
|
||||||
|
"@modelcontextprotocol/server-filesystem"
|
||||||
|
"/tmp"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test.asserts.assertions.expected = [
|
||||||
|
"`programs.claude-code.package` cannot be null when `mcpServers` is configured"
|
||||||
|
];
|
||||||
|
}
|
||||||
7
tests/modules/programs/claude-code/basic.nix
Normal file
7
tests/modules/programs/claude-code/basic.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
programs.claude-code.enable = true;
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertPathNotExists home-files/.claude
|
||||||
|
'';
|
||||||
|
}
|
||||||
6
tests/modules/programs/claude-code/default.nix
Normal file
6
tests/modules/programs/claude-code/default.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
claude-code-basic = ./basic.nix;
|
||||||
|
claude-code-full-config = ./full-config.nix;
|
||||||
|
claude-code-mcp = ./mcp.nix;
|
||||||
|
claude-code-assertion = ./assertion.nix;
|
||||||
|
}
|
||||||
7
tests/modules/programs/claude-code/expected-changelog
Normal file
7
tests/modules/programs/claude-code/expected-changelog
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
allowed-tools: Bash(git log:*), Bash(git diff:*)
|
||||||
|
argument-hint: [version] [change-type] [message]
|
||||||
|
description: Update CHANGELOG.md with new entry
|
||||||
|
---
|
||||||
|
Parse the version, change type, and message from the input
|
||||||
|
and update the CHANGELOG.md file accordingly.
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: code-reviewer
|
||||||
|
description: Specialized code review agent
|
||||||
|
tools: Read, Edit, Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a senior software engineer specializing in code reviews.
|
||||||
|
Focus on code quality, security, and maintainability.
|
||||||
13
tests/modules/programs/claude-code/expected-commit
Normal file
13
tests/modules/programs/claude-code/expected-commit
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
|
||||||
|
description: Create a git commit with proper message
|
||||||
|
---
|
||||||
|
## Context
|
||||||
|
|
||||||
|
- Current git status: !`git status`
|
||||||
|
- Current git diff: !`git diff HEAD`
|
||||||
|
- Recent commits: !`git log --oneline -5`
|
||||||
|
|
||||||
|
## Task
|
||||||
|
|
||||||
|
Based on the changes above, create a single atomic git commit with a descriptive message.
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
name: documentation
|
||||||
|
description: Documentation writing assistant
|
||||||
|
model: claude-3-5-sonnet-20241022
|
||||||
|
tools: Read, Write, Edit
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a technical writer who creates clear, comprehensive documentation.
|
||||||
|
Focus on user-friendly explanations and examples.
|
||||||
2
tests/modules/programs/claude-code/expected-mcp-wrapper
Normal file
2
tests/modules/programs/claude-code/expected-mcp-wrapper
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
#! /nix/store/00000000000000000000000000000000-bash/bin/bash -e
|
||||||
|
exec -a "$0" "/nix/store/00000000000000000000000000000000-claude-code/bin/.claude-wrapped" --mcp-config /nix/store/00000000000000000000000000000000-claude-code-mcp-config.json "$@"
|
||||||
55
tests/modules/programs/claude-code/expected-settings.json
Normal file
55
tests/modules/programs/claude-code/expected-settings.json
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||||
|
"hooks": {
|
||||||
|
"PreToolUse": [
|
||||||
|
{
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"command": "echo 'Running bash command: $CLAUDE_TOOL_INPUT'",
|
||||||
|
"type": "command"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matcher": "Bash"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"UserPromptSubmit": [
|
||||||
|
{
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"command": "echo 'User submitted: $CLAUDE_USER_PROMPT'",
|
||||||
|
"type": "command"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matcher": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"includeCoAuthoredBy": false,
|
||||||
|
"model": "claude-3-5-sonnet-20241022",
|
||||||
|
"permissions": {
|
||||||
|
"additionalDirectories": [
|
||||||
|
"../docs/"
|
||||||
|
],
|
||||||
|
"allow": [
|
||||||
|
"Bash(git diff:*)",
|
||||||
|
"Edit"
|
||||||
|
],
|
||||||
|
"ask": [
|
||||||
|
"Bash(git push:*)"
|
||||||
|
],
|
||||||
|
"defaultMode": "acceptEdits",
|
||||||
|
"deny": [
|
||||||
|
"WebFetch",
|
||||||
|
"Bash(curl:*)",
|
||||||
|
"Read(./.env)",
|
||||||
|
"Read(./secrets/**)"
|
||||||
|
],
|
||||||
|
"disableBypassPermissionsMode": "disable"
|
||||||
|
},
|
||||||
|
"statusLine": {
|
||||||
|
"command": "input=$(cat); echo \"[$(echo \"$input\" | jq -r '.model.display_name')] 📁 $(basename \"$(echo \"$input\" | jq -r '.workspace.current_dir')\")\"",
|
||||||
|
"padding": 0,
|
||||||
|
"type": "command"
|
||||||
|
},
|
||||||
|
"theme": "dark"
|
||||||
|
}
|
||||||
126
tests/modules/programs/claude-code/full-config.nix
Normal file
126
tests/modules/programs/claude-code/full-config.nix
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
{
|
||||||
|
programs.claude-code = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
theme = "dark";
|
||||||
|
permissions = {
|
||||||
|
allow = [
|
||||||
|
"Bash(git diff:*)"
|
||||||
|
"Edit"
|
||||||
|
];
|
||||||
|
ask = [ "Bash(git push:*)" ];
|
||||||
|
deny = [
|
||||||
|
"WebFetch"
|
||||||
|
"Bash(curl:*)"
|
||||||
|
"Read(./.env)"
|
||||||
|
"Read(./secrets/**)"
|
||||||
|
];
|
||||||
|
additionalDirectories = [ "../docs/" ];
|
||||||
|
defaultMode = "acceptEdits";
|
||||||
|
disableBypassPermissionsMode = "disable";
|
||||||
|
};
|
||||||
|
model = "claude-3-5-sonnet-20241022";
|
||||||
|
hooks = {
|
||||||
|
UserPromptSubmit = [
|
||||||
|
{
|
||||||
|
matcher = "";
|
||||||
|
hooks = [
|
||||||
|
{
|
||||||
|
type = "command";
|
||||||
|
command = "echo 'User submitted: $CLAUDE_USER_PROMPT'";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
PreToolUse = [
|
||||||
|
{
|
||||||
|
matcher = "Bash";
|
||||||
|
hooks = [
|
||||||
|
{
|
||||||
|
type = "command";
|
||||||
|
command = "echo 'Running bash command: $CLAUDE_TOOL_INPUT'";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
statusLine = {
|
||||||
|
type = "command";
|
||||||
|
command = "input=$(cat); echo \"[$(echo \"$input\" | jq -r '.model.display_name')] 📁 $(basename \"$(echo \"$input\" | jq -r '.workspace.current_dir')\")\"";
|
||||||
|
padding = 0;
|
||||||
|
};
|
||||||
|
includeCoAuthoredBy = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
commands = {
|
||||||
|
changelog = ''
|
||||||
|
---
|
||||||
|
allowed-tools: Bash(git log:*), Bash(git diff:*)
|
||||||
|
argument-hint: [version] [change-type] [message]
|
||||||
|
description: Update CHANGELOG.md with new entry
|
||||||
|
---
|
||||||
|
Parse the version, change type, and message from the input
|
||||||
|
and update the CHANGELOG.md file accordingly.
|
||||||
|
'';
|
||||||
|
commit = ''
|
||||||
|
---
|
||||||
|
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
|
||||||
|
description: Create a git commit with proper message
|
||||||
|
---
|
||||||
|
## Context
|
||||||
|
|
||||||
|
- Current git status: !`git status`
|
||||||
|
- Current git diff: !`git diff HEAD`
|
||||||
|
- Recent commits: !`git log --oneline -5`
|
||||||
|
|
||||||
|
## Task
|
||||||
|
|
||||||
|
Based on the changes above, create a single atomic git commit with a descriptive message.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
agents = {
|
||||||
|
code-reviewer = ''
|
||||||
|
---
|
||||||
|
name: code-reviewer
|
||||||
|
description: Specialized code review agent
|
||||||
|
tools: Read, Edit, Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a senior software engineer specializing in code reviews.
|
||||||
|
Focus on code quality, security, and maintainability.
|
||||||
|
'';
|
||||||
|
|
||||||
|
documentation = ''
|
||||||
|
---
|
||||||
|
name: documentation
|
||||||
|
description: Documentation writing assistant
|
||||||
|
model: claude-3-5-sonnet-20241022
|
||||||
|
tools: Read, Write, Edit
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a technical writer who creates clear, comprehensive documentation.
|
||||||
|
Focus on user-friendly explanations and examples.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileExists home-files/.claude/settings.json
|
||||||
|
assertFileContent home-files/.claude/settings.json ${./expected-settings.json}
|
||||||
|
|
||||||
|
assertFileExists home-files/.claude/agents/code-reviewer.md
|
||||||
|
assertFileContent home-files/.claude/agents/code-reviewer.md ${./expected-code-reviewer.md}
|
||||||
|
|
||||||
|
assertFileExists home-files/.claude/agents/documentation.md
|
||||||
|
assertFileContent home-files/.claude/agents/documentation.md ${./expected-documentation.md}
|
||||||
|
|
||||||
|
|
||||||
|
assertFileExists home-files/.claude/commands/changelog.md
|
||||||
|
assertFileContent home-files/.claude/commands/changelog.md ${./expected-changelog}
|
||||||
|
|
||||||
|
assertFileExists home-files/.claude/commands/commit.md
|
||||||
|
assertFileContent home-files/.claude/commands/commit.md ${./expected-commit}
|
||||||
|
'';
|
||||||
|
}
|
||||||
55
tests/modules/programs/claude-code/mcp.nix
Normal file
55
tests/modules/programs/claude-code/mcp.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.claude-code = {
|
||||||
|
package = config.lib.test.mkStubPackage {
|
||||||
|
name = "claude-code";
|
||||||
|
buildScript = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
touch $out/bin/claude
|
||||||
|
chmod 755 $out/bin/claude
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
mcpServers = {
|
||||||
|
github = {
|
||||||
|
type = "http";
|
||||||
|
url = "https://api.githubcopilot.com/mcp/";
|
||||||
|
};
|
||||||
|
filesystem = {
|
||||||
|
type = "stdio";
|
||||||
|
command = "npx";
|
||||||
|
args = [
|
||||||
|
"-y"
|
||||||
|
"@modelcontextprotocol/server-filesystem"
|
||||||
|
"/tmp"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
database = {
|
||||||
|
type = "stdio";
|
||||||
|
command = "npx";
|
||||||
|
args = [
|
||||||
|
"-y"
|
||||||
|
"@bytebase/dbhub"
|
||||||
|
"--dsn"
|
||||||
|
"postgresql://user:pass@localhost:5432/db"
|
||||||
|
];
|
||||||
|
env = {
|
||||||
|
DATABASE_URL = "postgresql://user:pass@localhost:5432/db";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
customTransport = {
|
||||||
|
type = "websocket";
|
||||||
|
url = "wss://example.com/mcp";
|
||||||
|
customOption = "value";
|
||||||
|
timeout = 5000;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
normalizedWrapper=$(normalizeStorePaths home-path/bin/claude)
|
||||||
|
assertFileContent $normalizedWrapper ${./expected-mcp-wrapper}
|
||||||
|
'';
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue