docs: update zellij-ps to reflect project switcher functionality

- Update package description and fix mainProgram typo
- Rewrite documentation to describe project switching, not process viewing
- Add PROJECT_FOLDERS configuration and usage examples
- Update all references across docs (README, guides, module overviews)
This commit is contained in:
m3tm3re
2025-12-30 15:42:52 +01:00
parent 744b6a8243
commit 44485c4c72
28 changed files with 8096 additions and 24 deletions

473
docs/ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,473 @@
# Architecture
Understanding the design and structure of m3ta-nixpkgs.
## Overview
m3ta-nixpkgs is organized as a modern Nix flake with a focus on reusability, consistency, and maintainability. The repository follows clear conventions and patterns to make it easy to understand, extend, and contribute to.
## Repository Structure
```
m3ta-nixpkgs/
├── flake.nix # Main entry point, defines all outputs
├── pkgs/ # Custom packages (callPackage registry)
│ ├── default.nix # Package registry (entry point)
│ ├── code2prompt/ # Individual packages
│ ├── hyprpaper-random/
│ ├── mem0/
│ └── ...
├── modules/
│ ├── nixos/ # NixOS modules
│ │ ├── default.nix # Module aggregator
│ │ ├── mem0.nix
│ │ └── ports.nix
│ └── home-manager/ # Home Manager modules
│ ├── default.nix # Module aggregator
│ ├── ports.nix
│ ├── cli/ # Categorized modules
│ │ ├── default.nix
│ │ └── zellij-ps.nix
│ └── coding/
│ ├── default.nix
│ └── editors.nix
├── lib/ # Shared utilities
│ ├── default.nix # Library aggregator
│ └── ports.nix # Port management functions
├── shells/ # Development environments
│ ├── default.nix # Shell registry
│ ├── python.nix
│ └── devops.nix
├── overlays/ # Package modifications
│ ├── default.nix # Overlay aggregator
│ └── mods/
│ └── default.nix # Individual overlays
├── templates/ # Boilerplate for new items
│ ├── package/
│ ├── nixos-module/
│ └── home-manager-module/
├── examples/ # Usage examples
│ ├── nixos-configuration.nix
│ └── home-manager-standalone.nix
└── docs/ # Documentation
```
## Flake Outputs
`flake.nix` is the entry point that defines all outputs:
### Packages
```nix
packages = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./pkgs {inherit pkgs;});
```
- Built for all supported systems
- Uses `callPackage` pattern for lazy evaluation
- Available via `nix build .#<package-name>`
### Overlays
```nix
overlays = {
# Default overlay: adds all custom packages
default = final: prev: import ./pkgs {pkgs = final;};
# Additions overlay: same as default
additions = final: prev: import ./pkgs {pkgs = final;};
# Modifications overlay: modifies existing nixpkgs packages
modifications = final: prev: import ./overlays/mods {inherit prev;};
};
```
- `default`: Adds all custom packages to nixpkgs
- `additions`: Individual package additions
- `modifications`: Overrides existing packages
### NixOS Modules
```nix
nixosModules = {
default = ./modules/nixos; # Import all modules
ports = ./modules/nixos/ports.nix; # Specific module
mem0 = ./modules/nixos/mem0.nix;
};
```
- System-level configuration modules
- Use `m3ta.*` namespace
- Can import all modules or individual ones
### Home Manager Modules
```nix
homeManagerModules = {
default = import ./modules/home-manager;
ports = import ./modules/home-manager/ports.nix;
zellij-ps = import ./modules/home-manager/zellij-ps.nix;
};
```
- User-level configuration modules
- Categorized by function (cli, coding)
- Use `m3ta.*` namespace
### Library Functions
```nix
lib = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./lib {lib = pkgs.lib;});
```
- Helper functions for configuration
- Port management utilities
- Can be used in your configurations
### Development Shells
```nix
devShells = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./shells {inherit pkgs;});
```
- Pre-configured development environments
- Available: `default`, `python`, `devops`
- Usage: `nix develop .#<shell-name>`
### Templates
```nix
templates = {
package = {
path = ./templates/package;
description = "Template for a new package";
};
nixos-module = {
path = ./templates/nixos-module;
description = "Template for a new NixOS module";
};
home-manager-module = {
path = ./templates/home-manager-module;
description = "Template for a new Home Manager module";
};
};
```
- Boilerplate for quick start
- Usage: `nix flake init -t .#template-name`
## Package Organization
### Registry Pattern
`pkgs/default.nix` acts as a central registry:
```nix
{
inherit (pkgs) callPackage;
} rec {
code2prompt = callPackage ./code2prompt {};
hyprpaper-random = callPackage ./hyprpaper-random {};
mem0 = callPackage ./mem0 {};
# ...
}
```
**Benefits**:
- Lazy evaluation: only builds requested packages
- Consistent interface: all packages use `callPackage`
- Easy discovery: one file lists all packages
### Package Structure
Each package lives in its own directory:
```
pkgs/your-package/
├── default.nix # Package definition
├── source.py # Optional: source files
└── README.md # Optional: package documentation
```
**Conventions**:
- Directory name matches registry attribute
- Use `callPackage` for dependencies
- Always include `meta` with all fields
### Common Package Patterns
#### Rust Packages
```nix
rustPlatform.buildRustPackage rec {
pname = "myapp";
version = "1.0.0";
src = fetchFromGitHub { ... };
cargoLock.lockFile = src + "/Cargo.lock";
# ...
}
```
#### Python Packages
```nix
python3.pkgs.buildPythonPackage rec {
pname = "mypythonapp";
version = "1.0.0";
src = fetchFromGitHub { ... };
dependencies = with python3.pkgs; [requests click];
# ...
}
```
#### Shell Scripts
```nix
writeShellScriptBin "myscript" ''
#!/usr/bin/env bash
echo "Hello World"
''
```
#### AppImage
```nix
appimageTools.wrapType2 rec {
name = "myapp";
src = fetchurl { ... };
# ...
}
```
## Module Organization
### NixOS Modules
Located in `modules/nixos/`:
```
modules/nixos/
├── default.nix # Imports all modules
├── ports.nix # Port management
├── mem0.nx # Individual module
```
**Pattern**:
```nix
{config, lib, pkgs, ...}:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "description";
# ... options
};
config = mkIf cfg.enable {
# ... configuration
};
}
```
### Home Manager Modules
Located in `modules/home-manager/` with categories:
```
modules/home-manager/
├── default.nix # Imports all modules
├── ports.nix # Port management
├── cli/
│ ├── default.nix # Aggregates CLI modules
│ └── zellij-ps.nix
└── coding/
├── default.nix # Aggregates coding modules
└── editors.nix
```
**Categories**:
- `cli/`: Command-line tools and utilities
- `coding/`: Development tools and editors
**Pattern** (same as NixOS):
```nix
{config, lib, pkgs, ...}:
with lib; let
cfg = config.m3ta.coding.editors;
in {
options.m3ta.coding.editors = {
enable = mkEnableOption "editor configuration";
# ... options
};
config = mkIf cfg.enable {
# ... configuration
};
}
```
## Library Functions
Located in `lib/`:
```nix
{lib}: {
# Port management utilities
ports = import ./ports.nix {inherit lib;};
}
```
### Port Management
Centralized port management across hosts:
```nix
# Usage in configuration
portHelpers = inputs.m3ta-nixpkgs.lib.${system}.ports.mkPortHelpers myPorts;
# Get port with host override
services.nginx.port = portHelpers.getPort "nginx" "laptop";
# Get all ports for host
allLaptopPorts = portHelpers.getHostPorts "laptop";
```
**Benefits**:
- Single source of truth for ports
- Host-specific overrides
- Avoid port conflicts
## Naming Conventions
| Context | Convention | Example |
|---------|------------|---------|
| Packages | `lowercase-hyphen` | `hyprpaper-random` |
| Variables | `camelCase` | `portHelpers` |
| Module options | `m3ta.*` | `m3ta.ports.enable` |
| Files | `lowercase-hyphen` | `my-module.nix` |
| Directories | `lowercase-hyphen` | `cli/`, `coding/` |
## Code Patterns
### Module Options
Always use `mkEnableOption` for enable flags:
```nix
options.m3ta.myModule = {
enable = mkEnableOption "description";
};
```
### Conditional Configuration
Use `mkIf` for conditional config:
```nix
config = mkIf cfg.enable {
# Only applied when cfg.enable is true
};
```
### Multiple Conditions
Use `mkMerge` for multiple conditions:
```nix
config = mkMerge [
(mkIf cfg.feature1.enable { ... })
(mkIf cfg.feature2.enable { ... })
];
```
### Imports
Multi-line, trailing commas:
```nix
{
lib,
stdenv,
fetchFromGitHub,
}:
```
### Meta Fields
Always include all fields:
```nix
meta = with lib; {
description = "...";
homepage = "...";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "program-name";
};
```
## Design Decisions
### Flakes-Only
**Decision**: Use flakes exclusively, no channels.
**Rationale**:
- Reproducible builds
- Explicit dependencies
- Better integration with modern Nix tooling
### CallPackage Pattern
**Decision**: Use `callPackage` for all packages.
**Rationale**:
- Lazy evaluation
- Clear dependency graph
- Consistent interface
### Module Categorization
**Decision**: Categorize Home Manager modules by function.
**Rationale**:
- Easier to find related modules
- Logical organization
- Follows user mental model
### Port Management
**Decision**: Centralized port management with host overrides.
**Rationale**:
- Avoid port conflicts
- Easy to manage multiple hosts
- Single source of truth
### Namespace Convention
**Decision**: Use `m3ta.*` namespace for all modules.
**Rationale**:
- Avoid conflicts
- Clear attribution
- Easy to discover
## Supported Systems
- `x86_64-linux` - Primary development target
- `aarch64-linux` - ARM Linux
- `x86_64-darwin` - macOS Intel
- `aarch64-darwin` - macOS Apple Silicon
**Note**: Some packages may be Linux-only (check `meta.platforms`).

360
docs/CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,360 @@
# Contributing
Contributing to m3ta-nixpkgs.
## Setting Up Development Environment
```bash
# Clone repository
git clone https://code.m3ta.dev/m3tam3re/nixpkgs.git
cd nixpkgs
# Enter development shell (includes linting tools)
nix develop
# Or use a specific shell
nix develop .#python
nix develop .#devops
```
## Code Style and Formatting
### Formatting
Use alejandra to format Nix files:
```bash
# Format all files
nix fmt
# Format specific file
alejandra path/to/file.nix
```
**Always run `nix fmt` before committing.**
### Linting
Linting tools are only available inside the dev shell:
```bash
# Enter dev shell first
nix develop
# Run statix (linter)
statix check .
# Run deadnix (find dead code)
deadnix .
```
## Conventions
### Naming
- **Packages**: `lowercase-hyphen` (e.g., `hyprpaper-random`)
- **Variables**: `camelCase` (e.g., `portHelpers`)
- **Module options**: `m3ta.*` namespace
- **Files**: `lowercase-hyphen` (e.g., `my-module.nix`)
### Imports
Multi-line, trailing commas:
```nix
{
lib,
stdenv,
fetchFromGitHub,
}:
```
### Meta Fields
Always include all fields in package definitions:
```nix
meta = with lib; {
description = "Short description";
homepage = "https://github.com/author/repo";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "program-name";
};
```
### Module Pattern
Standard module pattern:
```nix
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "description";
};
config = mkIf cfg.enable {
# Configuration
};
}
```
## Adding a Package
1. Create package directory in `pkgs/your-package/`
2. Write `default.nix` with package definition
3. Register in `pkgs/default.nix`
See [Adding Packages Guide](./guides/adding-packages.md) for detailed instructions.
### Package Testing
```bash
# Build the package
nix build .#your-package
# Test if package runs
nix run .#your-package -- --help
# Check with linter
nix develop
statix check pkgs/your-package/
```
## Adding a NixOS Module
1. Create module file in `modules/nixos/your-module.nix`
2. Import in `modules/nixos/default.nix` (or use directly)
```nix
# modules/nixos/default.nix
{
imports = [
./your-module.nix
./other-module.nix
];
}
```
## Adding a Home Manager Module
1. Choose appropriate category: `cli/`, `coding/`, or root
2. Create module file
3. Import in category's `default.nix` or root `default.nix`
```nix
# modules/home-manager/cli/default.nix
{
imports = [
./your-tool.nix
];
}
```
## Development Workflow
### Making Changes
```bash
# Create feature branch
git checkout -b feature/your-change
# Make changes
# Format code
nix fmt
# Test builds
nix build .#your-package
nix flake check
# Lint
nix develop
statix check .
deadnix .
```
### Commit Format
Use conventional commits:
```
type: brief description
Types:
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Code style changes (formatting)
- refactor: Code refactoring
- chore: Maintenance tasks
- test: Adding or updating tests
```
Examples:
```
feat: add new package for myapp
fix: resolve port conflict in mem0 module
docs: update installation instructions
style: format nix files
refactor: simplify port management
chore: update dependencies
```
### Before Committing
```bash
# Format all files
nix fmt
# Validate flake
nix flake check
# Run linters
nix develop
statix check .
deadnix .
# Add files
git add .
# Commit
git commit -m "type: description"
```
## Testing
### Package Testing
```bash
# Build for specific system
nix build .#your-package --system x86_64-linux
# Test on different systems
nix build .#your-package --system aarch64-linux
```
### Module Testing
```bash
# Test NixOS configuration
sudo nixos-rebuild test --flake .#hostname
# Test Home Manager configuration
home-manager switch --flake .#username@hostname
```
### Flake Validation
```bash
# Validate all outputs
nix flake check
# Show all outputs
nix flake show
```
## Pull Requests
### Before Submitting
1. [ ] Code formatted with `nix fmt`
2. [ ] Passes `statix check .`
3. [ ] Passes `deadnix .`
4. [ ] Passes `nix flake check`
5. [ ] New packages include `meta` fields
6. [ ] Documentation updated if needed
7. [ ] Commit messages follow convention
### PR Description
Include:
- What changed and why
- How to test
- Any breaking changes
- Related issues
## Troubleshooting
### Hash Errors
When building packages, you may encounter hash errors:
```
got: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
expected: sha256-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=
```
**Solution**: Copy the `got` hash and update the package:
```nix
src = fetchFromGitHub {
# ...
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Use actual hash
};
```
### Dependency Not Found
If a package isn't found, check:
1. Package registered in `pkgs/default.nix`
2. Overlay applied in your configuration
3. System matches supported platform
### Linting Errors
```bash
# Fix statix issues manually or use auto-fix where available
statix fix .
# Review deadnix suggestions
deadnix -e .
```
## Getting Help
- Check existing packages and modules for patterns
- Read [Architecture](./ARCHITECTURE.md) for design decisions
- Review [Code Patterns](./reference/patterns.md) for conventions
- Open an issue for questions
## Anti-Patterns
| Don't | Do Instead |
|-------|------------|
| `lib.fakeHash` in commits | Get real hash: `nix build`, copy from error |
| Flat module files | Organize by category (`cli/`, `coding/`) |
| Hardcode ports | Use `m3ta.ports` module |
| Skip meta fields | Include all: description, homepage, license, platforms, mainProgram |
| `with pkgs;` in modules | Explicit `pkgs.package` or `with pkgs; [ ... ]` in lists only |
| Suppress type errors | Fix underlying type issues |
| Delete tests to "pass" | Fix failing tests |
## Code Review Checklist
- [ ] Follows naming conventions
- [ ] Properly formatted (`nix fmt`)
- [ ] Passes linting (`statix`, `deadnix`)
- [ ] Has complete `meta` fields (packages)
- [ ] Documentation updated if needed
- [ ] No dead code
- [ ] No obvious bugs or issues
- [ ] Appropriate for scope
## Release Process
This is a personal repository, but semantic versioning is followed for tags:
1. Update versions as needed
2. Update changelog
3. Tag release
4. Push tags
```bash
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
```

316
docs/QUICKSTART.md Normal file
View File

