Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.2 KiB
MiBook Claude Code Module Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Add a my.profiles.claude-code NixOS module that installs the Claude Code CLI and companion tooling on the MiBook.
Architecture: A single new environment module (modules/environments/claude-code/default.nix) declares the my.profiles.claude-code.enable option and installs packages for user finn. It is registered in modules/environments/default.nix and toggled on in machines/mibook/environments.nix.
Tech Stack: Nix flakes, NixOS module system, pkgs.unstable overlay (already present in repo)
File Map
| Action | Path | Responsibility |
|---|---|---|
| Create | modules/environments/claude-code/default.nix |
Declares option + installs packages |
| Modify | modules/environments/default.nix |
Registers the new module so NixOS loads it |
| Modify | machines/mibook/environments.nix |
Enables the profile for the MiBook host |
Task 1: Verify claude-code exists in nixpkgs-unstable
Files:
-
Read-only check — no file changes
-
Step 1: Check if the package is available
Run:
nix eval --extra-experimental-features 'nix-command flakes' 'github:NixOS/nixpkgs/nixos-unstable#claude-code.version' 2>&1
Expected (success): prints a version string like "0.2.x"
Expected (failure): error: attribute 'claude-code' missing
- Step 2: If the package exists — note the attribute path and continue to Task 2
The module will use pkgs.unstable.claude-code.
- Step 3: If the package does NOT exist — add a custom derivation first
Create pkgs/claude-code/default.nix:
{ lib, buildNpmPackage, fetchFromGitHub }:
buildNpmPackage rec {
pname = "claude-code";
version = "0.2.116"; # update to latest release tag
src = fetchFromGitHub {
owner = "anthropics";
repo = "claude-code";
rev = "v${version}";
hash = lib.fakeHash; # run nix build to get real hash
};
npmDepsHash = lib.fakeHash; # run nix build to get real hash
meta = {
description = "Claude Code CLI by Anthropic";
homepage = "https://github.com/anthropics/claude-code";
license = lib.licenses.unfree;
mainProgram = "claude";
};
}
Then register it in pkgs/default.nix:
final: prev: {
claude-code = final.callPackage ./claude-code { };
}
And use pkgs.claude-code (not pkgs.unstable.claude-code) in the module.
Task 2: Create the claude-code module
Files:
-
Create:
modules/environments/claude-code/default.nix -
Step 1: Create the module file
Create modules/environments/claude-code/default.nix with this exact content:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.claude-code;
in
{
options.my.profiles.claude-code = with lib; {
enable = mkEnableOption "Claude Code CLI";
};
config = lib.mkIf cfg.enable {
users.users.finn.packages = with pkgs; [
unstable.claude-code
ripgrep
fd
gh
jq
];
# Future: headless Claude Code service
# A natural next step is exposing Claude Code as a persistent background service —
# e.g. a systemd user service that accepts work via an HTTP API or Unix socket,
# triggerable over SSH or a local network endpoint. This would turn the MiBook
# into a true remote execution node without requiring an interactive session.
# See: my.profiles.claude-code.service.enable (not yet implemented)
};
}
Note: if Task 1 Step 3 was taken (custom derivation), replace
unstable.claude-codewithclaude-code.
Task 3: Register the module
Files:
-
Modify:
modules/environments/default.nix -
Step 1: Add the import
In modules/environments/default.nix, add ./claude-code to the imports list (alphabetical order puts it between ./audiobookshelf and ./development):
{ ... }:
{
imports = [
./actual
./apps
./audiobookshelf
./claude-code
./development
./home-assistant
./hyprland
./zsh
./paperless
./prowlarr
./radarr
./docker
./homepage
./kde-desktop
./readarr
./sonarr
./jellyfin
./jellyseerr
];
}
- Step 2: Verify the option is now defined (without enabling it)
Run:
nix eval --extra-experimental-features 'nix-command flakes' '.#nixosConfigurations.mibook.options.my.profiles.claude-code.enable.description'
Expected: "Whether to enable Claude Code CLI."
If this errors, the module isn't loading — re-check the import path.
Task 4: Enable on MiBook and verify the build
Files:
-
Modify:
machines/mibook/environments.nix -
Step 1: Enable the profile
In machines/mibook/environments.nix, add claude-code.enable = true inside the my.profiles block:
my.profiles = {
kde-desktop.enable = true;
zsh.enable = true;
apps = {
desktop_apps = true;
dev_apps = true;
};
development.enable = true;
docker.enable = true;
claude-code.enable = true;
};
- Step 2: Verify the package appears in finn's user packages
Run:
nix eval --extra-experimental-features 'nix-command flakes' '.#nixosConfigurations.mibook.config.users.users.finn.packages' --apply 'builtins.map (p: p.name)' 2>&1 | grep -i claude
Expected: a line containing claude-code-<version>
- Step 3: Dry-run build to confirm the full config evaluates
Run:
nix build '.#nixosConfigurations.mibook.config.system.build.toplevel' --extra-experimental-features 'nix-command flakes' --dry-run 2>&1 | tail -5
Expected: exits 0, output lists derivations to build (or "nothing to do" if already cached). No evaluation errors.
Task 5: Commit
Files:
-
All changed files from Tasks 1–4
-
Step 1: Stage and commit
git add modules/environments/claude-code/default.nix \
modules/environments/default.nix \
machines/mibook/environments.nix
git commit -m "feat(mibook): add claude-code profile module"
If Task 1 Step 3 was taken, also stage pkgs/claude-code/default.nix and pkgs/default.nix.