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:
@@ -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
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -3,144 +3,87 @@
|
|||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
with lib; let
|
shared = import ./shared-options.nix {inherit lib;};
|
||||||
cfg = config.coding.agents.claude-code;
|
in
|
||||||
mcpCfg = config.programs.mcp or null;
|
with lib; let
|
||||||
in {
|
cfg = config.coding.agents.claude-code;
|
||||||
options.coding.agents.claude-code = {
|
mcpCfg = config.programs.mcp or null;
|
||||||
enable = mkEnableOption "Claude Code agent management via canonical agent.toml definitions";
|
in {
|
||||||
|
options.coding.agents.claude-code = {
|
||||||
|
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;
|
||||||
default =
|
default =
|
||||||
if mcpCfg != null
|
if mcpCfg != null
|
||||||
then mcpCfg.servers
|
then mcpCfg.servers
|
||||||
else {};
|
else {};
|
||||||
defaultText = literalExpression "config.programs.mcp.servers";
|
defaultText = literalExpression "config.programs.mcp.servers";
|
||||||
description = ''
|
description = ''
|
||||||
MCP server configurations for Claude Code.
|
MCP server configurations for Claude Code.
|
||||||
Merged into ~/.claude/settings.json alongside permissions.
|
Merged into ~/.claude/settings.json alongside permissions.
|
||||||
Automatically inherits from config.programs.mcp.servers.
|
Automatically inherits from config.programs.mcp.servers.
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable (let
|
|
||||||
agentsLib = (import ../../../../lib {inherit lib;}).agents;
|
|
||||||
|
|
||||||
# Rendered agents + permissions (only if agentsInput is set)
|
|
||||||
rendered = mkIf (cfg.agentsInput != null) (
|
|
||||||
agentsLib.renderForClaudeCode {
|
|
||||||
inherit pkgs;
|
|
||||||
canonical = cfg.agentsInput.lib.loadAgents;
|
|
||||||
modelOverrides = cfg.modelOverrides;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
# Merge MCP servers into the rendered settings.json.
|
|
||||||
# The renderer produces { permissions: { allow, deny } }.
|
|
||||||
# We add mcpServers on top.
|
|
||||||
settingsJson =
|
|
||||||
if cfg.agentsInput != null
|
|
||||||
then let
|
|
||||||
renderedSettings = builtins.fromJSON (builtins.readFile "${rendered}/.claude/settings.json");
|
|
||||||
withMcp =
|
|
||||||
if cfg.mcpServers != {}
|
|
||||||
then renderedSettings // {mcpServers = cfg.mcpServers;}
|
|
||||||
else renderedSettings;
|
|
||||||
in
|
|
||||||
pkgs.writeText "claude-settings.json" (builtins.toJSON withMcp)
|
|
||||||
else if cfg.mcpServers != {}
|
|
||||||
then pkgs.writeText "claude-settings.json" (builtins.toJSON {mcpServers = cfg.mcpServers;})
|
|
||||||
else null;
|
|
||||||
in {
|
|
||||||
# Rendered agent files symlinked to ~/.claude/agents/
|
|
||||||
home.file.".claude/agents" = mkIf (cfg.agentsInput != null) {
|
|
||||||
source = "${rendered}/.claude/agents";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Skills (merged from personal AGENTS repo + optional external skills)
|
|
||||||
home.file.".claude/skills" = mkIf (cfg.agentsInput != null) {
|
|
||||||
source = cfg.agentsInput.lib.mkOpencodeSkills {
|
|
||||||
inherit pkgs;
|
|
||||||
customSkills = "${cfg.agentsInput}/skills";
|
|
||||||
externalSkills =
|
|
||||||
map (
|
|
||||||
entry:
|
|
||||||
{inherit (entry) src skillsDir;}
|
|
||||||
// optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
|
|
||||||
)
|
|
||||||
cfg.externalSkills;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Rendered settings.json with permissions + MCP servers
|
config = mkIf cfg.enable (let
|
||||||
home.file.".claude/settings.json" = mkIf (settingsJson != null) {
|
agentsLib = (import ../../../../lib {inherit lib;}).agents;
|
||||||
source = "${settingsJson}";
|
|
||||||
};
|
# Rendered agents + permissions (only if agentsInput is set)
|
||||||
});
|
rendered = mkIf (cfg.agentsInput != null) (
|
||||||
}
|
agentsLib.renderForClaudeCode {
|
||||||
|
inherit pkgs;
|
||||||
|
canonical = cfg.agentsInput.lib.loadAgents;
|
||||||
|
modelOverrides = cfg.modelOverrides;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# Merge MCP servers into the rendered settings.json.
|
||||||
|
# The renderer produces { permissions: { allow, deny } }.
|
||||||
|
# We add mcpServers on top.
|
||||||
|
settingsJson =
|
||||||
|
if cfg.agentsInput != null
|
||||||
|
then let
|
||||||
|
renderedSettings = builtins.fromJSON (builtins.readFile "${rendered}/.claude/settings.json");
|
||||||
|
withMcp =
|
||||||
|
if cfg.mcpServers != {}
|
||||||
|
then renderedSettings // {mcpServers = cfg.mcpServers;}
|
||||||
|
else renderedSettings;
|
||||||
|
in
|
||||||
|
pkgs.writeText "claude-settings.json" (builtins.toJSON withMcp)
|
||||||
|
else if cfg.mcpServers != {}
|
||||||
|
then pkgs.writeText "claude-settings.json" (builtins.toJSON {mcpServers = cfg.mcpServers;})
|
||||||
|
else null;
|
||||||
|
in {
|
||||||
|
# Rendered agent files symlinked to ~/.claude/agents/
|
||||||
|
home.file.".claude/agents" = mkIf (cfg.agentsInput != null) {
|
||||||
|
source = "${rendered}/.claude/agents";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Skills (merged from personal AGENTS repo + optional external skills)
|
||||||
|
home.file.".claude/skills" = mkIf (cfg.agentsInput != null) {
|
||||||
|
source = cfg.agentsInput.lib.mkOpencodeSkills {
|
||||||
|
inherit pkgs;
|
||||||
|
customSkills = "${cfg.agentsInput}/skills";
|
||||||
|
externalSkills = shared.mapExternalSkills cfg.externalSkills;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Rendered settings.json with permissions + MCP servers
|
||||||
|
home.file.".claude/settings.json" = mkIf (settingsJson != null) {
|
||||||
|
source = "${settingsJson}";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,111 +3,67 @@
|
|||||||
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;
|
# Rendered agent files symlinked to ~/.config/opencode/agents/
|
||||||
default = {};
|
xdg.configFile."opencode/agents" = let
|
||||||
description = ''
|
cfg = config.coding.agents.opencode;
|
||||||
Per-agent model overrides. Maps agent slug to model string.
|
in
|
||||||
Example: { chiron = "anthropic/claude-sonnet-4"; }
|
mkIf (cfg.agentsInput != null) {
|
||||||
'';
|
source = (import ../../../../lib {inherit lib;}).agents.renderForOpencode {
|
||||||
example = literalExpression ''
|
inherit pkgs;
|
||||||
{
|
canonical = cfg.agentsInput.lib.loadAgents;
|
||||||
chiron = "anthropic/claude-sonnet-4";
|
modelOverrides = cfg.modelOverrides;
|
||||||
"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 {
|
# Skills (merged from personal AGENTS repo + optional external skills)
|
||||||
# Rendered agent files symlinked to ~/.config/opencode/agents/
|
xdg.configFile."opencode/skills" = let
|
||||||
xdg.configFile."opencode/agents" = mkIf (cfg.agentsInput != null) {
|
cfg = config.coding.agents.opencode;
|
||||||
source = (import ../../../../lib {inherit lib;}).agents.renderForOpencode {
|
in
|
||||||
inherit pkgs;
|
mkIf (cfg.agentsInput != null) {
|
||||||
canonical = cfg.agentsInput.lib.loadAgents;
|
source = cfg.agentsInput.lib.mkOpencodeSkills {
|
||||||
modelOverrides = cfg.modelOverrides;
|
inherit pkgs;
|
||||||
};
|
customSkills = "${cfg.agentsInput}/skills";
|
||||||
};
|
externalSkills = shared.mapExternalSkills cfg.externalSkills;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Skills (merged from personal AGENTS repo + optional external skills)
|
# Static config dirs from AGENTS repo
|
||||||
xdg.configFile."opencode/skills" = mkIf (cfg.agentsInput != null) {
|
xdg.configFile."opencode/context" = let
|
||||||
source = cfg.agentsInput.lib.mkOpencodeSkills {
|
cfg = config.coding.agents.opencode;
|
||||||
inherit pkgs;
|
in
|
||||||
customSkills = "${cfg.agentsInput}/skills";
|
mkIf (cfg.agentsInput != null) {
|
||||||
externalSkills =
|
source = "${cfg.agentsInput}/context";
|
||||||
map (
|
};
|
||||||
entry:
|
xdg.configFile."opencode/commands" = let
|
||||||
{inherit (entry) src skillsDir;}
|
cfg = config.coding.agents.opencode;
|
||||||
// optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
|
in
|
||||||
)
|
mkIf (cfg.agentsInput != null) {
|
||||||
cfg.externalSkills;
|
source = "${cfg.agentsInput}/commands";
|
||||||
};
|
};
|
||||||
|
xdg.configFile."opencode/prompts" = let
|
||||||
|
cfg = config.coding.agents.opencode;
|
||||||
|
in
|
||||||
|
mkIf (cfg.agentsInput != null) {
|
||||||
|
source = "${cfg.agentsInput}/prompts";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
}
|
||||||
# Static config dirs from AGENTS repo
|
|
||||||
xdg.configFile."opencode/context" = mkIf (cfg.agentsInput != null) {
|
|
||||||
source = "${cfg.agentsInput}/context";
|
|
||||||
};
|
|
||||||
xdg.configFile."opencode/commands" = mkIf (cfg.agentsInput != null) {
|
|
||||||
source = "${cfg.agentsInput}/commands";
|
|
||||||
};
|
|
||||||
xdg.configFile."opencode/prompts" = mkIf (cfg.agentsInput != null) {
|
|
||||||
source = "${cfg.agentsInput}/prompts";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,277 +3,225 @@
|
|||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
with lib; let
|
shared = import ./shared-options.nix {inherit lib;};
|
||||||
cfg = config.coding.agents.pi;
|
in
|
||||||
mcpCfg = config.programs.mcp or null;
|
with lib; let
|
||||||
in {
|
cfg = config.coding.agents.pi;
|
||||||
options.coding.agents.pi = {
|
mcpCfg = config.programs.mcp or null;
|
||||||
enable = mkEnableOption "Pi agent management via canonical agent.toml definitions";
|
in {
|
||||||
|
options.coding.agents.pi = {
|
||||||
|
enable = mkEnableOption "Pi agent management via canonical agent.toml definitions";
|
||||||
|
|
||||||
mcpServers = mkOption {
|
mcpServers = mkOption {
|
||||||
type = types.attrsOf types.anything;
|
type = types.attrsOf types.anything;
|
||||||
default = if mcpCfg != null then mcpCfg.servers else {};
|
default = if mcpCfg != null then mcpCfg.servers else {};
|
||||||
defaultText = literalExpression "config.programs.mcp.servers";
|
defaultText = literalExpression "config.programs.mcp.servers";
|
||||||
description = ''
|
description = ''
|
||||||
MCP server configurations for Pi (pi-mcp-adapter).
|
MCP server configurations for Pi (pi-mcp-adapter).
|
||||||
Written to ~/.pi/agent/mcp.json.
|
Written to ~/.pi/agent/mcp.json.
|
||||||
Automatically inherits from config.programs.mcp.servers.
|
Automatically inherits from config.programs.mcp.servers.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
Override which canonical agent is used as primary for SYSTEM.md.
|
Override which canonical agent is used as primary for SYSTEM.md.
|
||||||
When null, the first agent with mode="primary" is used.
|
When null, the first agent with mode="primary" is used.
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
|
|
||||||
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.basecamp; }
|
|
||||||
]
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
settings = mkOption {
|
|
||||||
type = types.submodule {
|
|
||||||
freeformType = types.attrsOf types.anything;
|
|
||||||
options = {
|
|
||||||
packages = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Pi packages to install (npm:, git:, or local paths).
|
|
||||||
These are written to ~/.pi/agent/settings.json.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultProvider = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Default LLM provider (e.g. 'anthropic', 'openai', 'zai').";
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultModel = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Default model ID.";
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultThinkingLevel = mkOption {
|
|
||||||
type = types.nullOr (types.enum ["off" "minimal" "low" "medium" "high" "xhigh"]);
|
|
||||||
default = null;
|
|
||||||
description = "Default extended thinking level.";
|
|
||||||
};
|
|
||||||
|
|
||||||
theme = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Pi theme name.";
|
|
||||||
};
|
|
||||||
|
|
||||||
hideThinkingBlock = mkOption {
|
|
||||||
type = types.nullOr types.bool;
|
|
||||||
default = null;
|
|
||||||
description = "Hide thinking blocks in output.";
|
|
||||||
};
|
|
||||||
|
|
||||||
quietStartup = mkOption {
|
|
||||||
type = types.nullOr types.bool;
|
|
||||||
default = null;
|
|
||||||
description = "Hide startup header.";
|
|
||||||
};
|
|
||||||
|
|
||||||
compaction = mkOption {
|
|
||||||
type = types.nullOr (types.submodule {
|
|
||||||
options = {
|
|
||||||
enabled = mkOption {
|
|
||||||
type = types.nullOr types.bool;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
reserveTokens = mkOption {
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
keepRecentTokens = mkOption {
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
default = null;
|
|
||||||
description = "Auto-compaction settings.";
|
|
||||||
};
|
|
||||||
|
|
||||||
enabledModels = mkOption {
|
|
||||||
type = types.nullOr (types.listOf types.str);
|
|
||||||
default = null;
|
|
||||||
description = "Model patterns for Ctrl+P cycling.";
|
|
||||||
};
|
|
||||||
|
|
||||||
sessionDir = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Directory where session files are stored.";
|
|
||||||
};
|
|
||||||
|
|
||||||
extensions = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = "Local extension file paths or directories.";
|
|
||||||
};
|
|
||||||
|
|
||||||
skills = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = "Local skill file paths or directories.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
default = {};
|
|
||||||
description = ''
|
|
||||||
Pi settings written to ~/.pi/agent/settings.json.
|
|
||||||
Only non-null values are included in the generated JSON.
|
|
||||||
See pi docs/settings.md for all options.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable (let
|
externalSkills = shared.externalSkillsOption;
|
||||||
# Build settings.json by filtering out null values recursively
|
|
||||||
filterNulls = attrs:
|
|
||||||
lib.filterAttrs (_: v: v != null) (
|
|
||||||
builtins.mapAttrs (_: v:
|
|
||||||
if builtins.isAttrs v
|
|
||||||
then let
|
|
||||||
filtered = filterNulls v;
|
|
||||||
in
|
|
||||||
if filtered == {} then null else filtered
|
|
||||||
else v) attrs
|
|
||||||
);
|
|
||||||
|
|
||||||
piSettings = filterNulls cfg.settings;
|
settings = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = types.attrsOf types.anything;
|
||||||
|
options = {
|
||||||
|
packages = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
Pi packages to install (npm:, git:, or local paths).
|
||||||
|
These are written to ~/.pi/agent/settings.json.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
# Rendered agents (only computed when agentsInput is set)
|
defaultProvider = mkOption {
|
||||||
rendered =
|
type = types.nullOr types.str;
|
||||||
if cfg.agentsInput != null
|
default = null;
|
||||||
then
|
description = "Default LLM provider (e.g. 'anthropic', 'openai', 'zai').";
|
||||||
(import ../../../../lib {inherit lib;}).agents.renderForPi {
|
};
|
||||||
inherit pkgs;
|
|
||||||
canonical = cfg.agentsInput.lib.loadAgents;
|
|
||||||
modelOverrides = cfg.modelOverrides;
|
|
||||||
primaryAgent = cfg.primaryAgent;
|
|
||||||
}
|
|
||||||
else null;
|
|
||||||
|
|
||||||
# Dynamic home.file entries for agent .md files
|
defaultModel = mkOption {
|
||||||
agentFiles =
|
type = types.nullOr types.str;
|
||||||
if cfg.agentsInput != null
|
default = null;
|
||||||
then
|
description = "Default model ID.";
|
||||||
let
|
};
|
||||||
agentNames = builtins.attrNames cfg.agentsInput.lib.loadAgents;
|
|
||||||
in
|
|
||||||
builtins.listToAttrs (
|
|
||||||
map (name: {
|
|
||||||
name = ".pi/agent/agents/${name}.md";
|
|
||||||
value = {source = "${rendered}/agents/${name}.md";};
|
|
||||||
})
|
|
||||||
agentNames
|
|
||||||
)
|
|
||||||
else {};
|
|
||||||
in {
|
|
||||||
home.file = mkMerge [
|
|
||||||
# ── MCP servers from programs.mcp → ~/.pi/agent/mcp.json ───────
|
|
||||||
(mkIf (cfg.mcpServers != {}) {
|
|
||||||
".pi/agent/mcp.json".text = builtins.toJSON {mcpServers = cfg.mcpServers;};
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── ~/.pi/agent/settings.json ──────────────────────────────────
|
defaultThinkingLevel = mkOption {
|
||||||
{
|
type = types.nullOr (types.enum ["off" "minimal" "low" "medium" "high" "xhigh"]);
|
||||||
".pi/agent/settings.json".text = builtins.toJSON piSettings;
|
default = null;
|
||||||
}
|
description = "Default extended thinking level.";
|
||||||
|
};
|
||||||
|
|
||||||
# ── AGENTS.md — agent descriptions and specialist listing ──────
|
theme = mkOption {
|
||||||
(mkIf (cfg.agentsInput != null) {
|
type = types.nullOr types.str;
|
||||||
".pi/agent/AGENTS.md".source = "${rendered}/AGENTS.md";
|
default = null;
|
||||||
})
|
description = "Pi theme name.";
|
||||||
|
};
|
||||||
|
|
||||||
# ── SYSTEM.md — primary agent's system prompt ──────────────────
|
hideThinkingBlock = mkOption {
|
||||||
(mkIf (cfg.agentsInput != null) {
|
type = types.nullOr types.bool;
|
||||||
".pi/agent/SYSTEM.md".source = "${rendered}/SYSTEM.md";
|
default = null;
|
||||||
})
|
description = "Hide thinking blocks in output.";
|
||||||
|
};
|
||||||
|
|
||||||
# ── Agents — pi-subagents .md files ────────────────────────────
|
quietStartup = mkOption {
|
||||||
agentFiles
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = "Hide startup header.";
|
||||||
|
};
|
||||||
|
|
||||||
# ── Skills symlinked from AGENTS repo + external skills ────────
|
compaction = mkOption {
|
||||||
(mkIf (cfg.agentsInput != null) {
|
type = types.nullOr (types.submodule {
|
||||||
".pi/agent/skills".source = cfg.agentsInput.lib.mkOpencodeSkills {
|
options = {
|
||||||
inherit pkgs;
|
enabled = mkOption {
|
||||||
customSkills = "${cfg.agentsInput}/skills";
|
type = types.nullOr types.bool;
|
||||||
externalSkills =
|
default = null;
|
||||||
map (
|
};
|
||||||
entry:
|
reserveTokens = mkOption {
|
||||||
{inherit (entry) src skillsDir;}
|
type = types.nullOr types.int;
|
||||||
// optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
|
default = null;
|
||||||
)
|
};
|
||||||
cfg.externalSkills;
|
keepRecentTokens = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = null;
|
||||||
|
description = "Auto-compaction settings.";
|
||||||
|
};
|
||||||
|
|
||||||
|
enabledModels = mkOption {
|
||||||
|
type = types.nullOr (types.listOf types.str);
|
||||||
|
default = null;
|
||||||
|
description = "Model patterns for Ctrl+P cycling.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sessionDir = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Directory where session files are stored.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extensions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "Local extension file paths or directories.";
|
||||||
|
};
|
||||||
|
|
||||||
|
skills = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "Local skill file paths or directories.";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
})
|
default = {};
|
||||||
];
|
description = ''
|
||||||
});
|
Pi settings written to ~/.pi/agent/settings.json.
|
||||||
}
|
Only non-null values are included in the generated JSON.
|
||||||
|
See pi docs/settings.md for all options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (let
|
||||||
|
# Build settings.json by filtering out null values recursively
|
||||||
|
filterNulls = attrs:
|
||||||
|
lib.filterAttrs (_: v: v != null) (
|
||||||
|
builtins.mapAttrs (_: v:
|
||||||
|
if builtins.isAttrs v
|
||||||
|
then let
|
||||||
|
filtered = filterNulls v;
|
||||||
|
in
|
||||||
|
if filtered == {} then null else filtered
|
||||||
|
else v) attrs
|
||||||
|
);
|
||||||
|
|
||||||
|
piSettings = filterNulls cfg.settings;
|
||||||
|
|
||||||
|
# Rendered agents (only computed when agentsInput is set)
|
||||||
|
rendered =
|
||||||
|
if cfg.agentsInput != null
|
||||||
|
then
|
||||||
|
(import ../../../../lib {inherit lib;}).agents.renderForPi {
|
||||||
|
inherit pkgs;
|
||||||
|
canonical = cfg.agentsInput.lib.loadAgents;
|
||||||
|
modelOverrides = cfg.modelOverrides;
|
||||||
|
primaryAgent = cfg.primaryAgent;
|
||||||
|
}
|
||||||
|
else null;
|
||||||
|
|
||||||
|
# Dynamic home.file entries for agent .md files
|
||||||
|
agentFiles =
|
||||||
|
if cfg.agentsInput != null
|
||||||
|
then
|
||||||
|
let
|
||||||
|
agentNames = builtins.attrNames cfg.agentsInput.lib.loadAgents;
|
||||||
|
in
|
||||||
|
builtins.listToAttrs (
|
||||||
|
map (name: {
|
||||||
|
name = ".pi/agent/agents/${name}.md";
|
||||||
|
value = {source = "${rendered}/agents/${name}.md";};
|
||||||
|
})
|
||||||
|
agentNames
|
||||||
|
)
|
||||||
|
else {};
|
||||||
|
in {
|
||||||
|
home.file = mkMerge [
|
||||||
|
# ── MCP servers from programs.mcp → ~/.pi/agent/mcp.json ───────
|
||||||
|
(mkIf (cfg.mcpServers != {}) {
|
||||||
|
".pi/agent/mcp.json".text = builtins.toJSON {mcpServers = cfg.mcpServers;};
|
||||||
|
})
|
||||||
|
|
||||||
|
# ── ~/.pi/agent/settings.json ──────────────────────────────────
|
||||||
|
{
|
||||||
|
".pi/agent/settings.json".text = builtins.toJSON piSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── AGENTS.md — agent descriptions and specialist listing ──────
|
||||||
|
(mkIf (cfg.agentsInput != null) {
|
||||||
|
".pi/agent/AGENTS.md".source = "${rendered}/AGENTS.md";
|
||||||
|
})
|
||||||
|
|
||||||
|
# ── SYSTEM.md — primary agent's system prompt ──────────────────
|
||||||
|
(mkIf (cfg.agentsInput != null) {
|
||||||
|
".pi/agent/SYSTEM.md".source = "${rendered}/SYSTEM.md";
|
||||||
|
})
|
||||||
|
|
||||||
|
# ── Agents — pi-subagents .md files ────────────────────────────
|
||||||
|
agentFiles
|
||||||
|
|
||||||
|
# ── Skills symlinked from AGENTS repo + external skills ────────
|
||||||
|
(mkIf (cfg.agentsInput != null) {
|
||||||
|
".pi/agent/skills".source = cfg.agentsInput.lib.mkOpencodeSkills {
|
||||||
|
inherit pkgs;
|
||||||
|
customSkills = "${cfg.agentsInput}/skills";
|
||||||
|
externalSkills = shared.mapExternalSkills cfg.externalSkills;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
75
modules/home-manager/coding/agents/shared-options.nix
Normal file
75
modules/home-manager/coding/agents/shared-options.nix
Normal 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;
|
||||||
|
}
|
||||||
@@ -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;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
})
|
|
||||||
@@ -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=";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
Reference in New Issue
Block a user