From 44485c4c7265e439aee72c0b1fa9eb6b2640b5dd Mon Sep 17 00:00:00 2001
From: m3tm3re
Date: Tue, 30 Dec 2025 15:42:52 +0100
Subject: [PATCH] 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)
---
README.md | 32 +-
docs/ARCHITECTURE.md | 473 +++++++++++++++
docs/CONTRIBUTING.md | 360 ++++++++++++
docs/QUICKSTART.md | 316 ++++++++++
docs/README.md | 146 +++++
docs/guides/adding-packages.md | 493 ++++++++++++++++
docs/guides/development-workflow.md | 527 +++++++++++++++++
docs/guides/getting-started.md | 402 +++++++++++++
docs/guides/port-management.md | 525 +++++++++++++++++
docs/guides/using-modules.md | 605 ++++++++++++++++++++
docs/modules/home-manager/cli/zellij-ps.md | 81 +++
docs/modules/home-manager/coding/editors.md | 317 ++++++++++
docs/modules/home-manager/overview.md | 206 +++++++
docs/modules/home-manager/ports.md | 272 +++++++++
docs/modules/nixos/mem0.md | 508 ++++++++++++++++
docs/modules/nixos/overview.md | 166 ++++++
docs/modules/nixos/ports.md | 229 ++++++++
docs/packages/code2prompt.md | 206 +++++++
docs/packages/hyprpaper-random.md | 190 ++++++
docs/packages/launch-webapp.md | 180 ++++++
docs/packages/mem0.md | 268 +++++++++
docs/packages/msty-studio.md | 172 ++++++
docs/packages/pomodoro-timer.md | 220 +++++++
docs/packages/tuxedo-backlight.md | 248 ++++++++
docs/packages/zellij-ps.md | 204 +++++++
docs/reference/functions.md | 272 +++++++++
docs/reference/patterns.md | 498 ++++++++++++++++
pkgs/zellij-ps/default.nix | 4 +-
28 files changed, 8096 insertions(+), 24 deletions(-)
create mode 100644 docs/ARCHITECTURE.md
create mode 100644 docs/CONTRIBUTING.md
create mode 100644 docs/QUICKSTART.md
create mode 100644 docs/README.md
create mode 100644 docs/guides/adding-packages.md
create mode 100644 docs/guides/development-workflow.md
create mode 100644 docs/guides/getting-started.md
create mode 100644 docs/guides/port-management.md
create mode 100644 docs/guides/using-modules.md
create mode 100644 docs/modules/home-manager/cli/zellij-ps.md
create mode 100644 docs/modules/home-manager/coding/editors.md
create mode 100644 docs/modules/home-manager/overview.md
create mode 100644 docs/modules/home-manager/ports.md
create mode 100644 docs/modules/nixos/mem0.md
create mode 100644 docs/modules/nixos/overview.md
create mode 100644 docs/modules/nixos/ports.md
create mode 100644 docs/packages/code2prompt.md
create mode 100644 docs/packages/hyprpaper-random.md
create mode 100644 docs/packages/launch-webapp.md
create mode 100644 docs/packages/mem0.md
create mode 100644 docs/packages/msty-studio.md
create mode 100644 docs/packages/pomodoro-timer.md
create mode 100644 docs/packages/tuxedo-backlight.md
create mode 100644 docs/packages/zellij-ps.md
create mode 100644 docs/reference/functions.md
create mode 100644 docs/reference/patterns.md
diff --git a/README.md b/README.md
index 0fd57ae..78d1022 100644
--- a/README.md
+++ b/README.md
@@ -22,36 +22,20 @@ Personal Nix flake repository: custom packages, overlays, NixOS modules, and Hom
- βοΈ [Modules](./docs/modules/)
- π [Guides](./docs/guides/)
-## Installation
-
-### Add to Your Flake
-
-```nix
-{
- inputs = {
- nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
- m3ta-nixpkgs.url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
- };
-}
-```
-
-### Quick Start
+## Quick Start
```bash
+# Add to your flake
+nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+m3ta-nixpkgs.url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
+
# 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
```
-## Documentation
-
-For detailed usage, module documentation, package references, and contribution guidelines, see the [full documentation](./docs).
-
## Available Packages
| Package | Description |
@@ -63,7 +47,11 @@ For detailed usage, module documentation, package references, and contribution g
| `msty-studio` | Msty Studio application |
| `pomodoro-timer` | Pomodoro timer utility |
| `tuxedo-backlight` | Backlight control for Tuxedo laptops |
-| `zellij-ps` | Process viewer for Zellij |
+| `zellij-ps` | Project switcher for Zellij |
+
+## Documentation
+
+For detailed usage, module documentation, package references, and contribution guidelines, see the [full documentation](./docs).
## License
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
new file mode 100644
index 0000000..2587e0f
--- /dev/null
+++ b/docs/ARCHITECTURE.md
@@ -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 .#`
+
+### 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 .#`
+
+### 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`).
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
new file mode 100644
index 0000000..e8e7438
--- /dev/null
+++ b/docs/CONTRIBUTING.md
@@ -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
+```
diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md
new file mode 100644
index 0000000..74bc7b3
--- /dev/null
+++ b/docs/QUICKSTART.md
@@ -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
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..9cdecb8
--- /dev/null
+++ b/docs/README.md
@@ -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 .#
+
+# 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)
diff --git a/docs/guides/adding-packages.md b/docs/guides/adding-packages.md
new file mode 100644
index 0000000..144f729
--- /dev/null
+++ b/docs/guides/adding-packages.md
@@ -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
diff --git a/docs/guides/development-workflow.md b/docs/guides/development-workflow.md
new file mode 100644
index 0000000..5816058
--- /dev/null
+++ b/docs/guides/development-workflow.md
@@ -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
diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md
new file mode 100644
index 0000000..a5d327d
--- /dev/null
+++ b/docs/guides/getting-started.md
@@ -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
diff --git a/docs/guides/port-management.md b/docs/guides/port-management.md
new file mode 100644
index 0000000..04016ca
--- /dev/null
+++ b/docs/guides/port-management.md
@@ -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
diff --git a/docs/guides/using-modules.md b/docs/guides/using-modules.md
new file mode 100644
index 0000000..90c3510
--- /dev/null
+++ b/docs/guides/using-modules.md
@@ -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
diff --git a/docs/modules/home-manager/cli/zellij-ps.md b/docs/modules/home-manager/cli/zellij-ps.md
new file mode 100644
index 0000000..9f2bee2
--- /dev/null
+++ b/docs/modules/home-manager/cli/zellij-ps.md
@@ -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
diff --git a/docs/modules/home-manager/coding/editors.md b/docs/modules/home-manager/coding/editors.md
new file mode 100644
index 0000000..67f7bc6
--- /dev/null
+++ b/docs/modules/home-manager/coding/editors.md
@@ -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
diff --git a/docs/modules/home-manager/overview.md b/docs/modules/home-manager/overview.md
new file mode 100644
index 0000000..1030465
--- /dev/null
+++ b/docs/modules/home-manager/overview.md
@@ -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
diff --git a/docs/modules/home-manager/ports.md b/docs/modules/home-manager/ports.md
new file mode 100644
index 0000000..0ee21aa
--- /dev/null
+++ b/docs/modules/home-manager/ports.md
@@ -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_=
+```
+
+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
diff --git a/docs/modules/nixos/mem0.md b/docs/modules/nixos/mem0.md
new file mode 100644
index 0000000..0607b48
--- /dev/null
+++ b/docs/modules/nixos/mem0.md
@@ -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
diff --git a/docs/modules/nixos/overview.md b/docs/modules/nixos/overview.md
new file mode 100644
index 0000000..5cbce80
--- /dev/null
+++ b/docs/modules/nixos/overview.md
@@ -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
diff --git a/docs/modules/nixos/ports.md b/docs/modules/nixos/ports.md
new file mode 100644
index 0000000..5a11392
--- /dev/null
+++ b/docs/modules/nixos/ports.md
@@ -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
diff --git a/docs/packages/code2prompt.md b/docs/packages/code2prompt.md
new file mode 100644
index 0000000..c255f04
--- /dev/null
+++ b/docs/packages/code2prompt.md
@@ -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
diff --git a/docs/packages/hyprpaper-random.md b/docs/packages/hyprpaper-random.md
new file mode 100644
index 0000000..775a906
--- /dev/null
+++ b/docs/packages/hyprpaper-random.md
@@ -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
diff --git a/docs/packages/launch-webapp.md b/docs/packages/launch-webapp.md
new file mode 100644
index 0000000..c7d2893
--- /dev/null
+++ b/docs/packages/launch-webapp.md
@@ -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
diff --git a/docs/packages/mem0.md b/docs/packages/mem0.md
new file mode 100644
index 0000000..4a5ba1c
--- /dev/null
+++ b/docs/packages/mem0.md
@@ -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
diff --git a/docs/packages/msty-studio.md b/docs/packages/msty-studio.md
new file mode 100644
index 0000000..28b03ce
--- /dev/null
+++ b/docs/packages/msty-studio.md
@@ -0,0 +1,172 @@
+# msty-studio
+
+Msty Studio enables advanced, privacyβpreserving 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
diff --git a/docs/packages/pomodoro-timer.md b/docs/packages/pomodoro-timer.md
new file mode 100644
index 0000000..17ffe14
--- /dev/null
+++ b/docs/packages/pomodoro-timer.md
@@ -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
diff --git a/docs/packages/tuxedo-backlight.md b/docs/packages/tuxedo-backlight.md
new file mode 100644
index 0000000..d045170
--- /dev/null
+++ b/docs/packages/tuxedo-backlight.md
@@ -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
diff --git a/docs/packages/zellij-ps.md b/docs/packages/zellij-ps.md
new file mode 100644
index 0000000..82811ed
--- /dev/null
+++ b/docs/packages/zellij-ps.md
@@ -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
diff --git a/docs/reference/functions.md b/docs/reference/functions.md
new file mode 100644
index 0000000..455f4aa
--- /dev/null
+++ b/docs/reference/functions.md
@@ -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
diff --git a/docs/reference/patterns.md b/docs/reference/patterns.md
new file mode 100644
index 0000000..7aef6ad
--- /dev/null
+++ b/docs/reference/patterns.md
@@ -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
diff --git a/pkgs/zellij-ps/default.nix b/pkgs/zellij-ps/default.nix
index 8e2a312..c979745 100644
--- a/pkgs/zellij-ps/default.nix
+++ b/pkgs/zellij-ps/default.nix
@@ -34,9 +34,9 @@ with lib;
'';
meta = {
- description = "A small project script for zellij";
+ description = "Zellij project switcher - quickly switch between project folders";
license = lib.licenses.mit;
platforms = platforms.unix;
- mainProgram = "zelli-ps";
+ mainProgram = "zellij-ps";
};
}