@@ -0,0 +1,316 @@
# Quick Start Guide
Get started with m3ta-nixpkgs in 5 minutes.
## Prerequisites
- Nix with flakes enabled (Nix 2.4+)
- Basic familiarity with NixOS and/or Home Manager
Enable flakes in `/etc/nixos/configuration.nix`:
```nix
nix.settings.experimental-features = ["nix-command" "flakes"];
```
## Adding to Your Flake
### NixOS Configuration
```nix
{
description = "My NixOS configuration";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
m3ta-nixpkgs = {
url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
home-manager,
m3ta-nixpkgs,
...
}: {
nixosConfigurations = {
hostname = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./hardware-configuration.nix
# Import m3ta's NixOS modules
m3ta-nixpkgs.nixosModules.default
# Apply overlay to make packages available
({pkgs, ...}: {
nixpkgs.overlays = [m3ta-nixpkgs.overlays.default];
environment.systemPackages = with pkgs; [
code2prompt
zellij-ps
# Regular nixpkgs packages
vim
];
})
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.yourusername = {
imports = [m3ta-nixpkgs.homeManagerModules.default];
home.packages = with pkgs; [
launch-webapp
];
};
}
];
};
};
};
}
```
### Standalone Home Manager
```nix
{
description = "My Home Manager configuration";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
m3ta-nixpkgs = {
url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
home-manager,
m3ta-nixpkgs,
} @ inputs: let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
overlays = [m3ta-nixpkgs.overlays.default];
};
in {
homeConfigurations.yourusername = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
extraSpecialArgs = {inherit inputs;};
modules = [
m3ta-nixpkgs.homeManagerModules.default
{
home.username = "yourusername";
home.homeDirectory = "/home/yourusername";
home.packages = with pkgs; [
code2prompt
zellij-ps
];
programs.home-manager.enable = true;
}
];
};
};
}
```
## Using Packages Without Configuration
You can build and run packages directly without adding to your configuration:
```bash
# Build a package
nix build git+https://code.m3ta.dev/m3tam3re/nixpkgs#code2prompt
# Run a package
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#zellij-ps
# List all available packages
nix flake show git+https://code.m3ta.dev/m3tam3re/nixpkgs
```
## Common Use Cases
### Use a Package System-Wide
```nix
# In configuration.nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
code2prompt # From m3ta-nixpkgs
git # From nixpkgs
];
}
```
### Use a Package for Your User Only
```nix
# In home.nix
{pkgs, ...}: {
home.packages = with pkgs; [
launch-webapp
zellij-ps
];
}
```
### Use a NixOS Module
```nix
{config, ...}: {
imports = [
# Or import the default which includes all modules
];
# Enable mem0 service
m3ta.mem0 = {
enable = true;
port = 8000;
llm = {
provider = "openai";
apiKeyFile = "/run/secrets/openai-api-key";
};
};
}
```
### Use Port Management
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
};
hostOverrides.laptop = {
nginx = 8080; # Override on laptop
};
currentHost = config.networking.hostName;
};
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
}
'';
};
}
```
## Available Packages
| Package | Description |
| ------------------ | ------------------------------------- |
| `code2prompt` | Convert code to prompts |
| `hyprpaper-random` | Random wallpaper setter for Hyprpaper |
| `launch-webapp` | Launch web applications |
| `mem0` | AI memory assistant with vector storage |
| `msty-studio` | Msty Studio application |
| `pomodoro-timer` | Pomodoro timer utility |
| `tuxedo-backlight` | Backlight control for Tuxedo laptops |
| `zellij-ps` | Project switcher for Zellij |
## Essential Commands
```bash
# Validate your configuration
nix flake check
# Format Nix files
nix fmt
# Apply NixOS configuration
sudo nixos-rebuild switch
# Apply Home Manager configuration
home-manager switch
# Enter development shell
nix develop .#python # Python shell
nix develop .#devops # DevOps shell
# List all outputs
nix flake show
```
## Development Workflow
```bash
# Clone repository
git clone https://code.m3ta.dev/m3tam3re/nixpkgs.git
cd nixpkgs
# Create a new package
nix flake init -t .#package
# Test package build
nix build .#your-package
# Run linting (in dev shell)
nix develop
statix check .
deadnix .
# Format before commit
nix fmt
```
## Troubleshooting
### Package Not Found
Make sure you applied the overlay:
```nix
nixpkgs.overlays = [m3ta-nixpkgs.overlays.default];
```
Or reference directly:
```nix
inputs.m3ta-nixpkgs.packages.${pkgs.system}.package-name
```
### Module Not Found
Make sure you imported the module:
```nix
imports = [
m3ta-nixpkgs.nixosModules.default
# or specific module:
m3ta-nixpkgs.nixosModules.mem0
];
```
### Hash Mismatch
If you're developing and get a hash error, rebuild to get the real hash:
```bash
nix build .#your-package
# Copy hash from error and update package
```
## Next Steps
- [Architecture](./ARCHITECTURE.md) - Understanding the repository structure
- [Adding Packages](./guides/adding-packages.md) - How to add new packages
- [Using Modules](./guides/using-modules.md) - Deep dive into modules
- [Port Management](./guides/port-management.md) - Managing service ports

146
docs/README.md Normal file
View File

@@ -0,0 +1,146 @@
# m3ta-nixpkgs Documentation
Complete documentation for m3ta's personal Nix flake repository.
## Overview
m3ta-nixpkgs is a collection of custom packages, overlays, NixOS modules, and Home Manager modules organized as a modern Nix flake. This repository follows a flakes-only approach (no channels) and provides reusable components for personal infrastructure.
## Getting Started
- **[Quick Start Guide](./QUICKSTART.md)** - Get up and running in 5 minutes
- **[Architecture](./ARCHITECTURE.md)** - Understanding the repository structure and design
- **[Contributing](./CONTRIBUTING.md)** - How to contribute to this repository
## Documentation Sections
### 📚 Guides
Step-by-step guides for common tasks:
- [Getting Started](./guides/getting-started.md) - Initial setup and basic usage
- [Adding Packages](./guides/adding-packages.md) - How to add new packages
- [Port Management](./guides/port-management.md) - Managing service ports across hosts
- [Using Modules](./guides/using-modules.md) - Using NixOS and Home Manager modules
- [Development Workflow](./guides/development-workflow.md) - Development and testing workflow
### 📦 Packages
Documentation for all custom packages:
- [code2prompt](./packages/code2prompt.md) - Convert code to prompts
- [hyprpaper-random](./packages/hyprpaper-random.md) - Random wallpaper setter for Hyprpaper
- [launch-webapp](./packages/launch-webapp.md) - Launch web applications
- [mem0](./packages/mem0.md) - AI memory assistant with vector storage
- [msty-studio](./packages/msty-studio.md) - Msty Studio application
- [pomodoro-timer](./packages/pomodoro-timer.md) - Pomodoro timer utility
- [tuxedo-backlight](./packages/tuxedo-backlight.md) - Backlight control for Tuxedo laptops
- [zellij-ps](./packages/zellij-ps.md) - Project switcher for Zellij
### ⚙️ Modules
Configuration modules for NixOS and Home Manager:
#### NixOS Modules
- [Overview](./modules/nixos/overview.md) - NixOS modules overview
- [mem0](./modules/nixos/mem0.md) - Mem0 REST API server module
- [ports](./modules/nixos/ports.md) - Port management module
#### Home Manager Modules
- [Overview](./modules/home-manager/overview.md) - Home Manager modules overview
- [CLI Tools](./modules/home-manager/cli/) - CLI-related modules
- [zellij-ps](./modules/home-manager/cli/zellij-ps.md) - Zellij project switcher
- [Coding](./modules/home-manager/coding/) - Development-related modules
- [editors](./modules/home-manager/coding/editors.md) - Editor configurations
### 📖 Reference
Technical references and APIs:
- [Functions](./reference/functions.md) - Library functions documentation
- [Patterns](./reference/patterns.md) - Code patterns and anti-patterns
## Repository Structure
```
m3ta-nixpkgs/
├── docs/ # This directory
│ ├── README.md
│ ├── QUICKSTART.md
│ ├── ARCHITECTURE.md
│ ├── CONTRIBUTING.md
│ ├── guides/
│ ├── packages/
│ ├── modules/
│ └── reference/
├── pkgs/ # Custom packages
├── modules/
│ ├── nixos/ # NixOS modules
│ └── home-manager/ # Home Manager modules
├── lib/ # Library functions
├── shells/ # Development shells
├── overlays/ # Package overlays
├── templates/ # Templates
└── examples/ # Usage examples
```
## Key Concepts
### Flakes-Only Approach
This repository uses modern Nix flakes exclusively. No channels or `nix-channel` commands are needed. All dependencies are declaratively specified in `flake.nix`.
### Namespace Convention
All modules use the `m3ta.*` namespace:
- `m3ta.ports.*` - Port management
- `m3ta.mem0.*` - Mem0 service configuration
- `m3ta.*.enable` - Enable/disable modules
### Port Management
Centralized port management across hosts using the `m3ta.ports` module:
```nix
m3ta.ports = {
enable = true;
definitions = { mem0 = 8000; };
hostOverrides.laptop = { mem0 = 8080; };
currentHost = "laptop";
};
```
## Supported Systems
- `x86_64-linux` - Primary
- `aarch64-linux` - ARM Linux
- `x86_64-darwin` - macOS (Intel)
- `aarch64-darwin` - macOS (Apple Silicon)
## Quick Commands
```bash
# Validate flake
nix flake check
# Format code
nix fmt
# Build package
nix build .#<package-name>
# List outputs
nix flake show
# Enter dev shell
nix develop
```
## License
Individual packages may have their own licenses. Check each package's `meta.license` attribute.
## Maintainer
[@m3tam3re](https://m3ta.dev)

View File

@@ -0,0 +1,493 @@
# Adding Packages Guide
How to add new packages to m3ta-nixpkgs.
## Overview
Packages in m3ta-nixpkgs are organized using a `callPackage` registry pattern. Each package lives in its own directory and is registered centrally.
## Quick Start
### Using Templates
Use the package template for quick setup:
```bash
nix flake init -t .#package my-new-package
```
This creates a template structure in `templates/package/` that you can copy.
### Manual Setup
1. Create directory: `pkgs/your-package/`
2. Write `default.nix` with package definition
3. Register in `pkgs/default.nix`
## Package Structure
```
pkgs/your-package/
├── default.nix # Package definition (required)
├── source.py # Optional: additional source files
├── wrapper.sh # Optional: wrapper scripts
└── README.md # Optional: package documentation
```
## Common Patterns
### Rust Package
```nix
{
lib,
rustPlatform,
fetchFromGitHub,
}:
rustPlatform.buildRustPackage rec {
pname = "my-rust-app";
version = "1.0.0";
src = fetchFromGitHub {
owner = "author";
repo = "my-rust-app";
rev = "v${version}";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
cargoLock.lockFile = src + "/Cargo.lock";
buildInputs = [openssl];
nativeBuildInputs = [pkg-config];
meta = with lib; {
description = "My Rust application";
homepage = "https://github.com/author/my-rust-app";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "my-rust-app";
};
}
```
### Python Package
```nix
{
lib,
python3,
fetchFromGitHub,
}:
python3.pkgs.buildPythonPackage rec {
pname = "my-python-app";
version = "1.0.0";
pyproject = true;
src = fetchFromGitHub {
owner = "author";
repo = "my-python-app";
rev = "v${version}";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
build-system = with python3.pkgs; [setuptools];
dependencies = with python3.pkgs; [
requests
click
];
optional-dependencies = with python3.pkgs; {
extras = [pyyaml];
};
doCheck = true;
pythonImportsCheck = ["myapp"];
meta = with lib; {
description = "My Python application";
homepage = "https://github.com/author/my-python-app";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "my-app";
};
}
```
### Shell Script Package
```nix
{
lib,
writeShellScriptBin,
}:
writeShellScriptBin "my-script" ''
#!/usr/bin/env bash
set -euo pipefail
echo "Hello from my script!"
# Your script logic here
''
# If you need to add dependencies
{
lib,
writeShellApplication,
bash,
curl,
}:
writeShellApplication {
name = "my-script";
runtimeInputs = [bash curl];
text = ''
#!/usr/bin/env bash
set -euo pipefail
curl -s https://example.com
'';
}
```
### AppImage Package
```nix
{
lib,
appimageTools,
fetchurl,
}:
appimageTools.wrapType2 rec {
name = "my-app";
version = "1.0.0";
src = fetchurl {
url = "https://github.com/author/my-app/releases/download/v${version}/My-App-${version}.AppImage";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
meta = with lib; {
description = "My AppImage application";
homepage = "https://github.com/author/my-app";
license = licenses.unfree;
platforms = platforms.linux;
mainProgram = name;
};
}
```
### Custom Source with Patch
```nix
{
lib,
stdenv,
fetchFromGitHub,
fetchpatch,
buildGoModule,
}:
buildGoModule rec {
pname = "my-go-app";
version = "1.0.0";
src = fetchFromGitHub {
owner = "author";
repo = "my-go-app";
rev = "v${version}";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
patches = [
# Add local patch
./fix-build.patch
# Add patch from URL
(fetchpatch {
url = "https://github.com/author/my-app/pull/123.patch";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
})
];
vendorHash = "sha256-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=";
meta = with lib; {
description = "My Go application";
homepage = "https://github.com/author/my-go-app";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "my-app";
};
}
```
### Package with Custom Installation
```nix
{
lib,
stdenv,
fetchFromGitHub,
makeWrapper,
}:
stdenv.mkDerivation rec {
pname = "my-app";
version = "1.0.0";
src = fetchFromGitHub {
owner = "author";
repo = "my-app";
rev = "v${version}";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
nativeBuildInputs = [makeWrapper];
buildPhase = ''
make build
'';
installPhase = ''
install -Dm755 my-app $out/bin/my-app
# Wrap with runtime dependencies
wrapProgram $out/bin/my-app \
--prefix PATH : ${lib.makeBinPath [some-dep]}
'';
meta = with lib; {
description = "My custom application";
homepage = "https://github.com/author/my-app";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "my-app";
};
}
```
## Registration
### Register in `pkgs/default.nix`
Add your package to the registry:
```nix
{
inherit (pkgs) callPackage;
} rec {
# Existing packages
code2prompt = callPackage ./code2prompt {};
zellij-ps = callPackage ./zellij-ps {};
# Your new package
my-new-package = callPackage ./my-new-package {};
}
```
### With Custom Arguments
If your package needs custom arguments:
```nix
# pkgs/default.nix
{
inherit (pkgs) callPackage;
} rec {
my-new-package = callPackage ./my-new-package {
customArg = "value";
};
}
# pkgs/my-new-package/default.nix
{
lib,
stdenv,
fetchurl,
customArg, # This will be passed from the registry
}:
stdenv.mkDerivation {
# ...
}
```
## Getting Hashes
### Using `lib.fakeHash`
During development, use `lib.fakeHash` to get the real hash:
```nix
src = fetchFromGitHub {
owner = "author";
repo = "my-app";
rev = "v${version}";
hash = lib.fakeHash; # Temporary placeholder
};
```
Build the package:
```bash
nix build .#my-new-package
```
Copy the actual hash from the error message and update the package:
```nix
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Real hash
```
**Important**: Never commit `lib.fakeHash` to the repository.
## Testing
### Build Package
```bash
nix build .#my-new-package
```
### Test Execution
```bash
nix run .#my-new-package -- --help
```
### Run in Shell
```bash
nix shell .#my-new-package
my-new-app --version
```
### Linting
```bash
nix develop
statix check pkgs/my-new-package/
```
## Best Practices
### Meta Fields
Always include complete `meta` information:
```nix
meta = with lib; {
description = "Short one-line description";
longDescription = ''
Longer description explaining what the package does,
its features, and use cases.
'';
homepage = "https://github.com/author/repo";
changelog = "https://github.com/author/repo/releases/tag/v${version}";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "program-name";
};
```
### Dependencies
Explicitly declare all dependencies:
```nix
{
lib,
stdenv,
fetchFromGitHub,
# Runtime dependencies
openssl,
curl,
# Native build dependencies
pkg-config,
cmake,
}:
```
### Versioning
Use `rec` to reference `version` in multiple places:
```nix
rec {
pname = "my-app";
version = "1.0.0";
src = fetchFromGitHub {
rev = "v${version}";
# ...
};
}
```
### Platform Restrictions
If package is platform-specific:
```nix
meta = with lib; {
# Linux only
platforms = platforms.linux;
# Or specific platforms
platforms = ["x86_64-linux" "aarch64-linux"];
# Or exclude platforms
broken = stdenv.isDarwin;
};
```
## Troubleshooting
### Hash Mismatch
Error: `got: sha256-AAAAAAAA... expected: sha256-BBBBBB...`
Solution: Copy `got` hash and update package definition.
### Dependency Not Found
Error: `error: undefined variable 'somedep'`
Solution: Add dependency to function arguments and build inputs:
```nix
{
lib,
somedep, # Add here
}:
stdenv.mkDerivation {
buildInputs = [somedep]; # Add here
}
```
### Import Check Failure
Error: `error: Python module 'mymodule' not found`
Solution: Disable or fix imports check:
```nix
pythonImportsCheck = ["mymodule"]; # Check this is correct
# Or if importing creates side effects:
pythonImportsCheck = [];
```
## Examples
See existing packages in the repository:
- `pkgs/code2prompt/` - Rust package
- `pkgs/mem0/` - Python package
- `pkgs/hyprpaper-random/` - Shell script
- `pkgs/msty-studio/` - AppImage
- `pkgs/zellij-ps/` - Fetch from Gitea
## Next Steps
- [Architecture](../ARCHITECTURE.md) - Understanding package organization
- [Using Modules](./using-modules.md) - If you need to create modules
- [Contributing](../CONTRIBUTING.md) - Code style and guidelines

View File

@@ -0,0 +1,527 @@
# Development Workflow Guide
Development, testing, and contribution workflow for m3ta-nixpkgs.
## Initial Setup
### Clone Repository
```bash
git clone https://code.m3ta.dev/m3tam3re/nixpkgs.git
cd nixpkgs
```
### Enter Development Shell
```bash
# Default shell (includes linting tools)
nix develop
# Python shell
nix develop .#python
# DevOps shell
nix develop .#devops
```
### Development Shell Tools
The default dev shell includes:
- `statix` - Nix linter
- `deadnix` - Find dead code
- `alejandra` - Code formatter
## Workflow
### 1. Create Feature Branch
```bash
# Checkout main and pull latest
git checkout main
git pull
# Create feature branch
git checkout -b feature/my-new-package
```
### 2. Make Changes
```bash
# Create new package
mkdir -p pkgs/my-package
vim pkgs/my-package/default.nix
# Or modify existing package
vim pkgs/existing-package/default.nix
# Or add module
vim modules/nixos/my-module.nix
```
### 3. Format Code
```bash
# Format all files
nix fmt
# Format specific file
alejandra path/to/file.nix
```
**Always format before committing.**
### 4. Test Changes
#### Build Package
```bash
# Build specific package
nix build .#my-package
# Build all packages
nix build .#packages.x86_64-linux
```
#### Run Package
```bash
# Test if package runs
nix run .#my-package -- --help
# Or enter shell with package
nix shell .#my-package
my-package --version
```
#### Validate Flake
```bash
# Validate all outputs
nix flake check
# Show all outputs
nix flake show
```
#### Test Module
```bash
# Test NixOS configuration
sudo nixos-rebuild test --flake .#hostname
# Test Home Manager configuration
home-manager switch --flake .#username@hostname
```
### 5. Lint Code
```bash
# Enter dev shell for linting tools
nix develop
# Run statix
statix check .
# Run deadnix
deadnix .
# Fix auto-fixable issues
statix fix .
```
### 6. Commit Changes
```bash
# Stage changes
git add .
# Commit with conventional format
git commit -m "feat: add my-package for doing X"
# Commit types: feat, fix, docs, style, refactor, chore, test
```
### 7. Push and Create PR
```bash
# Push branch
git push origin feature/my-new-package
# Create PR via web interface or CLI
gh pr create --title "feat: add my-package" --body "Description of changes"
```
## Testing Strategies
### Local Testing
#### Test Package Build
```bash
# Build for current system
nix build .#my-package
# Build for specific system
nix build .#my-package --system aarch64-linux
# Build for macOS
nix build .#my-package --system x86_64-darwin
```
#### Test Package Functionality
```bash
# Enter shell with package
nix shell .#my-package
# Run the program
my-package --help
my-package --version
# Test with sample data
echo "test" | my-package
```
#### Test Configuration
```bash
# Test NixOS configuration
sudo nixos-rebuild test --flake .#hostname
# Test Home Manager configuration
home-manager switch --flake .#username@hostname
# Check configuration syntax
nix eval .#nixosConfigurations.hostname.config --apply builtins.attrNames
```
### Integration Testing
#### Test with Real Services
```bash
# If package is a service
# 1. Add to configuration
# 2. Apply configuration
sudo nixos-rebuild switch
# 3. Test service
systemctl status my-service
journalctl -u my-service -f
# 4. Test functionality
curl http://localhost:8080
```
#### Test with Dependencies
```bash
# Build dependency chain
nix build .#my-package \
--rebuild \
--keep-going
# Check if dependencies are satisfied
nix path-info .#my-package --references
```
## Continuous Integration
### Pre-Commit Hook
Create `.git/hooks/pre-commit`:
```bash
#!/usr/bin/env bash
set -euo pipefail
# Format code
nix fmt
# Lint
statix check .
deadnix .
# Validate
nix flake check
# Test build
nix build .#your-package
```
Make executable:
```bash
chmod +x .git/hooks/pre-commit
```
### Pre-Push Hook
Create `.git/hooks/pre-push`:
```bash
#!/usr/bin/env bash
set -euo pipefail
# Validate flake
nix flake check
# Run tests if they exist
# make test
```
## Debugging
### Build Failures
#### Hash Mismatch
Error: `got: sha256-AAAAAAAA... expected: sha256-BBBBBB...`
Solution: Copy the `got` hash and update package:
```nix
src = fetchFromGitHub {
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Use actual hash
};
```
#### Dependency Not Found
Error: `error: undefined variable 'somelib'`
Solution: Check function arguments:
```nix
{
lib,
stdenv,
fetchFromGitHub,
somelib, # Add this if missing
}:
```
#### Build Failed
Error: `builder for '/nix/store/...' failed`
Solution:
```bash
# Build with verbose output
nix build .#my-package -v --show-trace
# Check build logs
nix log .#my-package
# Enter build environment for debugging
nix shell -f .#my-package .bashInteractive
```
### Runtime Failures
#### Package Not Executable
Error: `error: operation not permitted`
Solution: Check `mainProgram` in meta:
```nix
meta = with lib; {
mainProgram = "my-app"; # Must match executable name
};
```
#### Library Not Found
Error: `error while loading shared libraries: libfoo.so`
Solution: Add to build inputs:
```nix
buildInputs = [someLib];
```
### Configuration Failures
#### Option Not Found
Error: `error: The option 'm3ta.mymodule' does not exist`
Solution: Import the module:
```nix
imports = [
m3ta-nixpkgs.nixosModules.default
];
```
## Common Tasks
### Update Package Version
```bash
# 1. Update version in package definition
vim pkgs/my-package/default.nix
# 2. Build to get new hash
nix build .#my-package
# 3. Update hash from error message
# 4. Test new version
nix run .#my-package -- --version
# 5. Commit
git commit -m "chore: update my-package to v2.0.0"
```
### Update Dependencies
```bash
# 1. Update fetcher version/rev
vim pkgs/my-package/default.nix
# 2. Update dependencies if needed
vim pkgs/my-package/default.nix
# 3. Build and test
nix build .#my-package
nix run .#my-package -- --help
# 4. Commit
git commit -m "fix: update dependencies for my-package"
```
### Add Tests
```bash
# 1. Add test to package
vim pkgs/my-package/default.nix
# 2. Run tests
nix build .#my-package
# 3. Verify tests pass
# 4. Commit
git commit -m "test: add tests for my-package"
```
### Fix Linting Issues
```bash
# 1. Run linter
nix develop
statix check .
# 2. Fix issues manually or auto-fix
statix fix .
# 3. Check again
statix check .
# 4. Commit
git commit -m "style: fix linting issues"
```
## Performance Optimization
### Use Caching
```bash
# Use binary cache (if available)
nix build .#my-package --substituters https://cache.nixos.org https://your-cache.example.com
# Use local cache
nix build .#my-package --max-jobs 4
```
### Parallel Builds
```bash
# Build multiple packages in parallel
nix build .#package1 .#package2 .#package3
```
### Incremental Builds
```bash
# Only rebuild changed packages
nix build .#my-package --check
# Don't rebuild dependencies
nix build .#my-package --no-link
```
## Release Process
### Version Bump
```bash
# 1. Update versions as needed
vim pkgs/*/default.nix
# 2. Update CHANGELOG.md
vim CHANGELOG.md
# 3. Test all packages
nix flake check
# 4. Commit
git commit -m "chore: prepare release v1.0.0"
```
### Tag Release
```bash
# Create tag
git tag -a v1.0.0 -m "Release v1.0.0"
# Push tag
git push origin v1.0.0
# Push with tags
git push --follow-tags
```
### Update Flakes
Update flake lock after release:
```bash
# Update lock file
nix flake update
# Commit
git commit -m "chore: update flake lock"
```
## Checklist
### Before Committing
- [ ] Code formatted with `nix fmt`
- [ ] Passes `statix check .`
- [ ] Passes `deadnix .`
- [ ] Passes `nix flake check`
- [ ] Package builds successfully
- [ ] Package runs as expected
- [ ] Documentation updated (if needed)
- [ ] Commit message follows convention
### Before Merging PR
- [ ] All tests pass
- [ ] Code review approved
- [ ] No merge conflicts
- [ ] Documentation complete
- [ ] Breaking changes documented
## Resources
- [Contributing Guide](../CONTRIBUTING.md) - Code style and guidelines
- [Architecture](../ARCHITECTURE.md) - Understanding repository structure
- [Adding Packages](./adding-packages.md) - Package creation guide
- [Quick Start](../QUICKSTART.md) - Getting started guide

View File

@@ -0,0 +1,402 @@
# Getting Started Guide
Initial setup and basic usage of m3ta-nixpkgs.
## Installation
### Prerequisites
Make sure you have Nix installed with flakes enabled:
```bash
# Check Nix version (need 2.4+)
nix --version
# Enable flakes (in /etc/nixos/configuration.nix)
nix.settings.experimental-features = ["nix-command" "flakes"]
# Rebuild NixOS
sudo nixos-rebuild switch
```
### Adding to Your Flake
#### Option 1: NixOS Configuration
Add to your `flake.nix`:
```nix
{
description = "My NixOS configuration";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
m3ta-nixpkgs = {
url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
home-manager,
m3ta-nixpkgs,
...
}: {
nixosConfigurations = {
myhost = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./hardware-configuration.nix
# Import m3ta-nixpkgs modules
m3ta-nixpkgs.nixosModules.default
# Apply overlay
({pkgs, ...}: {
nixpkgs.overlays = [m3ta-nixpkgs.overlays.default];
# Packages from m3ta-nixpkgs are now available
environment.systemPackages = with pkgs; [
code2prompt
zellij-ps
];
})
# Home Manager integration
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.myusername = {
imports = [m3ta-nixpkgs.homeManagerModules.default];
home.packages = with pkgs; [
launch-webapp
];
};
}
];
};
};
};
}
```
#### Option 2: Standalone Home Manager
```nix
{
description = "My Home Manager configuration";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
m3ta-nixpkgs = {
url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
home-manager,
m3ta-nixpkgs,
}: let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
overlays = [m3ta-nixpkgs.overlays.default];
};
in {
homeConfigurations.myusername = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
m3ta-nixpkgs.homeManagerModules.default
{
home.username = "myusername";
home.homeDirectory = "/home/myusername";
home.packages = with pkgs; [
code2prompt
zellij-ps
];
programs.home-manager.enable = true;
}
];
};
};
}
```
## Quick Usage
### Using Packages Directly
Without adding to your configuration:
```bash
# Build a package
nix build git+https://code.m3ta.dev/m3tam3re/nixpkgs#code2prompt
# Run a package
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#zellij-ps
# List all available packages
nix flake show git+https://code.m3ta.dev/m3tam3re/nixpkgs
```
### Using Packages in Configuration
After applying overlay:
```nix
# System-wide (NixOS)
environment.systemPackages = with pkgs; [
code2prompt
zellij-ps
];
# User-only (Home Manager)
home.packages = with pkgs; [
launch-webapp
];
```
### Using Modules
```nix
# Import all modules
imports = [
m3ta-nixpkgs.nixosModules.default
];
# Or import specific module
imports = [
m3ta-nixpkgs.nixosModules.mem0
];
# Configure module
m3ta.mem0 = {
enable = true;
port = 8000;
};
```
## Common Tasks
### Install a Package System-Wide
```nix
# /etc/nixos/configuration.nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
code2prompt
hyprpaper-random
];
}
# Apply
sudo nixos-rebuild switch
```
### Install a Package for Your User
```nix
# home.nix
{pkgs, ...}: {
home.packages = with pkgs; [
launch-webapp
zellij-ps
];
}
# Apply
home-manager switch
```
### Enable a NixOS Module
```nix
# /etc/nixos/configuration.nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
];
m3ta.mem0 = {
enable = true;
port = 8000;
};
# Apply
# sudo nixos-rebuild switch
}
```
### Enable a Home Manager Module
```nix
# home.nix
{config, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
m3ta.cli.zellij-ps = {
enable = true;
};
# Apply
# home-manager switch
}
```
### Use Port Management
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
};
hostOverrides.laptop = {
nginx = 8080;
};
currentHost = config.networking.hostName;
};
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
root /var/www;
}
'';
};
}
```
## Available Packages
| Package | Description |
| ------------------ | ------------------------------------- |
| `code2prompt` | Convert code to prompts |
| `hyprpaper-random` | Random wallpaper setter for Hyprpaper |
| `launch-webapp` | Launch web applications |
| `mem0` | AI memory assistant with vector storage |
| `msty-studio` | Msty Studio application |
| `pomodoro-timer` | Pomodoro timer utility |
| `tuxedo-backlight` | Backlight control for Tuxedo laptops |
| `zellij-ps` | Project switcher for Zellij |
## Available Modules
### NixOS Modules
- `ports` - Port management across hosts
- `mem0` - Mem0 REST API server
### Home Manager Modules
- `ports` - Port management (with `generateEnvVars`)
- `cli.zellij-ps` - Zellij project switcher
- `coding.editors` - Editor configurations
## Development
### Development Shells
```bash
# Default dev shell
nix develop
# Python dev shell
nix develop .#python
# DevOps dev shell
nix develop .#devops
```
### Building and Testing
```bash
# Build package
nix build .#code2prompt
# Validate flake
nix flake check
# List outputs
nix flake show
# Format code
nix fmt
```
### Linting (in dev shell)
```bash
nix develop
# Run linter
statix check .
# Find dead code
deadnix .
```
## Troubleshooting
### Package Not Found
**Error**: `error: undefined variable 'code2prompt'`
**Solution**: Make sure you applied the overlay:
```nix
nixpkgs.overlays = [m3ta-nixpkgs.overlays.default];
```
### Module Not Found
**Error**: `error: The option 'm3ta.mem0' does not exist`
**Solution**: Make sure you imported the module:
```nix
imports = [
m3ta-nixpkgs.nixosModules.default
# or
m3ta-nixpkgs.nixosModules.mem0
];
```
### Hash Mismatch
**Error**: `got: sha256-AAAAAAAA... expected: sha256-BBBBBB...`
**Solution**: Copy the `got` hash from the error and update the package definition.
### Building for Different System
```bash
# Build for aarch64-linux
nix build .#code2prompt --system aarch64-linux
# Build for macOS
nix build .#code2prompt --system x86_64-darwin
```
## Next Steps
- [Adding Packages](./adding-packages.md) - How to add new packages
- [Using Modules](./using-modules.md) - Deep dive into modules
- [Port Management](./port-management.md) - Managing service ports
- [Architecture](../ARCHITECTURE.md) - Understanding the repository structure

View File

@@ -0,0 +1,525 @@
# Port Management Guide
Managing service ports across multiple hosts with the `m3ta.ports` module.
## Overview
The port management module provides a centralized way to define service ports that can have host-specific overrides. This prevents port conflicts and makes it easy to manage services across multiple machines.
## Basic Usage
### Enable Port Management
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
# Define default ports
definitions = {
nginx = 80;
grafana = 3000;
prometheus = 9090;
homepage = 8080;
};
# Define host-specific overrides
hostOverrides = {
laptop = {
nginx = 8080; # Override on laptop
homepage = 3001; # Override on laptop
};
server = {
homepage = 3002; # Override on server
};
};
# Set current host (determines which overrides to use)
currentHost = config.networking.hostName;
};
}
```
### Using Ports
```nix
{config, ...}: {
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
root /var/www;
}
'';
};
services.grafana = {
enable = true;
settings.server.http_port = config.m3ta.ports.get "grafana";
};
}
```
## Module Options
### `m3ta.ports.enable`
Enable port management module.
- Type: `boolean`
- Default: `false`
### `m3ta.ports.definitions`
Default port definitions.
- Type: `attrsOf int`
- Default: `{}`
```nix
definitions = {
nginx = 80;
grafana = 3000;
prometheus = 9090;
};
```
### `m3ta.ports.hostOverrides`
Host-specific port overrides.
- Type: `attrsOf (attrsOf int)`
- Default: `{}`
```nix
hostOverrides = {
laptop = {
nginx = 8080;
grafana = 3001;
};
server = {
grafana = 3002;
};
};
```
### `m3ta.ports.currentHost`
Current hostname. Determines which overrides to apply.
- Type: `string`
- Example: `config.networking.hostName`
```nix
currentHost = "laptop"; # Use laptop overrides
```
### `m3ta.ports.generateEnvVars` (Home Manager only)
Generate environment variables from ports.
- Type: `boolean`
- Default: `false` (Home Manager)
- NixOS: Not available
When enabled, generates environment variables like:
- `PORT_NGINX=8080`
- `PORT_GRAFANA=3000`
## Functions
### `config.m3ta.ports.get "service"`
Get port for a service with host-specific override.
```nix
services.nginx = {
port = config.m3ta.ports.get "nginx";
};
```
If current host is `laptop` and `hostOverrides.laptop.nginx = 8080`, returns `8080`.
If no override, returns default `80`.
### `config.m3ta.ports.getHostPorts "hostname"`
Get all ports for a specific host.
```nix
# Get all ports for laptop
laptopPorts = config.m3ta.ports.getHostPorts "laptop";
# Returns: { nginx = 8080; grafana = 3000; ... }
```
### `config.m3ta.ports.listServices`
List all defined service names.
```nix
allServices = config.m3ta.ports.listServices;
# Returns: ["nginx" "grafana" "prometheus" "homepage"]
```
## Examples
### NixOS Configuration
```nix
{config, ...}: {
# Define ports
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
prometheus = 9090;
loki = 3100;
promtail = 9080;
};
hostOverrides.laptop = {
nginx = 8080;
grafana = 3001;
};
currentHost = config.networking.hostName;
};
# Use ports
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
root /var/www;
}
'';
};
services.grafana = {
enable = true;
settings.server.http_port = config.m3ta.ports.get "grafana";
};
services.prometheus = {
enable = true;
port = config.m3ta.ports.get "prometheus";
};
services.loki = {
enable = true;
configuration.http_listen_port = config.m3ta.ports.get "loki";
};
}
```
### Home Manager Configuration
```nix
{config, ...}: {
# Define ports
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
nextjs = 3001;
vite = 5173;
};
hostOverrides.desktop = {
vite = 5174;
};
currentHost = "desktop";
generateEnvVars = true; # Generate env vars
};
# Ports are now available as env vars
# PORT_DEV_SERVER=3000
# PORT_NEXTJS=3001
# PORT_VITE=5174
home.sessionVariables = {
DEV_PORT = toString (config.m3ta.ports.get "dev-server");
};
}
```
### With Custom Modules
Using ports with custom modules (e.g., `m3ta.mem0`):
```nix
{config, ...}: {
# Define ports
m3ta.ports = {
enable = true;
definitions = {
mem0 = 8000;
qdrant = 6333;
};
hostOverrides.laptop = {
mem0 = 8080;
};
currentHost = config.networking.hostName;
};
# Use with mem0 module
m3ta.mem0 = {
enable = true;
port = config.m3ta.ports.get "mem0"; # 8000 or 8080 on laptop
};
# Use with qdrant service
services.qdrant = {
enable = true;
port = config.m3ta.ports.get "qdrant";
};
}
```
### Port File Generation
Generate a JSON file with all ports:
```nix
{config, pkgs, ...}: {
m3ta.ports = {
enable = true;
definitions = {
service1 = 80;
service2 = 443;
};
currentHost = config.networking.hostName;
};
# Generate port file
environment.etc."m3ta/ports.json".text = builtins.toJSON (
config.m3ta.ports.getHostPorts config.networking.hostName
);
}
```
## Advanced Usage
### Conditional Configuration
```nix
{config, ...}: {
services.nginx = {
enable = true;
# Only open firewall if binding to non-localhost
httpConfig = let
port = config.m3ta.ports.get "nginx";
in ''
server {
listen ${toString port};
}
'';
};
networking.firewall.allowedTCPPorts =
if config.m3ta.ports.get "nginx" == 80
then [80]
else [];
}
```
### Port Ranges
```nix
definitions = {
service-start = 8000;
service-end = 8999;
};
# Use in config
services.my-app = {
portRange = [
config.m3ta.ports.get "service-start"
config.m3ta.ports.get "service-end"
];
};
```
### Dynamic Port Allocation
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
# Reserve port ranges
app-range-start = 9000;
app-range-end = 9999;
};
currentHost = config.networking.hostName;
};
# Calculate next available port
services.my-app = {
port = config.m3ta.ports.get "app-range-start" + 0;
};
services.my-other-app = {
port = config.m3ta.ports.get "app-range-start" + 1;
};
}
```
## Best Practices
### Use Descriptive Service Names
```nix
# Good
definitions = {
nginx = 80;
grafana = 3000;
prometheus-ui = 9090;
prometheus-push = 9091;
};
# Avoid
definitions = {
p1 = 80;
p2 = 3000;
p3 = 9090;
};
```
### Group Related Services
```nix
definitions = {
# Monitoring stack
grafana = 3000;
prometheus = 9090;
loki = 3100;
promtail = 9080;
# Web services
nginx = 80;
homepage = 8080;
# Databases
postgres = 5432;
redis = 6379;
qdrant = 6333;
};
```
### Document Overrides
```nix
hostOverrides = {
# Laptop: Running multiple dev servers, use higher ports
laptop = {
nginx = 8080;
dev-server = 3000;
};
# Server: Production, use standard ports
server = {
nginx = 80;
dev-server = null; # Disable on server
};
};
```
### Handle Missing Ports
```nix
services.some-service = {
enable = true;
port = config.m3ta.ports.get "some-service" or 8080;
};
```
## Troubleshooting
### Service Not Found
Error: `Service "foo" not defined`
Solution: Add service to `definitions`:
```nix
definitions = {
foo = 8080;
};
```
### Current Host Not Set
Error: `currentHost not set`
Solution: Set `currentHost`:
```nix
currentHost = config.networking.hostName;
```
### Port Conflict
Issue: Two services trying to use same port.
Solution: Define both in port management:
```nix
definitions = {
service1 = 8080;
service2 = 8081; # Different port
};
```
## Migration from Hardcoded Ports
### Before
```nix
services.nginx = {
enable = true;
httpConfig = ''
server {
listen 80;
}
'';
};
services.grafana = {
enable = true;
settings.server.http_port = 3000;
};
```
### After
```nix
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
};
currentHost = config.networking.hostName;
};
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
}
'';
};
services.grafana = {
enable = true;
settings.server.http_port = config.m3ta.ports.get "grafana";
};
```
## Next Steps
- [Architecture](../ARCHITECTURE.md) - Understanding the library functions
- [Using Modules](./using-modules.md) - Using modules with port management
- [Contributing](../CONTRIBUTING.md) - Code style and guidelines

View File

@@ -0,0 +1,605 @@
# Using Modules Guide
How to use NixOS and Home Manager modules from m3ta-nixpkgs.
## Overview
Modules in m3ta-nixpkgs provide reusable configuration for NixOS (system-level) and Home Manager (user-level) settings. All modules use the `m3ta.*` namespace.
## Module Organization
### NixOS Modules
Located in `modules/nixos/`:
```
modules/nixos/
├── default.nix # Aggregates all NixOS modules
├── ports.nix # Port management
└── mem0.nix # Mem0 REST API server
```
### Home Manager Modules
Located in `modules/home-manager/` with categories:
```
modules/home-manager/
├── default.nix # Aggregates all HM modules
├── ports.nix # Port management
├── cli/ # CLI tools
│ ├── default.nix # Aggregates CLI modules
│ └── zellij-ps.nix
└── coding/ # Development tools
├── default.nix # Aggregates coding modules
└── editors.nix
```
## Importing Modules
### NixOS Modules
#### Import All Modules
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
];
}
```
#### Import Specific Module
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.mem0
];
}
```
#### Import from Local Path
```nix
{config, ...}: {
imports = [
./modules/nixos/mem0.nix
];
}
```
### Home Manager Modules
#### Import All Modules
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
}
```
#### Import Specific Module
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.ports
];
}
```
#### Import Category
```nix
{config, ...}: {
imports = [
# Import all CLI modules
m3ta-nixpkgs.homeManagerModules.cli.zellij-ps
];
}
```
## Available Modules
### NixOS Modules
#### `m3ta.ports`
Port management across hosts.
```nix
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
};
hostOverrides.laptop = {
nginx = 8080;
};
currentHost = config.networking.hostName;
};
```
**Documentation**: [Port Management Guide](./port-management.md)
#### `m3ta.mem0`
Mem0 REST API server for AI memory.
```nix
m3ta.mem0 = {
enable = true;
port = 8000;
llm = {
provider = "openai";
apiKeyFile = "/run/secrets/openai-api-key";
model = "gpt-4o-mini";
};
vectorStore = {
provider = "qdrant";
config = {
host = "localhost";
port = 6333;
};
};
};
```
**Documentation**: [mem0 Module](../modules/nixos/mem0.md)
### Home Manager Modules
#### `m3ta.ports`
Port management (similar to NixOS, with `generateEnvVars`).
```nix
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
};
generateEnvVars = true;
currentHost = config.networking.hostName;
};
```
**Documentation**: [Port Management Guide](./port-management.md)
#### `m3ta.cli.zellij-ps`
Zellij project switcher for quickly navigating between project folders.
```nix
m3ta.cli.zellij-ps = {
enable = true;
package = pkgs.zellij-ps;
};
```
**Documentation**: [zellij-ps Module](../modules/home-manager/cli/zellij-ps.md)
#### `m3ta.coding.editors`
Editor configurations.
```nix
m3ta.coding.editors = {
enable = true;
neovim.enable = true;
zed.enable = true;
};
```
**Documentation**: [Editors Module](../modules/home-manager/coding/editors.md)
## Common Patterns
### Module Configuration
All modules follow this pattern:
```nix
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "description";
# ... other options
};
config = mkIf cfg.enable {
# ... configuration
};
}
```
### Conditional Configuration
Use `mkIf` to conditionally apply config:
```nix
config = mkIf cfg.enable {
# Only applied when cfg.enable = true
services.my-service = {
enable = true;
};
}
```
### Multiple Conditions
Use `mkMerge` for multiple conditions:
```nix
config = mkMerge [
(mkIf cfg.feature1.enable {
# Applied when feature1 is enabled
})
(mkIf cfg.feature2.enable {
# Applied when feature2 is enabled
})
];
```
### Optional Dependencies
```nix
options.m3ta.myModule = {
enable = mkEnableOption "my module";
package = mkOption {
type = types.package;
default = pkgs.defaultPackage;
};
};
config = mkIf cfg.enable {
services.my-service = {
package = cfg.package;
};
};
```
## Configuration Examples
### Minimal NixOS Configuration
```nix
{pkgs, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
];
m3ta.ports = {
enable = true;
definitions = {
my-service = 8080;
};
currentHost = "laptop";
};
services.my-custom-service = {
enable = true;
port = config.m3ta.ports.get "my-service";
};
}
```
### Full NixOS Configuration
```nix
{config, pkgs, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
];
# Port management
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
prometheus = 9090;
mem0 = 8000;
};
hostOverrides.laptop = {
nginx = 8080;
mem0 = 8081;
};
currentHost = config.networking.hostName;
};
# Mem0 service
m3ta.mem0 = {
enable = true;
port = config.m3ta.ports.get "mem0";
llm = {
provider = "openai";
apiKeyFile = "/run/secrets/openai-api-key";
};
vectorStore = {
provider = "qdrant";
config = {
host = "localhost";
port = 6333;
};
};
};
# Nginx
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
root /var/www;
}
'';
};
# Grafana
services.grafana = {
enable = true;
settings.server.http_port = config.m3ta.ports.get "grafana";
};
}
```
### Minimal Home Manager Configuration
```nix
{pkgs, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
};
currentHost = "desktop";
};
home.sessionVariables = {
DEV_PORT = toString (config.m3ta.ports.get "dev-server");
};
}
```
### Full Home Manager Configuration
```nix
{config, pkgs, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
# Port management
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
nextjs = 3001;
vite = 5173;
};
hostOverrides.laptop = {
vite = 5174;
};
currentHost = config.networking.hostName;
};
# CLI tools
m3ta.cli.zellij-ps = {
enable = true;
};
# Coding tools
m3ta.coding.editors = {
enable = true;
neovim.enable = true;
};
# Packages
home.packages = with pkgs; [
code2prompt
zellij-ps
];
# Environment variables
home.sessionVariables = {
EDITOR = "nvim";
DEV_SERVER_PORT = toString (config.m3ta.ports.get "dev-server");
};
}
```
## Module Options Reference
### Standard Options
All modules typically include:
| Option | Type | Description |
|---------|-------|-------------|
| `enable` | `boolean` | Enable the module |
| `package` | `package` | Custom package to use |
| `extraConfig` | `attrs` | Additional configuration |
### Port Management Options
| Option | Type | Description |
|---------|-------|-------------|
| `definitions` | `attrsOf int` | Default port definitions |
| `hostOverrides` | `attrsOf attrs` | Host-specific overrides |
| `currentHost` | `string` | Current hostname |
| `generateEnvVars` | `boolean` | Generate environment variables (HM only) |
## Combining with Other Flakes
### Using Multiple Module Sources
```nix
{config, ...}: {
imports = [
# m3ta-nixpkgs modules
m3ta-nixpkgs.nixosModules.default
# Other flake modules
inputs.impermanence.nixosModules.impermanence
inputs.sops-nix.nixosModules.sops
];
# Configure all modules
m3ta.ports = {
enable = true;
definitions = {nginx = 80;};
currentHost = config.networking.hostName;
};
environment.persistence = {
"/persist" = {
directories = ["/var/lib/mem0"];
};
};
}
```
### Using with Secrets
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
inputs.sops-nix.nixosModules.sops
];
sops.secrets = {
openai-api-key = {};
};
m3ta.mem0 = {
enable = true;
llm = {
apiKeyFile = config.sops.secrets.openai-api-key.path;
};
};
}
```
## Troubleshooting
### Module Not Found
Error: `error: The option 'm3ta.mymodule' does not exist`
**Solutions**:
1. Make sure you imported the module:
```nix
imports = [
m3ta-nixpkgs.nixosModules.default
];
```
2. Check module name is correct
```nix
# Correct
m3ta.mem0.enable = true;
# Wrong
m3ta.mymodule.enable = true; # Doesn't exist
```
### Option Type Mismatch
Error: `type mismatch at 'm3ta.mymodule.enable', expected a boolean but got a list`
**Solution**: Check option types in documentation
```nix
# Correct
m3ta.mymodule.enable = true;
# Wrong
m3ta.mymodule.enable = [true]; # Should be boolean
```
### Port Not Defined
Error: `Service "foo" not defined`
**Solution**: Add to port definitions
```nix
m3ta.ports = {
definitions = {
foo = 8080; # Add this
};
};
```
## Best Practices
### Use Namespaces
Always use the `m3ta.*` namespace:
```nix
# Good
m3ta.mem0.enable = true;
# Bad (potential conflicts)
mem0.enable = true;
```
### Document Your Configuration
Add comments explaining module usage:
```nix
# Port management for multi-host setup
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
};
hostOverrides.laptop = {
nginx = 8080; # Use different port on laptop
};
currentHost = config.networking.hostName;
};
# Mem0 AI memory service
m3ta.mem0 = {
enable = true;
port = config.m3ta.ports.get "mem0";
};
```
### Test Configuration
```bash
# Test NixOS configuration without applying
sudo nixos-rebuild test --flake .#hostname
# Check configuration
nix flake check
# Show all options
nix eval .#nixosConfigurations.hostname.config.m3ta --apply builtins.attrNames
```
## Next Steps
- [Port Management](./port-management.md) - Detailed port management guide
- [Adding Packages](./adding-packages.md) - How to add new packages
- [Architecture](../ARCHITECTURE.md) - Understanding module structure
- [Contributing](../CONTRIBUTING.md) - Code style and guidelines

View File

@@ -0,0 +1,81 @@
# zellij-ps Home Manager Module
Zellij project switcher for Home Manager.
## Overview
This module configures the zellij-ps tool, a Fish script that provides a fast, interactive way to switch between project folders in Zellij terminal multiplexer sessions.
## Quick Start
```nix
{config, ...}: {
imports = [m3ta-nixpkgs.homeManagerModules.default];
m3ta.cli.zellij-ps = {
enable = true;
};
}
```
## Module Options
### `m3ta.cli.zellij-ps.enable`
Enable zellij-ps module.
- Type: `boolean`
- Default: `false`
### `m3ta.cli.zellij-ps.package`
Custom package to use.
- Type: `package`
- Default: `pkgs.zellij-ps`
## Usage
After enabling, zellij-ps will be available in your path:
```bash
# Run from outside Zellij to start a project session
zellij-ps
# Or pass a project path directly
zellij-ps ~/projects/my-project
```
### Basic Usage
1. Set `$PROJECT_FOLDERS` in your shell config (e.g., `~/projects:~/code`)
2. Run `zellij-ps` from outside a Zellij session
3. Use fzf to select a project from your configured folders
4. Zellij will create or attach to a session for that project
## Configuration
### Custom Package
Use a custom or modified package:
```nix
m3ta.cli.zellij-ps = {
enable = true;
package = pkgs.callPackage ./my-zellij-ps {};
};
```
## Dependencies
The module ensures these are installed:
- `fish` - Shell for script execution
- `fd` - Fast file search
- `fzf` - Fuzzy finder
- `zellij` - Terminal multiplexer
## Related
- [zellij-ps Package](../../packages/zellij-ps.md) - Package documentation
- [Using Modules Guide](../../guides/using-modules.md) - Module usage patterns

View File

@@ -0,0 +1,317 @@
# editors Home Manager Module
Editor configurations for Home Manager.
## Overview
This module provides pre-configured settings for various code editors, making it easy to set up your development environment.
## Quick Start
```nix
{config, ...}: {
imports = [m3ta-nixpkgs.homeManagerModules.default];
m3ta.coding.editors = {
enable = true;
neovim.enable = true;
zed.enable = true;
};
}
```
## Module Options
### `m3ta.coding.editors.enable`
Enable the editors module.
- Type: `boolean`
- Default: `false`
### `m3ta.coding.editors.neovim.enable`
Enable Neovim configuration.
- Type: `boolean`
- Default: `false`
### `m3ta.coding.editors.neovim.package`
Custom Neovim package.
- Type: `package`
- Default: `pkgs.neovim`
### `m3ta.coding.editors.zed.enable`
Enable Zed editor configuration.
- Type: `boolean`
- Default: `false`
### `m3ta.coding.editors.zed.package`
Custom Zed package.
- Type: `package`
- Default: `pkgs.zed`
## Supported Editors
### Neovim
Neovim is a highly extensible Vim-based text editor.
```nix
m3ta.coding.editors = {
enable = true;
neovim = {
enable = true;
package = pkgs.neovim;
};
}
```
**Features**:
- Vim-style editing
- Plugin system
- Lua scripting
- Fast performance
- Built-in LSP support
**Configuration**: The module provides sensible defaults. You can customize by adding your own configuration.
### Zed
Zed is a high-performance, multiplayer code editor.
```nix
m3ta.coding.editors = {
enable = true;
zed = {
enable = true;
package = pkgs.zed;
};
}
```
**Features**:
- Fast startup
- Built-in collaboration
- AI assistance (optional)
- Modern UI
- Low memory usage
**Configuration**: Zed uses JSON configuration files that can be customized.
## Usage Examples
### Minimal Neovim Setup
```nix
{config, ...}: {
m3ta.coding.editors = {
enable = true;
neovim.enable = true;
};
}
```
### Minimal Zed Setup
```nix
{config, ...}: {
m3ta.coding.editors = {
enable = true;
zed.enable = true;
};
}
```
### Multiple Editors
```nix
{config, ...}: {
m3ta.coding.editors = {
enable = true;
neovim.enable = true;
zed.enable = true;
};
}
```
### Custom Package
```nix
{config, ...}: {
m3ta.coding.editors = {
enable = true;
neovim = {
enable = true;
package = pkgs.neovim-unwrapped; # Use unwrapped version
};
};
}
```
## Configuration Files
### Neovim
The module sets up Neovim configuration in:
```
~/.config/nvim/
```
You can extend it with:
```nix
{config, ...}: {
xdg.configFile."nvim/init.lua".text = ''
-- Your custom Neovim configuration
'';
}
```
### Zed
Zed configuration is in:
```
~/.config/zed/settings.json
```
You can customize it with:
```nix
{config, ...}: {
xdg.configFile."zed/settings.json".text = builtins.toJSON {
# Your custom Zed settings
};
}
```
## Migration Guide
### From Manual Configuration
If you have existing editor configurations, you can:
1. Backup your current config
2. Enable the module
3. Test it out
4. Gradually migrate custom settings
**Backup**:
```bash
# Backup Neovim
cp -r ~/.config/nvim ~/.config/nvim.backup
# Backup Zed
cp -r ~/.config/zed ~/.config/zed.backup
```
### From Other Editors
**Vim to Neovim**:
- Most Vim configurations work with Neovim
- Enable module and test
- Migrate plugins to modern Lua versions
**VSCode to Zed**:
- Zed has built-in keybinding presets
- Enable module and check keybindings
- Adjust as needed
## Keybindings
### Neovim
Default keybindings (Vim-style):
| Mode | Key | Action |
|-------|------|---------|
| Normal | `i` | Enter insert mode |
| Normal | `ESC` | Exit insert mode |
| Normal | `:w` | Save |
| Normal | `:q` | Quit |
| Normal | `u` | Undo |
| Normal | `Ctrl+r` | Redo |
### Zed
Default keybindings:
| Mode | Key | Action |
|-------|------|---------|
| General | `Ctrl+S` | Save |
| General | `Ctrl+P` | Command palette |
| General | `Ctrl+Shift+P` | File palette |
| Navigation | `Ctrl+B` | Toggle sidebar |
| Navigation | `Ctrl+Shift+B` | Toggle activity bar |
## Plugins and Extensions
### Neovim
The module provides a base. You can add plugins using:
```nix
{pkgs, ...}: {
programs.neovim.plugins = with pkgs.vimPlugins; [
nvim-lspconfig
nvim-treesitter
telescope-nvim
];
}
```
### Zed
Zed extensions are managed through the editor:
1. Open Zed
2. Go to Extensions (Ctrl+Shift+X)
3. Browse and install extensions
## Troubleshooting
### Editor Not Found
Ensure the editor package is installed:
```bash
# Check Neovim
which nvim
# Check Zed
which zed
```
### Configuration Not Applied
Check if the module is enabled:
```bash
# Check Home Manager state
home-manager show
# View current config
nix eval .#homeConfigurations.username.config.m3ta.coding.editors --apply builtins.attrNames
```
### Conflicts with Existing Config
If you have existing configuration:
1. Backup current config
2. Test module with fresh config
3. Gradually add custom settings
## Related
- [Using Modules Guide](../../guides/using-modules.md) - How to use modules
- [Adding Packages](../../guides/adding-packages.md) - How to add new packages

View File

@@ -0,0 +1,206 @@
# Home Manager Modules Overview
Overview of available Home Manager modules in m3ta-nixpkgs.
## Available Modules
### Core Modules
- [ports](./ports.md) - Port management across hosts
### CLI Modules (`cli/`)
- [zellij-ps](./cli/zellij-ps.md) - Zellij project switcher
### Coding Modules (`coding/`)
- [editors](./coding/editors.md) - Editor configurations
## Importing Modules
### Import All Modules
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
}
```
### Import Specific Module
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.ports
m3ta-nixpkgs.homeManagerModules.zellij-ps
];
}
```
### Import Category
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.cli.zellij-ps
m3ta-nixpkgs.homeManagerModules.coding.editors
];
}
```
## Module Namespace
All Home Manager modules use the `m3ta.*` namespace:
```nix
# Port management
m3ta.ports = {
enable = true;
definitions = {dev-server = 3000;};
};
# CLI tools
m3ta.cli.zellij-ps = {
enable = true;
};
# Coding tools
m3ta.coding.editors = {
enable = true;
neovim.enable = true;
};
```
## Module Categories
### Core
Essential modules for all users:
- **ports** - Port management with optional environment variable generation
### CLI (`cli/`)
Command-line interface tools and utilities:
- **zellij-ps** - Project switcher for Zellij terminal multiplexer
### Coding (`coding/`)
Development tools and configurations:
- **editors** - Editor configurations (Neovim, Zed, etc.)
## Integration Examples
### With NixOS
```nix
{config, ...}: {
# NixOS modules
imports = [
m3ta-nixpkgs.nixosModules.default
];
# Home Manager integration
home-manager.users.myusername = {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
};
currentHost = config.networking.hostName;
};
};
}
```
### Standalone Home Manager
```nix
{config, pkgs, ...}: {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
};
currentHost = "desktop";
};
m3ta.cli.zellij-ps = {
enable = true;
};
m3ta.coding.editors = {
enable = true;
neovim.enable = true;
};
}
```
## Module Locations
### Core
- `modules/home-manager/ports.nix` - Port management module
### CLI
- `modules/home-manager/cli/default.nix` - CLI module aggregator
- `modules/home-manager/cli/zellij-ps.nix` - Zellij project switcher
### Coding
- `modules/home-manager/coding/default.nix` - Coding module aggregator
- `modules/home-manager/coding/editors.nix` - Editor configurations
## Adding New Modules
### Core Module
1. Create: `modules/home-manager/my-module.nix`
2. Add to `modules/home-manager/default.nix`
### CLI Module
1. Create: `modules/home-manager/cli/my-tool.nix`
2. Add to `modules/home-manager/cli/default.nix`
### Coding Module
1. Create: `modules/home-manager/coding/my-tool.nix`
2. Add to `modules/home-manager/coding/default.nix`
### Module Template
```nix
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.m3ta.category.myModule;
in {
options.m3ta.category.myModule = {
enable = mkEnableOption "my module";
# ... options
};
config = mkIf cfg.enable {
# Configuration
};
}
```
## Related
- [Using Modules Guide](../../guides/using-modules.md) - How to use modules
- [NixOS Modules](./nixos/overview.md) - System-level modules
- [Port Management Guide](../../guides/port-management.md) - Detailed port management

View File

@@ -0,0 +1,272 @@
# ports Home Manager Module
Port management module for Home Manager.
## Overview
This module provides centralized port management for user-level services, similar to the NixOS version but with additional support for generating environment variables.
See [Port Management Guide](../../guides/port-management.md) for detailed usage.
## Quick Start
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
# Define default ports
definitions = {
dev-server = 3000;
nextjs = 3001;
vite = 5173;
};
# Host-specific overrides
hostOverrides = {
laptop = {
vite = 5174;
};
};
# Current host
currentHost = "desktop";
# Generate environment variables (Home Manager only)
generateEnvVars = true;
};
}
```
## Module Options
### `m3ta.ports.enable`
Enable port management.
- Type: `boolean`
- Default: `false`
### `m3ta.ports.definitions`
Default port definitions.
- Type: `attrsOf int`
- Default: `{}`
Example:
```nix
definitions = {
dev-server = 3000;
nextjs = 3001;
vite = 5173;
};
```
### `m3ta.ports.hostOverrides`
Host-specific port overrides.
- Type: `attrsOf (attrsOf int)`
- Default: `{}`
Example:
```nix
hostOverrides = {
laptop = {
vite = 5174;
};
desktop = {
vite = 5173;
};
};
```
### `m3ta.ports.currentHost`
Current hostname.
- Type: `string`
- Example: `"desktop"`
### `m3ta.ports.generateEnvVars`
Generate environment variables from ports.
- Type: `boolean`
- Default: `false`
- Home Manager only
When enabled, generates environment variables like:
```bash
PORT_DEV_SERVER=3000
PORT_NEXTJS=3001
PORT_VITE=5173
```
## Functions
### `config.m3ta.ports.get "service"`
Get port for a service with host-specific override.
```nix
home.sessionVariables = {
DEV_PORT = toString (config.m3ta.ports.get "dev-server");
};
```
### `config.m3ta.ports.getHostPorts "hostname"`
Get all ports for a specific host.
```nix
laptopPorts = config.m3ta.ports.getHostPorts "laptop";
# Returns: { dev-server = 3000; vite = 5174; ... }
```
### `config.m3ta.ports.listServices`
List all defined service names.
```nix
allServices = config.m3ta.ports.listServices;
# Returns: ["dev-server" "nextjs" "vite"]
```
## Environment Variables
When `generateEnvVars = true`, the following environment variables are generated:
```
PORT_<SERVICE_UPPERCASE>=<port_number>
```
Example:
```nix
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
nextjs = 3001;
};
generateEnvVars = true;
};
```
Generates:
```bash
PORT_DEV_SERVER=3000
PORT_NEXTJS=3001
```
You can then use these in scripts:
```bash
#!/usr/bin/env bash
# Use environment variable directly
npm start --port=$PORT_DEV_SERVER
```
## Usage Examples
### Basic Usage
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
};
currentHost = "desktop";
};
home.sessionVariables = {
DEV_PORT = toString (config.m3ta.ports.get "dev-server");
};
}
```
### With Environment Variables
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
nextjs = 3001;
vite = 5173;
};
currentHost = "desktop";
generateEnvVars = true;
};
# Now available as environment variables
# PORT_DEV_SERVER=3000
# PORT_NEXTJS=3001
# PORT_VITE=5173
}
```
### With Multi-Host Setup
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
vite = 5173;
};
hostOverrides = {
laptop = {
vite = 5174;
};
desktop = {
vite = 5173;
};
};
currentHost = config.networking.hostName;
generateEnvVars = true;
};
}
```
### With Shell Scripts
Create `~/.config/zellij/scripts/dev.ksh`:
```ksh
#!/usr/bin/env ksh
# Start dev server using environment variable
cd ~/projects/my-app
npm start --port=$PORT_DEV_SERVER
```
## Difference from NixOS Module
The Home Manager version has one additional feature:
### `generateEnvVars`
Not available in NixOS module. Generates environment variables for all defined ports:
```nix
# Home Manager
m3ta.ports.generateEnvVars = true; # Available
# NixOS
# Not available
```
## Related
- [Port Management Guide](../../guides/port-management.md) - Detailed guide
- [NixOS Ports Module](../nixos/ports.md) - System-level port management

508
docs/modules/nixos/mem0.md Normal file
View File

@@ -0,0 +1,508 @@
# mem0 NixOS Module
Mem0 REST API server module for AI memory management.
## Overview
This module provides a systemd service for the Mem0 REST API server, enabling AI agents to maintain persistent memory across conversations.
## Quick Start
```nix
{config, ...}: {
imports = [m3ta-nixpkgs.nixosModules.mem0];
m3ta.mem0 = {
enable = true;
port = 8000;
llm = {
provider = "openai";
apiKeyFile = "/run/secrets/openai-api-key";
model = "gpt-4o-mini";
};
vectorStore = {
provider = "qdrant";
config = {
host = "localhost";
port = 6333;
};
};
};
}
```
## Module Options
### `m3ta.mem0.enable`
Enable the Mem0 REST API server.
- Type: `boolean`
- Default: `false`
### `m3ta.mem0.package`
The mem0 package to use.
- Type: `package`
- Default: `pkgs.mem0`
### `m3ta.mem0.host`
Host address to bind the server to.
- Type: `string`
- Default: `"127.0.0.1"`
### `m3ta.mem0.port`
Port to run the REST API server on.
- Type: `port`
- Default: `8000`
### `m3ta.mem0.workers`
Number of worker processes.
- Type: `integer`
- Default: `1`
### `m3ta.mem0.logLevel`
Logging level for the server.
- Type: `enum` ["critical" "error" "warning" "info" "debug" "trace"]
- Default: `"info"`
### `m3ta.mem0.stateDir`
Directory to store mem0 data and state.
- Type: `path`
- Default: `"/var/lib/mem0"`
### `m3ta.mem0.user`
User account under which mem0 runs.
- Type: `string`
- Default: `"mem0"`
### `m3ta.mem0.group`
Group under which mem0 runs.
- Type: `string`
- Default: `"mem0"`
### `m3ta.mem0.environmentFile`
Environment file containing additional configuration.
- Type: `nullOr path`
- Default: `null`
## LLM Configuration
### `m3ta.mem0.llm.provider`
LLM provider to use.
- Type: `enum` ["openai" "anthropic" "azure" "groq" "together" "ollama" "litellm"]
- Default: `"openai"`
### `m3ta.mem0.llm.model`
Model name to use.
- Type: `string`
- Default: `"gpt-4o-mini"`
### `m3ta.mem0.llm.apiKeyFile`
Path to file containing the API key.
- Type: `nullOr path`
- Default: `null`
- Example: `"/run/secrets/openai-api-key"`
### `m3ta.mem0.llm.temperature`
Temperature parameter for LLM generation.
- Type: `nullOr float`
- Default: `null`
### `m3ta.mem0.llm.maxTokens`
Maximum tokens for LLM generation.
- Type: `nullOr int`
- Default: `null`
### `m3ta.mem0.llm.extraConfig`
Additional LLM configuration options.
- Type: `attrs`
- Default: `{}`
## Vector Store Configuration
### `m3ta.mem0.vectorStore.provider`
Vector database provider.
- Type: `enum` ["qdrant" "chroma" "pinecone" "weaviate" "faiss" "pgvector" "redis" "elasticsearch" "milvus"]
- Default: `"qdrant"`
### `m3ta.mem0.vectorStore.config`
Configuration for the vector store.
- Type: `attrs`
- Default: `{}`
Example for Qdrant:
```nix
vectorStore.config = {
host = "localhost";
port = 6333;
collection_name = "mem0_memories";
};
```
Example for pgvector:
```nix
vectorStore.config = {
host = "localhost";
port = 5432;
dbname = "postgres";
user = "postgres";
password = "postgres";
};
```
## Embedder Configuration
### `m3ta.mem0.embedder.provider`
Embedding model provider.
- Type: `nullOr (enum` ["openai" "huggingface" "ollama" "vertexai"])
- Default: `null`
### `m3ta.mem0.embedder.model`
Embedding model name.
- Type: `nullOr string`
- Default: `null`
### `m3ta.mem0.embedder.config`
Configuration for the embedder.
- Type: `attrs`
- Default: `{}`
## Usage Examples
### Minimal Configuration
```nix
{config, ...}: {
m3ta.mem0 = {
enable = true;
};
}
```
### With OpenAI
```nix
{config, ...}: {
m3ta.mem0 = {
enable = true;
llm = {
provider = "openai";
apiKeyFile = "/run/secrets/openai-api-key";
model = "gpt-4";
};
};
}
```
### With Local LLM (Ollama)
```nix
{config, ...}: {
m3ta.mem0 = {
enable = true;
llm = {
provider = "ollama";
model = "llama2";
};
};
}
```
### With Port Management
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
mem0 = 8000;
};
currentHost = config.networking.hostName;
};
m3ta.mem0 = {
enable = true;
port = config.m3ta.ports.get "mem0";
};
}
```
### With Qdrant
```nix
{config, ...}: {
m3ta.mem0 = {
enable = true;
vectorStore = {
provider = "qdrant";
config = {
host = "localhost";
port = 6333;
};
};
};
}
services.qdrant = {
enable = true;
port = 6333;
};
```
### With Secrets (agenix)
```nix
{config, ...}: {
age.secrets.openai-api-key = {
file = ./secrets/openai-api-key.age;
};
m3ta.mem0 = {
enable = true;
llm = {
apiKeyFile = config.age.secrets.openai-api-key.path;
};
};
}
```
## Service Management
### Start/Stop/Restart
```bash
# Start service
sudo systemctl start mem0
# Stop service
sudo systemctl stop mem0
# Restart service
sudo systemctl restart mem0
# Check status
sudo systemctl status mem0
```
### View Logs
```bash
# View logs
sudo journalctl -u mem0 -f
# View last 100 lines
sudo journalctl -u mem0 -n 100
```
### Service File
The module creates a systemd service at `/etc/systemd/system/mem0.service` with:
- Security hardening enabled
- Automatic restart on failure
- Proper user/group setup
## API Usage
### Add Memory
```bash
curl -X POST http://localhost:8000/v1/memories \
-H "Content-Type: application/json" \
-d '{
"content": "User prefers coffee over tea",
"metadata": {"user_id": "123"}
}'
```
### Search Memories
```bash
curl http://localhost:8000/v1/memories/search?q=coffee
```
### Update Memory
```bash
curl -X PATCH http://localhost:8000/v1/memories/memory_id \
-H "Content-Type: application/json" \
-d '{
"content": "User prefers coffee over tea, but also likes chai"
}'
```
### Delete Memory
```bash
curl -X DELETE http://localhost:8000/v1/memories/memory_id
```
## Dependencies
### Required Services
Depending on your configuration, you may need:
- **qdrant** service (if using qdrant vector store)
- **postgresql** with pgvector (if using pgvector)
- **chroma** service (if using chroma)
- **ollama** (if using local LLMs)
### Example: Qdrant
```nix
services.qdrant = {
enable = true;
port = 6333;
};
```
### Example: PostgreSQL
```nix
services.postgresql = {
enable = true;
enableTCPIP = true;
package = pkgs.postgresql_15;
extensions = ["pgvector"];
settings = {
port = 5432;
};
};
```
## Firewall
The module automatically opens the firewall port if binding to non-localhost addresses:
```nix
# Opens port if host is not "127.0.0.1" or "localhost"
m3ta.mem0 = {
enable = true;
host = "0.0.0.0"; # Binds to all interfaces
port = 8000;
};
# Firewall automatically opens port 8000
```
## Security
### User/Group
Creates dedicated user and group:
- User: `mem0`
- Group: `mem0`
- Home: `/var/lib/mem0`
### Hardening
Systemd service includes security hardening:
- `NoNewPrivileges`
- `PrivateTmp`
- `ProtectSystem=strict`
- `ProtectHome=true`
- `RestrictRealtime=true`
- `RestrictNamespaces=true`
- `LockPersonality=true`
### Secrets
Use `apiKeyFile` for API keys instead of plain text:
```nix
# Good
llm.apiKeyFile = "/run/secrets/openai-api-key";
# Bad (insecure)
llm.apiKey = "sk-xxx";
```
## Troubleshooting
### Service Won't Start
Check logs:
```bash
sudo journalctl -u mem0 -n 50
```
Common issues:
1. **API key missing**: Ensure `apiKeyFile` exists and is readable
2. **Vector store unavailable**: Ensure qdrant/other store is running
3. **Port in use**: Check if port is available
### API Not Responding
Check service status:
```bash
sudo systemctl status mem0
# Check if port is open
ss -tuln | grep 8000
```
### Memory Issues
Increase memory limit in systemd override:
```bash
sudo systemctl edit mem0
[Service]
MemoryMax=2G
```
## Related
- [mem0 Package](../../packages/mem0.md) - Package documentation
- [Port Management Guide](../../guides/port-management.md) - Using with port management
- [Using Modules Guide](../../guides/using-modules.md) - Module usage patterns

View File

@@ -0,0 +1,166 @@
# NixOS Modules Overview
Overview of available NixOS modules in m3ta-nixpkgs.
## Available Modules
- [ports](./ports.md) - Port management across hosts
- [mem0](./mem0.md) - Mem0 REST API server
## Importing Modules
### Import All Modules
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
];
}
```
### Import Specific Module
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.ports
m3ta-nixpkgs.nixosModules.mem0
];
}
```
## Module Namespace
All NixOS modules use the `m3ta.*` namespace:
```nix
# Port management
m3ta.ports = {
enable = true;
definitions = {nginx = 80;};
};
# Mem0 service
m3ta.mem0 = {
enable = true;
port = 8000;
};
```
## Common Patterns
### Enable Module
All modules follow the pattern:
```nix
m3ta.moduleName = {
enable = true;
# ... options
};
```
### Configuration
Modules typically provide these sections:
- `enable` - Enable/disable module
- `package` - Custom package (optional)
- Configuration options specific to module
## Integration Examples
### With Port Management
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
];
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
mem0 = 8000;
};
currentHost = config.networking.hostName;
};
m3ta.mem0 = {
enable = true;
port = config.m3ta.ports.get "mem0";
};
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
root /var/www;
}
'';
};
}
```
### With Home Manager
```nix
{config, ...}: {
# NixOS modules
imports = [
m3ta-nixpkgs.nixosModules.default
];
# Home Manager integration
home-manager.users.myusername = {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
};
currentHost = config.networking.hostName;
};
};
}
```
## Module Locations
- `modules/nixos/ports.nix` - Port management module
- `modules/nixos/mem0.nix` - Mem0 REST API server module
## Adding New Modules
1. Create module file: `modules/nixos/my-module.nix`
2. Follow standard pattern:
```nix
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "my module";
};
config = mkIf cfg.enable {
# Configuration
};
}
```
3. Import in `modules/nixos/default.nix`
## Related
- [Port Management Guide](../guides/port-management.md) - Detailed port management usage
- [Using Modules Guide](../guides/using-modules.md) - How to use modules
- [Home Manager Modules](./home-manager/overview.md) - User-level modules

229
docs/modules/nixos/ports.md Normal file
View File

@@ -0,0 +1,229 @@
# ports NixOS Module
Port management module for NixOS.
## Overview
This module provides centralized port management across multiple hosts. Define default ports and host-specific overrides to prevent conflicts.
See [Port Management Guide](../../guides/port-management.md) for detailed usage.
## Quick Start
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
# Define default ports
definitions = {
nginx = 80;
grafana = 3000;
prometheus = 9090;
};
# Host-specific overrides
hostOverrides = {
laptop = {
nginx = 8080;
grafana = 3001;
};
};
# Current host
currentHost = config.networking.hostName;
};
}
```
## Module Options
### `m3ta.ports.enable`
Enable port management.
- Type: `boolean`
- Default: `false`
### `m3ta.ports.definitions`
Default port definitions.
- Type: `attrsOf int`
- Default: `{}`
Example:
```nix
definitions = {
nginx = 80;
grafana = 3000;
prometheus = 9090;
};
```
### `m3ta.ports.hostOverrides`
Host-specific port overrides.
- Type: `attrsOf (attrsOf int)`
- Default: `{}`
Example:
```nix
hostOverrides = {
laptop = {
nginx = 8080;
grafana = 3001;
};
server = {
nginx = 80;
prometheus = 9091;
};
};
```
### `m3ta.ports.currentHost`
Current hostname. Determines which overrides to apply.
- Type: `string`
- Example: `config.networking.hostName`
## Functions
### `config.m3ta.ports.get "service"`
Get port for a service with host-specific override.
```nix
services.nginx = {
port = config.m3ta.ports.get "nginx";
};
```
If current host is `laptop` and `hostOverrides.laptop.nginx = 8080`, returns `8080`.
If no override, returns default `80`.
### `config.m3ta.ports.getHostPorts "hostname"`
Get all ports for a specific host.
```nix
# Get all ports for laptop
laptopPorts = config.m3ta.ports.getHostPorts "laptop";
# Returns: { nginx = 8080; grafana = 3000; ... }
```
### `config.m3ta.ports.listServices`
List all defined service names.
```nix
allServices = config.m3ta.ports.listServices;
# Returns: ["nginx" "grafana" "prometheus"]
```
## Usage Examples
### Basic Usage
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
};
currentHost = "server";
};
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
}
'';
};
}
```
### Multi-Host Setup
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
prometheus = 9090;
};
hostOverrides = {
laptop = {
nginx = 8080;
grafana = 3001;
};
server = {
nginx = 80;
grafana = 3000;
};
};
currentHost = config.networking.hostName;
};
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
}
'';
};
}
```
### With Multiple Services
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
# Monitoring
grafana = 3000;
prometheus = 9090;
loki = 3100;
promtail = 9080;
# Web
nginx = 80;
# Databases
postgres = 5432;
redis = 6379;
qdrant = 6333;
};
currentHost = config.networking.hostName;
};
# Use ports
services.grafana = {
enable = true;
settings.server.http_port = config.m3ta.ports.get "grafana";
};
services.postgresql = {
enable = true;
port = config.m3ta.ports.get "postgres";
};
}
```
## Related
- [Port Management Guide](../../guides/port-management.md) - Detailed guide
- [Home Manager Ports Module](../home-manager/ports.md) - User-level port management

View File

@@ -0,0 +1,206 @@
# code2prompt
A CLI tool that converts your codebase into a single LLM prompt with a source tree, prompt templating, and token counting.
## Description
code2prompt is a command-line tool designed to help developers prepare their codebases for analysis by Large Language Models (LLMs). It creates a comprehensive prompt that includes:
- Source code tree structure
- Concatenated file contents
- Prompt templates
- Token counting for context management
## Features
- 📁 **Source Tree Generation**: Visual representation of your codebase structure
- 📝 **Code Concatenation**: Merges multiple files into a single prompt
- 🧩 **Prompt Templates**: Customizable prompt templates
- 🔢 **Token Counting**: Accurate token counting for various LLMs
- 🎯 **Selective Inclusion**: Choose specific files and directories
- 🔒 **Smart Filtering**: Exclude files by pattern (.git, node_modules, etc.)
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
code2prompt
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.code2prompt
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#code2prompt
```
## Usage
### Basic Usage
```bash
# Generate prompt for current directory
code2prompt
# Generate for specific directory
code2prompt /path/to/project
# Output to file
code2prompt -o prompt.txt
# Use custom template
code2prompt --template my_template.md
```
### Common Options
```bash
# Include specific files
code2prompt --include "*.py" "*.js"
# Exclude specific files
code2prompt --exclude "*.test.*" "node_modules/*"
# Generate source tree only
code2prompt --tree-only
# Add custom context
code2prompt --context "This is a Node.js project"
```
### Examples
#### Prepare Codebase for GPT-4
```bash
code2prompt \
--template gpt4-template.md \
--include "*.ts" "*.tsx" \
--exclude "node_modules" "*.test.ts" \
--context "Review this TypeScript codebase" \
-o codebase_prompt.txt
# Then feed to GPT-4
cat codebase_prompt.txt
```
#### Analyze Specific Directory
```bash
# Analyze only src directory
code2prompt src/ \
--include "*.rs" \
--context "Analyze this Rust codebase" \
-o src_analysis.txt
```
#### Create Source Tree
```bash
# Generate only source tree
code2prompt --tree-only > tree.txt
cat tree.txt
```
## Use Cases
### Code Review
Prepare code for AI-assisted code review:
```bash
code2prompt \
--template code-review.md \
--include "*.py" \
--context "Review this Python code for security issues" \
-o review_prompt.txt
```
### Documentation Generation
Generate documentation using LLMs:
```bash
code2prompt \
--template docs-template.md \
--include "*.js" "*.md" \
--context "Generate API documentation" \
-o docs_prompt.txt
```
### Code Migration
Prepare code for migration assistance:
```bash
code2prompt \
--template migration-template.md \
--include "*.js" \
--context "Migrate this JavaScript to TypeScript" \
-o migration_prompt.txt
```
## Configuration
### Environment Variables
- `CODE2PROMPT_TEMPLATE_DIR`: Directory containing custom templates
- `CODE2PROMPT_DEFAULT_TEMPLATE`: Default template to use
### Template Files
Custom templates can include:
```markdown
# Codebase Analysis
## Context
{context}
## Directory Tree
{tree}
## Code
{code}
## Instructions
{instructions}
```
## Build Information
- **Version**: 4.0.2
- **Language**: Rust
- **License**: MIT
- **Source**: [GitHub](https://github.com/mufeedvh/code2prompt)
## Dependencies
- `openssl` - Secure communication
- `pkg-config` - Build configuration
## Platform Support
- Linux (primary)
- macOS (may work)
- Windows (not tested)
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide

View File

@@ -0,0 +1,190 @@
# hyprpaper-random
Minimal random wallpaper setter for Hyprpaper.
## Description
hyprpaper-random is a shell script that randomly selects and applies a wallpaper from a configured directory for use with Hyprpaper on Hyprland. It's designed to be minimal and fast.
## Features
- 🎲 **Random Selection**: Picks a random wallpaper from directory
- 🖼️ **Multi-Monitor Support**: Applies wallpaper to all monitors
- 📁 **Flexible Directory**: Configurable via environment variable
- 🔍 **Format Support**: jpg, jpeg, png, webp, avif
-**Fast**: Uses `fd` for quick file searching
- 🔄 **Safe**: Null-safe handling and error checking
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
hyprpaper-random
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.hyprpaper-random
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#hyprpaper-random
```
## Usage
### Basic Usage
```bash
# Use default directory ($XDG_CONFIG_HOME/hypr/wallpapers or ~/.config/hypr/wallpapers)
hyprpaper-random
# Use custom directory
WALLPAPER_DIR=~/Pictures/wallpapers hyprpaper-random
# Or set directory permanently
export WALLPAPER_DIR=~/Pictures/wallpapers
hyprpaper-random
```
### With Hyprpaper
Make sure Hyprpaper is running and loaded:
```bash
# Start Hyprpaper
hyprpaper &
# Set random wallpaper
hyprpaper-random
```
### Automate with Keybinding
Add to Hyprland config:
```nix
{pkgs, ...}: {
wayland.windowManager.hyprland.settings = {
bindm = [
"SUPER, mouse, movewindow"
];
bind = [
# Set random wallpaper on SUPER + W
"SUPER, W, exec, ${pkgs.hyprpaper-random}/bin/hyprpaper-random"
];
};
}
```
### Automate with Cron
```bash
# Change wallpaper every hour
0 * * * * hyprpaper-random
```
## Configuration
### Directory Setup
Default wallpaper directory:
```
$XDG_CONFIG_HOME/hypr/wallpapers/
# or
~/.config/hypr/wallpapers/
```
Custom directory:
```bash
# Temporary
WALLPAPER_DIR=~/Pictures/my-wallpapers hyprpaper-random
# Permanent (add to shell config)
export WALLPAPER_DIR=~/Pictures/my-wallpapers
```
### Environment Variables
- `WALLPAPER_DIR`: Path to wallpaper directory (default: `$XDG_CONFIG_HOME/hypr/wallpapers`)
- `XDG_CONFIG_HOME`: Config directory base (default: `~/.config`)
## Requirements
- `hyprland`: Hyprland window manager (for `hyprctl`)
- `hyprpaper`: Wallpaper utility for Hyprland
- `fd`: Fast file search
- `coreutils`: For `shuf` command
- `gawk`: Text processing
## Platform Support
- Linux (primary, requires Hyprland)
- macOS (not supported)
- Windows (not supported)
## Build Information
- **Version**: 0.1.1
- **Type**: Shell script
- **License**: MIT
## Troubleshooting
### No Wallpapers Found
Error: `No wallpapers found in: /path/to/dir`
**Solution**: Ensure wallpaper directory exists and contains images:
```bash
ls -la $WALLPAPER_DIR # Check directory exists
ls -la $WALLPAPER_DIR/*.jpg # Check for images
```
### Hyprctl Not Found
Error: `hyprctl: command not found`
**Solution**: Ensure Hyprland is installed:
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
hyprland
hyprpaper
];
}
```
### Wallpaper Not Changing
**Solution**: Check if Hyprpaper is running:
```bash
# Check status
hyprctl hyprpaper listloaded
# Check for errors
journalctl -u hyprpaper -f
```
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide

View File

@@ -0,0 +1,180 @@
# launch-webapp
Launches a web app using your default browser in app mode.
## Description
launch-webapp is a shell script that launches web applications (like Discord, Spotify Web, etc.) in your default browser's "app mode". This provides a more native-like experience for web apps.
## Features
- 🌐 **Auto-Detection**: Detects your default web browser
- 🚀 **App Mode**: Launches in dedicated app window (no address bar)
- 🎨 **Native Feel**: Removes browser chrome for app-like experience
- 🔄 **Session Management**: Keeps web apps separate from regular browsing
- 🖥️ **Wayland Support**: Works with Wayland session managers (via `uwsm`)
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
launch-webapp
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.launch-webapp
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#launch-webapp
```
## Usage
### Basic Usage
```bash
# Launch web app
launch-webapp https://web.telegram.org
# Launch with additional arguments
launch-webapp https://web.whatsapp.com --app-name="WhatsApp"
```
### Examples
#### Launch Discord Web
```bash
launch-webapp https://discord.com/app
```
#### Launch Spotify Web
```bash
launch-webapp https://open.spotify.com
```
#### Launch Google Chat
```bash
launch-webapp https://chat.google.com
```
## Configuration
### Supported Browsers
The script auto-detects and supports:
- Google Chrome
- Brave Browser
- Microsoft Edge
- Opera
- Vivaldi
- Chromium (fallback)
### Default Browser
The script uses `xdg-settings` to detect your default browser.
```bash
# Check your default browser
xdg-settings get default-web-browser
```
### Wayland Support
The script uses `uwsm` (Wayland Session Manager) for proper Wayland support. Ensure `uwsm` is installed and configured.
## Desktop Integration
### Create Desktop Entry
Create `~/.local/share/applications/webapp-discord.desktop`:
```ini
[Desktop Entry]
Name=Discord Web
Comment=Discord Web App
Exec=launch-webapp https://discord.com/app
Icon=discord
Type=Application
Categories=Network;InstantMessaging;
```
### Add to Menu
The desktop entry will appear in your application menu after creating it.
## Requirements
- `xdg-utils`: For default browser detection
- `uwsm`: Wayland session manager
- Your preferred browser (Chrome, Brave, etc.)
## Platform Support
- Linux (primary, requires Wayland)
- macOS (not tested)
- Windows (not supported)
## Build Information
- **Version**: 0.1.0
- **Type**: Shell script
- **License**: MIT
## Troubleshooting
### Browser Not Found
If the script doesn't find your browser, ensure it's installed:
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
google-chrome
# or brave-browser, microsoft-edge, etc.
];
}
```
### Wayland Issues
If you encounter Wayland issues:
```bash
# Check uwsm is installed
which uwsm
# Check Wayland session
echo $XDG_SESSION_TYPE # Should be "wayland"
```
### App Won't Launch
Check the browser supports app mode:
```bash
# Test manually
google-chrome --app=https://example.com
```
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide

268
docs/packages/mem0.md Normal file
View File

@@ -0,0 +1,268 @@
# mem0
Long-term memory layer for AI agents with REST API support.
## Description
Mem0 provides a sophisticated memory management system for AI applications and agents. It enables AI assistants to maintain persistent memory across conversations and sessions using vector storage.
## Features
- 💾 **Long-term Memory**: Persistent memory across conversations
- 🔍 **Semantic Search**: Vector-based similarity search
- 🤖 **Multiple LLM Support**: OpenAI, Anthropic, Groq, Ollama, etc.
- 📊 **Vector Stores**: Qdrant, Chroma, Pinecone, pgvector, etc.
- 🌐 **REST API**: Easy integration via HTTP endpoints
- 🎯 **Multi-modal Support**: Text and image memories
- 🔧 **Configurable**: Flexible LLM and embedding models
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
mem0
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.mem0
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#mem0
```
## Usage
### Command Line
```bash
# Start mem0 server
mem0-server
# With custom port
MEM0_PORT=8080 mem0-server
# With LLM provider
MEM0_LLM_PROVIDER=openai OPENAI_API_KEY=sk-xxx mem0-server
```
### Python Library
```python
from mem0 import Memory
# Initialize with OpenAI
memory = Memory(
llm_provider="openai",
llm_model="gpt-4o-mini",
vector_store="qdrant",
openai_api_key="sk-xxx"
)
# Add a memory
result = memory.add(
"I prefer coffee over tea",
metadata={"user_id": "123"}
)
# Search memories
memories = memory.search("What does the user prefer?")
```
### REST API
```bash
# Start server
mem0-server
# Add memory
curl -X POST http://localhost:8000/v1/memories \
-H "Content-Type: application/json" \
-d '{"content": "User likes Python"}'
# Search memories
curl http://localhost:8000/v1/memories/search?q=Python
```
## Configuration
### Environment Variables
```bash
# LLM Configuration
export MEM0_LLM_PROVIDER=openai
export MEM0_LLM_MODEL=gpt-4o-mini
export MEM0_LLM_TEMPERATURE=0.7
export OPENAI_API_KEY=sk-xxx
# Vector Store
export MEM0_VECTOR_PROVIDER=qdrant
export QDRANT_HOST=localhost
export QDRANT_PORT=6333
# Server
export MEM0_HOST=0.0.0.0
export MEM0_PORT=8000
export MEM0_WORKERS=4
export MEM0_LOG_LEVEL=info
```
### NixOS Module (Recommended)
Use the NixOS module for production:
```nix
{config, ...}: {
imports = [m3ta-nixpkgs.nixosModules.mem0];
m3ta.mem0 = {
enable = true;
port = 8000;
llm = {
provider = "openai";
apiKeyFile = "/run/secrets/openai-api-key";
model = "gpt-4o-mini";
};
vectorStore = {
provider = "qdrant";
config = {
host = "localhost";
port = 6333;
};
};
};
}
```
See [mem0 Module](../modules/nixos/mem0.md) for full module documentation.
## Supported LLM Providers
| Provider | Model Examples | Notes |
|----------|---------------|-------|
| `openai` | gpt-4, gpt-3.5-turbo | Most tested |
| `anthropic` | claude-3-opus, claude-3-sonnet | Requires key |
| `groq` | mixtral-8x7b-32768 | Fast inference |
| `ollama` | llama2, mistral | Local only |
| `together` | llama-2-70b | API access |
## Supported Vector Stores
| Provider | Requirements | Notes |
|----------|--------------|-------|
| `qdrant` | qdrant server | Recommended |
| `chroma` | chroma server | Simple setup |
| `pgvector` | PostgreSQL + pgvector | SQL-based |
| `pinecone` | Pinecone API | Cloud only |
| `redis` | Redis stack | Fast |
| `elasticsearch` | ES cluster | Scalable |
## Use Cases
### AI Chatbot with Memory
```python
from mem0 import Memory
memory = Memory()
# During conversation
memory.add("User works at Google as a software engineer")
# Later conversations
memories = memory.search("Where does the user work?")
# Returns: ["User works at Google as a software engineer"]
```
### Personal Assistant
```python
memory = Memory()
# Store preferences
memory.add("User prefers dark mode", metadata={"category": "preferences"})
memory.add("User is vegetarian", metadata={"category": "diet"})
# Retrieve relevant info
memories = memory.search("What should I cook for the user?")
```
### Code Assistant
```python
memory = Memory()
# Store project context
memory.add("This is a NixOS project with custom packages")
# Later analysis
memories = memory.search("What kind of project is this?")
```
## Requirements
### Vector Store
You need a vector store running. Example with Qdrant:
```nix
services.qdrant = {
enable = true;
port = 6333;
};
```
### LLM Provider
You need API keys or local models:
```nix
# OpenAI
services.mem0.llm.apiKeyFile = "/run/secrets/openai-api-key";
# Or use agenix
age.secrets.openai-api-key.file = ./secrets/openai.age;
```
## Build Information
- **Version**: 1.0.0
- **Language**: Python
- **License**: Apache-2.0
- **Source**: [GitHub](https://github.com/mem0ai/mem0)
## Python Dependencies
- `litellm` - Multi-LLM support
- `qdrant-client` - Qdrant client
- `pydantic` - Data validation
- `openai` - OpenAI client
- `fastapi` - REST API
- `uvicorn` - ASGI server
- `sqlalchemy` - Database ORM
## Platform Support
- Linux (primary)
- macOS (may work)
- Windows (not tested)
## Related
- [mem0 Module](../modules/nixos/mem0.md) - NixOS module documentation
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Port Management](../guides/port-management.md) - Managing service ports
- [Quick Start](../QUICKSTART.md) - Getting started guide

View File

@@ -0,0 +1,172 @@
# msty-studio
Msty Studio enables advanced, privacypreserving AI workflows entirely on your local machine.
## Description
Msty Studio is a desktop application that provides a powerful AI development environment with a focus on privacy. All AI processing happens locally on your machine, ensuring your data never leaves your system.
## Features
- 🔒 **Privacy-First**: All AI processing happens locally
- 🤖 **Local AI Models**: Support for running local LLMs
- 📝 **Code Editor**: Integrated development environment
- 🔄 **Multiple Models**: Switch between different AI models
- 📊 **Model Management**: Download and manage local models
- 🎨 **Modern UI**: Clean, intuitive interface
-**Fast Performance**: Optimized for speed
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
msty-studio
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.msty-studio
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#msty-studio
```
## Usage
### Launch Application
```bash
# Launch Msty Studio
msty-studio
# Or from application menu
# Applications -> Msty Studio
```
### First Run
On first launch, you'll need to:
1. Download an AI model (if not already downloaded)
2. Configure model settings
3. Set up your workspace
### Managing Models
Through the Msty Studio interface, you can:
- Download new models
- Remove unused models
- Switch between models
- Configure model parameters
## Configuration
### Model Directory
Models are stored in your home directory:
```
~/.local/share/msty-studio/models/
```
### Settings
Msty Studio stores settings in:
```
~/.config/msty-studio/
```
### Integration with Nix
The package includes required dependencies:
- Node.js (for runtime)
- npm (for package management)
- uv (for Python packages)
- Python (for AI models)
## Requirements
### System Requirements
- Linux (x86_64)
- 8GB RAM minimum (16GB+ recommended)
- Modern CPU with AVX2 support
- GPU recommended (for faster inference)
### Dependencies
The package includes these dependencies:
- `nodejs` - JavaScript runtime
- `nodePackages.npm` - Package manager
- `uv` - Python package installer
- `python3` - Python runtime
## Platform Support
- Linux (x86_64 only)
- macOS (not supported)
- Windows (not supported)
**Note**: Msty Studio is distributed as an AppImage for Linux.
## Build Information
- **Version**: 2.0.0-beta.4
- **Type**: AppImage
- **License**: Proprietary (Unfree)
- **Source**: [msty.studio](https://msty.studio)
## Troubleshooting
### AppImage Won't Launch
Ensure executable bit is set:
```bash
chmod +x ~/.local/share/applications/msty-studio.desktop
```
### Models Not Downloading
Check disk space and network:
```bash
# Check disk space
df -h
# Check network
ping google.com
```
### Performance Issues
- Ensure you're using a GPU-accelerated model
- Close other resource-intensive applications
- Check system resources:
```bash
htop
nvidia-smi # If using NVIDIA GPU
```
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide

View File

@@ -0,0 +1,220 @@
# pomodoro-timer
A work timer based on the Pomodoro Technique.
## Description
A simple, shell-based Pomodoro timer that uses `timer`, Kitty terminal, Rofi, libnotify, and speech synthesis to provide visual and audio feedback for work and break sessions.
## Features
- ⏱️ **Pomodoro Technique**: 45-minute work, 10-minute break cycles
- 🎨 **Terminal UI**: Floating Kitty terminal window
- 📋 **Rofi Menu**: Easy session selection
- 🔔 **Notifications**: Desktop and voice notifications
- ⚙️ **Custom Times**: Set custom durations
- 🎯 **Quick Access**: Simple keybinding integration
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
launch-timer # The main program is named launch-timer
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.launch-timer
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#launch-timer
```
## Usage
### Basic Usage
```bash
# Launch timer selection menu
launch-timer
```
This opens a Rofi menu with three options:
1. **work** - 45-minute work session
2. **break** - 10-minute break session
3. **custom** - Custom time duration
### Session Options
#### Work Session
```bash
# Select "work" from menu
# Starts 45-minute timer
```
#### Break Session
```bash
# Select "break" from menu
# Starts 10-minute timer
```
#### Custom Time
```bash
# Select "custom" from menu
# Enter time in format: 25m, 1h, 30s
# Examples:
# 25m - 25 minutes
# 1h - 1 hour
# 30s - 30 seconds
```
### Time Formats
Supported formats:
| Format | Example | Description |
|---------|----------|-------------|
| `Xm` | `25m` | X minutes |
| `Xh` | `1h` | X hours |
| `Xs` | `30s` | X seconds |
## Configuration
### Keybinding Integration
Add to Hyprland config:
```nix
{pkgs, ...}: {
wayland.windowManager.hyprland.settings = {
bind = [
# Launch Pomodoro timer with SUPER + T
"SUPER, T, exec, ${pkgs.launch-timer}/bin/launch-timer"
];
};
}
```
### Custom Defaults
Modify the script for custom defaults:
```bash
# Change work duration
start_timer "60m" "work"
# Change break duration
start_timer "15m" "break"
```
## Requirements
### Dependencies
- `timer` - Terminal timer utility
- `kitty` - Terminal emulator
- `rofi` - Application launcher
- `libnotify` - Desktop notifications
- `speechd` - Text-to-speech synthesis
### System Requirements
- Linux (primary)
- Desktop environment with notification support
- Audio output for speech synthesis
## Platform Support
- Linux (primary)
- macOS (not supported)
- Windows (not supported)
## Behavior
### Timer Window
- Opens as floating Kitty window
- Window class: `floating-pomodoro`
- Window title: `floating-pomodoro`
### Notifications
When session ends, you'll receive:
1. Desktop notification: "work session ended!" or "break session ended!"
2. Voice announcement: "work session ended" or "break session ended"
### Input Validation
For custom times:
- Valid: `25m`, `1h`, `30s`, `1h30m`
- Invalid: `25`, `abc`, `1.5h`
## Build Information
- **Version**: 0.1.0
- **Type**: Shell script
- **License**: MIT
- **Main Program**: `launch-timer`
## Troubleshooting
### Kitty Not Found
Ensure Kitty is installed:
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
kitty
];
}
```
### No Notifications
Ensure notification daemon is running:
```bash
# Check for notification daemon
ps aux | grep -i notify
# Start notification daemon
# Depends on your DE: dunst, mako, etc.
```
### Speech Not Working
Check if speech synthesis is working:
```bash
# Test speech
spd-say "Hello"
# Check if speech-dispatcher is running
ps aux | grep speech-dispatcher
```
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide

View File

@@ -0,0 +1,248 @@
# tuxedo-backlight
Keyboard backlight control for Tuxedo laptops.
## Description
A shell script that sets up RGB keyboard backlight colors for Tuxedo laptops with customizable colors for different key groups.
## Features
- ⌨️ **RGB Backlight**: Full RGB keyboard backlight support
- 🎨 **Color Groups**: Different colors for different key groups
- 🔤 **Key Highlighting**: Special colors for modifier keys
- 🎯 **One-Command Setup**: Apply all colors with single command
-**Fast**: Direct sysfs control
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
tuxedo-backlight
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.tuxedo-backlight
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#tuxedo-backlight
```
## Usage
### Basic Usage
```bash
# Apply default color scheme
tuxedo-backlight
```
### Colors
The script applies these colors by default:
| Key Group | Color (RGB) | Description |
|-----------|-------------|-------------|
| Main keys | `0 150 255` | Blue (Cyan-ish) |
| Function keys (F1-F12) | `0 255 80` | Green (Lime) |
| Arrow keys | `0 255 80` | Green (Lime) |
| Numpad area | `255 150 0` | Orange |
| DEL key | `255 0 155` | Pink/Magenta |
| ESC key | `255 0 155` | Pink/Magenta |
## Customization
### Modify Colors
Edit the script to customize colors:
```nix
# In pkgs/tuxedo-backlight/default.nix
# All keys
echo 'R G B' | tee /sys/class/leds/rgb:kbd_backlight*/multi_intensity
# Specific key (e.g., ESC)
echo 'R G B' | tee /sys/class/leds/rgb:kbd_backlight/multi_intensity
```
RGB format: `Red Green Blue` (0-255 each)
### Color Examples
| Color | RGB Value |
|--------|-----------|
| Red | `255 0 0` |
| Green | `0 255 0` |
| Blue | `0 0 255` |
| Cyan | `0 255 255` |
| Magenta | `255 0 255` |
| Yellow | `255 255 0` |
| White | `255 255 255` |
| Orange | `255 150 0` |
| Purple | `150 0 255` |
## Automatic Startup
### Systemd Service
Create `/etc/systemd/system/tuxedo-backlight.service`:
```ini
[Unit]
Description=Tuxedo Keyboard Backlight
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/run/current-system/sw/bin/tuxedo-backlight
[Install]
WantedBy=multi-user.target
```
Enable and start:
```bash
sudo systemctl enable tuxedo-backlight.service
sudo systemctl start tuxedo-backlight.service
```
### NixOS Configuration
```nix
{pkgs, ...}: {
# Run at boot
systemd.services.tuxedo-backlight = {
description = "Set Tuxedo keyboard backlight";
after = ["multi-user.target"];
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.tuxedo-backlight}/bin/tuxedo-backlight";
};
};
}
```
## Requirements
### Hardware
- Tuxedo laptop with RGB keyboard backlight
- Linux kernel with appropriate driver support
### System Requirements
- Linux (Tuxedo laptops)
- Write access to `/sys/class/leds/`
### Permissions
The script requires write access to sysfs:
```bash
# Check permissions
ls -la /sys/class/leds/rgb:kbd_backlight*
# If permissions are needed
sudo tuxedo-backlight
```
## Platform Support
- Linux (Tuxedo laptops only)
- macOS (not supported)
- Windows (not supported)
## Troubleshooting
### No Such Device
Error: `No such file or directory`
**Solution**: Ensure you're on a Tuxedo laptop with RGB keyboard:
```bash
# Check if RGB backlight exists
ls -la /sys/class/leds/rgb:kbd_backlight*
```
### Permission Denied
Error: `Permission denied`
**Solution**: Run with sudo or configure udev rules:
```bash
# Run with sudo
sudo tuxedo-backlight
# Or create udev rule for user access
sudo vim /etc/udev/rules.d/99-tuxedo-backlight.rules
```
udev rule:
```
SUBSYSTEM=="leds", ATTR{brightness}=="*", ACTION=="add", RUN+="/usr/bin/chgrp -R input /sys/class/leds/rgb:*"
SUBSYSTEM=="leds", ATTR{brightness}=="*", ACTION=="add", RUN+="/usr/bin/chmod -R g+w /sys/class/leds/rgb:*"
```
### Colors Not Applied
**Solution**:
1. Check RGB backlight is supported:
```bash
cat /sys/class/leds/rgb:kbd_backlight*/multi_intensity
```
2. Ensure driver is loaded:
```bash
# Check for Tuxedo drivers
lsmod | grep tuxedo
# Load if needed
sudo modprobe tuxedo_keyboard
```
## Key Layout Reference
The script sets colors for these key groups:
### Key Numbers
- **All keys**: Main keyboard area (except special keys)
- **15**: DEL key
- **No number**: ESC key
- **1-12, 102**: Function keys (F1-F12, Fn)
- **16-19, 36-39, 56-59, 76-79, 96-99, 117-119**: Numpad and keys above numpad
- **95, 114-116**: Arrow keys
## Build Information
- **Version**: 0.1.0
- **Type**: Shell script
- **License**: MIT
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide

204
docs/packages/zellij-ps.md Normal file
View File

@@ -0,0 +1,204 @@
# zellij-ps
A Zellij project switcher for quickly navigating and opening project workspaces.
## Description
zellij-ps is a Fish script inspired by ThePrimeagen's tmux-sessionizer. It provides a fast, interactive way to switch between project folders in Zellij. Using `fd` for fast directory discovery and `fzf` for fuzzy selection, it helps you quickly jump into your work.
The script searches through your configured project folders (`$PROJECT_FOLDERS`) and either creates a new Zellij session for the selected project or attaches to an existing one.
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
zellij-ps
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.zellij-ps
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#zellij-ps
```
## Usage
### Basic Usage
```bash
# Run from outside Zellij to start a project session
zellij-ps
# Or pass a project path directly
zellij-ps ~/projects/my-project
```
This will:
1. Search through your `$PROJECT_FOLDERS` for directories
2. Open fzf for fuzzy project selection (if no argument provided)
3. Create a new Zellij session or attach to existing one for the selected project
### Configuration
Set your project folders in your shell configuration:
**Fish example:**
```fish
set -x PROJECT_FOLDERS ~/projects:~/code:~/work
```
**Bash/Zsh example:**
```bash
export PROJECT_FOLDERS="$HOME/projects:$HOME/code:$HOME/work"
```
Folders should be delimited by `:` and can include `~` for home directory.
## Home Manager Module
### Enable Module
```nix
{config, ...}: {
imports = [m3ta-nixpkgs.homeManagerModules.default];
m3ta.cli.zellij-ps = {
enable = true;
};
}
```
### Module Options
#### `m3ta.cli.zellij-ps.enable`
Enable the zellij-ps module.
- Type: `boolean`
- Default: `false`
#### `m3ta.cli.zellij-ps.package`
Custom package to use.
- Type: `package`
- Default: `pkgs.zellij-ps`
## Requirements
### System Requirements
- Linux or Unix-like system
- Configured `$PROJECT_FOLDERS` environment variable
## Platform Support
- Linux (primary)
- macOS (may work)
- Windows (not supported)
## Build Information
- **Version**: 0.1.0
- **Type**: Fish script
- **License**: MIT
- **Inspired by**: [ThePrimeagen's tmux-sessionizer](https://github.com/ThePrimeagen/.dotfiles/blob/master/bin/.local/scripts/tmux-sessionizer)
- **Source**: [Gitea](https://code.m3ta.dev/m3tam3re/helper-scripts)
## Source Code
The script is available at:
```
https://code.m3ta.dev/m3tam3re/helper-scripts/src/branch/main/zellij-ps.fish
```
## Troubleshooting
### No Projects Found
If fzf shows no results, check your `$PROJECT_FOLDERS` variable:
```bash
# In fish
echo $PROJECT_FOLDERS
# In bash/zsh
echo $PROJECT_FOLDERS
```
Ensure the folders exist and contain subdirectories.
### Already in Zellij Session
If you're already inside a Zellij session, you'll see:
```
You are in a Zellij Session!
Please use the session manager to switch sessions.
```
Use Zellij's built-in session manager (`Ctrl+p``s`) to switch sessions instead.
### fd Not Found
Error: `fd: command not found`
**Solution**: Ensure fd is installed:
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
fd
];
}
```
### Fish Not Found
Error: `fish: command not found`
**Solution**: Ensure Fish is installed:
```nix
{pkgs, ...}: {
programs.fish = {
enable = true;
};
}
```
### fzf Not Working
Ensure fzf is installed and configured:
```bash
# Check fzf
which fzf
# Test fzf
echo -e "item1\nitem2\nitem3" | fzf
```
## Related
- [zellij-ps Module](../modules/home-manager/cli/zellij-ps.md) - Home Manager module documentation
- [Using Modules](../guides/using-modules.md) - How to use modules
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide

272
docs/reference/functions.md Normal file
View File

@@ -0,0 +1,272 @@
# Library Functions
Documentation for library functions available in m3ta-nixpkgs.
## Overview
The library provides helper functions for your NixOS and Home Manager configurations.
## Available Libraries
### `m3ta-lib.ports`
Port management utilities for managing service ports across hosts.
## Port Management Functions
### `mkPortHelpers`
Create port helper functions from a ports configuration.
#### Signature
```nix
mkPortHelpers :: portsConfig -> portHelpers
```
#### Arguments
`portsConfig` - An attribute set with structure:
```nix
{
ports = { service-name = port-number; ... };
hostPorts = { hostname = { service-name = port-number; ... }; ... };
}
```
#### Returns
An attribute set containing helper functions:
```nix
{
getPort = service: host -> port-number-or-null;
getHostPorts = host -> ports-attrs;
listServices = -> [string];
}
```
#### Usage
```nix
{config, inputs, ...}: let
m3taLib = inputs.m3ta-nixpkgs.lib.${config.system};
myPorts = {
ports = {
nginx = 80;
grafana = 3000;
};
hostPorts = {
laptop = {
nginx = 8080;
};
};
};
portHelpers = m3taLib.ports.mkPortHelpers myPorts;
in {
# Get port with host override
services.nginx.port = portHelpers.getPort "nginx" config.networking.hostName;
# Get all ports for host
laptopPorts = portHelpers.getHostPorts "laptop";
# List all services
allServices = portHelpers.listServices;
}
```
### `getPort` (from portHelpers)
Get port for a service, with optional host-specific override.
#### Signature
```nix
getPort :: string -> string -> int-or-null
```
#### Arguments
1. `service` - The service name (string)
2. `host` - The hostname (string), or `null` for default
#### Returns
Port number (int) or `null` if service not found.
#### Usage
```nix
services.nginx = {
port = portHelpers.getPort "nginx" "laptop"; # Returns host-specific port
# or
port = portHelpers.getPort "nginx" null; # Returns default port
};
```
### `getHostPorts` (from portHelpers)
Get all ports for a specific host (merges defaults with host overrides).
#### Signature
```nix
getHostPorts :: string -> attrs
```
#### Arguments
1. `host` - The hostname (string)
#### Returns
Attribute set of all ports for the host.
#### Usage
```nix
laptopPorts = portHelpers.getHostPorts "laptop";
# Returns: { nginx = 8080; grafana = 3000; prometheus = 9090; ... }
```
### `listServices` (from portHelpers)
List all defined service names.
#### Signature
```nix
listServices :: -> [string]
```
#### Returns
List of service names (strings).
#### Usage
```nix
allServices = portHelpers.listServices;
# Returns: ["nginx" "grafana" "prometheus" "homepage"]
```
### `getDefaultPort`
Simple helper to get a port without host override.
#### Signature
```nix
getDefaultPort :: portsConfig -> string -> int-or-null
```
#### Arguments
1. `portsConfig` - Same structure as `mkPortHelpers`
2. `service` - The service name (string)
#### Returns
Port number (int) or `null` if service not found.
#### Usage
```nix
services.my-service = {
port = m3taLib.ports.getDefaultPort myPorts "my-service";
};
```
## Using Library Functions
### Importing
```nix
{config, inputs, ...}: let
# Import library
m3taLib = inputs.m3ta-nixpkgs.lib.${config.system};
in {
# Use library functions
}
```
### Example: Custom Port Management
```nix
{config, inputs, ...}: let
m3taLib = inputs.m3ta-nixpkgs.lib.${config.system};
myPorts = {
ports = {
web = 80;
api = 8080;
db = 5432;
};
hostPorts = {
dev = {
web = 8080;
api = 8081;
};
};
};
portHelpers = m3taLib.ports.mkPortHelpers myPorts;
hostname = config.networking.hostName;
in {
services.nginx = {
enable = true;
virtualHosts.${hostname} = {
locations."/" = {
proxyPass = "http://localhost:${toString (portHelpers.getPort "api" hostname)}";
};
};
};
services.postgresql = {
enable = true;
port = portHelpers.getPort "db" hostname;
};
}
```
### Example: Generate Config Files
```nix
{inputs, ...}: let
m3taLib = inputs.m3ta-nixpkgs.lib.${system};
myPorts = {
ports = {
service1 = 3000;
service2 = 3001;
};
};
portHelpers = m3taLib.ports.mkPortHelpers myPorts;
in {
environment.etc."ports.toml".text = generators.toTOML {} {
services = portHelpers.getHostPorts "desktop";
};
}
```
## Function Reference Summary
| Function | Purpose | Return Type |
|----------|---------|------------|
| `mkPortHelpers` | Create port helper functions | `portHelpers` attrs |
| `getPort` | Get port with optional host override | `int or null` |
| `getHostPorts` | Get all ports for host | `attrs` |
| `listServices` | List all service names | `[string]` |
| `getDefaultPort` | Get default port only | `int or null` |
## Related
- [Port Management Guide](../guides/port-management.md) - Detailed usage guide
- [NixOS Ports Module](../modules/nixos/ports.md) - Port management module
- [Home Manager Ports Module](../modules/home-manager/ports.md) - User-level port management
- [Architecture](../ARCHITECTURE.md) - Understanding library functions

498
docs/reference/patterns.md Normal file
View File

@@ -0,0 +1,498 @@
# Code Patterns and Anti-Patterns
Common code patterns and anti-patterns used in m3ta-nixpkgs.
## Overview
This document outlines recommended patterns and common pitfalls when working with m3ta-nixpkgs.
## Code Patterns
### Package Pattern
#### CallPackage Registry
Use `callPackage` for lazy evaluation:
```nix
# Good - pkgs/default.nix
{
inherit (pkgs) callPackage;
} rec {
code2prompt = callPackage ./code2prompt {};
mem0 = callPackage ./mem0 {};
}
```
#### Meta Fields
Always include complete `meta` information:
```nix
# Good
meta = with lib; {
description = "My awesome package";
homepage = "https://github.com/author/package";
changelog = "https://github.com/author/package/releases/tag/v${version}";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "program-name";
};
```
### Module Pattern
#### Standard Module Structure
```nix
# Good
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "my module";
# ... options
};
config = mkIf cfg.enable {
# ... configuration
};
}
```
#### mkEnableOption
Always use `mkEnableOption` for enable flags:
```nix
# Good
options.m3ta.myModule = {
enable = mkEnableOption "my module";
};
# Bad
options.m3ta.myModule.enable = mkOption {
type = types.bool;
default = false;
};
```
#### Conditional Configuration
Use `mkIf` for conditional config:
```nix
# Good
config = mkIf cfg.enable {
services.my-service.enable = true;
};
```
#### Multiple Conditions
Use `mkMerge` for multiple conditions:
```nix
# Good
config = mkMerge [
(mkIf cfg.feature1.enable {
# config for feature1
})
(mkIf cfg.feature2.enable {
# config for feature2
})
];
```
### Import Pattern
#### Multi-line Imports
Multi-line, trailing commas:
```nix
# Good
{
lib,
stdenv,
fetchFromGitHub,
}:
```
#### Explicit Dependencies
```nix
# Good
{
lib,
stdenv,
openssl,
pkg-config,
}:
stdenv.mkDerivation {
buildInputs = [openssl pkg-config];
}
```
## Anti-Patterns
### lib.fakeHash in Commits
**Bad**: Committing `lib.fakeHash`
```nix
# Bad - Never commit this!
src = fetchFromGitHub {
hash = lib.fakeHash;
};
```
**Solution**: Build to get real hash:
```bash
nix build .#your-package
# Copy actual hash from error message
```
### Flat Module Files
**Bad**: All modules in one file
```nix
# Bad - Hard to maintain
{config, lib, pkgs, ...}: {
options.m3ta.cli = {
tool1 = mkEnableOption "tool1";
tool2 = mkEnableOption "tool2";
# ... many more
};
config = mkMerge [
(mkIf config.m3ta.cli.tool1.enable {...})
(mkIf config.m3ta.cli.tool2.enable {...})
# ... many more
];
}
```
**Solution**: Organize by category
```nix
# Good - modules/home-manager/cli/
# modules/home-manager/cli/default.nix
{
imports = [
./tool1.nix
./tool2.nix
];
}
```
### Hardcoded Ports
**Bad**: Hardcoding ports in services
```nix
# Bad
services.nginx = {
enable = true;
httpConfig = ''
server {
listen 80;
}
'';
};
```
**Solution**: Use port management
```nix
# Good
m3ta.ports = {
enable = true;
definitions = {nginx = 80;};
};
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
}
'';
};
```
### Skipping Meta Fields
**Bad**: Incomplete meta information
```nix
# Bad
meta = {
description = "My package";
};
```
**Solution**: Include all fields
```nix
# Good
meta = with lib; {
description = "My awesome package";
homepage = "https://github.com/author/package";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "program-name";
};
```
### with pkgs; in Modules
**Bad**: Using `with pkgs;` at module level
```nix
# Bad
{config, lib, pkgs, ...}: with pkgs; {
config.environment.systemPackages = [
vim
git
];
}
```
**Solution**: Explicit package references or limited with
```nix
# Good - Explicit references
{config, lib, pkgs, ...}: {
config.environment.systemPackages = with pkgs; [
vim
git
];
}
# Or - Full references
{config, lib, pkgs, ...}: {
config.environment.systemPackages = [
pkgs.vim
pkgs.git
];
}
```
### Orphaned Package Directories
**Bad**: Creating directory without registering
```nix
# Bad - Package not visible
# pkgs/my-package/default.nix exists
# But pkgs/default.nix doesn't reference it
```
**Solution**: Register in `pkgs/default.nix`
```nix
# Good
{
inherit (pkgs) callPackage;
} rec {
my-package = callPackage ./my-package {};
}
```
## Type Safety
### No Type Suppression
**Bad**: Using `as any`
```nix
# Bad
let
value = someFunction config as any;
in
# ...
```
**Solution**: Fix underlying type issues
```nix
# Good
let
value = someFunction config;
in
# Ensure value has correct type
```
### Proper Type Definitions
```nix
# Good
options.m3ta.myModule = {
enable = mkEnableOption "my module";
port = mkOption {
type = types.port;
default = 8080;
description = "Port to run on";
};
};
```
## Naming Conventions
### Package Names
**Good**: `lowercase-hyphen`
```nix
code2prompt
hyprpaper-random
launch-webapp
```
**Bad**: CamelCase or underscores
```nix
code2Prompt # Bad
hyprpaper_random # Bad
```
### Variables
**Good**: `camelCase`
```nix
portHelpers
configFile
serviceName
```
**Bad**: Snake_case or kebab-case
```nix
port_helpers # Bad
port-helpers # Bad
```
### Module Options
**Good**: `m3ta.*` namespace
```nix
m3ta.ports.enable = true;
m3ta.cli.zellij-ps.enable = true;
```
**Bad**: Flat namespace
```nix
ports.enable = true; # Potential conflict
cli.zellij-ps.enable = true; # Hard to find
```
## Performance
### Lazy Evaluation
**Good**: Use `callPackage`
```nix
# Good - Only builds requested package
code2prompt = callPackage ./code2prompt {};
```
**Bad**: Building all packages
```nix
# Bad - Builds everything even if not used
code2prompt = import ./code2prompt {};
```
### Selective Imports
**Good**: Import only needed modules
```nix
# Good
imports = [
m3ta-nixpkgs.nixosModules.mem0
];
```
**Bad**: Importing all modules
```nix
# Bad - Imports and evaluates all modules
imports = [
m3ta-nixpkgs.nixosModules.default
];
```
## Security
### No Secrets in Store
**Bad**: Putting secrets in configuration
```nix
# Bad - Secret in Nix store
m3ta.mem0.llm.apiKey = "sk-xxx";
```
**Solution**: Use secret files
```nix
# Good - Secret from file
m3ta.mem0.llm.apiKeyFile = "/run/secrets/openai-api-key";
```
### Proper User/Group
**Good**: Dedicated users for services
```nix
# Good
users.users.mem0 = {
isSystemUser = true;
group = "mem0";
};
```
### Service Hardening
**Good**: Enable systemd hardening
```nix
# Good
systemd.services.mem0.serviceConfig = {
NoNewPrivileges = true;
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
};
```
## Best Practices Summary
| Practice | Do | Don't |
|----------|-----|--------|
| Hash fetching | Get real hash from build error | Commit `lib.fakeHash` |
| Module organization | Categorize by function | Put all in one file |
| Port management | Use `m3ta.ports` module | Hardcode ports |
| Meta fields | Include all fields | Skip fields |
| Type safety | Fix type errors | Use `as any` |
| Dependencies | Explicit declarations | Implicit deps |
| Imports | Multi-line, trailing comma | Single-line, no comma |
| Naming | Follow conventions | Mix styles |
| Secrets | Use file-based | Put in config |
| Evaluation | Lazy (`callPackage`) | Import everything |
## Related
- [Contributing Guide](../CONTRIBUTING.md) - Code style and guidelines
- [Architecture](../ARCHITECTURE.md) - Understanding repository structure
- [Adding Packages](../guides/adding-packages.md) - Package creation patterns