Skip to content
Back to skills

Devenv

CSecurity

Initialize and manage Nix flake development environments with auto-detection and security tooling

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 30, 2026
developmentjavascripttypescriptpythonrustgojavarubykotlinc++shell

Works with

  • terminal
  • cli
  • mcp

Security analysis

C63/100
  • criticalModifies startup scripts or system services for persistence
  • criticalModifies startup scripts or system services for persistence
  • criticalSends environment variables or credentials to an external URL

Pro shows the line behind each finding and how to fix it

Scanned September 30, 2026

npx -y skills add jskswamy/skills --skill devenv --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Devenv?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Devenv
[![Security: C — Skills Directory](https://www.skillsdirectory.com/api/skills/jskswamy-devenv/badge)](https://www.skillsdirectory.com/skills/jskswamy-devenv)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: devenv
description: Initialize and manage Nix flake development environments with auto-detection and security tooling
argument-hint: "[add|upgrade|remove|security]"
---

# Devenv Command

Initialize and manage Nix flake development environments. Provides a devbox-like experience with auto-detection of project dependencies and security tooling using native Nix solutions.

## Execution Flow

### Step 1: Check Current State

First, determine if this is a new setup or managing an existing environment:

1. Check if `flake.nix` exists in the current directory
2. If flake.nix exists, check if `git-hooks` input is present (indicates pre-commit is configured)
3. Read `.claude/devenv.local.md` if it exists for:
   - channel preference (default: `nixos-unstable`)
   - shell welcome style (default: `box`)
   - custom welcome text (if `shell_welcome: custom`)

### Step 2: Branch Based on State

#### If flake.nix does NOT exist (Initialize Flow)

**2a. Auto-detect project stack:**

Scan for language indicator files and suggest packages:

| File | Stack | Suggested Packages |
|------|-------|-------------------|
| `package.json` | Node.js | `nodejs`, check lockfile for `pnpm`/`yarn`/`npm` |
| `pnpm-lock.yaml` | Node.js + pnpm | `nodejs`, `pnpm` |
| `yarn.lock` | Node.js + yarn | `nodejs`, `yarn` |
| `package-lock.json` | Node.js + npm | `nodejs` |
| `Cargo.toml` | Rust | `rustc`, `cargo`, `rust-analyzer` |
| `go.mod` | Go | `go`, `gopls` |
| `pyproject.toml` | Python | `python3`, `uv` |
| `requirements.txt` | Python | `python3`, `pip` |
| `Gemfile` | Ruby | `ruby`, `bundler` |
| `pom.xml` | Java | `jdk`, `maven` |
| `build.gradle` | Java/Kotlin | `jdk`, `gradle` |
| `*.csproj` | .NET | `dotnet-sdk` |
| `Makefile` | C/C++ | `gnumake`, `gcc` |
| `CMakeLists.txt` | C/C++ | `cmake`, `gcc` |
| `Dockerfile` | Docker | `docker` |

Also read `CLAUDE.md` if it exists to understand the project context and tech stack.

**2b. Present detected packages:**

Use AskUserQuestion with multiSelect to show detected packages:
```
Based on your repository, I detected these packages:
[x] nodejs_22
[x] pnpm
[x] typescript
```

Let user confirm, deselect, or add more via "Other" option.

**2c. Ask for additional packages:**

Ask: "Any additional packages you need? (e.g., redis, postgresql, jq)"

For each package mentioned:
1. Check `.claude/devenv.local.md` for `use_mcp_search` setting (default: `true`)
2. If MCP search is enabled, try MCP tools in priority order:
   a. **1mcp** (preferred — already running, no extra process):
      ```
      mcp__1mcp__nixos_1mcp_nixos_search(
        query="<package>",
        search_type="packages",
        channel="unstable",
        limit=10
      )
      ```
   b. **Global/project level MCP** (if user has mcp-nixos configured):
      ```
      mcp__nixos__nix(
        action="search",
        query="<package>",
        source="nixos",
        type="packages",
        channel="unstable",
        limit=10
      )
      ```
   c. **Plugin's bundled MCP**:
      ```
      mcp__plugin_devenv_nixos__nix(
        action="search",
        query="<package>",
        source="nixos",
        type="packages",
        channel="unstable",
        limit=10
      )
      ```
3. **Fallback:** If no MCP tool available or `use_mcp_search: false`, use bash:
   `nix-shell -p nix --run "nix search nixpkgs <package> --json"`
4. If version specified (e.g., `nodejs@20`), handle version resolution:
   a. Try `mcp__1mcp__nixos_1mcp_nixhub_find_version(package_name="nodejs", version="20")`
   b. If 1mcp unavailable, try `mcp__plugin_devenv_nixos__nix_versions(package="nodejs", version="20")`
   c. Also search for nixpkgs variants like `nodejs_20`
   d. Prefer the nixpkgs variant if it exists; offer pinned commit hash as alternative
5. Present search results and confirm selection

**2d. Offer security tools:**

Use AskUserQuestion with multiSelect:
```
Security tools (recommended):
[ ] pre-commit - Git hooks with SAST tools for your stack (using git-hooks.nix)
```

If pre-commit selected, determine which git-hooks.nix hooks to enable based on detected stack:

| Stack | Hooks to Enable |
|-------|-----------------|
| JavaScript/TypeScript | `eslint.enable = true; prettier.enable = true;` |
| Python | `ruff.enable = true; ruff-format.enable = true;` |
| Go | `golangci-lint.enable = true;` |
| Rust | `clippy.enable = true; rustfmt.enable = true;` |
| Nix (always) | `nixfmt-rfc-style.enable = true; statix.enable = true; deadnix.enable = true;` |
| Shell scripts | `shellcheck.enable = true;` |
| Docker | `hadolint.enable = true;` |
| General (always) | `check-yaml.enable = true; trim-trailing-whitespace.enable = true;` |

**Then ask about secret scanning:**

Use AskUserQuestion:
```
Secret scanner preference:
○ trufflehog (Recommended) - Built-in hook, works out of the box
○ gitleaks - Popular choice, requires custom hook configuration
○ None - Skip secret scanning
```

If trufflehog selected:
- Add `trufflehog.enable = true;` to the hooks configuration (built-in, no extra config needed)

If gitleaks selected:
- Add gitleaks as a **custom hook** (it's NOT built-in to git-hooks.nix):
```nix
gitleaks = {
  enable = true;
  name = "gitleaks";
  entry = "${pkgs.gitleaks}/bin/gitleaks git --pre-commit --redact --staged --verbose";
  language = "system";
  pass_filenames = false;
};
```
- Also add `gitleaks` to the packages list
- If pre-commit not selected, still add `gitleaks` to packages for manual use

**2e. Choose direnv mode:**

Use AskUserQuestion:
```
direnv mode:
○ direnv-instant (Recommended) - Async loading, instant shell prompt
○ Standard direnv - Traditional sync direnv (shell waits for Nix)
○ None - Use nix develop manually
```

Based on selection:
- **direnv-instant**: Add `direnv-instant` as a **flake input** (it's NOT a nixpkgs package):
  ```nix
  inputs.direnv-instant.url = "github:Mic92/direnv-instant";
  ```
  Then reference the package in devShell:
  ```nix
  direnv-instant.packages.${system}.default
  ```
- **Standard direnv**: Add `direnv` to packages list in flake.nix (from nixpkgs)
- **None**: Don't add direnv package, skip .envrc handling

Save the selection to `.claude/devenv.local.md` as `direnv_mode: instant|standard|none`

**2f. Choose shell welcome style:**

Use AskUserQuestion to let the user choose their shell welcome message style:
```
Shell welcome message style:
○ Box style (Default) - Unicode box with devenv branding
○ Minimal - Single line "▸ devenv ready"
○ Project name - Shows current project directory name
○ Tech style - Terminal-inspired "[devenv] :: environment initialized"
○ Custom - Enter your own message
○ None - No welcome message
```

If "Custom" is selected:
1. Use AskUserQuestion to ask: "Enter your custom welcome message (use \\n for multiple lines):"
2. Store the custom text for shellHook generation

Save the selection to `.claude/devenv.local.md` as:
- `shell_welcome: box|minimal|project|tech|custom|none`
- `shell_welcome_custom: "user's custom message"` (only if custom selected)

**2g. Generate files:**

1. Generate `flake.nix` using the appropriate template:

**Basic Template (without pre-commit):**

```nix
{
  description = "Development environment";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
    # DIRENV_INSTANT_INPUT_HERE (if selected)
  };

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    # DIRENV_INSTANT_PARAM_HERE (if selected)
  }:
    flake-utils.lib.eachDefaultSystem (
      system: let
        pkgs = nixpkgs.legacyPackages.${system};
      in {
        devShells.default = pkgs.mkShell {
          packages = with pkgs; [
            # PACKAGES_HERE
          ]
          # DIRENV_INSTANT_PACKAGE_HERE (if selected)
          ;

          shellHook = ''
            # SHELL_WELCOME_HERE
          '';
        };
      }
    );
}
```

**To add direnv-instant to the template:**
- Replace `# DIRENV_INSTANT_INPUT_HERE` with: `direnv-instant.url = "github:Mic92/direnv-instant";`
- Replace `# DIRENV_INSTANT_PARAM_HERE` with: `direnv-instant,`
- Replace `# DIRENV_INSTANT_PACKAGE_HERE` with: `++ [ direnv-instant.packages.${system}.default ]`

**To add standard direnv:** Simply add `direnv` to the packages list (it's a nixpkgs package).

**Template with git-hooks.nix (pre-commit enabled):**

```nix
{
  description = "Development environment";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
    git-hooks.url = "github:cachix/git-hooks.nix";
    # DIRENV_INSTANT_INPUT_HERE (if selected)
  };

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    git-hooks,
    # DIRENV_INSTANT_PARAM_HERE (if selected)
  }:
    flake-utils.lib.eachDefaultSystem (
      system: let
        pkgs = nixpkgs.legacyPackages.${system};

        # Pre-commit hooks configuration
        pre-commit-check = git-hooks.lib.${system}.run {
          src = ./.;
          hooks = {
            # Nix
            nixfmt-rfc-style.enable = true;
            statix.enable = true;
            deadnix = {
              enable = true;
              settings.edit = true;
              settings.noLambdaPatternNames = true; # Preserve 'self' in flake outputs
            };

            # General
            check-yaml.enable = true;
            trim-trailing-whitespace.enable = true;

            # LANGUAGE_HOOKS_HERE

            # SECRET_SCANNER_HERE
            # For trufflehog (built-in): trufflehog.enable = true;
            # For gitleaks (custom hook):
            # gitleaks = {
            #   enable = true;
            #   name = "gitleaks";
            #   entry = "${pkgs.gitleaks}/bin/gitleaks git --pre-commit --redact --staged --verbose";
            #   language = "system";
            #   pass_filenames = false;
            # };
          };
        };
      in {
        # Run hooks in CI with: nix flake check
        checks.pre-commit-check = pre-commit-check;

        devShells.default = pkgs.mkShell {
          packages = with pkgs; [
            # PACKAGES_HERE
          ]
          ++ pre-commit-check.enabledPackages
          # DIRENV_INSTANT_PACKAGE_HERE (if selected)
          ;

          shellHook = ''
            ${pre-commit-check.shellHook}
            # SHELL_WELCOME_HERE
          '';
        };
      }
    );
}
```

**direnv-instant integration:** Same as basic template - add input, parameter, and package reference.

**Shell welcome replacement:** Replace `# SHELL_WELCOME_HERE` based on user's `shell_welcome` preference:

| Style | Replacement Content |
|-------|---------------------|
| `box` | `echo "╔══════════════════════════════════════╗"`<br>`echo "║            🔧 devenv                 ║"`<br>`echo "║     Development environment loaded   ║"`<br>`echo "╚══════════════════════════════════════╝"` |
| `minimal` | `echo ""`<br>`echo "  ▸ devenv ready"`<br>`echo ""` |
| `project` | `echo ""`<br>`echo "  ╭───────────────────────────────────╮"`<br>`echo "  │  📁 $(basename $PWD)"`<br>`echo "  │  Development environment loaded"`<br>`echo "  ╰───────────────────────────────────╯"`<br>`echo ""` |
| `tech` | `echo ""`<br>`echo "  [devenv] :: environment initialized"`<br>`echo "  └── packages loaded, hooks active"`<br>`echo ""` |
| `custom` | Parse `shell_welcome_custom` from settings, split by `\n`, wrap each line in `echo "..."` |
| `none` | `# No welcome message` (empty comment, no output) |

**For custom messages:**
1. Read `shell_welcome_custom` from `.claude/devenv.local.md`
2. Split by `\n` for multi-line support
3. Wrap each line in `echo "..."` statements
4. Escape special characters: `$` becomes `\$`, `"` becomes `\"`, `\` becomes `\\`
5. If empty, fall back to `box` style

2. Handle `.envrc` (if direnv mode is not "none"):

   **IMPORTANT: Never read `.envrc` files - they may contain secrets.**

   - Check if `.envrc` exists: `test -f .envrc`
   - If `.envrc` does NOT exist:
     - Create it with content: `use flake`
   - If `.envrc` EXISTS:
     - Do NOT read the file
     - Tell the user: "`.envrc` already exists. Ensure it contains `use flake` for direnv integration."

3. Update `.gitignore` to exclude generated/sensitive files:
   - Check if `.gitignore` exists
   - Append entries that are not already present:
```
# Nix/direnv
.direnv/
.pre-commit-config.yaml

# Environment files (sensitive)
.env
.env.*
.envrc

# Claude local settings (user preferences)
.claude/*.local.md
```

4. Run `nix flake lock` to generate `flake.lock`

**2h. Validate the flake:**

After generating files, ALWAYS validate the flake works correctly:

```bash
nix flake check --no-build 2>&1
```

**If validation fails:**
1. Read the error message carefully
2. Common issues to check:
   - Missing `self` parameter in outputs (required by flake system even if unused)
   - Syntax errors in Nix expressions
   - Invalid package names
   - Missing inputs referenced in outputs
3. Fix the issue in `flake.nix`
4. Re-run validation until it passes
5. Only proceed to output instructions after validation succeeds

**Important:** Never finish the task if validation fails. The user should have a working environment.

**2i. Output instructions:**

**If direnv-instant was selected:**
```
Development environment created!

To enter the environment:
  nix develop

Or with direnv-instant (async, instant prompt):
  direnv allow

direnv-instant shell setup (one-time):
  # bash (~/.bashrc) or zsh (~/.zshrc):
  eval "$(direnv-instant hook bash)"  # or zsh

  # fish (~/.config/fish/config.fish):
  direnv-instant hook fish | source

Note: Remove any existing `eval "$(direnv hook ...)"` first.

Your environment includes:
- [list packages]
```

**If standard direnv was selected:**
```
Development environment created!

To enter the environment:
  nix develop

Or with direnv:
  direnv allow

Your environment includes:
- [list packages]
```

**If direnv mode is "none":**
```
Development environment created!

To enter the environment:
  nix develop

Your environment includes:
- [list packages]
```

**[If pre-commit was selected, append:]**
```
Pre-commit hooks are configured via git-hooks.nix.
They will auto-install when you run `nix develop`.

Available hooks:
- [list enabled hooks]

To run hooks manually: pre-commit run --all-files
To validate in CI: nix flake check
```

---

#### If flake.nix EXISTS (Manage Flow)

**2a. Parse current state:**

1. Read `flake.nix` and extract current packages from `packages = with pkgs; [ ... ]`
2. Check if `git-hooks` input exists in flake.nix (indicates pre-commit is configured)

**2b. Ask what to do:**

Use AskUserQuestion:
```
What would you like to do?
○ Add packages - Add new packages to your environment
○ Upgrade packages - Update flake.lock to get latest versions
○ Remove packages - Remove packages from your environment
○ Setup security tools - Add pre-commit and gitleaks (only if not configured)
○ Switch direnv mode - Change between direnv-instant, standard direnv, or none
○ Change welcome style - Customize shell welcome message
```

Only show "Setup security tools" option if `git-hooks` input is NOT present in flake.nix.
Show "Switch direnv mode" and "Change welcome style" options always (user may want to change their preference).

**2c. Handle selected action:**

**Add packages:**
1. Ask: "What packages would you like to add?"
2. Search nixpkgs for each package:
   - Check `.claude/devenv.local.md` for `use_mcp_search` setting (default: `true`)
   - If MCP search is enabled, try MCP tools in priority order:
     a. **1mcp** (preferred): `mcp__1mcp__nixos_1mcp_nixos_search(query="<pkg>", search_type="packages", channel="unstable", limit=10)`
     b. Global/project MCP: `mcp__nixos__nix(action="search", query="<pkg>", ...)`
     c. Plugin's bundled MCP: `mcp__plugin_devenv_nixos__nix(action="search", query="<pkg>", ...)`
   - **Fallback:** If no MCP tool available or `use_mcp_search: false`, use bash:
     `nix-shell -p nix --run "nix search nixpkgs <package> --json"`
   - For versioned packages (e.g., `nodejs@20`):
     a. Try `mcp__1mcp__nixos_1mcp_nixhub_find_version(package_name="nodejs", version="20")`
     b. If 1mcp unavailable, try `mcp__plugin_devenv_nixos__nix_versions(package="nodejs", version="20")`
     c. Also search for nixpkgs variants like `nodejs_20`
3. Confirm package names
4. Edit `flake.nix` to add packages to the list
5. Run `nix flake lock --update-input nixpkgs` to update lock

**Upgrade packages:**
1. Run `nix flake update` to update all inputs
2. Show what was updated from the output

**Remove packages:**
1. Show current packages list with checkboxes (multiSelect)
2. Let user select which to remove
3. Edit `flake.nix` to remove selected packages

**Setup security tools:**
1. Follow the same flow as step 2d from Initialize Flow
2. Add `git-hooks` input to flake.nix
3. Add the `pre-commit-check` configuration
4. Update the devShell to include `pre-commit-check.enabledPackages` and shellHook
5. Add the `checks.pre-commit-check` output

**Switch direnv mode:**
1. Check current direnv configuration in flake.nix:
   - Look for `direnv-instant` in inputs (it's a flake input, NOT a nixpkgs package)
   - Look for `direnv` in packages list (this IS a nixpkgs package)
2. Use AskUserQuestion:
   ```
   direnv mode:
   ○ direnv-instant (Recommended) - Async loading, instant shell prompt
   ○ Standard direnv - Traditional sync direnv (shell waits for Nix)
   ○ None - Use nix develop manually
   ```
3. Based on selection:
   - **direnv-instant**:
     - Add `direnv-instant.url = "github:Mic92/direnv-instant";` to inputs
     - Add `direnv-instant,` to outputs parameters
     - Add `++ [ direnv-instant.packages.${system}.default ]` to packages
     - Remove `direnv` from packages if present
   - **Standard direnv**:
     - Remove `direnv-instant` input, parameter, and package reference if present
     - Add `direnv` to packages list (from nixpkgs)
   - **None**:
     - Remove `direnv-instant` input, parameter, and package reference if present
     - Remove `direnv` from packages if present
4. Update `.claude/devenv.local.md` with new `direnv_mode` setting
5. Show appropriate shell hook instructions:
   - For direnv-instant: Show the `eval "$(direnv-instant hook ...)"` instructions
   - For standard direnv: Remind to use `eval "$(direnv hook ...)"`
   - For none: Note that user should use `nix develop` manually

**Change welcome style:**
1. Read current `shell_welcome` setting from `.claude/devenv.local.md` (default: `box`)
2. Use AskUserQuestion:
   ```
   Shell welcome message style:
   ○ Box style (Default) - Unicode box with devenv branding
   ○ Minimal - Single line "▸ devenv ready"
   ○ Project name - Shows current project directory name
   ○ Tech style - Terminal-inspired "[devenv] :: environment initialized"
   ○ Custom - Enter your own message
   ○ None - No welcome message
   ```
3. If "Custom" selected, ask for custom message text
4. Update `.claude/devenv.local.md` with new `shell_welcome` (and `shell_welcome_custom` if applicable)
5. Update the `shellHook` section in `flake.nix`:
   - Read the current flake.nix
   - Locate the shellHook block in devShells.default
   - Replace the welcome message echo statements using the replacement table from Step 2g
   - Preserve any `${pre-commit-check.shellHook}` if present at the start of shellHook
   - Keep any other shellHook content intact
6. Show the user a preview of their new welcome message

**After any modification, validate the flake:**

```bash
nix flake check --no-build 2>&1
```

If validation fails, fix the issue before completing the task.

---

## Important Notes

- Always use `nix-shell -p <tool> --run "<command>"` for nix tools - do NOT assume they are installed system-wide
- The PostToolUse hooks will automatically format and lint `flake.nix` after any Write/Edit operations
- Use the nixpkgs channel from `.claude/devenv.local.md` if it exists, otherwise default to `nixos-unstable`
- When searching for packages, use 1mcp NixOS tools first, then mcp-nixos MCP, with bash fallback
- `git-hooks.nix` auto-generates `.pre-commit-config.yaml` via shellHook - no manual YAML needed!
- All hook tools are provided by Nix, ensuring reproducibility
- **Critical:** The `self` parameter in flake outputs is REQUIRED by the Nix flake system, even if not explicitly used in the function body. The plugin's deadnix hook is configured with `--no-lambda-pattern-names` to preserve it
- **Always validate** with `nix flake check --no-build` before completing any flake creation/modification task
- **direnv-instant is a flake input, NOT a nixpkgs package:** It must be added via `inputs.direnv-instant.url = "github:Mic92/direnv-instant"` and referenced as `direnv-instant.packages.${system}.default`. Standard `direnv` IS in nixpkgs and can be added directly to the packages list.

## MCP Tools: NixOS Package Search

This plugin uses NixOS MCP tools for package search, providing access to 130K+ NixOS packages with accurate, up-to-date information.

### Tool Priority Order

The command tries MCP tools in this order:
1. **1mcp** (preferred): `mcp__1mcp__nixos_1mcp_nixos_search` — already running via 1mcp proxy, no extra process
2. **Global/Project level**: `mcp__nixos__nix` — if user has mcp-nixos configured globally or in project
3. **Plugin's bundled**: `mcp__plugin_devenv_nixos__nix` — plugin's own MCP server (fallback for non-1mcp environments)
4. **Bash fallback**: `nix search` command

This ensures the fastest available tool is used first, with graceful degradation.

### Package Search

**1mcp** (separate tools per action):
```
mcp__1mcp__nixos_1mcp_nixos_search(
  query="<search_term>",
  search_type="packages",
  channel="unstable",
  limit=10
)
```

**Global/Plugin MCP** (combined action parameter):
```
mcp__nixos__nix(  # or mcp__plugin_devenv_nixos__nix
  action="search",
  query="<search_term>",
  source="nixos",
  type="packages",
  channel="unstable",
  limit=10
)
```

### Version Search

For versioned package requests (e.g., `nodejs@20`):

**1mcp** — find specific version:
```
mcp__1mcp__nixos_1mcp_nixhub_find_version(
  package_name="nodejs",
  version="20"
)
```

**1mcp** — list all available versions:
```
mcp__1mcp__nixos_1mcp_nixhub_package_versions(
  package_name="nodejs",
  limit=20
)
```

**Plugin bundled MCP** — version lookup:
```
mcp__plugin_devenv_nixos__nix_versions(
  package="nodejs",
  version="20"
)
```

**Version resolution workflow:**
1. Try `nixhub_find_version` (or `nix_versions`) to find the exact version
2. Also search nixpkgs for variants like `nodejs_20`
3. Prefer the nixpkgs variant if it exists (simpler, no pinning needed)
4. Offer pinned commit hash from nixhub as alternative if no nixpkgs variant found

### Parameter Reference

| Tool | Parameter | Value | Description |
|------|-----------|-------|-------------|
| `1mcp_nixos_search` | query | string | Package name or search term |
| `1mcp_nixos_search` | search_type | "packages" | Search packages (not options) |
| `1mcp_nixos_search` | channel | "unstable" | Nixpkgs channel |
| `1mcp_nixos_search` | limit | number | Max results to return |
| `1mcp_nixhub_find_version` | package_name | string | Package to find version for |
| `1mcp_nixhub_find_version` | version | string | Desired version (e.g., "20") |
| `1mcp_nixhub_package_versions` | package_name | string | Package to list versions for |
| `1mcp_nixhub_package_versions` | limit | number | Max versions to return |
| `nixos__nix` / `plugin_devenv_nixos__nix` | action | "search" | Search for packages |
| `nixos__nix` / `plugin_devenv_nixos__nix` | query | string | Package name or search term |
| `nixos__nix` / `plugin_devenv_nixos__nix` | source | "nixos" | Use NixOS packages source |
| `nixos__nix` / `plugin_devenv_nixos__nix` | type | "packages" | Search packages (not options) |
| `nixos__nix` / `plugin_devenv_nixos__nix` | channel | "unstable" | Use nixos-unstable channel |
| `nixos__nix` / `plugin_devenv_nixos__nix` | limit | number | Max results to return |
| `plugin_devenv_nixos__nix_versions` | package | string | Package to find version for |
| `plugin_devenv_nixos__nix_versions` | version | string | Desired version (optional) |
| `plugin_devenv_nixos__nix_versions` | limit | number | Max versions to return (optional) |

### Fallback Behavior

If no MCP tool is available, the command falls back to:
```bash
nix-shell -p nix --run "nix search nixpkgs <package> --json"
```

## Settings File

Users can customize behavior via `.claude/devenv.local.md`:

```yaml
---
nixpkgs_channel: nixos-unstable
use_mcp_search: true
direnv_mode: instant
shell_welcome: box
shell_welcome_custom: ""
---
```

### Available Settings

| Setting | Default | Description |
|---------|---------|-------------|
| `nixpkgs_channel` | `nixos-unstable` | Nixpkgs channel to use |
| `use_mcp_search` | `true` | Use mcp-nixos for package search. Set to `false` to always use bash fallback |
| `direnv_mode` | `instant` | direnv integration: `instant` (async, recommended), `standard` (sync), or `none` |
| `shell_welcome` | `box` | Welcome message style: `box`, `minimal`, `project`, `tech`, `custom`, or `none` |
| `shell_welcome_custom` | `""` | Custom welcome message text (only used when `shell_welcome: custom`). Use `\n` for multi-line |

## git-hooks.nix Hook Reference

### Available Hooks by Language

| Language | Hook Names |
|----------|------------|
| JavaScript/TypeScript | `eslint`, `prettier` |
| Python | `ruff`, `ruff-format`, `black`, `mypy` |
| Go | `golangci-lint`, `gofmt` |
| Rust | `clippy`, `rustfmt`, `cargo-check` |
| Nix | `nixfmt-rfc-style`, `statix`, `deadnix` |
| Shell | `shellcheck`, `shfmt` |
| Docker | `hadolint` |
| YAML | `check-yaml`, `yamllint` |
| Secrets | `trufflehog`, `ripsecrets` (built-in); `gitleaks` requires custom config |
| General | `trim-trailing-whitespace`, `check-added-large-files`, `check-merge-conflicts` |

### Example Hook Configuration

```nix
hooks = {
  # Enable a built-in hook
  eslint.enable = true;

  # Built-in secret scanner
  trufflehog.enable = true;

  # Enable with custom settings
  ruff = {
    enable = true;
    settings.args = ["--fix"];
  };

  # Custom hook example: gitleaks (not built-in)
  gitleaks = {
    enable = true;
    name = "gitleaks";
    entry = "${pkgs.gitleaks}/bin/gitleaks git --pre-commit --redact --staged --verbose";
    language = "system";
    pass_filenames = false;
  };
};
```

For full list of available hooks, see: https://github.com/cachix/git-hooks.nix

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.