diff options
Diffstat (limited to 'openspec/changes/add-claude-code-slack-spotify-discord-teams')
5 files changed, 116 insertions, 0 deletions
diff --git a/openspec/changes/add-claude-code-slack-spotify-discord-teams/.openspec.yaml b/openspec/changes/add-claude-code-slack-spotify-discord-teams/.openspec.yaml new file mode 100644 index 0000000..563fab5 --- /dev/null +++ b/openspec/changes/add-claude-code-slack-spotify-discord-teams/.openspec.yaml | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | schema: spec-driven | ||
| 2 | created: 2026-09-21 | ||
diff --git a/openspec/changes/add-claude-code-slack-spotify-discord-teams/design.md b/openspec/changes/add-claude-code-slack-spotify-discord-teams/design.md new file mode 100644 index 0000000..d2cfd05 --- /dev/null +++ b/openspec/changes/add-claude-code-slack-spotify-discord-teams/design.md | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | ## Context | ||
| 2 | |||
| 3 | See proposal.md - Why/What Changes for motivation. Two constraints shape this design: | ||
| 4 | |||
| 5 | - `lib/mkHome.nix` builds standalone `homeConfigurations` by passing a pre-instantiated `pkgs = inputs.nixpkgs.legacyPackages.${system}` directly into `homeManagerConfiguration`. Because `pkgs` is supplied rather than left for home-manager to construct, the home-manager `nixpkgs.config` module option has no effect there - unfree gating has to happen when `pkgs` itself is built. | ||
| 6 | - `lib/mkNixos.nix` builds NixOS hosts with `home-manager.useGlobalPkgs = true`, so the home-manager profile shares whatever `pkgs` the NixOS module system constructs - there, a `nixpkgs.config` module option set anywhere in the module list does take effect. | ||
| 7 | - No package in this repo has ever needed to vary by architecture before; `modules/home/dotfiles.nix` conditions on `isDarwin`/`isLinux` for stow directories, not on `pkgs.stdenv.hostPlatform` for a Nix package. | ||
| 8 | |||
| 9 | ## Goals / Non-Goals | ||
| 10 | |||
| 11 | **Goals:** | ||
| 12 | - One shared mechanism for "this package isn't supported on this system, skip it" that works for both current architectures (x86_64-linux, aarch64-darwin) and any future host without per-package manual bookkeeping. | ||
| 13 | - Unfree package access scoped to exactly the packages this change needs. | ||
| 14 | |||
| 15 | **Non-Goals:** | ||
| 16 | - Adding nix-darwin or Homebrew support for nicer macOS app delivery (tracked separately in the README). | ||
| 17 | - Standing up a real `aarch64-linux` host to test the skip behavior on - none exists in this repo today; the mechanism is verified by evaluating the existing configs and reasoning about `meta.platforms`, not by building on that architecture. | ||
| 18 | |||
| 19 | ## Decisions | ||
| 20 | |||
| 21 | **Use `lib.meta.availableOn pkgs.stdenv.hostPlatform pkg`, filtered over a candidate list, instead of hand-written per-package platform conditionals.** | ||
| 22 | `lib.meta.availableOn` is nixpkgs' own check against a derivation's `meta.platforms`/`meta.badPlatforms`, so it stays correct automatically if nixpkgs adds or drops platform support for one of these packages later. The alternative - hardcoding e.g. `lib.optional (system == "x86_64-linux") pkgs.discord` - would silently go stale and requires knowing each package's exact supported-platform list up front. | ||
| 23 | |||
| 24 | **Scope unfree access via `nixpkgs.config.allowUnfreePredicate` backed by a single `lib/unfree-allowlist.nix`, not blanket `allowUnfree = true`.** | ||
| 25 | Chosen explicitly over the blanket option: it names exactly `slack`, `discord`, `spotify`, `claude-code` rather than permitting any future unfree package by default, matching this repo's existing preference for minimal, explicit scoping (see `dotfiles.nix`'s platform-exclude list and its accompanying comment). The list is a single file imported by both `lib/mkHome.nix` and `lib/mkNixos.nix` so the two builders can't drift out of sync. | ||
| 26 | |||
| 27 | **`lib/mkHome.nix` switches from `inputs.nixpkgs.legacyPackages.${system}` to `import inputs.nixpkgs { inherit system; config.allowUnfreePredicate = ...; }`.** | ||
| 28 | This is the minimal change that makes unfree gating actually take effect for standalone home-manager, per the Context constraint above. Alternative considered: leave `pkgs` as `legacyPackages` and instead set `nixpkgs.config` as a home-manager module option - rejected because home-manager ignores that option once `pkgs` is passed in directly (it would silently do nothing, which is worse than an explicit fix here). | ||
| 29 | |||
| 30 | **`lib/mkNixos.nix` sets the same predicate via a small inline module prepended to its `modules` list**, rather than editing `modules/nixos/common.nix`. Keeping it in the builder (alongside where `mkHome.nix` does the equivalent) keeps both unfree-gating call sites next to each other and next to the shared allowlist, instead of splitting the concern across `lib/` and `modules/nixos/`. | ||
| 31 | |||
| 32 | **`claude-code` is added to `modules/home/dev-tools.nix`, not the new `desktop-applications` capability.** | ||
| 33 | It's a CLI tool, and `developer-environment`'s existing requirement already generically covers "the shared profile SHALL include the user's evidenced most-used CLI and client tools" - no new requirement text is needed, just a package addition guarded by the same `lib.meta.availableOn` check for consistency. | ||
| 34 | |||
| 35 | **`teams-for-linux` gets an explicit `pkgs.stdenv.hostPlatform.isLinux` guard in addition to the `availableOn` filter**, rather than relying on `availableOn` alone. | ||
| 36 | Belt-and-suspenders: the product is Linux-only by design regardless of what nixpkgs' `meta.platforms` happens to list for it, so the explicit guard keeps behavior correct even if that metadata is ever loose or changes. | ||
| 37 | |||
| 38 | ## Risks / Trade-offs | ||
| 39 | |||
| 40 | - **No local Nix to verify eval/build** → Mitigation: tasks.md verification steps target a machine with Nix installed; this is a pre-existing gap in this environment, not new to this change. | ||
| 41 | - **`lib.meta.availableOn` trusts nixpkgs' `meta.platforms` accuracy** → Mitigation: cross-checked against current nixpkgs metadata (Slack/Discord/Spotify unfree and missing `aarch64-linux`; `claude-code` unfree and available on all four systems; `teams-for-linux` free/GPL and broadly available) before writing this design; if nixpkgs metadata is ever wrong for a package, the filter fails closed (excludes it) rather than failing the build. | ||
| 42 | - **macOS apps come from nixpkgs' darwin builds, not Homebrew casks** → Mitigation: explicitly out of scope (see Non-Goals); flagged in proposal.md's Impact section as a known limitation. | ||
diff --git a/openspec/changes/add-claude-code-slack-spotify-discord-teams/proposal.md b/openspec/changes/add-claude-code-slack-spotify-discord-teams/proposal.md new file mode 100644 index 0000000..4bb3e10 --- /dev/null +++ b/openspec/changes/add-claude-code-slack-spotify-discord-teams/proposal.md | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | ## Why | ||
| 2 | |||
| 3 | The shared home-manager profile currently provisions only CLI/client tooling; there is no way to get everyday desktop GUI applications (chat, communication, music) or the Claude Code CLI onto a machine built from this flake without installing them by hand outside of Nix. The user wants Claude Code, Slack, Spotify, Discord, and [teams-for-linux](https://ismaelmartinez.github.io/teams-for-linux/) declared in the config, with the understanding that several of these are unfree-licensed and some (Discord, Spotify, Slack) do not have `aarch64-linux` builds in nixpkgs today — an unsupported package must be skipped rather than break evaluation on that architecture. | ||
| 4 | |||
| 5 | ## What Changes | ||
| 6 | |||
| 7 | - Add a new `modules/home/desktop-apps.nix` home-manager module provisioning Slack, Discord, Spotify, and teams-for-linux, filtered through `lib.meta.availableOn` so any package unsupported on the current system/architecture is silently omitted instead of failing the build; teams-for-linux is additionally restricted to Linux only. | ||
| 8 | - Add `claude-code` to the existing `modules/home/dev-tools.nix` CLI tool list, guarded the same way. | ||
| 9 | - Introduce a shared `lib/unfree-allowlist.nix` naming exactly the unfree packages this change adds (`slack`, `discord`, `spotify`, `claude-code`; teams-for-linux is GPL-licensed and needs no allowance), and wire `nixpkgs.config.allowUnfreePredicate` from it in both `lib/mkHome.nix` (standalone home-manager) and `lib/mkNixos.nix` (NixOS + home-manager), since neither currently permits any unfree package. | ||
| 10 | - **BREAKING**: none — additive only; existing configurations continue to evaluate and activate unchanged aside from gaining new optional packages. | ||
| 11 | |||
| 12 | ## Capabilities | ||
| 13 | |||
| 14 | ### New Capabilities | ||
| 15 | - `desktop-applications`: provisioning of user-facing desktop GUI applications (Slack, Discord, Spotify, teams-for-linux) through the shared home-manager profile, including the rule that a package unsupported on the current system is skipped rather than causing failure. | ||
| 16 | |||
| 17 | ### Modified Capabilities | ||
| 18 | (none — adding `claude-code` to the shared CLI toolset is already covered by `developer-environment`'s existing requirement that the shared profile "SHALL include the user's evidenced most-used CLI and client tools"; no requirement text changes.) | ||
| 19 | |||
| 20 | ## Impact | ||
| 21 | |||
| 22 | - **Affected code**: `lib/mkHome.nix`, `lib/mkNixos.nix` (new `lib/unfree-allowlist.nix` dependency), `modules/home/default.nix` (new import), `modules/home/desktop-apps.nix` (new file), `modules/home/dev-tools.nix`. | ||
| 23 | - **Dependencies**: relies on nixpkgs' unfree-licensed `slack`, `discord`, `spotify`, `claude-code` packages and the free `teams-for-linux` package; no new flake inputs. | ||
| 24 | - **Platforms**: applies to both `homeConfigurations` (`tom@linux` = x86_64-linux, `tom@darwin` = aarch64-darwin) and any future NixOS host built via `lib/mkNixos.nix`. On `aarch64-darwin`, `teams-for-linux` is intentionally excluded (Linux-only product); on any future `aarch64-linux` host, Discord/Spotify/Slack are expected to be excluded automatically since nixpkgs does not currently build them for that platform. | ||
| 25 | - **Known limitation, out of scope**: this repo has no nix-darwin/Homebrew integration yet (tracked separately in the README as a follow-up), so on macOS these apps are provisioned from nixpkgs' darwin builds only, not Homebrew casks. | ||
| 26 | - **Verification gap**: no local Nix installation in this environment, so `nix flake check` / `home-manager build` cannot be run here; verification must happen on a machine with Nix installed (see tasks.md). | ||
diff --git a/openspec/changes/add-claude-code-slack-spotify-discord-teams/specs/desktop-applications/spec.md b/openspec/changes/add-claude-code-slack-spotify-discord-teams/specs/desktop-applications/spec.md new file mode 100644 index 0000000..ae1e6f3 --- /dev/null +++ b/openspec/changes/add-claude-code-slack-spotify-discord-teams/specs/desktop-applications/spec.md | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | ## Purpose | ||
| 2 | |||
| 3 | Provisions everyday desktop GUI applications (chat, communication, and music clients) through the shared home-manager profile, mirroring how `developer-environment` provisions CLI tooling but for user-facing graphical applications instead. | ||
| 4 | |||
| 5 | ## ADDED Requirements | ||
| 6 | |||
| 7 | ### Requirement: Desktop GUI applications are provisioned via the shared home profile | ||
| 8 | The shared home-manager profile SHALL include Slack, Discord, Spotify, and teams-for-linux as GUI application packages, available wherever that profile is activated and the underlying package supports the current system. | ||
| 9 | |||
| 10 | #### Scenario: GUI app available after activation | ||
| 11 | - **WHEN** the shared home profile is activated on a system for which a given desktop application's package is supported | ||
| 12 | - **THEN** that application is available without any additional manual installation step | ||
| 13 | |||
| 14 | ### Requirement: Packages unsupported on the current system are skipped, not failed | ||
| 15 | A desktop application package that has no supported build for the currently evaluated system SHALL be omitted from the provisioned package set rather than causing profile evaluation or activation to fail. | ||
| 16 | |||
| 17 | #### Scenario: Unsupported package excluded without failure | ||
| 18 | - **WHEN** the shared home profile is evaluated on a system for which one of the desktop application packages (e.g. an `aarch64-linux` target lacking a Discord, Spotify, or Slack build) has no supported build | ||
| 19 | - **THEN** that package is excluded from the provisioned set and the rest of the profile evaluates and activates successfully | ||
| 20 | |||
| 21 | ### Requirement: teams-for-linux is Linux-only | ||
| 22 | teams-for-linux SHALL be provisioned only on Linux systems, consistent with its scope as a Linux-only Microsoft Teams client. | ||
| 23 | |||
| 24 | #### Scenario: Excluded on a non-Linux system | ||
| 25 | - **WHEN** the shared home profile is activated on a non-Linux system | ||
| 26 | - **THEN** teams-for-linux is not included in the provisioned package set | ||
diff --git a/openspec/changes/add-claude-code-slack-spotify-discord-teams/tasks.md b/openspec/changes/add-claude-code-slack-spotify-discord-teams/tasks.md new file mode 100644 index 0000000..82aa94f --- /dev/null +++ b/openspec/changes/add-claude-code-slack-spotify-discord-teams/tasks.md | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | ## 1. Unfree package gating | ||
| 2 | |||
| 3 | - [ ] 1.1 Create `lib/unfree-allowlist.nix` containing `[ "slack" "discord" "spotify" "claude-code" ]` and verify it evaluates with `nix eval --file lib/unfree-allowlist.nix` (or `nix-instantiate --eval`) | ||
| 4 | - [ ] 1.2 Update `lib/mkHome.nix` to construct `pkgs` via `import inputs.nixpkgs { inherit system; config.allowUnfreePredicate = pkg: builtins.elem (inputs.nixpkgs.lib.getName pkg) (import ./unfree-allowlist.nix); }` instead of `inputs.nixpkgs.legacyPackages.${system}`, and verify `nix flake show` still lists both `homeConfigurations` without error | ||
| 5 | - [ ] 1.3 Update `lib/mkNixos.nix` to prepend a module setting the same `nixpkgs.config.allowUnfreePredicate` (reusing `lib/unfree-allowlist.nix`), and verify `nix flake check` (or `nix eval .#nixosConfigurations` for any configured host) still evaluates without an "unfree package" error | ||
| 6 | |||
| 7 | ## 2. Desktop applications module | ||
| 8 | |||
| 9 | - [ ] 2.1 Create `modules/home/desktop-apps.nix` with `home.packages = builtins.filter (lib.meta.availableOn pkgs.stdenv.hostPlatform) ([ pkgs.slack pkgs.discord pkgs.spotify ] ++ lib.optional pkgs.stdenv.hostPlatform.isLinux pkgs.teams-for-linux);` and verify the file evaluates standalone via `nix-instantiate --eval --strict -E 'import ./modules/home/desktop-apps.nix { pkgs = import <nixpkgs> {}; lib = (import <nixpkgs> {}).lib; }'` or equivalent | ||
| 10 | - [ ] 2.2 Add `./desktop-apps.nix` to the `imports` list in `modules/home/default.nix` and verify `home-manager build --flake .#tom@linux` and `home-manager build --flake .#tom@darwin` both evaluate successfully (run on a machine with Nix installed - not available in this environment) | ||
| 11 | - [ ] 2.3 Verify on the build output (or via `nix eval`) that `tom@darwin`'s closure excludes `teams-for-linux` while `tom@linux`'s includes it, confirming the Linux-only guard works as intended | ||
| 12 | |||
| 13 | ## 3. Claude Code CLI | ||
| 14 | |||
| 15 | - [ ] 3.1 Add `pkgs.claude-code` to `modules/home/dev-tools.nix`'s `home.packages`, guarded with `lib.optional (lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.claude-code) pkgs.claude-code`, and verify `claude-code` appears on `PATH` after `home-manager build --flake .#tom@linux` (or `.#tom@darwin`) followed by activation on a machine with Nix installed | ||
| 16 | |||
| 17 | ## 4. End-to-end verification | ||
| 18 | |||
| 19 | - [ ] 4.1 Run `nix flake check` on a machine with Nix installed and confirm no evaluation errors for either `homeConfigurations` entry | ||
| 20 | - [ ] 4.2 Run `statix check` and `deadnix` (already used by this repo's `devShells.default`) over the changed files and fix any findings | ||
