refactor: remove dead code, extract shared agent options, optimize flake

- Remove dead overlays/default.nix (flake defines overlays inline)
- Remove orphaned overlays/mods/{beads,n8n}.nix (never imported)
- Remove docs/packages/notesmd-cli.md (package doesn't exist)
- Extract externalSkills submodule to shared-options.nix (eliminates
  ~100 lines of duplication across opencode/claude-code/pi modules)
- Fix lib output: use nixpkgs.lib directly instead of instantiating
  a full nixpkgs just to get lib
- Add lib unit tests to flake checks
- Update stale comment in coding-rules.nix
This commit is contained in:
Chiron
2026-04-18 10:15:50 +00:00
parent c9ecc0809f
commit 54fa93574b
10 changed files with 408 additions and 661 deletions

View File

@@ -1,117 +0,0 @@
# notesmd-cli
Obsidian CLI (Community) - Interact with Obsidian in the terminal.
## Description
notesmd-cli is a command-line interface for interacting with Obsidian, the popular knowledge management and note-taking application. It allows you to create, search, and manipulate notes directly from the terminal.
## Features
- 📝 **Note Creation**: Create new notes from the command line
- 🔍 **Search**: Search through your Obsidian vault
- 📂 **Vault Management**: Interact with your vault structure
- 🔗 **WikiLink Support**: Work with Obsidian's WikiLink format
- 🏷️ **Tag Support**: Manage and search by tags
-**Fast**: Lightweight Go binary with no external dependencies
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
notesmd-cli
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.notesmd-cli
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#notesmd-cli
```
## Usage
### Basic Commands
```bash
# Show help
notesmd-cli --help
# Create a new note
notesmd-cli new "My Note Title"
# Search notes
notesmd-cli search "search term"
# List notes
notesmd-cli list
```
### Working with Vaults
```bash
# Specify vault path
notesmd-cli --vault /path/to/vault new "Note Title"
# Open a note in Obsidian
notesmd-cli open "Note Name"
```
### Advanced Usage
```bash
# Search with tags
notesmd-cli search --tag "project"
# Append to existing note
notesmd-cli append "Note Name" "Additional content"
```
## Configuration
### Environment Variables
- `OBSIDIAN_VAULT`: Default vault path
### Command Line Options
Run `notesmd-cli --help` for a complete list of options.
## Build Information
- **Version**: 0.3.0
- **Language**: Go
- **License**: MIT
- **Source**: [GitHub](https://github.com/Yakitrak/notesmd-cli)
- **Vendor Hash**: null (no external dependencies)
## Platform Support
- Linux
- macOS (Unix systems)
## Notes
- No vendor dependencies (pure Go stdlib)
- The binary is named `notesmd-cli` (not `notesmd`)
- This is the community CLI, not the official Obsidian CLI
## Related
- [Obsidian](https://obsidian.md) - The Obsidian application
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide

View File

@@ -77,10 +77,7 @@
}; };
# Library functions - helper utilities for your configuration # Library functions - helper utilities for your configuration
lib = forAllSystems (system: let lib = forAllSystems (system: import ./lib {lib = nixpkgs.lib;});
pkgs = pkgsFor system;
in
import ./lib {lib = pkgs.lib;});
# Development shells for various programming environments # Development shells for various programming environments
# Usage: nix develop .#<shell-name> # Usage: nix develop .#<shell-name>
@@ -104,6 +101,9 @@
${pkgs.alejandra}/bin/alejandra --check ${./.} ${pkgs.alejandra}/bin/alejandra --check ${./.}
touch $out touch $out
''; '';
# Lib unit tests
lib-agents = import ./tests/lib/agents-test.nix;
lib-coding-rules = import ./tests/lib/coding-rules-test.nix;
}); });
# Templates for creating new packages/modules # Templates for creating new packages/modules

View File

@@ -1,4 +1,4 @@
# Opencode rules management utilities # Coding rules management utilities
# #
# This module provides functions to configure Opencode agent rules across # This module provides functions to configure Opencode agent rules across
# multiple projects. Rules are defined in the AGENTS repository and can be # multiple projects. Rules are defined in the AGENTS repository and can be

View File

@@ -3,7 +3,9 @@
lib, lib,
pkgs, pkgs,
... ...
}: }: let
shared = import ./shared-options.nix {inherit lib;};
in
with lib; let with lib; let
cfg = config.coding.agents.claude-code; cfg = config.coding.agents.claude-code;
mcpCfg = config.programs.mcp or null; mcpCfg = config.programs.mcp or null;
@@ -11,68 +13,15 @@ in {
options.coding.agents.claude-code = { options.coding.agents.claude-code = {
enable = mkEnableOption "Claude Code agent management via canonical agent.toml definitions"; enable = mkEnableOption "Claude Code agent management via canonical agent.toml definitions";
agentsInput = mkOption { agentsInput = shared.mkAgentsInputOption ''
type = types.nullOr types.anything;
default = null;
description = ''
The `agents` flake input (your personal AGENTS repo). The `agents` flake input (your personal AGENTS repo).
When set, agents are rendered from canonical agent.toml files When set, agents are rendered from canonical agent.toml files
and symlinked to ~/.claude/agents/. and symlinked to ~/.claude/agents/.
''; '';
};
modelOverrides = mkOption { modelOverrides = shared.mkModelOverridesOption;
type = types.attrsOf types.str;
default = {};
description = ''
Per-agent model overrides. Maps agent slug to model alias or ID.
Example: { chiron = "claude-sonnet-4-20250514"; }
'';
example = literalExpression ''
{
chiron = "claude-sonnet-4-20250514";
"chiron-forge" = "claude-sonnet-4-20250514";
}
'';
};
externalSkills = mkOption { externalSkills = shared.externalSkillsOption;
type = types.listOf (types.submodule {
options = {
src = mkOption {
type = types.anything;
description = "Flake input pointing to a skills repository root.";
};
skillsDir = mkOption {
type = types.str;
default = "skills";
description = ''
Subdirectory inside src that contains skill folders.
'';
};
selectSkills = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
description = ''
List of skill names to cherry-pick from this source.
null means include every skill found in skillsDir.
'';
};
};
});
default = [];
description = ''
External skill sources passed to mkOpencodeSkills.
Each entry maps directly to an element of the externalSkills
list accepted by the AGENTS flake's lib.mkOpencodeSkills.
'';
example = literalExpression ''
[
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
{ src = inputs.skills-vercel; }
]
'';
};
mcpServers = mkOption { mcpServers = mkOption {
type = types.attrsOf types.anything; type = types.attrsOf types.anything;
@@ -128,13 +77,7 @@ in {
source = cfg.agentsInput.lib.mkOpencodeSkills { source = cfg.agentsInput.lib.mkOpencodeSkills {
inherit pkgs; inherit pkgs;
customSkills = "${cfg.agentsInput}/skills"; customSkills = "${cfg.agentsInput}/skills";
externalSkills = externalSkills = shared.mapExternalSkills cfg.externalSkills;
map (
entry:
{inherit (entry) src skillsDir;}
// optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
)
cfg.externalSkills;
}; };
}; };

View File

@@ -3,80 +3,30 @@
lib, lib,
pkgs, pkgs,
... ...
}: }: let
with lib; let shared = import ./shared-options.nix {inherit lib;};
cfg = config.coding.agents.opencode; in
in { with lib; {
options.coding.agents.opencode = { options.coding.agents.opencode = {
enable = mkEnableOption "OpenCode agent management via canonical agent.toml definitions"; enable = mkEnableOption "OpenCode agent management via canonical agent.toml definitions";
agentsInput = mkOption { agentsInput = shared.mkAgentsInputOption ''
type = types.nullOr types.anything;
default = null;
description = ''
The `agents` flake input (your personal AGENTS repo). The `agents` flake input (your personal AGENTS repo).
When set, agents are rendered from canonical agent.toml files When set, agents are rendered from canonical agent.toml files
and symlinked to ~/.config/opencode/agents/. and symlinked to ~/.config/opencode/agents/.
''; '';
modelOverrides = shared.mkModelOverridesOption;
externalSkills = shared.externalSkillsOption;
}; };
modelOverrides = mkOption { config = mkIf config.coding.agents.opencode.enable {
type = types.attrsOf types.str;
default = {};
description = ''
Per-agent model overrides. Maps agent slug to model string.
Example: { chiron = "anthropic/claude-sonnet-4"; }
'';
example = literalExpression ''
{
chiron = "anthropic/claude-sonnet-4";
"chiron-forge" = "anthropic/claude-sonnet-4";
}
'';
};
externalSkills = mkOption {
type = types.listOf (types.submodule {
options = {
src = mkOption {
type = types.anything;
description = "Flake input pointing to a skills repository root.";
};
skillsDir = mkOption {
type = types.str;
default = "skills";
description = ''
Subdirectory inside src that contains skill folders.
'';
};
selectSkills = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
description = ''
List of skill names to cherry-pick from this source.
null means include every skill found in skillsDir.
'';
};
};
});
default = [];
description = ''
External skill sources passed to mkOpencodeSkills.
Each entry maps directly to an element of the externalSkills
list accepted by the AGENTS flake's lib.mkOpencodeSkills.
'';
example = literalExpression ''
[
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
{ src = inputs.skills-vercel; }
]
'';
};
};
config = mkIf cfg.enable {
# Rendered agent files symlinked to ~/.config/opencode/agents/ # Rendered agent files symlinked to ~/.config/opencode/agents/
xdg.configFile."opencode/agents" = mkIf (cfg.agentsInput != null) { xdg.configFile."opencode/agents" = let
cfg = config.coding.agents.opencode;
in
mkIf (cfg.agentsInput != null) {
source = (import ../../../../lib {inherit lib;}).agents.renderForOpencode { source = (import ../../../../lib {inherit lib;}).agents.renderForOpencode {
inherit pkgs; inherit pkgs;
canonical = cfg.agentsInput.lib.loadAgents; canonical = cfg.agentsInput.lib.loadAgents;
@@ -85,28 +35,34 @@ in {
}; };
# Skills (merged from personal AGENTS repo + optional external skills) # Skills (merged from personal AGENTS repo + optional external skills)
xdg.configFile."opencode/skills" = mkIf (cfg.agentsInput != null) { xdg.configFile."opencode/skills" = let
cfg = config.coding.agents.opencode;
in
mkIf (cfg.agentsInput != null) {
source = cfg.agentsInput.lib.mkOpencodeSkills { source = cfg.agentsInput.lib.mkOpencodeSkills {
inherit pkgs; inherit pkgs;
customSkills = "${cfg.agentsInput}/skills"; customSkills = "${cfg.agentsInput}/skills";
externalSkills = externalSkills = shared.mapExternalSkills cfg.externalSkills;
map (
entry:
{inherit (entry) src skillsDir;}
// optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
)
cfg.externalSkills;
}; };
}; };
# Static config dirs from AGENTS repo # Static config dirs from AGENTS repo
xdg.configFile."opencode/context" = mkIf (cfg.agentsInput != null) { xdg.configFile."opencode/context" = let
cfg = config.coding.agents.opencode;
in
mkIf (cfg.agentsInput != null) {
source = "${cfg.agentsInput}/context"; source = "${cfg.agentsInput}/context";
}; };
xdg.configFile."opencode/commands" = mkIf (cfg.agentsInput != null) { xdg.configFile."opencode/commands" = let
cfg = config.coding.agents.opencode;
in
mkIf (cfg.agentsInput != null) {
source = "${cfg.agentsInput}/commands"; source = "${cfg.agentsInput}/commands";
}; };
xdg.configFile."opencode/prompts" = mkIf (cfg.agentsInput != null) { xdg.configFile."opencode/prompts" = let
cfg = config.coding.agents.opencode;
in
mkIf (cfg.agentsInput != null) {
source = "${cfg.agentsInput}/prompts"; source = "${cfg.agentsInput}/prompts";
}; };
}; };

View File

@@ -3,7 +3,9 @@
lib, lib,
pkgs, pkgs,
... ...
}: }: let
shared = import ./shared-options.nix {inherit lib;};
in
with lib; let with lib; let
cfg = config.coding.agents.pi; cfg = config.coding.agents.pi;
mcpCfg = config.programs.mcp or null; mcpCfg = config.programs.mcp or null;
@@ -22,25 +24,13 @@ in {
''; '';
}; };
agentsInput = mkOption { agentsInput = shared.mkAgentsInputOption ''
type = types.nullOr types.anything;
default = null;
description = ''
The `agents` flake input (your personal AGENTS repo). The `agents` flake input (your personal AGENTS repo).
When set, the primary agent's system prompt is rendered as SYSTEM.md, When set, the primary agent's system prompt is rendered as SYSTEM.md,
all agents are listed in AGENTS.md, and subagent .md files are deployed. all agents are listed in AGENTS.md, and subagent .md files are deployed.
''; '';
};
modelOverrides = mkOption { modelOverrides = shared.mkModelOverridesOption;
type = types.attrsOf types.str;
default = {};
description = ''
Per-agent model overrides for Pi subagents.
Maps agent slug to model string, e.g.:
{ chiron = "anthropic/claude-sonnet-4"; chiron-forge = "anthropic/claude-sonnet-4"; }
'';
};
primaryAgent = mkOption { primaryAgent = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
@@ -51,43 +41,7 @@ in {
''; '';
}; };
externalSkills = mkOption { externalSkills = shared.externalSkillsOption;
type = types.listOf (types.submodule {
options = {
src = mkOption {
type = types.anything;
description = "Flake input pointing to a skills repository root.";
};
skillsDir = mkOption {
type = types.str;
default = "skills";
description = ''
Subdirectory inside src that contains skill folders.
'';
};
selectSkills = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
description = ''
List of skill names to cherry-pick from this source.
null means include every skill found in skillsDir.
'';
};
};
});
default = [];
description = ''
External skill sources passed to mkOpencodeSkills.
Each entry maps directly to an element of the externalSkills
list accepted by the AGENTS flake's lib.mkOpencodeSkills.
'';
example = literalExpression ''
[
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
{ src = inputs.basecamp; }
]
'';
};
settings = mkOption { settings = mkOption {
type = types.submodule { type = types.submodule {
@@ -265,13 +219,7 @@ in {
".pi/agent/skills".source = cfg.agentsInput.lib.mkOpencodeSkills { ".pi/agent/skills".source = cfg.agentsInput.lib.mkOpencodeSkills {
inherit pkgs; inherit pkgs;
customSkills = "${cfg.agentsInput}/skills"; customSkills = "${cfg.agentsInput}/skills";
externalSkills = externalSkills = shared.mapExternalSkills cfg.externalSkills;
map (
entry:
{inherit (entry) src skillsDir;}
// optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
)
cfg.externalSkills;
}; };
}) })
]; ];

View File

@@ -0,0 +1,75 @@
# Shared option definitions for agent modules.
# Prevents copy-pasting the externalSkills submodule across opencode/claude-code/pi.
{lib}: let
inherit (lib) mkOption mkEnableOption types literalExpression;
in {
# Common agentsInput option used by all agent modules.
mkAgentsInputOption = description: mkOption {
type = types.nullOr types.anything;
default = null;
inherit description;
};
# Common modelOverrides option.
mkModelOverridesOption = mkOption {
type = types.attrsOf types.str;
default = {};
description = ''
Per-agent model overrides. Maps agent slug to model string.
Example: { chiron = "anthropic/claude-sonnet-4"; }
'';
example = literalExpression ''
{
chiron = "anthropic/claude-sonnet-4";
"chiron-forge" = "anthropic/claude-sonnet-4";
}
'';
};
# External skills submodule — used by opencode, claude-code, and pi modules.
externalSkillsOption = mkOption {
type = types.listOf (types.submodule {
options = {
src = mkOption {
type = types.anything;
description = "Flake input pointing to a skills repository root.";
};
skillsDir = mkOption {
type = types.str;
default = "skills";
description = ''
Subdirectory inside src that contains skill folders.
'';
};
selectSkills = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
description = ''
List of skill names to cherry-pick from this source.
null means include every skill found in skillsDir.
'';
};
};
});
default = [];
description = ''
External skill sources passed to mkOpencodeSkills.
Each entry maps directly to an element of the externalSkills
list accepted by the AGENTS flake's lib.mkOpencodeSkills.
'';
example = literalExpression ''
[
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
{ src = inputs.basecamp; }
]
'';
};
# Helper to map externalSkills from module config to mkOpencodeSkills format.
mapExternalSkills = cfgEntries:
map (
entry:
{inherit (entry) src skillsDir;}
// lib.optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
) cfgEntries;
}

View File

@@ -1,24 +0,0 @@
{inputs, ...}: {
# This one brings our custom packages from the 'pkgs' directory
additions = final: prev: (import ../pkgs {pkgs = final;});
# This one contains whatever you want to overlay
# You can change versions, add patches, set compilation flags, anything really.
# https://nixos.wiki/wiki/Overlays
modifications = final: prev:
# Import all package modifications from mods directory
(import ./mods/default.nix {inherit prev;})
// {
# Direct configuration overrides
brave = prev.brave.override {
commandLineArgs = "--password-store=gnome-libsecret";
};
};
master-packages = final: _prev: {
master = import inputs.nixpkgs-master {
system = final.stdenv.hostPlatform.system;
config.allowUnfree = true;
};
};
}

View File

@@ -1,16 +0,0 @@
{prev}:
prev.beads.overrideAttrs (oldAttrs: rec {
version = "0.47.1";
src = prev.fetchFromGitHub {
owner = "steveyegge";
repo = "beads";
tag = "v${version}";
hash = "sha256-DwIR/r1TJnpVd/CT1E2OTkAjU7k9/KHbcVwg5zziFVg=";
};
vendorHash = "sha256-pY5m5ODRgqghyELRwwxOr+xlW41gtJWLXaW53GlLaFw=";
# Tests require git worktree operations that fail in Nix sandbox
doCheck = false;
})

View File

@@ -1,18 +0,0 @@
{prev}:
prev.n8n.overrideAttrs (oldAttrs: rec {
version = "2.4.1";
src = prev.fetchFromGitHub {
owner = "n8n-io";
repo = "n8n";
rev = "n8n@${version}";
hash = "sha256-EQP9ZI8kt30SUYE1+/UUpxQXpavzKqDu8qE24zsNifg=";
};
pnpmDeps = prev.pnpm_10.fetchDeps {
pname = oldAttrs.pname;
inherit version src;
fetcherVersion = 1;
hash = "sha256-Q30IuFEQD3896Hg0HCLd38YE2i8fJn74JY0o95LKJis=";
};
})