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"; }; }