Compare commits

..
Author SHA1 Message Date
m3tam3re e89b961b0b dolt remote info 2026-07-04 09:30:30 +02:00
94 changed files with 7 additions and 15002 deletions
-44
View File
@@ -1,44 +0,0 @@
# SQLite databases
*.db
*.db?*
*.db-journal
*.db-wal
*.db-shm
# Daemon runtime files
daemon.lock
daemon.log
daemon.pid
bd.sock
sync-state.json
last-touched
# Local version tracking (prevents upgrade notification spam after git ops)
.local_version
# Legacy database files
db.sqlite
bd.db
# Worktree redirect file (contains relative path to main repo's .beads/)
# Must not be committed as paths would be wrong in other clones
redirect
# Merge artifacts (temporary files from 3-way merge)
beads.base.jsonl
beads.base.meta.json
beads.left.jsonl
beads.left.meta.json
beads.right.jsonl
beads.right.meta.json
# Sync state (local-only, per-machine)
# These files are machine-specific and should not be shared across clones
.sync.lock
sync_base.jsonl
# NOTE: Do NOT add negation patterns (e.g., !issues.jsonl) here.
# They would override fork protection in .git/info/exclude, allowing
# contributors to accidentally commit upstream issue databases.
# The JSONL files (issues.jsonl, interactions.jsonl) and config files
# are tracked by git by default since no pattern above ignores them.
View File
-81
View File
@@ -1,81 +0,0 @@
# Beads - AI-Native Issue Tracking
Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
## What is Beads?
Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
## Quick Start
### Essential Commands
```bash
# Create new issues
bd create "Add user authentication"
# View all issues
bd list
# View issue details
bd show <issue-id>
# Update issue status
bd update <issue-id> --status in_progress
bd update <issue-id> --status done
# Sync with git remote
bd sync
```
### Working with Issues
Issues in Beads are:
- **Git-native**: Stored in `.beads/issues.jsonl` and synced like code
- **AI-friendly**: CLI-first design works perfectly with AI coding agents
- **Branch-aware**: Issues can follow your branch workflow
- **Always in sync**: Auto-syncs with your commits
## Why Beads?
**AI-Native Design**
- Built specifically for AI-assisted development workflows
- CLI-first interface works seamlessly with AI coding agents
- No context switching to web UIs
🚀 **Developer Focused**
- Issues live in your repo, right next to your code
- Works offline, syncs when you push
- Fast, lightweight, and stays out of your way
🔧 **Git Integration**
- Automatic sync with git commits
- Branch-aware issue tracking
- Intelligent JSONL merge resolution
## Get Started with Beads
Try Beads in your own projects:
```bash
# Install Beads
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
# Initialize in your repo
bd init
# Create your first issue
bd create "Try out Beads"
```
## Learn More
- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
- **Quick Start Guide**: Run `bd quickstart`
- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
---
*Beads: Issue tracking that moves at the speed of thought*
-62
View File
@@ -1,62 +0,0 @@
# Beads Configuration File
# This file configures default behavior for all bd commands in this repository
# All settings can also be set via environment variables (BD_* prefix)
# or overridden with command-line flags
# Issue prefix for this repository (used by bd init)
# If not set, bd init will auto-detect from directory name
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
# issue-prefix: ""
# Use no-db mode: load from JSONL, no SQLite, write back after each command
# When true, bd will use .beads/issues.jsonl as the source of truth
# instead of SQLite database
# no-db: false
# Disable daemon for RPC communication (forces direct database access)
# no-daemon: false
# Disable auto-flush of database to JSONL after mutations
# no-auto-flush: false
# Disable auto-import from JSONL when it's newer than database
# no-auto-import: false
# Enable JSON output by default
# json: false
# Default actor for audit trails (overridden by BD_ACTOR or --actor)
# actor: ""
# Path to database (overridden by BEADS_DB or --db)
# db: ""
# Auto-start daemon if not running (can also use BEADS_AUTO_START_DAEMON)
# auto-start-daemon: true
# Debounce interval for auto-flush (can also use BEADS_FLUSH_DEBOUNCE)
# flush-debounce: "5s"
# Git branch for beads commits (bd sync will commit to this branch)
# IMPORTANT: Set this for team projects so all clones use the same sync branch.
# This setting persists across clones (unlike database config which is gitignored).
# Can also use BEADS_SYNC_BRANCH env var for local override.
# If not set, bd sync will require you to run 'bd config set sync.branch <branch>'.
# sync-branch: "beads-sync"
# Multi-repo configuration (experimental - bd-307)
# Allows hydrating from multiple repositories and routing writes to the correct JSONL
# repos:
# primary: "." # Primary repo (where this database lives)
# additional: # Additional repos to hydrate from (read-only)
# - ~/beads-planning # Personal planning repo
# - ~/work-planning # Work planning repo
# Integration settings (access with 'bd config get/set')
# These are stored in the database, not in this file:
# - jira.url
# - jira.project
# - linear.url
# - linear.api-key
# - github.org
# - github.repo
View File
-20
View File
@@ -1,20 +0,0 @@
{"id":"nixpkgs-1xm","title":"Package Basecamp MCP Server","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-12T05:01:20.465656454+01:00","created_by":"m3tam3re","updated_at":"2026-01-12T05:01:26.623404603+01:00","closed_at":"2026-01-12T05:01:26.623404603+01:00","close_reason":"Packaged successfully with env file support"}
{"id":"nixpkgs-3k8","title":"Export project config as environment variable","description":"Export project configuration as home.sessionVariables (similar to zellij-ps pattern). Use JSON format for the env var since projects now have structured data (path + args).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-05T12:45:50.803017318+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:48:22.968626155+01:00","closed_at":"2026-01-05T12:48:22.968626155+01:00","close_reason":"Added home.sessionVariables.ROFI_PROJECT_OPENER_CONFIG with JSON config","dependencies":[{"issue_id":"nixpkgs-3k8","depends_on_id":"nixpkgs-hrh","type":"parent-child","created_at":"2026-01-05T12:46:03.16885012+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-3w3","title":"Add authentication command and environment file generation to basecamp-mcp-server","description":"The basecamp-mcp-server package at pkgs/basecamp-mcp-server/default.nix wraps the FastMCP server for Basecamp 3 integration. Currently, there's no convenient way for users to:\n\n1. Set up OAuth 2.0 authentication interactively\n2. Generate a sample environment file with required credentials\n3. Guide users through the Basecamp OAuth flow\n\n## Current State\n\nThe package wraps but users must:\n- Manually clone the upstream repository\n- Run to generate template\n- Edit with OAuth credentials from https://launchpad.37signals.com/integrations\n- Run to complete OAuth flow\n- Handle token storage manually\n\n## Required Environment Variables\n\n### OAuth Configuration (Primary)\n- - OAuth client ID from Basecamp\n- - OAuth client secret\n- - Found in Basecamp URL: https://3.basecamp.com/ID/...\n- - Format: \"App Name (email@domain.com)\"\n- - http://localhost:8000/auth/callback\n- - For Flask session security\n\n### Basic Auth (Legacy)\n- - Email for direct API access\n- - Password for direct API access\n\n## Proposed Solution\n\nAdd a Nix package wrapper command () that:\n\n1. **Interactive Setup Wizard**\n - Guides users through OAuth app creation at launchpad.37signals.com\n - Prompts for credentials (with secure input for secrets)\n - Validates inputs before proceeding\n\n2. **Environment File Generation**\n - Creates or project-local \n - Includes all required variables with clear documentation\n - Sets secure permissions (600)\n - Provides example values\n\n3. **OAuth Flow Handler**\n - Starts local Flask server on port 8000\n - Opens browser to initiate OAuth flow\n - Handles callback and token exchange\n - Stores tokens securely in \n - Shows success/failure status\n\n4. **Documentation**\n - Inline help for all steps\n - Links to Basecamp integration setup\n - Account ID discovery instructions\n\n## References\n\n- Upstream repo: https://github.com/georgeantonopoulos/Basecamp-MCP-Server\n- Key files: , , , \n- OAuth endpoints: launchpad.37signals.com/authorization/new\n\n## Subtasks\n\n- [ ] Create auth command wrapper (basecamp-mcp-auth)\n- [ ] Implement interactive OAuth wizard\n- [ ] Generate sample environment file template\n- [ ] Add token storage handling\n- [ ] Update package documentation\n- [ ] Add Home Manager module support (optional)","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-12T18:25:50.929926505+01:00","created_by":"m3tam3re","updated_at":"2026-01-12T19:12:57.941267399+01:00","closed_at":"2026-01-12T19:12:57.941267399+01:00","close_reason":"Closed"}
{"id":"nixpkgs-5ml","title":"Update rofi-project-opener script to pass args to opencode","description":"Modify pkgs/rofi-project-opener script to read the new config format and launch opencode with: 'opencode \u003cdirectory\u003e \u003carguments\u003e' instead of just 'opencode' in the directory.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-05T12:45:49.748958951+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:49:40.800083615+01:00","closed_at":"2026-01-05T12:49:40.800083615+01:00","close_reason":"Script updated to read JSON config and pass args to opencode","dependencies":[{"issue_id":"nixpkgs-5ml","depends_on_id":"nixpkgs-w3u","type":"parent-child","created_at":"2026-01-05T12:46:02.338350208+01:00","created_by":"m3tam3re"},{"issue_id":"nixpkgs-5ml","depends_on_id":"nixpkgs-sys","type":"blocks","created_at":"2026-01-05T12:46:04.966269033+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-61l","title":"Update documentation to reflect latest changes","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-10T18:48:19.599467206+01:00","created_by":"m3tam3re","updated_at":"2026-01-10T19:12:26.294895563+01:00","closed_at":"2026-01-10T19:12:26.294895563+01:00","close_reason":"Documentation updated: Added stt-ptt language support docs, rofi-project-opener module docs, and updated zellij-ps docs"}
{"id":"nixpkgs-69z","title":"n8n overlay -\u003e pkgs","description":"Create a full package definition in pkgs/n8n/default.nix that mirrors nixpkgs-unstable's n8n package but with version 2.4.1 and updated hashes from overlays/mods/n8n.nix. Register the new package in pkgs/default.nix. The overlay overrides: src (n8n-io/n8n@2.4.1) and pnpmDeps hash. Reference nixpkgs-unstable for the base package structure, then apply the version/hash modifications.","status":"closed","priority":2,"issue_type":"chore","owner":"p@m3ta.dev","created_at":"2026-01-13T19:42:35.643928163+01:00","created_by":"m3tm3re","updated_at":"2026-01-13T20:25:53.712987689+01:00","closed_at":"2026-01-13T20:25:53.712987689+01:00","close_reason":"Packages created successfully: pkgs/n8n/default.nix, pkgs/beads/default.nix, pkgs/opencode/default.nix. All packages build successfully."}
{"id":"nixpkgs-7ez","title":"Add authentication command for basecamp-mcp-server","description":"Add a command for the basecamp-mcp-server that will guide the user through the authentication flow and create a sample environment file with the necessary values. This involves researching the original basecamp-mcp-server repository for authentication details and implementing a user-friendly authentication workflow.","status":"tombstone","priority":0,"issue_type":"feature","created_at":"2026-01-12T18:20:55.665717166+01:00","created_by":"m3tam3re","updated_at":"2026-01-13T19:46:32.112562429+01:00","dependencies":[{"issue_id":"nixpkgs-7ez","depends_on_id":"nixpkgs-3w3","type":"blocks","created_at":"2026-01-12T18:48:31.806330931+01:00","created_by":"m3tam3re"}],"deleted_at":"2026-01-13T19:46:32.112562429+01:00","deleted_by":"daemon","delete_reason":"delete","original_type":"feature"}
{"id":"nixpkgs-8jw","title":"fix: self-hosted nixos runner missing node in PATH for Gitea Actions","description":"The nix-update workflow fails on self-hosted nixos runner because node is not available in PATH. Error: Cannot find: node in PATH. Root cause: actions/checkout@v4 requires Node.js to execute post-checkout steps. The self-hosted nixos runner does not have node installed or not in PATH. Possible solutions: 1) Add Node.js to the nixos runner environment, 2) Use container-based runner instead of bare nixos, 3) Use a different checkout action that does not require node, 4) Configure PATH to include node installation. Impact: Automated package updates are completely blocked.","status":"closed","priority":1,"issue_type":"bug","owner":"p@m3ta.dev","created_at":"2026-01-14T20:50:59.153145341+01:00","created_by":"m3tm3re","updated_at":"2026-01-18T18:36:50.926416564+01:00","closed_at":"2026-01-17T09:49:26.658187402+01:00"}
{"id":"nixpkgs-8ng","title":"fix: Add nix-update arguments for opencode subpackage","description":"The Gitea workflow does not work correctly on the opencode package because opencode uses a subpackage. To fix this, nix-update needs to be run with additional arguments to adjust the output hash of the subpackage.\n\n**Solution:**\nRun nix-update with the following arguments:\n$ nix-instantiate --eval --json --strict /nix/store/ybiynv89drnshjdlb089r3i687c5k878-nix-update-1.14.0/lib/python3.13/site-packages/nix_update/eval.nix --argstr importPath /home/m3tam3re/p/NIX/nixpkgs --argstr attribute '[\"opencode\"]' --arg isFlake true --arg sanitizePositions true\nfetch https://github.com/anomalyco/opencode/releases.atom\nNot updating version, already 1.1.25\nUpdating subpackage node_modules\n$ nix-instantiate --eval --json --strict /nix/store/ybiynv89drnshjdlb089r3i687c5k878-nix-update-1.14.0/lib/python3.13/site-packages/nix_update/eval.nix --argstr importPath /home/m3tam3re/p/NIX/nixpkgs --argstr attribute '[\"opencode\", \"node_modules\"]' --arg isFlake true --arg sanitizePositions true\n$ nix-build --expr 'let src = (let flake = builtins.getFlake \"/home/m3tam3re/p/NIX/nixpkgs\"; in flake.packages.${builtins.currentSystem}.\"opencode\".\"node_modules\" or flake.\"opencode\".\"node_modules\").src; in (src.overrideAttrs or (f: src // f src)) (_: { outputHash = \"\"; outputHashAlgo = \"sha256\"; })' --extra-experimental-features 'flakes nix-command'\n$ nix-build --expr 'let src = (let flake = builtins.getFlake \"/home/m3tam3re/p/NIX/nixpkgs\"; in flake.packages.${builtins.currentSystem}.\"opencode\".\"node_modules\" or flake.\"opencode\".\"node_modules\"); in (src.overrideAttrs or (f: src // f src)) (_: { outputHash = \"\"; outputHashAlgo = \"sha256\"; })' --extra-experimental-features 'flakes nix-command'\nPackage maintainers:\n - Thierry Delafontaine (@delafthi)\n$ git -C /home/m3tam3re/p/NIX/nixpkgs diff -- /home/m3tam3re/p/NIX/nixpkgs/pkgs/opencode\n\nThe workflow file needs to be updated to pass these arguments when updating the opencode package.","status":"closed","priority":2,"issue_type":"bug","owner":"p@m3ta.dev","created_at":"2026-01-17T09:47:55.750805329+01:00","created_by":"m3tm3re","updated_at":"2026-01-18T10:38:06.536530593+01:00","closed_at":"2026-01-18T10:38:06.536530593+01:00","close_reason":"Closed"}
{"id":"nixpkgs-98j","title":"beads overlay -\u003e pkgs","description":"Create a full package definition in pkgs/beads/default.nix that mirrors nixpkgs-unstable's beads package but with version 0.47.1 and updated hashes from overlays/mods/beads.nix. Register the new package in pkgs/default.nix. The overlay overrides: src (steveyegge/beads@v0.47.1), vendorHash, and disables tests (doCheck = false). Reference nixpkgs-unstable for the base package structure, then apply the version/hash modifications.","status":"closed","priority":2,"issue_type":"chore","owner":"p@m3ta.dev","created_at":"2026-01-13T19:43:35.645275221+01:00","created_by":"m3tm3re","updated_at":"2026-01-13T20:25:53.715613545+01:00","closed_at":"2026-01-13T20:25:53.715613545+01:00","close_reason":"Packages created successfully: pkgs/n8n/default.nix, pkgs/beads/default.nix, pkgs/opencode/default.nix. All packages build successfully."}
{"id":"nixpkgs-bqc","title":"opencode overlay -\u003e pkgs","description":"Create a full package definition in pkgs/opencode/default.nix that mirrors nixpkgs-unstable's opencode package but with version 1.1.18 and updated hashes from overlays/mods/opencode.nix. Register the new package in pkgs/default.nix. The overlay overrides: src (anomalyco/opencode@v1.1.18) and node_modules hash. Reference nixpkgs-unstable for the base package structure, then apply the version/hash modifications.","status":"closed","priority":2,"issue_type":"chore","owner":"p@m3ta.dev","created_at":"2026-01-13T19:43:36.450930004+01:00","created_by":"m3tm3re","updated_at":"2026-01-13T20:25:53.717928297+01:00","closed_at":"2026-01-13T20:25:53.717928297+01:00","close_reason":"Packages created successfully: pkgs/n8n/default.nix, pkgs/beads/default.nix, pkgs/opencode/default.nix. All packages build successfully."}
{"id":"nixpkgs-e2u","title":"Change projectDirs from list to attrset with path and args","description":"Change projectDirs option type from 'types.listOf types.str' to an attrset like:\n\nprojectDirs = {\n nixpkgs = { path = \"~/p/NIX/nixpkgs\"; args = \"--agent Planner-Sisyphus\"; };\n myproject = { path = \"~/dev/myproject\"; }; # args optional\n};\n\nMust maintain backward compatibility consideration.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-05T12:45:48.6992807+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:48:12.178120719+01:00","closed_at":"2026-01-05T12:48:12.178120719+01:00","close_reason":"Changed projectDirs from listOf str to attrsOf submodule with path+args","dependencies":[{"issue_id":"nixpkgs-e2u","depends_on_id":"nixpkgs-w3u","type":"parent-child","created_at":"2026-01-05T12:46:00.515400521+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-fka","title":"Ensure docs are staged and committed","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-10T18:48:18.05472995+01:00","created_by":"m3tam3re","updated_at":"2026-01-10T19:12:26.306880401+01:00","closed_at":"2026-01-10T19:12:26.306880401+01:00","close_reason":"Documentation staged and ready for commit"}
{"id":"nixpkgs-hrh","title":"projectDirs on rofi-project-switcher should be exported to users home-manager environment","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-05T11:46:43.640224459+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:49:43.584087541+01:00","closed_at":"2026-01-05T12:49:43.584087541+01:00","close_reason":"Feature complete: config exported as ROFI_PROJECT_OPENER_CONFIG env var","dependencies":[{"issue_id":"nixpkgs-hrh","depends_on_id":"nixpkgs-w3u","type":"blocks","created_at":"2026-01-05T12:46:05.867959608+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-p79","title":"feat: Add auto-language detection support to stt-ptt package","description":"## Current State\n- **Package**: `/home/m3tam3re/p/NIX/nixpkgs/pkgs/stt-ptt/default.nix`\n- **Module**: `/home/m3tam3re/p/NIX/nixpkgs/modules/home-manager/cli/stt-ptt.nix`\n- **Current whisper-cli call** (line 55): `\"$WHISPER\" -m \"$STT_MODEL\" -f \"$AUDIO\" -np -nt 2\u003e/dev/null`\n- **Missing**: Language configuration option and auto-detection\n\n## Required Changes\n\n### 1. Update Package (`pkgs/stt-ptt/default.nix`)\nAdd support for language configuration:\n- Add `STT_LANGUAGE` environment variable (default: \"auto\" for auto-detection)\n- Modify whisper-cli call to use `-l \"$STT_LANGUAGE\"` flag\n- Support the special value \"auto\" for automatic language detection\n- Update help text to document the new environment variable\n\n### 2. Update Home Manager Module (`modules/home-manager/cli/stt-ptt.nix`)\nAdd new `language` option:\n- Add `language` option with type `types.enum [\"auto\" \"en\" \"es\" \"fr\" \"de\" \"it\" \"pt\" \"ru\" \"zh\" \"ja\" \"ko\" ...]`\n- Default should be \"auto\" (auto-detect)\n- Set `STT_LANGUAGE` environment variable in `home.sessionVariables`\n- Add documentation describing available languages and auto-detection behavior\n- Consider using `types.nullOr(types.str)` with \"auto\" as default for more flexibility\n\n### 3. Technical Details\nFrom whisper.cpp CLI documentation:\n- `-l LANG, --language LANG [en] spoken language ('auto' for auto-detect)`\n- Auto-detection analyzes audio to determine spoken language automatically\n- Specifying a language can improve accuracy if you know the language\n- Language codes follow ISO 639-1 standard (2-letter codes)\n\n## Implementation Plan\n\n### Package Changes:\n```nix\n# Add to environment variables section:\nSTT_LANGUAGE=\"${STT_LANGUAGE:-auto}\"\n\n# Modify whisper call:\n\"$WHISPER\" -m \"$STT_MODEL\" -f \"$AUDIO\" -l \"$STT_LANGUAGE\" -np -nt 2\u003e/dev/null\n\n# Update help text:\necho \" STT_LANGUAGE - Language code or 'auto' for auto-detection (default: auto)\"\n```\n\n### Module Changes:\n```nix\nlanguage = mkOption {\n type = types.enum [\"auto\" \"en\" \"es\" \"fr\" \"de\" \"it\" \"pt\" \"ru\" \"zh\" \"ja\" \"ko\"];\n default = \"auto\";\n description = ''\n Language for speech recognition. Use \"auto\" for automatic language detection,\n or specify a language code (e.g., \"en\", \"es\", \"fr\") for better accuracy.\n Auto-detection analyzes the audio to determine the spoken language.\n '';\n};\n\nhome.sessionVariables = {\n STT_LANGUAGE = cfg.language;\n # ... existing variables\n};\n```\n\n## Benefits\n- **Multilingual support**: Users can speak in any language\n- **Convenience**: Auto-detection eliminates need to specify language\n- **Accuracy**: Explicit language selection improves transcription accuracy\n- **Backward compatible**: Default behavior (auto) matches current functionality\n\n## Testing Considerations\n1. Test auto-detection with multiple languages\n2. Test explicit language selection\n3. Test fallback behavior when auto-detection fails\n4. Test with different Whisper models\n\n## Related\n- whisper.cpp supports 100+ languages\n- Language codes follow ISO 639-1 standard\n- Auto-detection adds slight processing overhead","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-10T08:40:51.478869019+01:00","created_by":"m3tam3re","updated_at":"2026-01-10T09:35:49.421572334+01:00","closed_at":"2026-01-10T09:35:49.421572334+01:00","close_reason":"Implemented auto-language detection support: Added STT_LANGUAGE environment variable to package, modified whisper-cli call to use -l flag, updated help text, and added language option to HM module with enum support for 23 common languages plus 'auto'."}
{"id":"nixpkgs-r3u","title":"Add a Gitea action for nix-update to automatically update packages","description":"Create a Gitea action that runs nix-update to automatically update packages in this repository. My Gitea instance runs on NixOS (hostname: m3-atlas). Check the Gitea configuration in /home/m3tam3re/p/NIX/nixos-config for reference on how to set up actions. The action should target the packages directory and create PRs with updates when nix-update finds newer versions.","status":"closed","priority":2,"issue_type":"task","owner":"p@m3ta.dev","created_at":"2026-01-13T19:50:22.953433727+01:00","created_by":"m3tm3re","updated_at":"2026-01-18T18:36:50.936219311+01:00","closed_at":"2026-01-17T09:49:05.573319795+01:00","dependencies":[{"issue_id":"nixpkgs-r3u","depends_on_id":"nixpkgs-69z","type":"discovered-from","created_at":"2026-01-13T19:52:40.98774707+01:00","created_by":"m3tm3re"},{"issue_id":"nixpkgs-r3u","depends_on_id":"nixpkgs-98j","type":"discovered-from","created_at":"2026-01-13T19:52:41.501620297+01:00","created_by":"m3tm3re"},{"issue_id":"nixpkgs-r3u","depends_on_id":"nixpkgs-bqc","type":"discovered-from","created_at":"2026-01-13T19:52:42.010721971+01:00","created_by":"m3tm3re"}]}
{"id":"nixpkgs-sys","title":"Update config file format to include args per project","description":"Update the config file at ~/.config/rofi-project-opener/config to support per-project args. Change from PROJECT_DIRS to a format that encodes both path and args, e.g. JSON or structured text.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-05T12:45:51.793810575+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:48:21.75755315+01:00","closed_at":"2026-01-05T12:48:21.75755315+01:00","close_reason":"Config file now writes JSON (projects.json) with per-project path and args","dependencies":[{"issue_id":"nixpkgs-sys","depends_on_id":"nixpkgs-w3u","type":"parent-child","created_at":"2026-01-05T12:46:01.400263722+01:00","created_by":"m3tam3re"},{"issue_id":"nixpkgs-sys","depends_on_id":"nixpkgs-e2u","type":"blocks","created_at":"2026-01-05T12:46:04.055948778+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-tsh","title":"Prevent verification of ignored packages in nix-update workflow","status":"closed","priority":2,"issue_type":"task","owner":"p@m3ta.dev","created_at":"2026-01-18T10:36:45.393068138+01:00","created_by":"m3tm3re","updated_at":"2026-01-18T10:37:31.686158451+01:00","closed_at":"2026-01-18T10:37:31.686158451+01:00","close_reason":"Fixed by changing return 0 to return 1 for ignored packages"}
{"id":"nixpkgs-w3u","title":"projectDirs should support args, for example --agent \u003cagentname\u003e","description":"This means project directories need to be an attribute set and we also need to change the launch command to \"opencode \u003cdirectory name\u003e \u003carguments\u003e\".\n","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-05T11:56:13.844735432+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:49:42.34144046+01:00","closed_at":"2026-01-05T12:49:42.34144046+01:00","close_reason":"Feature complete: projectDirs now supports args per directory"}
{"id":"nixpkgs-xi7","title":"There is a bug in the basecamp-mcp server","description":"OSError: [Errno 30] Read-only file system when trying to write log file.\n\nTraceback:\nFile: /nix/store/708ksr7z3484bj8faysd7djwpa8xvw12-basecamp-mcp-server-0.0.1-unstable/lib/basecamp-mcp-server/basecamp_fastmcp.py, line 35\nError: logging.FileHandler(LOG_FILE_PATH) - attempting to write to read-only Nix store location: /nix/store/708ksr7z3484bj8faysd7djwpa8xvw12-basecamp-mcp-server-0.0.1-unstable/lib/basecamp-mcp-server/basecamp_fastmcp.log\n\nThe package needs to use a writable directory (e.g., XDG_DATA_HOME or /tmp) for log files instead of the Nix store.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-12T18:16:37.597147907+01:00","created_by":"m3tam3re","updated_at":"2026-01-12T19:12:57.91076765+01:00","closed_at":"2026-01-12T19:12:57.91076765+01:00","close_reason":"Closed"}
-4
View File
@@ -1,4 +0,0 @@
{
"database": "beads.db",
"jsonl_export": "issues.jsonl"
}
-18
View File
@@ -1,18 +0,0 @@
{"id":"nixpkgs-1xm","title":"Package Basecamp MCP Server","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-12T05:01:20.465656454+01:00","created_by":"m3tam3re","updated_at":"2026-01-12T05:01:26.623404603+01:00","closed_at":"2026-01-12T05:01:26.623404603+01:00","close_reason":"Packaged successfully with env file support"}
{"id":"nixpkgs-3k8","title":"Export project config as environment variable","description":"Export project configuration as home.sessionVariables (similar to zellij-ps pattern). Use JSON format for the env var since projects now have structured data (path + args).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-05T12:45:50.803017318+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:48:22.968626155+01:00","closed_at":"2026-01-05T12:48:22.968626155+01:00","close_reason":"Added home.sessionVariables.ROFI_PROJECT_OPENER_CONFIG with JSON config","dependencies":[{"issue_id":"nixpkgs-3k8","depends_on_id":"nixpkgs-hrh","type":"parent-child","created_at":"2026-01-05T12:46:03.16885012+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-3w3","title":"Add authentication command and environment file generation to basecamp-mcp-server","description":"The basecamp-mcp-server package at pkgs/basecamp-mcp-server/default.nix wraps the FastMCP server for Basecamp 3 integration. Currently, there's no convenient way for users to:\n\n1. Set up OAuth 2.0 authentication interactively\n2. Generate a sample environment file with required credentials\n3. Guide users through the Basecamp OAuth flow\n\n## Current State\n\nThe package wraps but users must:\n- Manually clone the upstream repository\n- Run to generate template\n- Edit with OAuth credentials from https://launchpad.37signals.com/integrations\n- Run to complete OAuth flow\n- Handle token storage manually\n\n## Required Environment Variables\n\n### OAuth Configuration (Primary)\n- - OAuth client ID from Basecamp\n- - OAuth client secret\n- - Found in Basecamp URL: https://3.basecamp.com/ID/...\n- - Format: \"App Name (email@domain.com)\"\n- - http://localhost:8000/auth/callback\n- - For Flask session security\n\n### Basic Auth (Legacy)\n- - Email for direct API access\n- - Password for direct API access\n\n## Proposed Solution\n\nAdd a Nix package wrapper command () that:\n\n1. **Interactive Setup Wizard**\n - Guides users through OAuth app creation at launchpad.37signals.com\n - Prompts for credentials (with secure input for secrets)\n - Validates inputs before proceeding\n\n2. **Environment File Generation**\n - Creates or project-local \n - Includes all required variables with clear documentation\n - Sets secure permissions (600)\n - Provides example values\n\n3. **OAuth Flow Handler**\n - Starts local Flask server on port 8000\n - Opens browser to initiate OAuth flow\n - Handles callback and token exchange\n - Stores tokens securely in \n - Shows success/failure status\n\n4. **Documentation**\n - Inline help for all steps\n - Links to Basecamp integration setup\n - Account ID discovery instructions\n\n## References\n\n- Upstream repo: https://github.com/georgeantonopoulos/Basecamp-MCP-Server\n- Key files: , , , \n- OAuth endpoints: launchpad.37signals.com/authorization/new\n\n## Subtasks\n\n- [ ] Create auth command wrapper (basecamp-mcp-auth)\n- [ ] Implement interactive OAuth wizard\n- [ ] Generate sample environment file template\n- [ ] Add token storage handling\n- [ ] Update package documentation\n- [ ] Add Home Manager module support (optional)","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-12T18:25:50.929926505+01:00","created_by":"m3tam3re","updated_at":"2026-01-12T19:12:57.941267399+01:00","closed_at":"2026-01-12T19:12:57.941267399+01:00","close_reason":"Closed"}
{"id":"nixpkgs-5ml","title":"Update rofi-project-opener script to pass args to opencode","description":"Modify pkgs/rofi-project-opener script to read the new config format and launch opencode with: 'opencode <directory> <arguments>' instead of just 'opencode' in the directory.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-05T12:45:49.748958951+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:49:40.800083615+01:00","closed_at":"2026-01-05T12:49:40.800083615+01:00","close_reason":"Script updated to read JSON config and pass args to opencode","dependencies":[{"issue_id":"nixpkgs-5ml","depends_on_id":"nixpkgs-w3u","type":"parent-child","created_at":"2026-01-05T12:46:02.338350208+01:00","created_by":"m3tam3re"},{"issue_id":"nixpkgs-5ml","depends_on_id":"nixpkgs-sys","type":"blocks","created_at":"2026-01-05T12:46:04.966269033+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-61l","title":"Update documentation to reflect latest changes","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-10T18:48:19.599467206+01:00","created_by":"m3tam3re","updated_at":"2026-01-10T19:12:26.294895563+01:00","closed_at":"2026-01-10T19:12:26.294895563+01:00","close_reason":"Documentation updated: Added stt-ptt language support docs, rofi-project-opener module docs, and updated zellij-ps docs"}
{"id":"nixpkgs-69z","title":"n8n overlay -> pkgs","description":"Create a full package definition in pkgs/n8n/default.nix that mirrors nixpkgs-unstable's n8n package but with version 2.4.1 and updated hashes from overlays/mods/n8n.nix. Register the new package in pkgs/default.nix. The overlay overrides: src (n8n-io/n8n@2.4.1) and pnpmDeps hash. Reference nixpkgs-unstable for the base package structure, then apply the version/hash modifications.","status":"closed","priority":2,"issue_type":"chore","owner":"p@m3ta.dev","created_at":"2026-01-13T19:42:35.643928163+01:00","created_by":"m3tm3re","updated_at":"2026-01-13T20:25:53.712987689+01:00","closed_at":"2026-01-13T20:25:53.712987689+01:00","close_reason":"Packages created successfully: pkgs/n8n/default.nix, pkgs/beads/default.nix, pkgs/opencode/default.nix. All packages build successfully."}
{"id":"nixpkgs-7ez","title":"Add authentication command for basecamp-mcp-server","description":"Add a command for the basecamp-mcp-server that will guide the user through the authentication flow and create a sample environment file with the necessary values. This involves researching the original basecamp-mcp-server repository for authentication details and implementing a user-friendly authentication workflow.","status":"tombstone","priority":0,"issue_type":"feature","created_at":"2026-01-12T18:20:55.665717166+01:00","created_by":"m3tam3re","updated_at":"2026-01-13T19:46:32.112562429+01:00","dependencies":[{"issue_id":"nixpkgs-7ez","depends_on_id":"nixpkgs-3w3","type":"blocks","created_at":"2026-01-12T18:48:31.806330931+01:00","created_by":"m3tam3re"}],"deleted_at":"2026-01-13T19:46:32.112562429+01:00","deleted_by":"daemon","delete_reason":"delete","original_type":"feature"}
{"id":"nixpkgs-8jw","title":"fix: self-hosted nixos runner missing node in PATH for Gitea Actions","description":"The nix-update workflow fails on self-hosted nixos runner because node is not available in PATH. Error: Cannot find: node in PATH. Root cause: actions/checkout@v4 requires Node.js to execute post-checkout steps. The self-hosted nixos runner does not have node installed or not in PATH. Possible solutions: 1) Add Node.js to the nixos runner environment, 2) Use container-based runner instead of bare nixos, 3) Use a different checkout action that does not require node, 4) Configure PATH to include node installation. Impact: Automated package updates are completely blocked.","status":"open","priority":1,"issue_type":"bug","owner":"p@m3ta.dev","created_at":"2026-01-14T20:50:59.153145341+01:00","created_by":"m3tm3re","updated_at":"2026-01-14T20:51:34.044954071+01:00"}
{"id":"nixpkgs-98j","title":"beads overlay -> pkgs","description":"Create a full package definition in pkgs/beads/default.nix that mirrors nixpkgs-unstable's beads package but with version 0.47.1 and updated hashes from overlays/mods/beads.nix. Register the new package in pkgs/default.nix. The overlay overrides: src (steveyegge/beads@v0.47.1), vendorHash, and disables tests (doCheck = false). Reference nixpkgs-unstable for the base package structure, then apply the version/hash modifications.","status":"closed","priority":2,"issue_type":"chore","owner":"p@m3ta.dev","created_at":"2026-01-13T19:43:35.645275221+01:00","created_by":"m3tm3re","updated_at":"2026-01-13T20:25:53.715613545+01:00","closed_at":"2026-01-13T20:25:53.715613545+01:00","close_reason":"Packages created successfully: pkgs/n8n/default.nix, pkgs/beads/default.nix, pkgs/opencode/default.nix. All packages build successfully."}
{"id":"nixpkgs-bqc","title":"opencode overlay -> pkgs","description":"Create a full package definition in pkgs/opencode/default.nix that mirrors nixpkgs-unstable's opencode package but with version 1.1.18 and updated hashes from overlays/mods/opencode.nix. Register the new package in pkgs/default.nix. The overlay overrides: src (anomalyco/opencode@v1.1.18) and node_modules hash. Reference nixpkgs-unstable for the base package structure, then apply the version/hash modifications.","status":"closed","priority":2,"issue_type":"chore","owner":"p@m3ta.dev","created_at":"2026-01-13T19:43:36.450930004+01:00","created_by":"m3tm3re","updated_at":"2026-01-13T20:25:53.717928297+01:00","closed_at":"2026-01-13T20:25:53.717928297+01:00","close_reason":"Packages created successfully: pkgs/n8n/default.nix, pkgs/beads/default.nix, pkgs/opencode/default.nix. All packages build successfully."}
{"id":"nixpkgs-e2u","title":"Change projectDirs from list to attrset with path and args","description":"Change projectDirs option type from 'types.listOf types.str' to an attrset like:\n\nprojectDirs = {\n nixpkgs = { path = \"~/p/NIX/nixpkgs\"; args = \"--agent Planner-Sisyphus\"; };\n myproject = { path = \"~/dev/myproject\"; }; # args optional\n};\n\nMust maintain backward compatibility consideration.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-05T12:45:48.6992807+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:48:12.178120719+01:00","closed_at":"2026-01-05T12:48:12.178120719+01:00","close_reason":"Changed projectDirs from listOf str to attrsOf submodule with path+args","dependencies":[{"issue_id":"nixpkgs-e2u","depends_on_id":"nixpkgs-w3u","type":"parent-child","created_at":"2026-01-05T12:46:00.515400521+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-fka","title":"Ensure docs are staged and committed","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-10T18:48:18.05472995+01:00","created_by":"m3tam3re","updated_at":"2026-01-10T19:12:26.306880401+01:00","closed_at":"2026-01-10T19:12:26.306880401+01:00","close_reason":"Documentation staged and ready for commit"}
{"id":"nixpkgs-hrh","title":"projectDirs on rofi-project-switcher should be exported to users home-manager environment","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-05T11:46:43.640224459+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:49:43.584087541+01:00","closed_at":"2026-01-05T12:49:43.584087541+01:00","close_reason":"Feature complete: config exported as ROFI_PROJECT_OPENER_CONFIG env var","dependencies":[{"issue_id":"nixpkgs-hrh","depends_on_id":"nixpkgs-w3u","type":"blocks","created_at":"2026-01-05T12:46:05.867959608+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-p79","title":"feat: Add auto-language detection support to stt-ptt package","description":"## Current State\n- **Package**: `/home/m3tam3re/p/NIX/nixpkgs/pkgs/stt-ptt/default.nix`\n- **Module**: `/home/m3tam3re/p/NIX/nixpkgs/modules/home-manager/cli/stt-ptt.nix`\n- **Current whisper-cli call** (line 55): `\"$WHISPER\" -m \"$STT_MODEL\" -f \"$AUDIO\" -np -nt 2>/dev/null`\n- **Missing**: Language configuration option and auto-detection\n\n## Required Changes\n\n### 1. Update Package (`pkgs/stt-ptt/default.nix`)\nAdd support for language configuration:\n- Add `STT_LANGUAGE` environment variable (default: \"auto\" for auto-detection)\n- Modify whisper-cli call to use `-l \"$STT_LANGUAGE\"` flag\n- Support the special value \"auto\" for automatic language detection\n- Update help text to document the new environment variable\n\n### 2. Update Home Manager Module (`modules/home-manager/cli/stt-ptt.nix`)\nAdd new `language` option:\n- Add `language` option with type `types.enum [\"auto\" \"en\" \"es\" \"fr\" \"de\" \"it\" \"pt\" \"ru\" \"zh\" \"ja\" \"ko\" ...]`\n- Default should be \"auto\" (auto-detect)\n- Set `STT_LANGUAGE` environment variable in `home.sessionVariables`\n- Add documentation describing available languages and auto-detection behavior\n- Consider using `types.nullOr(types.str)` with \"auto\" as default for more flexibility\n\n### 3. Technical Details\nFrom whisper.cpp CLI documentation:\n- `-l LANG, --language LANG [en] spoken language ('auto' for auto-detect)`\n- Auto-detection analyzes audio to determine spoken language automatically\n- Specifying a language can improve accuracy if you know the language\n- Language codes follow ISO 639-1 standard (2-letter codes)\n\n## Implementation Plan\n\n### Package Changes:\n```nix\n# Add to environment variables section:\nSTT_LANGUAGE=\"${STT_LANGUAGE:-auto}\"\n\n# Modify whisper call:\n\"$WHISPER\" -m \"$STT_MODEL\" -f \"$AUDIO\" -l \"$STT_LANGUAGE\" -np -nt 2>/dev/null\n\n# Update help text:\necho \" STT_LANGUAGE - Language code or 'auto' for auto-detection (default: auto)\"\n```\n\n### Module Changes:\n```nix\nlanguage = mkOption {\n type = types.enum [\"auto\" \"en\" \"es\" \"fr\" \"de\" \"it\" \"pt\" \"ru\" \"zh\" \"ja\" \"ko\"];\n default = \"auto\";\n description = ''\n Language for speech recognition. Use \"auto\" for automatic language detection,\n or specify a language code (e.g., \"en\", \"es\", \"fr\") for better accuracy.\n Auto-detection analyzes the audio to determine the spoken language.\n '';\n};\n\nhome.sessionVariables = {\n STT_LANGUAGE = cfg.language;\n # ... existing variables\n};\n```\n\n## Benefits\n- **Multilingual support**: Users can speak in any language\n- **Convenience**: Auto-detection eliminates need to specify language\n- **Accuracy**: Explicit language selection improves transcription accuracy\n- **Backward compatible**: Default behavior (auto) matches current functionality\n\n## Testing Considerations\n1. Test auto-detection with multiple languages\n2. Test explicit language selection\n3. Test fallback behavior when auto-detection fails\n4. Test with different Whisper models\n\n## Related\n- whisper.cpp supports 100+ languages\n- Language codes follow ISO 639-1 standard\n- Auto-detection adds slight processing overhead","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-10T08:40:51.478869019+01:00","created_by":"m3tam3re","updated_at":"2026-01-10T09:35:49.421572334+01:00","closed_at":"2026-01-10T09:35:49.421572334+01:00","close_reason":"Implemented auto-language detection support: Added STT_LANGUAGE environment variable to package, modified whisper-cli call to use -l flag, updated help text, and added language option to HM module with enum support for 23 common languages plus 'auto'."}
{"id":"nixpkgs-r3u","title":"Add a Gitea action for nix-update to automatically update packages","description":"Create a Gitea action that runs nix-update to automatically update packages in this repository. My Gitea instance runs on NixOS (hostname: m3-atlas). Check the Gitea configuration in /home/m3tam3re/p/NIX/nixos-config for reference on how to set up actions. The action should target the packages directory and create PRs with updates when nix-update finds newer versions.","status":"open","priority":2,"issue_type":"task","owner":"p@m3ta.dev","created_at":"2026-01-13T19:50:22.953433727+01:00","created_by":"m3tm3re","updated_at":"2026-01-13T19:52:40.071361668+01:00","dependencies":[{"issue_id":"nixpkgs-r3u","depends_on_id":"nixpkgs-69z","type":"discovered-from","created_at":"2026-01-13T19:52:40.98774707+01:00","created_by":"m3tm3re"},{"issue_id":"nixpkgs-r3u","depends_on_id":"nixpkgs-98j","type":"discovered-from","created_at":"2026-01-13T19:52:41.501620297+01:00","created_by":"m3tm3re"},{"issue_id":"nixpkgs-r3u","depends_on_id":"nixpkgs-bqc","type":"discovered-from","created_at":"2026-01-13T19:52:42.010721971+01:00","created_by":"m3tm3re"}]}
{"id":"nixpkgs-sys","title":"Update config file format to include args per project","description":"Update the config file at ~/.config/rofi-project-opener/config to support per-project args. Change from PROJECT_DIRS to a format that encodes both path and args, e.g. JSON or structured text.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-05T12:45:51.793810575+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:48:21.75755315+01:00","closed_at":"2026-01-05T12:48:21.75755315+01:00","close_reason":"Config file now writes JSON (projects.json) with per-project path and args","dependencies":[{"issue_id":"nixpkgs-sys","depends_on_id":"nixpkgs-w3u","type":"parent-child","created_at":"2026-01-05T12:46:01.400263722+01:00","created_by":"m3tam3re"},{"issue_id":"nixpkgs-sys","depends_on_id":"nixpkgs-e2u","type":"blocks","created_at":"2026-01-05T12:46:04.055948778+01:00","created_by":"m3tam3re"}]}
{"id":"nixpkgs-w3u","title":"projectDirs should support args, for example --agent <agentname>","description":"This means project directories need to be an attribute set and we also need to change the launch command to \"opencode <directory name> <arguments>\".\n","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-05T11:56:13.844735432+01:00","created_by":"m3tam3re","updated_at":"2026-01-05T12:49:42.34144046+01:00","closed_at":"2026-01-05T12:49:42.34144046+01:00","close_reason":"Feature complete: projectDirs now supports args per directory"}
{"id":"nixpkgs-xi7","title":"There is a bug in the basecamp-mcp server","description":"OSError: [Errno 30] Read-only file system when trying to write log file.\n\nTraceback:\nFile: /nix/store/708ksr7z3484bj8faysd7djwpa8xvw12-basecamp-mcp-server-0.0.1-unstable/lib/basecamp-mcp-server/basecamp_fastmcp.py, line 35\nError: logging.FileHandler(LOG_FILE_PATH) - attempting to write to read-only Nix store location: /nix/store/708ksr7z3484bj8faysd7djwpa8xvw12-basecamp-mcp-server-0.0.1-unstable/lib/basecamp-mcp-server/basecamp_fastmcp.log\n\nThe package needs to use a writable directory (e.g., XDG_DATA_HOME or /tmp) for log files instead of the Nix store.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-12T18:16:37.597147907+01:00","created_by":"m3tam3re","updated_at":"2026-01-12T19:12:57.91076765+01:00","closed_at":"2026-01-12T19:12:57.91076765+01:00","close_reason":"Closed"}
-3
View File
@@ -1,3 +0,0 @@
# Use bd merge for beads JSONL files
.beads/issues.jsonl merge=beads
-398
View File
@@ -1,398 +0,0 @@
name: Update Nix Packages with nix-update
on:
schedule:
- cron: "0 2,14 * * *" # Every 12 hours at 2 AM and 2 PM
workflow_dispatch:
inputs:
package:
description: "Specific package to update (optional)"
required: false
type: string
concurrency:
group: nix-update-${{ github.ref }}
cancel-in-progress: true
env:
GIT_AUTHOR_NAME: "nix-update bot"
GIT_AUTHOR_EMAIL: "bot@m3ta.dev"
GIT_COMMITTER_NAME: "nix-update bot"
GIT_COMMITTER_EMAIL: "bot@m3ta.dev"
REPO_DIR: "/tmp/nixpkgs"
# Nix configuration
NIX_PATH: "nixpkgs=channel:nixos-unstable"
NIX_CONFIG: "experimental-features = nix-command flakes"
# Non-interactive mode
DEBIAN_FRONTEND: "noninteractive"
GIT_TERMINAL_PROMPT: "0"
jobs:
nix-update:
runs-on: nixos
timeout-minutes: 180
steps:
- name: Setup Environment and Authenticate
run: |
if [ -d "$REPO_DIR" ]; then rm -rf "$REPO_DIR"; fi
git config --global credential.helper store
echo "https://m3tam3re:${{ secrets.NIX_UPDATE_TOKEN }}@code.m3ta.dev" > ~/.git-credentials
chmod 600 ~/.git-credentials
git config --global user.name "$GIT_AUTHOR_NAME"
git config --global user.email "$GIT_AUTHOR_EMAIL"
git config --global init.defaultBranch master
- name: Checkout Repository
run: |
git clone --no-single-branch \
"https://m3tam3re@code.m3ta.dev/m3tam3re/nixpkgs.git" \
"$REPO_DIR"
- name: Update opencode Flake Input
id: update-opencode
run: |
cd "$REPO_DIR"
echo "::group::Checking for opencode updates"
# Get latest release from GitHub API (strip v prefix for comparison)
LATEST_RELEASE=$(curl -s "https://api.github.com/repos/anomalyco/opencode/releases/latest" | jq -r '.tag_name' | sed 's/^v//')
# Extract current version from flake.nix
CURRENT_VERSION=$(grep -oP 'opencode\.url = "github:anomalyco/opencode/v\K[^"]+' flake.nix)
echo "Current opencode version: $CURRENT_VERSION"
echo "Latest opencode version: $LATEST_RELEASE"
# Check if update is needed
if [ "$LATEST_RELEASE" != "$CURRENT_VERSION" ]; then
echo "🔄 Updating opencode from $CURRENT_VERSION to $LATEST_RELEASE"
# Update flake.nix with new version
sed -i 's|opencode\.url = "github:anomalyco/opencode/v.*"|opencode.url = "github:anomalyco/opencode/v'"$LATEST_RELEASE"'"|' flake.nix
# Update flake lock to fetch new revision
nix flake update opencode
# Format with alejandra
nix fmt flake.nix
# Verify the update
echo "::endgroup::"
echo "::group::Verifying opencode update"
# Run flake check
if ! nix flake check; then
echo "❌ Flake check failed after opencode update"
git checkout flake.nix flake.lock
exit 1
fi
# Build opencode package
if ! nix build .#opencode 2>&1 | tee /tmp/opencode-build.log; then
echo "❌ Build failed for opencode"
git checkout flake.nix flake.lock
exit 1
fi
echo "✅ Flake check passed"
echo "✅ Build successful for opencode"
echo "::endgroup::"
# Commit the change
echo "::group::Committing opencode update"
git add flake.nix flake.lock
git commit -m "chore: update opencode flake input to $LATEST_RELEASE"
echo "opencode_update=true" >> $GITHUB_OUTPUT
echo "opencode_version=${LATEST_RELEASE}" >> $GITHUB_OUTPUT
echo "::endgroup::"
echo "✅ Updated opencode to $LATEST_RELEASE"
else
echo "✓ opencode is already up to date"
echo "opencode_update=false" >> $GITHUB_OUTPUT
echo "opencode_version=${CURRENT_VERSION}" >> $GITHUB_OUTPUT
echo "::endgroup::"
fi
- name: Check Prerequisites
id: check
run: |
cd "$REPO_DIR"
if [ ! -d "pkgs" ]; then
echo "❌ Error: 'pkgs' directory not found."
exit 1
fi
if [ -f "flake.nix" ]; then
echo "has_flake=true" >> $GITHUB_OUTPUT
else
echo "has_flake=false" >> $GITHUB_OUTPUT
fi
- name: Update Packages
id: update
run: |
cd "$REPO_DIR"
set -e
git checkout master
UPDATES_FOUND=false
UPDATED_PACKAGES=""
check_commit() {
[ "$1" != "$(git rev-parse HEAD)" ] && echo "true" || echo "false"
}
has_update_script() {
local pkg=$1
# Check if package has passthru.updateScript attribute
nix eval .#${pkg}.passthru.updateScript --json >/dev/null 2>&1
}
run_update() {
local pkg=$1
local before_hash=$(git rev-parse HEAD)
echo "::group::Updating $pkg"
local args=("--flake" "--commit" "--use-github-releases")
args+=("$pkg")
if nix-update "${args[@]}" 2>&1 | tee /tmp/update-${pkg}.log; then
if [ "$(check_commit "$before_hash")" = "true" ]; then
echo "✅ Updated $pkg"
echo "::endgroup::"
return 0
fi
fi
# Clean up any uncommitted changes from failed update
git checkout -- . 2>/dev/null || true
git clean -fd 2>/dev/null || true
echo "::endgroup::"
if ! grep -q "already up to date\|No new version found" /tmp/update-${pkg}.log; then
echo "⚠️ Update failed for $pkg"
fi
return 1
}
if [ -n "${{ inputs.package }}" ]; then
pkg="${{ inputs.package }}"
if [ -d "pkgs/$pkg" ]; then
if run_update "$pkg"; then
UPDATES_FOUND=true
UPDATED_PACKAGES="$pkg"
fi
else
echo "❌ Package 'pkgs/$pkg' not found"
fi
else
# Dynamically discover packages with updateScript attribute
echo "🔍 Discovering packages with passthru.updateScript..."
# Get all packages and filter those with updateScript
ALL_PACKAGES=$(find pkgs -mindepth 1 -maxdepth 1 -type d -exec basename {} \; 2>/dev/null | sort)
UPDATABLE_PACKAGES=""
if [ -z "$ALL_PACKAGES" ]; then
echo "No packages found in pkgs/"
exit 0
fi
for pkg in $ALL_PACKAGES; do
if has_update_script "$pkg"; then
echo " ✓ $pkg (has updateScript)"
UPDATABLE_PACKAGES="$UPDATABLE_PACKAGES $pkg"
else
echo " ⊘ $pkg (no updateScript - skipping)"
fi
done
if [ -z "$UPDATABLE_PACKAGES" ]; then
echo "️ No packages with updateScript found."
exit 0
fi
echo ""
echo "📦 Found $(echo $UPDATABLE_PACKAGES | wc -w) updatable packages"
echo ""
for pkg in $UPDATABLE_PACKAGES; do
if run_update "$pkg"; then
UPDATES_FOUND=true
if [ -n "$UPDATED_PACKAGES" ]; then
UPDATED_PACKAGES="$UPDATED_PACKAGES, $pkg"
else
UPDATED_PACKAGES="$pkg"
fi
fi
done
fi
COMMIT_COUNT=$(git rev-list --count origin/master..HEAD)
if [ "$COMMIT_COUNT" -gt 0 ]; then
echo "✅ $COMMIT_COUNT updates committed locally."
echo "has_updates=true" >> $GITHUB_OUTPUT
echo "updated_packages=${UPDATED_PACKAGES}" >> $GITHUB_OUTPUT
else
echo "️ No updates found."
echo "has_updates=false" >> $GITHUB_OUTPUT
fi
- name: Verify Builds
if: steps.update.outputs.has_updates == 'true' || steps.update-opencode.outputs.opencode_update == 'true'
run: |
cd "$REPO_DIR"
echo "::group::Running flake check"
if ! nix flake check; then
echo "❌ Flake check failed"
exit 1
fi
echo "✅ Flake check passed"
echo "::endgroup::"
IFS=', ' read -ra PKGS <<< "${{ steps.update.outputs.updated_packages }}"
FAILED_PACKAGES=()
SUCCESSFUL_PACKAGES=()
for pkg in "${PKGS[@]}"; do
echo "::group::Building $pkg"
if nix build .#$pkg 2>&1 | tee /tmp/build-${pkg}.log; then
echo "✅ Build successful for $pkg"
SUCCESSFUL_PACKAGES+=("$pkg")
else
echo "❌ Build failed for $pkg"
FAILED_PACKAGES+=("$pkg")
fi
echo "::endgroup::"
done
if [ ${#FAILED_PACKAGES[@]} -gt 0 ]; then
echo ""
echo "❌ Failed packages: ${FAILED_PACKAGES[*]}"
echo "✅ Successful packages: ${SUCCESSFUL_PACKAGES[*]}"
echo ""
# Upload logs as artifacts for debugging
echo "## Build Failure Logs" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
for pkg in "${FAILED_PACKAGES[@]}"; do
echo "### $pkg" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
cat /tmp/build-${pkg}.log >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
done
exit 1
fi
echo ""
echo "✅ All packages built successfully: ${SUCCESSFUL_PACKAGES[*]}"
- name: Push Changes
if: steps.update.outputs.has_updates == 'true' || steps.update-opencode.outputs.opencode_update == 'true'
run: |
cd "$REPO_DIR"
PACKAGES="${{ steps.update.outputs.updated_packages }}"
if [ "${{ steps.update-opencode.outputs.opencode_update }}" = "true" ]; then
if [ -n "$PACKAGES" ]; then
PACKAGES="$PACKAGES, opencode"
else
PACKAGES="opencode"
fi
fi
echo "::group::Git Operations"
echo "Current commit: $(git rev-parse HEAD)"
echo "Pending commits: $(git rev-list --count origin/master..HEAD)"
echo ""
echo "Pulling latest changes (rebase)..."
if git pull --rebase origin master; then
echo "✅ Rebase successful"
else
echo "⚠️ Rebase failed, resetting and retrying..."
git rebase --abort 2>/dev/null || true
git reset --hard origin/master
echo "❌ Could not rebase, updates lost. Will retry next run."
exit 0
fi
echo ""
echo "Pushing changes to master..."
git push origin master
echo ""
echo "✅ Successfully pushed updates for: $PACKAGES"
echo "::endgroup::"
- name: Cleanup
if: always()
run: |
# Remove git credentials securely
rm -f ~/.git-credentials
git config --global --unset credential.helper 2>/dev/null || true
# Remove temporary directory
rm -rf "$REPO_DIR"
# Remove all log files
rm -f /tmp/update-*.log /tmp/build-*.log /tmp/opencode-build.log /tmp/update-log.txt /tmp/success-packages.txt
# Clear sensitive environment variables
unset GIT_AUTHOR_EMAIL GIT_COMMITTER_EMAIL
- name: Summary
if: always()
run: |
HAS_UPDATES="false"
if [ "${{ steps.update.outputs.has_updates }}" = "true" ]; then
HAS_UPDATES="true"
echo "# ✅ Update Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Updated Packages" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`${{ steps.update.outputs.updated_packages }}\`" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ steps.update-opencode.outputs.opencode_update }}" = "true" ]; then
HAS_UPDATES="true"
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Updated Flake Input" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **opencode**: \`v${{ steps.update-opencode.outputs.opencode_version }}\`" >> $GITHUB_STEP_SUMMARY
fi
if [ "$HAS_UPDATES" = "true" ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Status" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- ✅ All updates validated with \`nix flake check\`" >> $GITHUB_STEP_SUMMARY
echo "- ✅ All builds successful" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Changes pushed to master" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Workflow Performance" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- Started: ${{ github.event.head_commit.timestamp }}" >> $GITHUB_STEP_SUMMARY
echo "- Completed: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
echo "- Workflow Run: [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
else
echo "# ️ No Updates Required" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "No updates found this run. All packages and flake inputs are up to date." >> $GITHUB_STEP_SUMMARY
fi
-33
View File
@@ -1,33 +0,0 @@
# Nix build outputs
result
result-*
# Direnv
.direnv/
.envrc
# Development shells
shell.nix
# Editor files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
# Nix-specific
.pre-commit-config.yaml
.envrc.local
# Temporary files
*.tmp
*.log
# Testing
test-result/
# Local configuration (if you want to keep local overrides)
local.nix
flake.lock.bak
-165
View File
@@ -1,165 +0,0 @@
# m3ta-nixpkgs Knowledge Base
**Generated:** 2026-01-13
**Commit:** 366af12
**Branch:** master
## OVERVIEW
Personal Nix flake: custom packages, overlays, NixOS/Home Manager modules, dev shells. Flakes-only (no channels).
## STRUCTURE
```
.
├── flake.nix # Entry: packages, overlays, modules, shells, lib
├── pkgs/ # Custom packages (one dir each, callPackage registry)
├── modules/
│ ├── nixos/ # System modules (ports.nix)
│ └── home-manager/ # User modules by category (cli/, coding/, ports.nix)
├── lib/ # Shared utilities (ports.nix)
├── shells/ # Dev environments (default, python, devops)
├── overlays/mods/ # Package modifications (n8n version bump)
├── templates/ # Boilerplate for new packages/modules
├── examples/ # Usage examples
└── .gitea/workflows/ # CI/CD workflows (nix-update automation)
```
## WHERE TO LOOK
| Task | Location | Notes |
| -------------------- | ---------------------------------- | ------------------------------------- |
| Add package | `pkgs/<name>/default.nix` | Register in `pkgs/default.nix` |
| Add NixOS module | `modules/nixos/<name>.nix` | Import in `modules/nixos/default.nix` |
| Add HM module | `modules/home-manager/<category>/` | Category: cli, coding, or root |
| Override nixpkgs pkg | `overlays/mods/<name>.nix` | Import in `overlays/mods/default.nix` |
| Add dev shell | `shells/<name>.nix` | Register in `shells/default.nix` |
| Use port management | `config.m3ta.ports.get "service"` | Host-specific via `hostOverrides` |
| CI/CD workflows | `.gitea/workflows/<name>.yml` | Automated package updates (nix-update) |
## CONVENTIONS
**Formatter**: `nix fmt` before commit (alejandra)
**Naming**:
- Packages: `lowercase-hyphen` (e.g., `hyprpaper-random`)
- Variables: `camelCase` (e.g., `portHelpers`)
- Module options: `m3ta.*` namespace
**Imports**: Multi-line, trailing commas:
```nix
{
lib,
stdenv,
fetchFromGitHub,
}:
```
**Modules**: Standard pattern:
```nix
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "description";
};
config = mkIf cfg.enable { ... };
}
```
**Meta**: Always include all fields:
```nix
meta = with lib; {
description = "...";
homepage = "...";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "...";
};
```
## PACKAGE PATTERNS
**Rust**: `rustPlatform.buildRustPackage rec { cargoLock.lockFile = src + "/Cargo.lock"; }`
**Shell**: `writeShellScriptBin "name" ''script''` or `mkDerivation` with custom `installPhase`
**AppImage**: `appimageTools.wrapType2 { ... }`
**Custom fetcher**: `fetchFromGitea { domain = "code.m3ta.dev"; owner = "m3tam3re"; ... }`
## MODULE PATTERNS
**Simple**: `options.cli.name = { enable = mkEnableOption "..."; }; config = mkIf cfg.enable { ... };`
**Multiple**: `config = mkMerge [ (mkIf cfg.x.enable { ... }) (mkIf cfg.y.enable { ... }) ];`
**Shared lib**: `portsLib = import ../../lib/ports.nix { inherit lib; }; portHelpers = portsLib.mkPortHelpers { ... };`
## PORT MANAGEMENT
Central port management: `config.m3ta.ports.get "service"` with host-specific via `hostOverrides`
Generated: `/etc/m3ta/ports.json` (NixOS), `~/.config/m3ta/ports.json` (HM)
## COMMANDS
```bash
nix flake check # Validate flake
nix fmt # Format (alejandra)
nix build .#<pkg> # Build package
nix flake show # List outputs
nix develop # Enter dev shell
nix develop .#python # Python shell
nix develop .#devops # DevOps shell
# In dev shell only:
statix check . # Lint
deadnix . # Find dead code
```
## 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 |
## COMMIT FORMAT
```
type: brief description
```
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `chore`
## NOTES
- **Hash fetching**: Use `lib.fakeHash` initially, build to get real hash
- **HM modules**: Category subdirs (`cli/`, `coding/`) have own `default.nix` aggregators
- **Ports module**: Different for NixOS vs HM (HM adds `generateEnvVars` option)
- **Overlays**: `modifications` overlay uses `{prev}:` pattern, not `{final, prev}:`
- **Dev shell tools**: `statix`, `deadnix` only available inside `nix develop`
- **Automated package updates**: Packages are automatically updated weekly via Gitea Actions using `nix-update`. Review PRs from the automation before merging. For urgent updates, manually run the workflow or update manually.
## Issue Tracking
This project uses **bd (beads)** for issue tracking.
Run `bd prime` for workflow context, or install hooks (`bd hooks install`) for auto-injection.
**Quick reference:**
- `bd ready` - Find unblocked work
- `bd create "Title" --type task --priority 2` - Create issue
- `bd close <id>` - Complete work
- `bd sync` - Sync with git (run at session end)
For full workflow details: `bd prime`
+7
View File
@@ -0,0 +1,7 @@
This repository is being used as a Dolt remote.
ref=refs/dolt/data
head=43d141bca1faebdf2ed20deb3c147ca1b2946eea
timestamp=2026-07-04T07:30:30Z
-89
View File
@@ -1,89 +0,0 @@
# m3ta-nixpkgs
Personal Nix flake repository: custom packages, overlays, NixOS modules, and Home Manager modules.
## Features
- 🎁 **Custom Packages**: Collection of personal Nix packages
- 🔄 **Overlays**: Package modifications and enhancements
- 🐚 **Development Shells**: Pre-configured environments (Python, DevOps)
- ⚙️ **NixOS Modules**: System-level configuration modules
- 🏠 **Home Manager Modules**: User-level configuration modules
- 📚 **Library Functions**: Helper utilities for configuration management
- ❄️ **Flakes Only**: Modern Nix flakes support (no channels)
## Quick Links
- 📖 [Full Documentation](./docs)
- 🚀 [Quick Start Guide](./docs/QUICKSTART.md)
- 📚 [Architecture](./docs/ARCHITECTURE.md)
- 🤝 [Contributing](./docs/CONTRIBUTING.md)
- 📦 [Packages](./docs/packages/)
- ⚙️ [Modules](./docs/modules/)
- 📖 [Guides](./docs/guides/)
## 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
```
## Available Packages
| Package | Description |
| ------------------ | ------------------------------------- |
| `beads` | Lightweight memory system for AI coding agents with graph-based issue tracking |
| `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 |
| `n8n` | Free and source-available fair-code licensed workflow automation tool |
| `opencode` | AI coding agent built for the terminal |
| `pomodoro-timer` | Pomodoro timer utility |
| `rofi-project-opener` | Rofi-based project launcher |
| `stt-ptt` | Push to Talk Speech to Text |
| `tuxedo-backlight` | Backlight control for Tuxedo laptops |
| `zellij-ps` | Project switcher for Zellij |
## Automated Package Updates
This repository uses Gitea Actions to automatically update packages using `nix-update`:
**Workflow**: [`.gitea/workflows/nix-update.yml`](./.gitea/workflows/nix-update.yml)
**Schedule**: Runs weekly on Sundays, and can be triggered manually.
**What it does**:
- Checks all packages in `pkgs/` for updates
- Updates versions and hashes using `nix-update --flake --commit`
- Creates a new branch with updates
- Opens a pull request automatically
**Manual Trigger**:
Go to **Actions → Update Nix Packages with nix-update → Run workflow** in Gitea UI, then optionally specify a specific package to update.
**Setup Required**:
1. Create a Personal Access Token in Gitea (Settings → Applications → Generate Token)
2. Token scopes needed: `user`, `repo`, `write:issue`
3. Add token as secret: Settings → Secrets → New → `NIX_UPDATE_TOKEN`
**Note:** The `opencode-desktop` package is currently disabled due to an upstream issue with missing specta dependency hashes. See [issue #11755](https://github.com/anomalyco/opencode/issues/11755) for details. This is a temporary workaround until the upstream issue is resolved.
For detailed usage, module documentation, package references, and contribution guidelines, see the [full documentation](./docs).
## License
Individual packages may have their own licenses. Check each package's `meta.license` attribute.
## Maintainer
[@m3tam3re](https://m3ta.dev)
-473
View File
@@ -1,473 +0,0 @@
# Architecture
Understanding the design and structure of m3ta-nixpkgs.
## Overview
m3ta-nixpkgs is organized as a modern Nix flake with a focus on reusability, consistency, and maintainability. The repository follows clear conventions and patterns to make it easy to understand, extend, and contribute to.
## Repository Structure
```
m3ta-nixpkgs/
├── flake.nix # Main entry point, defines all outputs
├── pkgs/ # Custom packages (callPackage registry)
│ ├── default.nix # Package registry (entry point)
│ ├── code2prompt/ # Individual packages
│ ├── hyprpaper-random/
│ ├── mem0/
│ └── ...
├── modules/
│ ├── nixos/ # NixOS modules
│ │ ├── default.nix # Module aggregator
│ │ ├── mem0.nix
│ │ └── ports.nix
│ └── home-manager/ # Home Manager modules
│ ├── default.nix # Module aggregator
│ ├── ports.nix
│ ├── cli/ # Categorized modules
│ │ ├── default.nix
│ │ └── zellij-ps.nix
│ └── coding/
│ ├── default.nix
│ └── editors.nix
├── lib/ # Shared utilities
│ ├── default.nix # Library aggregator
│ └── ports.nix # Port management functions
├── shells/ # Development environments
│ ├── default.nix # Shell registry
│ ├── python.nix
│ └── devops.nix
├── overlays/ # Package modifications
│ ├── default.nix # Overlay aggregator
│ └── mods/
│ └── default.nix # Individual overlays
├── templates/ # Boilerplate for new items
│ ├── package/
│ ├── nixos-module/
│ └── home-manager-module/
├── examples/ # Usage examples
│ ├── nixos-configuration.nix
│ └── home-manager-standalone.nix
└── docs/ # Documentation
```
## Flake Outputs
`flake.nix` is the entry point that defines all outputs:
### Packages
```nix
packages = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./pkgs {inherit pkgs;});
```
- Built for all supported systems
- Uses `callPackage` pattern for lazy evaluation
- Available via `nix build .#<package-name>`
### Overlays
```nix
overlays = {
# Default overlay: adds all custom packages
default = final: prev: import ./pkgs {pkgs = final;};
# Additions overlay: same as default
additions = final: prev: import ./pkgs {pkgs = final;};
# Modifications overlay: modifies existing nixpkgs packages
modifications = final: prev: import ./overlays/mods {inherit prev;};
};
```
- `default`: Adds all custom packages to nixpkgs
- `additions`: Individual package additions
- `modifications`: Overrides existing packages
### NixOS Modules
```nix
nixosModules = {
default = ./modules/nixos; # Import all modules
ports = ./modules/nixos/ports.nix; # Specific module
mem0 = ./modules/nixos/mem0.nix;
};
```
- System-level configuration modules
- Use `m3ta.*` namespace
- Can import all modules or individual ones
### Home Manager Modules
```nix
homeManagerModules = {
default = import ./modules/home-manager;
ports = import ./modules/home-manager/ports.nix;
zellij-ps = import ./modules/home-manager/zellij-ps.nix;
};
```
- User-level configuration modules
- Categorized by function (cli, coding)
- Use `m3ta.*` namespace
### Library Functions
```nix
lib = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./lib {lib = pkgs.lib;});
```
- Helper functions for configuration
- Port management utilities
- Can be used in your configurations
### Development Shells
```nix
devShells = forAllSystems (system: let
pkgs = pkgsFor system;
in
import ./shells {inherit pkgs;});
```
- Pre-configured development environments
- Available: `default`, `python`, `devops`
- Usage: `nix develop .#<shell-name>`
### Templates
```nix
templates = {
package = {
path = ./templates/package;
description = "Template for a new package";
};
nixos-module = {
path = ./templates/nixos-module;
description = "Template for a new NixOS module";
};
home-manager-module = {
path = ./templates/home-manager-module;
description = "Template for a new Home Manager module";
};
};
```
- Boilerplate for quick start
- Usage: `nix flake init -t .#template-name`
## Package Organization
### Registry Pattern
`pkgs/default.nix` acts as a central registry:
```nix
{
inherit (pkgs) callPackage;
} rec {
code2prompt = callPackage ./code2prompt {};
hyprpaper-random = callPackage ./hyprpaper-random {};
mem0 = callPackage ./mem0 {};
# ...
}
```
**Benefits**:
- Lazy evaluation: only builds requested packages
- Consistent interface: all packages use `callPackage`
- Easy discovery: one file lists all packages
### Package Structure
Each package lives in its own directory:
```
pkgs/your-package/
├── default.nix # Package definition
├── source.py # Optional: source files
└── README.md # Optional: package documentation
```
**Conventions**:
- Directory name matches registry attribute
- Use `callPackage` for dependencies
- Always include `meta` with all fields
### Common Package Patterns
#### Rust Packages
```nix
rustPlatform.buildRustPackage rec {
pname = "myapp";
version = "1.0.0";
src = fetchFromGitHub { ... };
cargoLock.lockFile = src + "/Cargo.lock";
# ...
}
```
#### Python Packages
```nix
python3.pkgs.buildPythonPackage rec {
pname = "mypythonapp";
version = "1.0.0";
src = fetchFromGitHub { ... };
dependencies = with python3.pkgs; [requests click];
# ...
}
```
#### Shell Scripts
```nix
writeShellScriptBin "myscript" ''
#!/usr/bin/env bash
echo "Hello World"
''
```
#### AppImage
```nix
appimageTools.wrapType2 rec {
name = "myapp";
src = fetchurl { ... };
# ...
}
```
## Module Organization
### NixOS Modules
Located in `modules/nixos/`:
```
modules/nixos/
├── default.nix # Imports all modules
├── ports.nix # Port management
├── mem0.nx # Individual module
```
**Pattern**:
```nix
{config, lib, pkgs, ...}:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "description";
# ... options
};
config = mkIf cfg.enable {
# ... configuration
};
}
```
### Home Manager Modules
Located in `modules/home-manager/` with categories:
```
modules/home-manager/
├── default.nix # Imports all modules
├── ports.nix # Port management
├── cli/
│ ├── default.nix # Aggregates CLI modules
│ └── zellij-ps.nix
└── coding/
├── default.nix # Aggregates coding modules
└── editors.nix
```
**Categories**:
- `cli/`: Command-line tools and utilities
- `coding/`: Development tools and editors
**Pattern** (same as NixOS):
```nix
{config, lib, pkgs, ...}:
with lib; let
cfg = config.m3ta.coding.editors;
in {
options.m3ta.coding.editors = {
enable = mkEnableOption "editor configuration";
# ... options
};
config = mkIf cfg.enable {
# ... configuration
};
}
```
## Library Functions
Located in `lib/`:
```nix
{lib}: {
# Port management utilities
ports = import ./ports.nix {inherit lib;};
}
```
### Port Management
Centralized port management across hosts:
```nix
# Usage in configuration
portHelpers = inputs.m3ta-nixpkgs.lib.${system}.ports.mkPortHelpers myPorts;
# Get port with host override
services.nginx.port = portHelpers.getPort "nginx" "laptop";
# Get all ports for host
allLaptopPorts = portHelpers.getHostPorts "laptop";
```
**Benefits**:
- Single source of truth for ports
- Host-specific overrides
- Avoid port conflicts
## Naming Conventions
| Context | Convention | Example |
|---------|------------|---------|
| Packages | `lowercase-hyphen` | `hyprpaper-random` |
| Variables | `camelCase` | `portHelpers` |
| Module options | `m3ta.*` | `m3ta.ports.enable` |
| Files | `lowercase-hyphen` | `my-module.nix` |
| Directories | `lowercase-hyphen` | `cli/`, `coding/` |
## Code Patterns
### Module Options
Always use `mkEnableOption` for enable flags:
```nix
options.m3ta.myModule = {
enable = mkEnableOption "description";
};
```
### Conditional Configuration
Use `mkIf` for conditional config:
```nix
config = mkIf cfg.enable {
# Only applied when cfg.enable is true
};
```
### Multiple Conditions
Use `mkMerge` for multiple conditions:
```nix
config = mkMerge [
(mkIf cfg.feature1.enable { ... })
(mkIf cfg.feature2.enable { ... })
];
```
### Imports
Multi-line, trailing commas:
```nix
{
lib,
stdenv,
fetchFromGitHub,
}:
```
### Meta Fields
Always include all fields:
```nix
meta = with lib; {
description = "...";
homepage = "...";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "program-name";
};
```
## Design Decisions
### Flakes-Only
**Decision**: Use flakes exclusively, no channels.
**Rationale**:
- Reproducible builds
- Explicit dependencies
- Better integration with modern Nix tooling
### CallPackage Pattern
**Decision**: Use `callPackage` for all packages.
**Rationale**:
- Lazy evaluation
- Clear dependency graph
- Consistent interface
### Module Categorization
**Decision**: Categorize Home Manager modules by function.
**Rationale**:
- Easier to find related modules
- Logical organization
- Follows user mental model
### Port Management
**Decision**: Centralized port management with host overrides.
**Rationale**:
- Avoid port conflicts
- Easy to manage multiple hosts
- Single source of truth
### Namespace Convention
**Decision**: Use `m3ta.*` namespace for all modules.
**Rationale**:
- Avoid conflicts
- Clear attribution
- Easy to discover
## Supported Systems
- `x86_64-linux` - Primary development target
- `aarch64-linux` - ARM Linux
- `x86_64-darwin` - macOS Intel
- `aarch64-darwin` - macOS Apple Silicon
**Note**: Some packages may be Linux-only (check `meta.platforms`).
-373
View File
@@ -1,373 +0,0 @@
# 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.
**Note**: Package versions are automatically updated weekly via Gitea Actions using `nix-update`. You don't need to worry about keeping versions current - the automation will create PRs for updates. Just focus on ensuring the package builds and works correctly.
### 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
### Handling Automated Update PRs
The repository has automated package updates via Gitea Actions (see main README for details). When reviewing automated update PRs:
1. **Build and test**: Verify the updated package builds successfully
2. **Check changelinks**: Review upstream release notes for breaking changes
3. **Test functionality**: Ensure the package still works as expected
4. **Review package definition**: Check if any manual adjustments are needed
For urgent updates, you can manually trigger the workflow from the Gitea UI or update the package manually.
### PR Description
Include:
- What changed and why
- How to test
- Any breaking changes
- Related issues
## Troubleshooting
### Hash Errors
When building packages, you may encounter hash errors:
```
got: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
expected: sha256-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=
```
**Solution**: Copy the `got` hash and update the package:
```nix
src = fetchFromGitHub {
# ...
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Use actual hash
};
```
### Dependency Not Found
If a package isn't found, check:
1. Package registered in `pkgs/default.nix`
2. Overlay applied in your configuration
3. System matches supported platform
### Linting Errors
```bash
# Fix statix issues manually or use auto-fix where available
statix fix .
# Review deadnix suggestions
deadnix -e .
```
## Getting Help
- Check existing packages and modules for patterns
- Read [Architecture](./ARCHITECTURE.md) for design decisions
- Review [Code Patterns](./reference/patterns.md) for conventions
- Open an issue for questions
## Anti-Patterns
| Don't | Do Instead |
|-------|------------|
| `lib.fakeHash` in commits | Get real hash: `nix build`, copy from error |
| Flat module files | Organize by category (`cli/`, `coding/`) |
| Hardcode ports | Use `m3ta.ports` module |
| Skip meta fields | Include all: description, homepage, license, platforms, mainProgram |
| `with pkgs;` in modules | Explicit `pkgs.package` or `with pkgs; [ ... ]` in lists only |
| Suppress type errors | Fix underlying type issues |
| Delete tests to "pass" | Fix failing tests |
## Code Review Checklist
- [ ] Follows naming conventions
- [ ] Properly formatted (`nix fmt`)
- [ ] Passes linting (`statix`, `deadnix`)
- [ ] Has complete `meta` fields (packages)
- [ ] Documentation updated if needed
- [ ] No dead code
- [ ] No obvious bugs or issues
- [ ] Appropriate for scope
## Release Process
This is a personal repository, but semantic versioning is followed for tags:
1. Update versions as needed
2. Update changelog
3. Tag release
4. Push tags
```bash
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
```
-316
View File
@@ -1,316 +0,0 @@
# 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
-153
View File
@@ -1,153 +0,0 @@
# 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:
- [beads](./packages/beads.md) - Lightweight memory system for AI coding agents with graph-based issue tracking
- [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
- [n8n](./packages/n8n.md) - Free and source-available fair-code licensed workflow automation tool
- [opencode](./packages/opencode.md) - AI coding agent built for terminal
- [pomodoro-timer](./packages/pomodoro-timer.md) - Pomodoro timer utility
- [rofi-project-opener](./packages/rofi-project-opener.md) - Rofi-based project launcher with custom args
- [stt-ptt](./packages/stt-ptt.md) - Push to Talk Speech to Text using Whisper
- [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
- [rofi-project-opener](./modules/home-manager/cli/rofi-project-opener.md) - Rofi-based project launcher
- [stt-ptt](./modules/home-manager/cli/stt-ptt.md) - Push to Talk Speech to Text
- [zellij-ps](./modules/home-manager/cli/zellij-ps.md) - Zellij project switcher
- [Coding](./modules/home-manager/coding/) - Development-related modules
- [editors](./modules/home-manager/coding/editors.md) - Editor configurations
### 📖 Reference
Technical references and APIs:
- [Functions](./reference/functions.md) - Library functions documentation
- [Patterns](./reference/patterns.md) - Code patterns and anti-patterns
## Repository Structure
```
m3ta-nixpkgs/
├── docs/ # This directory
│ ├── README.md
│ ├── QUICKSTART.md
│ ├── ARCHITECTURE.md
│ ├── CONTRIBUTING.md
│ ├── guides/
│ ├── packages/
│ ├── modules/
│ └── reference/
├── pkgs/ # Custom packages
├── modules/
│ ├── nixos/ # NixOS modules
│ └── home-manager/ # Home Manager modules
├── lib/ # Library functions
├── shells/ # Development shells
├── overlays/ # Package overlays
├── templates/ # Templates
└── examples/ # Usage examples
```
## Key Concepts
### Flakes-Only Approach
This repository uses modern Nix flakes exclusively. No channels or `nix-channel` commands are needed. All dependencies are declaratively specified in `flake.nix`.
### Namespace Convention
All modules use the `m3ta.*` namespace:
- `m3ta.ports.*` - Port management
- `m3ta.mem0.*` - Mem0 service configuration
- `m3ta.*.enable` - Enable/disable modules
### Port Management
Centralized port management across hosts using the `m3ta.ports` module:
```nix
m3ta.ports = {
enable = true;
definitions = { mem0 = 8000; };
hostOverrides.laptop = { mem0 = 8080; };
currentHost = "laptop";
};
```
## Supported Systems
- `x86_64-linux` - Primary
- `aarch64-linux` - ARM Linux
- `x86_64-darwin` - macOS (Intel)
- `aarch64-darwin` - macOS (Apple Silicon)
## Quick Commands
```bash
# Validate flake
nix flake check
# Format code
nix fmt
# Build package
nix build .#<package-name>
# List outputs
nix flake show
# Enter dev shell
nix develop
```
## License
Individual packages may have their own licenses. Check each package's `meta.license` attribute.
## Maintainer
[@m3tam3re](https://m3ta.dev)
-504
View File
@@ -1,504 +0,0 @@
# 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.
### Automatic Updates
**Important**: This repository uses automated package updates via Gitea Actions and `nix-update`. When adding a new package:
- Use any stable, working version for the initial package
- You don't need to use the absolute latest version
- The automation will keep the package updated automatically on a weekly basis
- Review and merge automated update PRs as they come in
See the main README.md for more details on the automated update workflow.
### 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
-527
View File
@@ -1,527 +0,0 @@
# 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
-402
View File
@@ -1,402 +0,0 @@
# 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
];
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
-525
View File
@@ -1,525 +0,0 @@
# 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
-605
View File
@@ -1,605 +0,0 @@
# 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)
#### `cli.zellij-ps`
Zellij project switcher for quickly navigating between project folders.
```nix
cli.zellij-ps = {
enable = true;
package = pkgs.zellij-ps;
};
```
**Documentation**: [zellij-ps Module](../modules/home-manager/cli/zellij-ps.md)
#### `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
cli.zellij-ps = {
enable = true;
};
# Coding tools
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
@@ -1,219 +0,0 @@
# rofi-project-opener Module
Home Manager module for configuring the rofi-project-opener package.
## Overview
This module provides declarative configuration for rofi-project-opener, a Rofi-based project launcher. It generates the necessary configuration files and installs the package.
## Quick Start
```nix
{config, pkgs, ...}: {
cli.rofi-project-opener = {
enable = true;
projectDirs = {
dev = { path = "~/dev"; };
work = { path = "~/work"; args = "--agent work-assistant"; };
};
};
}
```
## Options
### `cli.rofi-project-opener.enable`
Whether to enable rofi-project-opener.
**Type:** `boolean`
**Default:** `false`
### `cli.rofi-project-opener.projectDirs`
Attribute set of base directories to scan for project subdirectories.
**Type:** `attrsOf (submodule)`
Each entry is a submodule with:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `path` | `str` | required | Base directory path (supports `~`) |
| `args` | `str` | `""` | Arguments to pass to command |
**Default:**
```nix
{
dev = { path = "~/dev"; };
projects = { path = "~/projects"; };
}
```
**Example:**
```nix
projectDirs = {
nixpkgs = { path = "~/p/NIX"; args = "--agent nix-expert"; };
chat = { path = "~/p/CHAT"; args = "--agent chiron"; };
dev = { path = "~/dev"; };
work = { path = "~/work"; args = "--profile work"; };
};
```
### `cli.rofi-project-opener.terminal`
Terminal emulator to use for launching projects.
**Type:** `either str package`
**Default:** `"kitty"`
**Examples:**
```nix
# Using a package
terminal = pkgs.kitty;
terminal = pkgs.alacritty;
# Using a string (must be in PATH)
terminal = "kitty";
terminal = "wezterm";
```
### `cli.rofi-project-opener.terminalCommand`
Command to run in the terminal after navigating to the project directory.
**Type:** `str`
**Default:** `""` (runs `opencode` with args)
**Placeholders:**
- `%s` - Project path
- `%a` - Project args (from `projectDirs.<name>.args`)
**Examples:**
```nix
# Default behavior - run opencode with project args
terminalCommand = "";
# Explicit opencode with args
terminalCommand = "opencode %a";
# Different editor
terminalCommand = "nvim";
# VSCode with path
terminalCommand = "code %s";
# Custom application
terminalCommand = "my-dev-tool --project %s %a";
```
### `cli.rofi-project-opener.rofiPrompt`
Prompt text displayed in the Rofi menu.
**Type:** `str`
**Default:** `"Select project"`
### `cli.rofi-project-opener.rofiArgs`
Arguments to pass to Rofi.
**Type:** `listOf str`
**Default:** `["-dmenu" "-i"]`
**Example:**
```nix
rofiArgs = ["-dmenu" "-i" "-theme" "gruvbox" "-width" "50"];
```
## Generated Files
The module generates these configuration files:
### `~/.config/rofi-project-opener/projects.json`
JSON file containing project directories:
```json
{
"dev": {"path": "~/dev", "args": ""},
"work": {"path": "~/work", "args": "--agent work-assistant"}
}
```
### `~/.config/rofi-project-opener/config`
Shell configuration file:
```bash
TERMINAL="/nix/store/.../bin/kitty"
TERMINAL_CMD="opencode %a"
ROFI_PROMPT="Select project"
ROFI_ARGS="-dmenu -i"
```
## Full Example
```nix
{config, pkgs, ...}: {
imports = [m3ta-nixpkgs.homeManagerModules.default];
cli.rofi-project-opener = {
enable = true;
# Project directories with optional args
projectDirs = {
nixpkgs = {
path = "~/p/NIX";
args = "";
};
chat = {
path = "~/p/CHAT";
args = "--agent chiron";
};
dev = {
path = "~/dev";
args = "";
};
};
# Terminal configuration
terminal = pkgs.kitty;
terminalCommand = "opencode %a";
# Rofi configuration
rofiPrompt = "Open Project";
rofiArgs = ["-dmenu" "-i" "-theme" "nord"];
};
}
```
## Usage
After enabling, run:
```bash
rofi-project-opener
```
Or bind to a keyboard shortcut in your window manager:
**Hyprland:**
```nix
wayland.windowManager.hyprland.settings.bind = [
"$mod, P, exec, rofi-project-opener"
];
```
**Sway:**
```nix
wayland.windowManager.sway.config.keybindings = {
"${modifier}+p" = "exec rofi-project-opener";
};
```
## Related
- [rofi-project-opener Package](../../../packages/rofi-project-opener.md) - Package documentation
- [zellij-ps Module](./zellij-ps.md) - Similar project switcher for Zellij
- [Home Manager Overview](../overview.md) - All Home Manager modules
-312
View File
@@ -1,312 +0,0 @@
# stt-ptt Home Manager Module
Push to Talk Speech to Text for Home Manager.
## Overview
This module configures stt-ptt, a push-to-talk speech-to-text tool using whisper.cpp. It handles model downloads, environment configuration, and package installation.
## Quick Start
```nix
{config, ...}: {
imports = [m3ta-nixpkgs.homeManagerModules.default];
cli.stt-ptt = {
enable = true;
};
}
```
This will:
- Install stt-ptt with default whisper-cpp
- Download the `ggml-large-v3-turbo` model on first activation
- Set environment variables for model path and notification timeout
## Module Options
### `cli.stt-ptt.enable`
Enable the stt-ptt module.
- Type: `boolean`
- Default: `false`
### `cli.stt-ptt.whisperPackage`
The whisper-cpp package to use for transcription.
- Type: `package`
- Default: `pkgs.whisper-cpp`
**Pre-built variants:**
```nix
# CPU (default)
whisperPackage = pkgs.whisper-cpp;
# Vulkan GPU acceleration (pre-built)
whisperPackage = pkgs.whisper-cpp-vulkan;
```
**Override options** (can be combined):
| Option | Description |
|--------|-------------|
| `cudaSupport` | NVIDIA CUDA acceleration |
| `rocmSupport` | AMD ROCm acceleration |
| `vulkanSupport` | Vulkan GPU acceleration |
| `coreMLSupport` | Apple CoreML (macOS only) |
| `metalSupport` | Apple Metal (macOS ARM only) |
```nix
# NVIDIA CUDA support
whisperPackage = pkgs.whisper-cpp.override { cudaSupport = true; };
# AMD ROCm support
whisperPackage = pkgs.whisper-cpp.override { rocmSupport = true; };
# Vulkan support (manual override)
whisperPackage = pkgs.whisper-cpp.override { vulkanSupport = true; };
```
### `cli.stt-ptt.model`
The Whisper model to use. Models are automatically downloaded from HuggingFace on first activation.
- Type: `string`
- Default: `"ggml-large-v3-turbo"`
Available models (sorted by size):
| Model | Size | Notes |
|-------|------|-------|
| `ggml-tiny` | 75MB | Fastest, lowest quality |
| `ggml-tiny.en` | 75MB | English-only, slightly faster |
| `ggml-base` | 142MB | Fast, basic quality |
| `ggml-base.en` | 142MB | English-only |
| `ggml-small` | 466MB | Balanced speed/quality |
| `ggml-small.en` | 466MB | English-only |
| `ggml-medium` | 1.5GB | Good quality |
| `ggml-medium.en` | 1.5GB | English-only |
| `ggml-large-v1` | 2.9GB | High quality (original) |
| `ggml-large-v2` | 2.9GB | High quality (improved) |
| `ggml-large-v3` | 2.9GB | Highest quality |
| `ggml-large-v3-turbo` | 1.6GB | High quality, optimized speed (recommended) |
Quantized versions (`q5_0`, `q5_1`, `q8_0`) are also available for reduced size.
### `cli.stt-ptt.notifyTimeout`
Notification timeout in milliseconds for the recording indicator.
- Type: `integer`
- Default: `3000`
- Example: `5000` (5 seconds), `0` (persistent)
### `cli.stt-ptt.language`
Language for speech recognition. Use "auto" for automatic language detection, or specify a language code for better accuracy.
- Type: `enum ["auto", "en", "es", "fr", "de", "it", "pt", "ru", "zh", "ja", "ko", "ar", "hi", "tr", "pl", "nl", "sv", "da", "fi", "no", "vi", "th", "id", "uk", "cs"]`
- Default: `"auto"`
**Auto-detection**: When set to "auto", whisper.cpp analyzes the audio to determine the spoken language automatically.
**Language specification**: Specifying a language code improves transcription accuracy if you know the language in advance.
```nix
# Automatic language detection (default)
language = "auto";
# Force English transcription
language = "en";
# Spanish transcription
language = "es";
```
**Common language codes:**
| Code | Language |
|------|----------|
| `en` | English |
| `es` | Spanish |
| `fr` | French |
| `de` | German |
| `zh` | Chinese |
| `ja` | Japanese |
| `ko` | Korean |
whisper.cpp supports 100+ languages. See whisper.cpp documentation for the full list.
## Usage
After enabling, bind `stt-ptt start` and `stt-ptt stop` to a key:
```bash
# Start recording
stt-ptt start
# Stop recording and transcribe (types result)
stt-ptt stop
```
### Keybinding Examples
#### Hyprland
```nix
wayland.windowManager.hyprland.settings = {
bind = [
"SUPER, V, exec, stt-ptt start"
];
bindr = [
"SUPER, V, exec, stt-ptt stop"
];
};
```
Or in `hyprland.conf`:
```conf
# Press to start recording, release to transcribe
bind = SUPER, V, exec, stt-ptt start
bindr = SUPER, V, exec, stt-ptt stop
```
#### Sway
```conf
bindsym --no-repeat $mod+v exec stt-ptt start
bindsym --release $mod+v exec stt-ptt stop
```
## Configuration Examples
### Basic Setup
```nix
cli.stt-ptt = {
enable = true;
};
```
### Fast English Transcription
```nix
cli.stt-ptt = {
enable = true;
model = "ggml-base.en";
notifyTimeout = 2000;
};
```
### Language-Specific Transcription
```nix
cli.stt-ptt = {
enable = true;
model = "ggml-large-v3-turbo";
language = "es"; # Force Spanish transcription
};
```
### High Quality with NVIDIA GPU
```nix
cli.stt-ptt = {
enable = true;
model = "ggml-large-v3";
whisperPackage = pkgs.whisper-cpp.override { cudaSupport = true; };
};
```
### Vulkan GPU Acceleration
```nix
cli.stt-ptt = {
enable = true;
model = "ggml-large-v3-turbo";
whisperPackage = pkgs.whisper-cpp-vulkan;
};
```
### AMD GPU with ROCm
```nix
cli.stt-ptt = {
enable = true;
model = "ggml-large-v3-turbo";
whisperPackage = pkgs.whisper-cpp.override { rocmSupport = true; };
};
```
### Balanced Setup
```nix
cli.stt-ptt = {
enable = true;
model = "ggml-small";
notifyTimeout = 3000;
};
```
## File Locations
| Path | Description |
|------|-------------|
| `~/.local/share/stt-ptt/models/` | Downloaded Whisper models |
| `~/.cache/stt-ptt/stt.wav` | Temporary audio recording |
| `~/.cache/stt-ptt/stt.pid` | PID file for recording process |
## Environment Variables
The module sets these automatically:
| Variable | Value |
|----------|-------|
| `STT_MODEL` | `~/.local/share/stt-ptt/models/<model>.bin` |
| `STT_LANGUAGE` | Configured language ("auto" by default) |
| `STT_NOTIFY_TIMEOUT` | Configured timeout in ms |
## Requirements
- Wayland compositor (wtype is Wayland-only)
- PipeWire for audio recording
- Desktop notification daemon
## Troubleshooting
### Model Download Failed
The model downloads on first `home-manager switch`. If it fails:
```bash
# Manual download
mkdir -p ~/.local/share/stt-ptt/models
curl -L -o ~/.local/share/stt-ptt/models/ggml-large-v3-turbo.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin
```
### Transcription Too Slow
Use a smaller model or enable GPU acceleration:
```nix
cli.stt-ptt = {
enable = true;
model = "ggml-tiny.en"; # Much faster
};
```
### Text Not Appearing
1. Ensure you're on Wayland: `echo $XDG_SESSION_TYPE`
2. Check if wtype works: `wtype "test"`
3. Some apps may need focus; try clicking the text field first
## Related
- [stt-ptt Package](../../../packages/stt-ptt.md) - Package documentation
- [Using Modules Guide](../../../guides/using-modules.md) - Module usage patterns
@@ -1,81 +0,0 @@
# 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];
cli.zellij-ps = {
enable = true;
};
}
```
## Module Options
### `cli.zellij-ps.enable`
Enable zellij-ps module.
- Type: `boolean`
- Default: `false`
### `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
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
-317
View File
@@ -1,317 +0,0 @@
# 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
-206
View File
@@ -1,206 +0,0 @@
# 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
cli.zellij-ps = {
enable = true;
};
# Coding tools
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";
};
cli.zellij-ps = {
enable = true;
};
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
-272
View File
@@ -1,272 +0,0 @@
# ports Home Manager Module
Port management module for Home Manager.
## Overview
This module provides centralized port management for user-level services, similar to the NixOS version but with additional support for generating environment variables.
See [Port Management Guide](../../guides/port-management.md) for detailed usage.
## Quick Start
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
# Define default ports
definitions = {
dev-server = 3000;
nextjs = 3001;
vite = 5173;
};
# Host-specific overrides
hostOverrides = {
laptop = {
vite = 5174;
};
};
# Current host
currentHost = "desktop";
# Generate environment variables (Home Manager only)
generateEnvVars = true;
};
}
```
## Module Options
### `m3ta.ports.enable`
Enable port management.
- Type: `boolean`
- Default: `false`
### `m3ta.ports.definitions`
Default port definitions.
- Type: `attrsOf int`
- Default: `{}`
Example:
```nix
definitions = {
dev-server = 3000;
nextjs = 3001;
vite = 5173;
};
```
### `m3ta.ports.hostOverrides`
Host-specific port overrides.
- Type: `attrsOf (attrsOf int)`
- Default: `{}`
Example:
```nix
hostOverrides = {
laptop = {
vite = 5174;
};
desktop = {
vite = 5173;
};
};
```
### `m3ta.ports.currentHost`
Current hostname.
- Type: `string`
- Example: `"desktop"`
### `m3ta.ports.generateEnvVars`
Generate environment variables from ports.
- Type: `boolean`
- Default: `false`
- Home Manager only
When enabled, generates environment variables like:
```bash
PORT_DEV_SERVER=3000
PORT_NEXTJS=3001
PORT_VITE=5173
```
## Functions
### `config.m3ta.ports.get "service"`
Get port for a service with host-specific override.
```nix
home.sessionVariables = {
DEV_PORT = toString (config.m3ta.ports.get "dev-server");
};
```
### `config.m3ta.ports.getHostPorts "hostname"`
Get all ports for a specific host.
```nix
laptopPorts = config.m3ta.ports.getHostPorts "laptop";
# Returns: { dev-server = 3000; vite = 5174; ... }
```
### `config.m3ta.ports.listServices`
List all defined service names.
```nix
allServices = config.m3ta.ports.listServices;
# Returns: ["dev-server" "nextjs" "vite"]
```
## Environment Variables
When `generateEnvVars = true`, the following environment variables are generated:
```
PORT_<SERVICE_UPPERCASE>=<port_number>
```
Example:
```nix
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
nextjs = 3001;
};
generateEnvVars = true;
};
```
Generates:
```bash
PORT_DEV_SERVER=3000
PORT_NEXTJS=3001
```
You can then use these in scripts:
```bash
#!/usr/bin/env bash
# Use environment variable directly
npm start --port=$PORT_DEV_SERVER
```
## Usage Examples
### Basic Usage
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
};
currentHost = "desktop";
};
home.sessionVariables = {
DEV_PORT = toString (config.m3ta.ports.get "dev-server");
};
}
```
### With Environment Variables
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
nextjs = 3001;
vite = 5173;
};
currentHost = "desktop";
generateEnvVars = true;
};
# Now available as environment variables
# PORT_DEV_SERVER=3000
# PORT_NEXTJS=3001
# PORT_VITE=5173
}
```
### With Multi-Host Setup
```nix
{config, ...}: {
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
vite = 5173;
};
hostOverrides = {
laptop = {
vite = 5174;
};
desktop = {
vite = 5173;
};
};
currentHost = config.networking.hostName;
generateEnvVars = true;
};
}
```
### With Shell Scripts
Create `~/.config/zellij/scripts/dev.ksh`:
```ksh
#!/usr/bin/env ksh
# Start dev server using environment variable
cd ~/projects/my-app
npm start --port=$PORT_DEV_SERVER
```
## Difference from NixOS Module
The Home Manager version has one additional feature:
### `generateEnvVars`
Not available in NixOS module. Generates environment variables for all defined ports:
```nix
# Home Manager
m3ta.ports.generateEnvVars = true; # Available
# NixOS
# Not available
```
## Related
- [Port Management Guide](../../guides/port-management.md) - Detailed guide
- [NixOS Ports Module](../nixos/ports.md) - System-level port management
-508
View File
@@ -1,508 +0,0 @@
# 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
-166
View File
@@ -1,166 +0,0 @@
# NixOS Modules Overview
Overview of available NixOS modules in m3ta-nixpkgs.
## Available Modules
- [ports](./ports.md) - Port management across hosts
- [mem0](./mem0.md) - Mem0 REST API server
## Importing Modules
### Import All Modules
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
];
}
```
### Import Specific Module
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.ports
m3ta-nixpkgs.nixosModules.mem0
];
}
```
## Module Namespace
All NixOS modules use the `m3ta.*` namespace:
```nix
# Port management
m3ta.ports = {
enable = true;
definitions = {nginx = 80;};
};
# Mem0 service
m3ta.mem0 = {
enable = true;
port = 8000;
};
```
## Common Patterns
### Enable Module
All modules follow the pattern:
```nix
m3ta.moduleName = {
enable = true;
# ... options
};
```
### Configuration
Modules typically provide these sections:
- `enable` - Enable/disable module
- `package` - Custom package (optional)
- Configuration options specific to module
## Integration Examples
### With Port Management
```nix
{config, ...}: {
imports = [
m3ta-nixpkgs.nixosModules.default
];
m3ta.ports = {
enable = true;
definitions = {
nginx = 80;
grafana = 3000;
mem0 = 8000;
};
currentHost = config.networking.hostName;
};
m3ta.mem0 = {
enable = true;
port = config.m3ta.ports.get "mem0";
};
services.nginx = {
enable = true;
httpConfig = ''
server {
listen ${toString (config.m3ta.ports.get "nginx")};
root /var/www;
}
'';
};
}
```
### With Home Manager
```nix
{config, ...}: {
# NixOS modules
imports = [
m3ta-nixpkgs.nixosModules.default
];
# Home Manager integration
home-manager.users.myusername = {
imports = [
m3ta-nixpkgs.homeManagerModules.default
];
m3ta.ports = {
enable = true;
definitions = {
dev-server = 3000;
};
currentHost = config.networking.hostName;
};
};
}
```
## Module Locations
- `modules/nixos/ports.nix` - Port management module
- `modules/nixos/mem0.nix` - Mem0 REST API server module
## Adding New Modules
1. Create module file: `modules/nixos/my-module.nix`
2. Follow standard pattern:
```nix
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "my module";
};
config = mkIf cfg.enable {
# Configuration
};
}
```
3. Import in `modules/nixos/default.nix`
## Related
- [Port Management Guide](../guides/port-management.md) - Detailed port management usage
- [Using Modules Guide](../guides/using-modules.md) - How to use modules
- [Home Manager Modules](./home-manager/overview.md) - User-level modules
-229
View File
@@ -1,229 +0,0 @@
# 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
-220
View File
@@ -1,220 +0,0 @@
# beads
Lightweight memory system for AI coding agents with graph-based issue tracking.
## Description
beads is a command-line tool designed to provide persistent memory and issue tracking for AI coding agents. It features a graph-based system for managing issues, dependencies, and discovered work across development sessions.
## Features
- 🧠 **Persistent Memory**: Store and retrieve context across AI sessions
- 📊 **Graph-Based Issue Tracking**: Manage issues with dependency relationships
- 🔄 **Discovered Work**: Track work discovered during development
- 🎯 **Multi-Session Continuity**: Resume work from previous sessions
- 📝 **Git Integration**: Seamless integration with git workflows
- 🐚 **Shell Completions**: Bash, Fish, and Zsh completions included
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
beads
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.beads
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#beads
```
## Usage
### Basic Commands
```bash
# Show available issues ready to work on
bd ready
# Create a new issue
bd create "Fix authentication bug" --type bug --priority 2
# Show issue details
bd show beads-123
# Update issue status
bd update beads-123 --status in_progress
# Close completed issues
bd close beads-123
# Sync with git remote
bd sync
```
### Issue Types
- `task`: General tasks
- `bug`: Bug fixes
- `feature`: New features
- `epic`: Large-scale initiatives
### Priority Levels
- `0` (P0): Critical
- `1` (P1): High
- `2` (P2): Medium
- `3` (P3): Low
- `4` (P4): Backlog
### Dependency Management
```bash
# Add dependency (beads-123 depends on beads-456)
bd dep add beads-123 beads-456
# Show blocked issues
bd blocked
# Show what blocks an issue
bd show beads-123 --blocked-by
```
## Advanced Usage
### Finding Work
```bash
# Show ready tasks (no blockers)
bd ready
# Show all open issues
bd list --status open
# Show in-progress work
bd list --status in_progress
```
### Assignment
```bash
# Assign issue to yourself
bd update beads-123 --assignee username
# Create assigned issue
bd create "Review PR" --assignee reviewer
```
### Bulk Operations
```bash
# Close multiple issues at once
bd close beads-123 beads-456 beads-789
# Close with reason
bd close beads-123 --reason "Completed in v1.2.0"
```
### Hooks
```bash
# Install git hooks for automatic sync
bd hooks install
# Remove hooks
bd hooks uninstall
```
## Configuration
### Environment Variables
- `BEADS_DATA_DIR`: Custom directory for beads data (default: `.beads/`)
- `BEADS_CONFIG`: Custom configuration file path
- `BEADS_EDITOR`: Default editor for editing issues
### Git Integration
beads integrates with git for version-controlled issue tracking:
- Automatic sync before commits (via hooks)
- Issue references in commit messages
- Branch name tracking
- Git-aware issue states
## Workflow Integration
### Typical Development Workflow
1. **Start session**: `bd prime` or check `bd ready`
2. **Claim work**: `bd update beads-123 --status in_progress`
3. **Work on task**: Implement changes
4. **Discover new work**: `bd create "Discovered subtask"` as needed
5. **Complete task**: `bd close beads-123`
6. **Sync**: `bd sync` (automatic via hooks)
### Team Collaboration
```bash
# Create issue and assign
bd create "Implement feature X" --assignee dev1
# Review assigned work
bd list --assignee yourname
# Close with review notes
bd close beads-123 --reason "Reviewed and approved"
```
## Shell Completions
beads provides shell completions for bash, fish, and zsh:
```bash
# Bash completions are auto-loaded
source <(bd completion bash)
# Fish completions
bd completion fish | source
# Zsh completions
bd completion zsh > ~/.zfunc/_bd
```
## Build Information
- **Version**: 0.47.1
- **Language**: Go
- **License**: MIT
- **Source**: [GitHub](https://github.com/steveyegge/beads)
## Platform Support
- Linux
- macOS
## Notes
- Tests are disabled in the Nix package due to git worktree operations that fail in the sandbox
- Security tests on Darwin are skipped due to `/etc/passwd` unavailability in sandbox
- Shell completions are installed for platforms that can execute the build target
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide
-206
View File
@@ -1,206 +0,0 @@
# 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
-190
View File
@@ -1,190 +0,0 @@
# 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
-180
View File
@@ -1,180 +0,0 @@
# launch-webapp
Launches a web app using your default browser in app mode.
## Description
launch-webapp is a shell script that launches web applications (like Discord, Spotify Web, etc.) in your default browser's "app mode". This provides a more native-like experience for web apps.
## Features
- 🌐 **Auto-Detection**: Detects your default web browser
- 🚀 **App Mode**: Launches in dedicated app window (no address bar)
- 🎨 **Native Feel**: Removes browser chrome for app-like experience
- 🔄 **Session Management**: Keeps web apps separate from regular browsing
- 🖥️ **Wayland Support**: Works with Wayland session managers (via `uwsm`)
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
launch-webapp
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.launch-webapp
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#launch-webapp
```
## Usage
### Basic Usage
```bash
# Launch web app
launch-webapp https://web.telegram.org
# Launch with additional arguments
launch-webapp https://web.whatsapp.com --app-name="WhatsApp"
```
### Examples
#### Launch Discord Web
```bash
launch-webapp https://discord.com/app
```
#### Launch Spotify Web
```bash
launch-webapp https://open.spotify.com
```
#### Launch Google Chat
```bash
launch-webapp https://chat.google.com
```
## Configuration
### Supported Browsers
The script auto-detects and supports:
- Google Chrome
- Brave Browser
- Microsoft Edge
- Opera
- Vivaldi
- Chromium (fallback)
### Default Browser
The script uses `xdg-settings` to detect your default browser.
```bash
# Check your default browser
xdg-settings get default-web-browser
```
### Wayland Support
The script uses `uwsm` (Wayland Session Manager) for proper Wayland support. Ensure `uwsm` is installed and configured.
## Desktop Integration
### Create Desktop Entry
Create `~/.local/share/applications/webapp-discord.desktop`:
```ini
[Desktop Entry]
Name=Discord Web
Comment=Discord Web App
Exec=launch-webapp https://discord.com/app
Icon=discord
Type=Application
Categories=Network;InstantMessaging;
```
### Add to Menu
The desktop entry will appear in your application menu after creating it.
## Requirements
- `xdg-utils`: For default browser detection
- `uwsm`: Wayland session manager
- Your preferred browser (Chrome, Brave, etc.)
## Platform Support
- Linux (primary, requires Wayland)
- macOS (not tested)
- Windows (not supported)
## Build Information
- **Version**: 0.1.0
- **Type**: Shell script
- **License**: MIT
## Troubleshooting
### Browser Not Found
If the script doesn't find your browser, ensure it's installed:
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
google-chrome
# or brave-browser, microsoft-edge, etc.
];
}
```
### Wayland Issues
If you encounter Wayland issues:
```bash
# Check uwsm is installed
which uwsm
# Check Wayland session
echo $XDG_SESSION_TYPE # Should be "wayland"
```
### App Won't Launch
Check the browser supports app mode:
```bash
# Test manually
google-chrome --app=https://example.com
```
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide
-268
View File
@@ -1,268 +0,0 @@
# 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
-172
View File
@@ -1,172 +0,0 @@
# msty-studio
Msty Studio enables advanced, privacypreserving AI workflows entirely on your local machine.
## Description
Msty Studio is a desktop application that provides a powerful AI development environment with a focus on privacy. All AI processing happens locally on your machine, ensuring your data never leaves your system.
## Features
- 🔒 **Privacy-First**: All AI processing happens locally
- 🤖 **Local AI Models**: Support for running local LLMs
- 📝 **Code Editor**: Integrated development environment
- 🔄 **Multiple Models**: Switch between different AI models
- 📊 **Model Management**: Download and manage local models
- 🎨 **Modern UI**: Clean, intuitive interface
-**Fast Performance**: Optimized for speed
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
msty-studio
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.msty-studio
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#msty-studio
```
## Usage
### Launch Application
```bash
# Launch Msty Studio
msty-studio
# Or from application menu
# Applications -> Msty Studio
```
### First Run
On first launch, you'll need to:
1. Download an AI model (if not already downloaded)
2. Configure model settings
3. Set up your workspace
### Managing Models
Through the Msty Studio interface, you can:
- Download new models
- Remove unused models
- Switch between models
- Configure model parameters
## Configuration
### Model Directory
Models are stored in your home directory:
```
~/.local/share/msty-studio/models/
```
### Settings
Msty Studio stores settings in:
```
~/.config/msty-studio/
```
### Integration with Nix
The package includes required dependencies:
- Node.js (for runtime)
- npm (for package management)
- uv (for Python packages)
- Python (for AI models)
## Requirements
### System Requirements
- Linux (x86_64)
- 8GB RAM minimum (16GB+ recommended)
- Modern CPU with AVX2 support
- GPU recommended (for faster inference)
### Dependencies
The package includes these dependencies:
- `nodejs` - JavaScript runtime
- `nodePackages.npm` - Package manager
- `uv` - Python package installer
- `python3` - Python runtime
## Platform Support
- Linux (x86_64 only)
- macOS (not supported)
- Windows (not supported)
**Note**: Msty Studio is distributed as an AppImage for Linux.
## Build Information
- **Version**: 2.0.0-beta.4
- **Type**: AppImage
- **License**: Proprietary (Unfree)
- **Source**: [msty.studio](https://msty.studio)
## Troubleshooting
### AppImage Won't Launch
Ensure executable bit is set:
```bash
chmod +x ~/.local/share/applications/msty-studio.desktop
```
### Models Not Downloading
Check disk space and network:
```bash
# Check disk space
df -h
# Check network
ping google.com
```
### Performance Issues
- Ensure you're using a GPU-accelerated model
- Close other resource-intensive applications
- Check system resources:
```bash
htop
nvidia-smi # If using NVIDIA GPU
```
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide
-310
View File
@@ -1,310 +0,0 @@
# n8n
Free and source-available fair-code licensed workflow automation tool. Easily automate tasks across different services.
## Description
n8n (pronounced "n-eight-n") is a workflow automation tool that helps you connect different services and automate tasks without writing code. It features a visual node-based editor for creating workflows with hundreds of integrations.
## Features
- 🎨 **Visual Workflow Editor**: Drag-and-drop interface for creating workflows
- 🔗 **Hundreds of Integrations**: Connect to popular services (Slack, GitHub, Google, etc.)
- 🔄 **Webhook Support**: Trigger workflows via HTTP requests
- 📝 **Code Node**: Execute JavaScript/TypeScript code within workflows
- 🚀 **Cloud & Self-Hosted**: Use n8n Cloud or self-host on your own infrastructure
- 📊 **Data Transformation**: Map and transform data between services
-**Scheduling**: Run workflows on schedules (cron-like)
- 🔒 **Security**: Credential management and secure data handling
- 🎯 **Fair-Code License**: Source available with usage restrictions for commercial use
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
n8n
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.n8n
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#n8n
```
## Usage
### Basic Usage
```bash
# Start n8n (default configuration)
n8n start
# Start with custom configuration file
n8n start --config /path/to/config
# Run in worker mode (for production with queue)
n8n worker
# Execute a workflow from file
n8n execute /path/to/workflow.json
```
### Development Mode
```bash
# Start with tunnel (external access)
n8n start --tunnel
# Disable telemetry
n8n start --no-telemetry
# Specify workflow directory
n8n start --workflows /path/to/workflows
# Enable/disable features
n8n start --enable-editor
n8n start --disable-metrics
```
### Workflow Management
```bash
# Export workflow to file
n8n export:workflow --id=123 --output=workflow.json
# Import workflow from file
n8n import:workflow --input=workflow.json
# Execute workflow
n8n execute:workflow --id=123
```
## Configuration
### Environment Variables
- `N8N_BASIC_AUTH_ACTIVE`: Enable basic authentication (default: false)
- `N8N_BASIC_AUTH_USER`: Basic auth username
- `N8N_BASIC_AUTH_PASSWORD`: Basic auth password
- `N8N_ENCRYPTION_KEY`: Encryption key for credentials
- `N8N_HOST`: Host URL for web UI (default: localhost)
- `N8N_PORT`: Port for web UI (default: 5678)
- `N8N_PROTOCOL`: Protocol (http or https)
- `N8N_PATH`: Path to mount n8n (default: /)
- `N8N_EDITOR_BASE_URL`: Base URL for editor
- `N8N_WEBHOOK_URL`: URL for webhook endpoints
- `N8N_TIMEZONE`: Timezone for execution (default: UTC)
- `N8N_LOG_LEVEL`: Logging level (output, warn, error, verbose)
- `N8N_LOG_OUTPUT`: Log output destination (console, file)
- `N8N_METRICS`: Enable metrics collection (default: true)
- `DB_TYPE`: Database type (sqlite3db, postgresdb, mysqldb)
- `DB_SQLITE_VACUUM_ON_STARTUP`: Vacuum SQLite on startup
### Database Configuration
By default, n8n uses SQLite for simplicity. For production, use PostgreSQL or MySQL:
```bash
# PostgreSQL
export DB_TYPE=postgresdb
export DB_POSTGRESDB_HOST=localhost
export DB_POSTGRESDB_PORT=5432
export DB_POSTGRESDB_DATABASE=n8n
export DB_POSTGRESDB_USER=n8n
export DB_POSTGRESDB_PASSWORD=yourpassword
# MySQL/MariaDB
export DB_TYPE=mysqldb
export DB_MYSQLDB_HOST=localhost
export DB_MYSQLDB_PORT=3306
export DB_MYSQLDB_DATABASE=n8n
export DB_MYSQLDB_USER=n8n
export DB_MYSQLDB_PASSWORD=yourpassword
```
### Security
Set up encryption for credentials:
```bash
# Generate encryption key
export N8N_ENCRYPTION_KEY=$(openssl rand -base64 32)
# Use in production
export N8N_ENCRYPTION_KEY="your-32-char-encryption-key"
```
## NixOS Module
For NixOS, use the n8n module from nixpkgs for a complete service configuration:
```nix
services.n8n = {
enable = true;
settings = {
host = "0.0.0.0";
port = 5678;
timezone = "UTC";
};
environment = {
N8N_ENCRYPTION_KEY = "your-encryption-key";
DB_TYPE = "postgresdb";
DB_POSTGRESDB_HOST = "/var/run/postgresql";
DB_POSTGRESDB_DATABASE = "n8n";
};
};
```
## Use Cases
### Webhook Automation
Trigger workflows via HTTP requests:
```bash
# Start n8n with tunnel for public URL
n8n start --tunnel
# Create webhook workflow in UI
# Workflow receives data from external service
# Process and send to another service
```
### Scheduled Tasks
Run tasks on a schedule:
```javascript
// In workflow editor, use Schedule Trigger
// Set cron expression: "0 9 * * *" (daily at 9 AM)
// Connect to nodes that perform tasks
```
### Data Sync Between Services
Keep data synchronized:
```bash
# Create workflow with:
# 1. Webhook trigger (service A)
# 2. Data transformation node
# 3. HTTP request node (service B)
# 4. Response back to service A
```
### Automated Reporting
Generate and send reports:
```javascript
// Workflow steps:
// 1. Schedule trigger (daily/weekly)
// 2. Database query node
// 3. Data formatting
// 4. Email or Slack notification
```
## Integration Examples
### Slack Integration
```javascript
// Create Slack notification workflow
// 1. Trigger (webhook or schedule)
// 2. Process data
// 3. Send message to Slack channel
```
### GitHub Integration
```javascript
// GitHub repository automation
// 1. GitHub webhook trigger (push, PR, issue)
// 2. Conditional logic
// 3. Actions (create issue, comment, etc.)
```
### Email Automation
```javascript
// Email processing workflow
// 1. Email trigger (IMAP)
// 2. Parse email content
// 3. Process data
// 4. Send response or forward
```
## Performance Optimization
### Production Tips
- Use PostgreSQL or MySQL instead of SQLite
- Enable queue mode with Redis
- Use worker nodes for scaling
- Configure proper resource limits
- Set up load balancing for web UI
### Queue Mode
```bash
# Start main n8n process
export QUEUE_BULL_REDIS_HOST=redis-server
export QUEUE_BULL_REDIS_PORT=6379
n8n start
# Start worker processes
n8n worker
```
## Build Information
- **Version**: 2.4.1
- **Language**: TypeScript/JavaScript (Node.js)
- **Package Manager**: pnpm
- **License**: Sustainable Use (Fair-Code)
- **Source**: [GitHub](https://github.com/n8n-io/n8n)
## Dependencies
- `nodejs` - JavaScript runtime
- `pnpm` - Package manager (build-time)
- `python3` - Required for SQLite bindings
- `node-gyp` - Node.js native addon build tool
- `libkrb5` - Kerberos authentication
- `libmongocrypt` - MongoDB encryption
- `libpq` - PostgreSQL client library
## Platform Support
- Linux
- macOS
## Notes
- Package has ~80,000 files, so stripping and ELF patching are disabled for performance
- SQLite3 bindings are rebuilt during build phase
- TypeScript files and source maps are removed in preInstall phase
- Non-deterministic files (.turbo, .modules.yaml, types) are removed
- Node modules are pruned to production dependencies only
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide
- [n8n Documentation](https://docs.n8n.io) - Official documentation
- [n8n Community](https://community.n8n.io) - Community forum
-346
View File
@@ -1,346 +0,0 @@
# opencode
AI coding agent built for the terminal that can build anything. Combines a TypeScript/JavaScript core with a Go-based TUI for an interactive AI coding experience.
## Description
OpenCode is a terminal-based AI coding agent designed for power users. It provides a comprehensive development environment with AI assistance, code generation, refactoring, and project management capabilities. The tool features a sophisticated TUI (Terminal User Interface) built with Go, while the core functionality is implemented in TypeScript/JavaScript.
## Features
- 🤖 **AI-Powered Coding**: Generate, refactor, and optimize code with AI assistance
- 🖥️ **Modern TUI**: Beautiful terminal interface built with Go
- 🔍 **Code Understanding**: Parse and understand existing codebases
- 🌳 **Tree-Sitter Integration**: Accurate syntax highlighting and code structure analysis
- 📁 **Project Management**: Navigate and manage projects efficiently
- 🧠 **Multi-LLM Support**: Works with various language models (OpenAI, Anthropic, etc.)
- 📝 **Code Generation**: Create new files and features from natural language
- 🔄 **Refactoring**: Intelligent code refactoring with AI
- 🐛 **Bug Detection**: Find and fix bugs automatically
- 📚 **Context Awareness**: Maintains context across editing sessions
- 🎯 **Task Orchestration**: Break down and execute complex tasks
- 💾 **Local Development**: Runs entirely on your machine
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
opencode
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.opencode
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#opencode
```
## Usage
### Basic Usage
```bash
# Start OpenCode in current directory
opencode
# Open specific project
opencode /path/to/project
# Start with specific task description
opencode "Fix the login bug"
# Show help
opencode --help
# Show version
opencode --version
```
### Interactive Commands
OpenCode provides an interactive TUI with various commands:
- **Navigation**: Arrow keys to move, Enter to select
- **Search**: `/` to search files, `?` for help
- **Edit**: `e` to edit selected file
- **Command Palette**: `Ctrl+p` to access commands
- **AI Chat**: `Ctrl+c` to open AI chat
- **Exit**: `q` or `Ctrl+d` to quit
### AI Chat Mode
```bash
# Start OpenCode
opencode
# Enter AI chat mode (Ctrl+c)
# Ask questions, request code changes, etc.
# Examples:
# - "Generate a REST API endpoint for user management"
# - "Refactor this function to use async/await"
# - "Find and fix potential memory leaks"
# - "Add unit tests for this module"
```
### Task Management
```bash
# Ask OpenCode to work on a specific task
opencode "Implement authentication with JWT tokens"
# The agent will:
# 1. Understand the codebase
# 2. Plan the implementation
# 3. Generate necessary code
# 4. Make the changes
# 5. Verify the implementation
```
## Configuration
### Environment Variables
- `OPENCODE_API_KEY`: API key for LLM provider
- `OPENCODE_MODEL`: Default model to use (e.g., gpt-4, claude-3-opus)
- `OPENCODE_PROVIDER`: LLM provider (openai, anthropic, etc.)
- `OPENCODE_MAX_TOKENS`: Maximum tokens for responses
- `OPENCODE_TEMPERATURE`: Sampling temperature (0-1)
- `OPENCODE_CONFIG`: Path to configuration file
### Configuration File
Create `~/.opencode/config.json`:
```json
{
"model": "gpt-4",
"provider": "openai",
"maxTokens": 4096,
"temperature": 0.7,
"systemPrompt": "You are a helpful coding assistant"
}
```
### Project-Specific Config
Create `.opencode.json` in your project:
```json
{
"include": ["src/**/*.ts", "tests/**/*.ts"],
"exclude": ["node_modules", "dist", "*.test.ts"],
"systemPrompt": "You are a TypeScript expert"
}
```
## Advanced Usage
### Code Refactoring
```bash
# Ask for refactoring suggestions
opencode "Review and refactor src/utils.ts for better performance"
# Apply refactoring automatically
opencode "Optimize the database queries in src/db/*.ts"
```
### Bug Fixing
```bash
# Describe the bug
opencode "Fix the race condition in the payment processing module"
# OpenCode will:
# 1. Analyze the code
# 2. Identify the issue
# 3. Propose and implement fixes
# 4. Verify the solution
```
### Feature Implementation
```bash
# Request new features
opencode "Add support for OAuth2 authentication"
# Be specific about requirements
opencode "Create a REST API with these endpoints: GET /users, POST /users, PUT /users/:id, DELETE /users/:id"
```
### Code Review
```bash
# Get code review
opencode "Review src/api/*.ts for security vulnerabilities"
# Check for best practices
opencode "Review the entire codebase and suggest improvements following SOLID principles"
```
### Documentation Generation
```bash
# Generate documentation
opencode "Add JSDoc comments to all functions in src/utils.ts"
# Create README
opencode "Generate a comprehensive README.md for this project"
```
## Integration with Editors
### VS Code
OpenCode can work alongside your editor:
```bash
# Keep VS Code running for editing
code .
# Use OpenCode for AI assistance in another terminal
opencode
# Switch between them as needed
```
### Vim/Neovim
```bash
# Use Vim/Neovim as your editor
vim src/main.ts
# Use OpenCode for complex tasks
opencode "Refactor the authentication module"
```
## Use Cases
### Learning New Codebases
```bash
# OpenCode will:
# 1. Analyze the code structure
# 2. Explain how components work
# 3. Answer questions about the code
opencode "Explain how this project handles user authentication"
```
### Porting Code
```bash
# Port from one language to another
opencode "Port this Python function to TypeScript"
```
### Writing Tests
```bash
# Generate unit tests
opencode "Add comprehensive unit tests for src/utils.ts with 100% coverage"
```
### Debugging
```bash
# Get help with debugging
opencode "I'm getting a null pointer exception in src/api/users.ts. Help me debug it"
```
## Keyboard Shortcuts
### Global
- `Ctrl+p` - Open command palette
- `Ctrl+c` - Open AI chat
- `Ctrl+s` - Save current file
- `Ctrl+q` - Quit
- `?` - Show help
### Navigation
- `j` / `k` - Down / Up
- `h` / `l` - Left / Right
- `gg` - Go to top
- `G` - Go to bottom
- `/` - Search
- `n` - Next search result
- `N` - Previous search result
### File Operations
- `e` - Edit file
- `o` - Open in external editor
- `d` - Delete file (with confirmation)
- `y` - Yank (copy)
- `p` - Paste
## Build Information
- **Version**: 1.1.18
- **Language**: TypeScript/JavaScript (core), Go (TUI)
- **Runtime**: Bun
- **License**: MIT
- **Source**: [GitHub](https://github.com/anomalyco/opencode)
## Dependencies
- `bun` - JavaScript runtime and package manager
- `fzf` - Fuzzy finder for file selection
- `ripgrep` - Fast text search
- `models-dev` - Model definitions and schemas
## Platform Support
- Linux (aarch64, x86_64)
- macOS (aarch64, x86_64)
## Notes
- Includes a patch to relax Bun version check (changed to warning instead of error)
- Shell completions are installed for supported platforms (excludes x86_64-darwin)
- Tree-sitter WASM files are patched to use absolute store paths
- JSON schema is generated and installed to `$out/share/opencode/schema.json`
## Tips and Best Practices
### Getting Started
1. **Start Small**: Begin with simple tasks to get familiar with the interface
2. **Provide Context**: Give clear, detailed descriptions of what you want
3. **Iterate**: Work with OpenCode iteratively, refining requests as needed
4. **Review Changes**: Always review AI-generated code before committing
### Effective Prompts
- Be specific about requirements
- Provide examples of expected behavior
- Mention constraints or preferences
- Break complex tasks into smaller steps
### Project Structure
- Keep your project well-organized
- Use consistent naming conventions
- Add clear comments to complex logic
- Maintain a clean git history
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide
- [OpenCode Documentation](https://github.com/anomalyco/opencode) - Official repository and documentation
-220
View File
@@ -1,220 +0,0 @@
# 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
-245
View File
@@ -1,245 +0,0 @@
# rofi-project-opener
A Rofi-based project directory launcher for quickly opening projects in your terminal with custom commands.
## Description
rofi-project-opener scans configured base directories for project subdirectories and presents them in a Rofi menu. When a project is selected, it opens a terminal, navigates to the project directory, and runs a configurable command (defaults to `opencode`).
Key features:
- JSON-based configuration for project directories
- Per-directory custom arguments (e.g., `--agent chiron` for AI coding assistants)
- Placeholder support (`%s` for path, `%a` for args) in custom commands
- Works with any terminal emulator
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
rofi-project-opener
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.rofi-project-opener
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#rofi-project-opener
```
## Usage
### Basic Usage
```bash
# Launch rofi project selector
rofi-project-opener
```
This will:
1. Read project directories from `~/.config/rofi-project-opener/projects.json`
2. Scan each directory for subdirectories (non-hidden)
3. Display projects in Rofi for fuzzy selection
4. Open terminal, cd to project, and run the configured command
### Configuration Files
The script uses two configuration files in `~/.config/rofi-project-opener/`:
**projects.json** - Project directories with optional args:
```json
{
"nixpkgs": {"path": "~/p/NIX", "args": ""},
"chat": {"path": "~/p/CHAT", "args": "--agent chiron"},
"dev": {"path": "~/dev", "args": ""}
}
```
**config** - Terminal and Rofi settings:
```bash
TERMINAL="/path/to/kitty"
TERMINAL_CMD="opencode %a"
ROFI_PROMPT="Select project"
ROFI_ARGS="-dmenu -i"
```
### Placeholders
When using `terminalCommand`, these placeholders are available:
| Placeholder | Description |
|-------------|-------------|
| `%s` | Full path to selected project |
| `%a` | Args from projectDirs config |
**Examples:**
```nix
terminalCommand = "opencode %a"; # opencode with project args
terminalCommand = "nvim"; # just nvim, no args
terminalCommand = "code %s"; # vscode with explicit path
terminalCommand = "myapp --dir %s %a"; # custom app with both
```
## Home Manager Module
### Enable Module
```nix
{config, pkgs, ...}: {
imports = [m3ta-nixpkgs.homeManagerModules.default];
cli.rofi-project-opener = {
enable = true;
projectDirs = {
nixpkgs = { path = "~/p/NIX"; };
chat = { path = "~/p/CHAT"; args = "--agent chiron"; };
dev = { path = "~/dev"; };
};
terminal = pkgs.kitty;
terminalCommand = "opencode %a";
};
}
```
### Module Options
#### `cli.rofi-project-opener.enable`
Enable the rofi-project-opener module.
- Type: `boolean`
- Default: `false`
#### `cli.rofi-project-opener.projectDirs`
Attribute set of base directories to scan for projects.
- Type: `attrsOf (submodule { path, args })`
- Default: `{ dev = { path = "~/dev"; }; projects = { path = "~/projects"; }; }`
Each entry supports:
- `path` (required): Base directory path
- `args` (optional): Arguments to pass to the command
#### `cli.rofi-project-opener.terminal`
Terminal emulator to use.
- Type: `either str package`
- Default: `"kitty"`
#### `cli.rofi-project-opener.terminalCommand`
Command to run in the terminal. Supports `%s` (path) and `%a` (args) placeholders.
- Type: `str`
- Default: `""` (runs `opencode %a`)
#### `cli.rofi-project-opener.rofiPrompt`
Prompt text displayed in Rofi.
- Type: `str`
- Default: `"Select project"`
#### `cli.rofi-project-opener.rofiArgs`
Arguments to pass to Rofi.
- Type: `listOf str`
- Default: `["-dmenu" "-i"]`
## Requirements
### System Requirements
- Linux with Rofi installed
- A terminal emulator (kitty, alacritty, etc.)
- jq (included as dependency)
### Runtime Dependencies
These are automatically included:
- rofi
- jq
- coreutils
- gnugrep
- gnused
- libnotify
## Platform Support
- Linux (primary)
- macOS (not tested)
- Windows (not supported)
## Build Information
- **Type**: Bash script
- **License**: MIT
## Troubleshooting
### No Projects Found
Check that your project directories exist and contain subdirectories:
```bash
cat ~/.config/rofi-project-opener/projects.json
ls ~/p/NIX # Should show subdirectories
```
### Args Not Being Passed
Make sure you're using `%a` placeholder in your `terminalCommand`:
```nix
# Wrong - args not passed
terminalCommand = "opencode";
# Correct - args passed via placeholder
terminalCommand = "opencode %a";
# Also correct - empty uses default behavior with args
terminalCommand = "";
```
### Rofi Not Showing
Ensure Rofi is installed and working:
```bash
echo -e "item1\nitem2" | rofi -dmenu
```
### Terminal Not Opening
Check terminal configuration:
```nix
# Using package
terminal = pkgs.kitty;
# Using string (must be in PATH)
terminal = "kitty";
```
## Related
- [rofi-project-opener Module](../modules/home-manager/cli/rofi-project-opener.md) - Home Manager module documentation
- [zellij-ps](./zellij-ps.md) - Similar project switcher for Zellij
- [Using Modules](../guides/using-modules.md) - How to use modules
-202
View File
@@ -1,202 +0,0 @@
# stt-ptt
Push to Talk Speech to Text using Whisper.
## Description
stt-ptt is a simple push-to-talk speech-to-text tool that uses whisper.cpp for transcription. It records audio via PipeWire, transcribes it using a local Whisper model, and types the result using wtype (Wayland).
## Features
- **Push to Talk**: Start/stop recording with simple commands
- **Local Processing**: Uses whisper.cpp for fast, offline transcription
- **Wayland Native**: Types transcribed text using wtype
- **Configurable**: Model path and notification timeout via environment variables
- **Lightweight**: Minimal dependencies, no cloud services
## Installation
### Via Home Manager Module (Recommended)
See [stt-ptt Home Manager Module](../modules/home-manager/cli/stt-ptt.md) for the recommended setup with automatic model download.
### Via Overlay
```nix
{pkgs, ...}: {
home.packages = [pkgs.stt-ptt];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
home.packages = [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.stt-ptt
];
}
```
## Usage
### Basic Commands
```bash
# Start recording
stt-ptt start
# Stop recording and transcribe
stt-ptt stop
```
### Keybinding Setup
The tool is designed to be bound to a key (e.g., hold to record, release to transcribe).
#### Hyprland
```nix
# In your Hyprland config
wayland.windowManager.hyprland.settings = {
bind = [
# Press Super+V to start, release to stop and transcribe
"SUPER, V, exec, stt-ptt start"
];
bindr = [
# Release trigger
"SUPER, V, exec, stt-ptt stop"
];
};
```
Or in `hyprland.conf`:
```conf
bind = SUPER, V, exec, stt-ptt start
bindr = SUPER, V, exec, stt-ptt stop
```
#### Sway
```conf
# Hold to record, release to transcribe
bindsym --no-repeat $mod+v exec stt-ptt start
bindsym --release $mod+v exec stt-ptt stop
```
#### i3 (X11 - requires xdotool instead of wtype)
Note: stt-ptt uses wtype which is Wayland-only. For X11, you would need to modify the script to use xdotool.
### Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `STT_MODEL` | Path to Whisper model file | `~/.local/share/stt-ptt/models/ggml-large-v3-turbo.bin` |
| `STT_NOTIFY_TIMEOUT` | Notification timeout in ms | `3000` |
## Requirements
- **whisper-cpp**: Speech recognition engine
- **wtype**: Wayland text input (Wayland compositor required)
- **libnotify**: Desktop notifications
- **pipewire**: Audio recording
## Model Setup
Download a Whisper model from [HuggingFace](https://huggingface.co/ggerganov/whisper.cpp/tree/main):
```bash
# Create model directory
mkdir -p ~/.local/share/stt-ptt/models
# Download model (example: large-v3-turbo)
curl -L -o ~/.local/share/stt-ptt/models/ggml-large-v3-turbo.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin
```
Or use the Home Manager module which handles this automatically.
## Available Models
| Model | Size | Quality | Speed |
|-------|------|---------|-------|
| `ggml-tiny` / `ggml-tiny.en` | 75MB | Basic | Fastest |
| `ggml-base` / `ggml-base.en` | 142MB | Good | Fast |
| `ggml-small` / `ggml-small.en` | 466MB | Better | Medium |
| `ggml-medium` / `ggml-medium.en` | 1.5GB | High | Slower |
| `ggml-large-v3-turbo` | 1.6GB | High | Fast |
| `ggml-large-v3` | 2.9GB | Highest | Slowest |
Models ending in `.en` are English-only and slightly faster for English text.
## Platform Support
- Linux with Wayland (primary)
- Requires PipeWire for audio
- X11 not supported (wtype is Wayland-only)
## Build Information
- **Version**: 0.1.0
- **Type**: Shell script wrapper
- **License**: MIT
## Troubleshooting
### Model Not Found
Error: `Error: Model not found at /path/to/model`
**Solution**: Download a model or use the Home Manager module:
```bash
curl -L -o ~/.local/share/stt-ptt/models/ggml-large-v3-turbo.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin
```
### No Audio Recorded
**Solution**: Ensure PipeWire is running:
```bash
systemctl --user status pipewire
```
### Text Not Typed
**Solution**: Ensure you're on Wayland and wtype has access:
```bash
# Check if running on Wayland
echo $XDG_SESSION_TYPE # Should print "wayland"
```
### Slow Transcription
**Solution**: Use a smaller model or enable GPU acceleration:
```nix
cli.stt-ptt = {
enable = true;
model = "ggml-base.en"; # Smaller, faster model
};
```
Or with GPU acceleration:
```nix
cli.stt-ptt = {
enable = true;
# Choose one:
whisperPackage = pkgs.whisper-cpp-vulkan; # Vulkan (pre-built)
# whisperPackage = pkgs.whisper-cpp.override { cudaSupport = true; }; # NVIDIA
# whisperPackage = pkgs.whisper-cpp.override { rocmSupport = true; }; # AMD
};
```
## Related
- [stt-ptt Home Manager Module](../modules/home-manager/cli/stt-ptt.md) - Module documentation
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
-248
View File
@@ -1,248 +0,0 @@
# tuxedo-backlight
Keyboard backlight control for Tuxedo laptops.
## Description
A shell script that sets up RGB keyboard backlight colors for Tuxedo laptops with customizable colors for different key groups.
## Features
- ⌨️ **RGB Backlight**: Full RGB keyboard backlight support
- 🎨 **Color Groups**: Different colors for different key groups
- 🔤 **Key Highlighting**: Special colors for modifier keys
- 🎯 **One-Command Setup**: Apply all colors with single command
-**Fast**: Direct sysfs control
## Installation
### Via Overlay
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
tuxedo-backlight
];
}
```
### Direct Reference
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
inputs.m3ta-nixpkgs.packages.${pkgs.system}.tuxedo-backlight
];
}
```
### Run Directly
```bash
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#tuxedo-backlight
```
## Usage
### Basic Usage
```bash
# Apply default color scheme
tuxedo-backlight
```
### Colors
The script applies these colors by default:
| Key Group | Color (RGB) | Description |
|-----------|-------------|-------------|
| Main keys | `0 150 255` | Blue (Cyan-ish) |
| Function keys (F1-F12) | `0 255 80` | Green (Lime) |
| Arrow keys | `0 255 80` | Green (Lime) |
| Numpad area | `255 150 0` | Orange |
| DEL key | `255 0 155` | Pink/Magenta |
| ESC key | `255 0 155` | Pink/Magenta |
## Customization
### Modify Colors
Edit the script to customize colors:
```nix
# In pkgs/tuxedo-backlight/default.nix
# All keys
echo 'R G B' | tee /sys/class/leds/rgb:kbd_backlight*/multi_intensity
# Specific key (e.g., ESC)
echo 'R G B' | tee /sys/class/leds/rgb:kbd_backlight/multi_intensity
```
RGB format: `Red Green Blue` (0-255 each)
### Color Examples
| Color | RGB Value |
|--------|-----------|
| Red | `255 0 0` |
| Green | `0 255 0` |
| Blue | `0 0 255` |
| Cyan | `0 255 255` |
| Magenta | `255 0 255` |
| Yellow | `255 255 0` |
| White | `255 255 255` |
| Orange | `255 150 0` |
| Purple | `150 0 255` |
## Automatic Startup
### Systemd Service
Create `/etc/systemd/system/tuxedo-backlight.service`:
```ini
[Unit]
Description=Tuxedo Keyboard Backlight
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/run/current-system/sw/bin/tuxedo-backlight
[Install]
WantedBy=multi-user.target
```
Enable and start:
```bash
sudo systemctl enable tuxedo-backlight.service
sudo systemctl start tuxedo-backlight.service
```
### NixOS Configuration
```nix
{pkgs, ...}: {
# Run at boot
systemd.services.tuxedo-backlight = {
description = "Set Tuxedo keyboard backlight";
after = ["multi-user.target"];
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.tuxedo-backlight}/bin/tuxedo-backlight";
};
};
}
```
## Requirements
### Hardware
- Tuxedo laptop with RGB keyboard backlight
- Linux kernel with appropriate driver support
### System Requirements
- Linux (Tuxedo laptops)
- Write access to `/sys/class/leds/`
### Permissions
The script requires write access to sysfs:
```bash
# Check permissions
ls -la /sys/class/leds/rgb:kbd_backlight*
# If permissions are needed
sudo tuxedo-backlight
```
## Platform Support
- Linux (Tuxedo laptops only)
- macOS (not supported)
- Windows (not supported)
## Troubleshooting
### No Such Device
Error: `No such file or directory`
**Solution**: Ensure you're on a Tuxedo laptop with RGB keyboard:
```bash
# Check if RGB backlight exists
ls -la /sys/class/leds/rgb:kbd_backlight*
```
### Permission Denied
Error: `Permission denied`
**Solution**: Run with sudo or configure udev rules:
```bash
# Run with sudo
sudo tuxedo-backlight
# Or create udev rule for user access
sudo vim /etc/udev/rules.d/99-tuxedo-backlight.rules
```
udev rule:
```
SUBSYSTEM=="leds", ATTR{brightness}=="*", ACTION=="add", RUN+="/usr/bin/chgrp -R input /sys/class/leds/rgb:*"
SUBSYSTEM=="leds", ATTR{brightness}=="*", ACTION=="add", RUN+="/usr/bin/chmod -R g+w /sys/class/leds/rgb:*"
```
### Colors Not Applied
**Solution**:
1. Check RGB backlight is supported:
```bash
cat /sys/class/leds/rgb:kbd_backlight*/multi_intensity
```
2. Ensure driver is loaded:
```bash
# Check for Tuxedo drivers
lsmod | grep tuxedo
# Load if needed
sudo modprobe tuxedo_keyboard
```
## Key Layout Reference
The script sets colors for these key groups:
### Key Numbers
- **All keys**: Main keyboard area (except special keys)
- **15**: DEL key
- **No number**: ESC key
- **1-12, 102**: Function keys (F1-F12, Fn)
- **16-19, 36-39, 56-59, 76-79, 96-99, 117-119**: Numpad and keys above numpad
- **95, 114-116**: Arrow keys
## Build Information
- **Version**: 0.1.0
- **Type**: Shell script
- **License**: MIT
## Related
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide
-204
View File
@@ -1,204 +0,0 @@
# 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];
cli.zellij-ps = {
enable = true;
};
}
```
### Module Options
#### `cli.zellij-ps.enable`
Enable the zellij-ps module.
- Type: `boolean`
- Default: `false`
#### `cli.zellij-ps.package`
Custom package to use.
- Type: `package`
- Default: `pkgs.zellij-ps`
## Requirements
### System Requirements
- Linux or Unix-like system
- Configured `$PROJECT_FOLDERS` environment variable
## Platform Support
- Linux (primary)
- macOS (may work)
- Windows (not supported)
## Build Information
- **Version**: 0.1.0
- **Type**: Fish script
- **License**: MIT
- **Inspired by**: [ThePrimeagen's tmux-sessionizer](https://github.com/ThePrimeagen/.dotfiles/blob/master/bin/.local/scripts/tmux-sessionizer)
- **Source**: [Gitea](https://code.m3ta.dev/m3tam3re/helper-scripts)
## Source Code
The script is available at:
```
https://code.m3ta.dev/m3tam3re/helper-scripts/src/branch/main/zellij-ps.fish
```
## Troubleshooting
### No Projects Found
If fzf shows no results, check your `$PROJECT_FOLDERS` variable:
```bash
# In fish
echo $PROJECT_FOLDERS
# In bash/zsh
echo $PROJECT_FOLDERS
```
Ensure the folders exist and contain subdirectories.
### Already in Zellij Session
If you're already inside a Zellij session, you'll see:
```
You are in a Zellij Session!
Please use the session manager to switch sessions.
```
Use Zellij's built-in session manager (`Ctrl+p``s`) to switch sessions instead.
### fd Not Found
Error: `fd: command not found`
**Solution**: Ensure fd is installed:
```nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
fd
];
}
```
### Fish Not Found
Error: `fish: command not found`
**Solution**: Ensure Fish is installed:
```nix
{pkgs, ...}: {
programs.fish = {
enable = true;
};
}
```
### fzf Not Working
Ensure fzf is installed and configured:
```bash
# Check fzf
which fzf
# Test fzf
echo -e "item1\nitem2\nitem3" | fzf
```
## Related
- [zellij-ps Module](../modules/home-manager/cli/zellij-ps.md) - Home Manager module documentation
- [Using Modules](../guides/using-modules.md) - How to use modules
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
- [Quick Start](../QUICKSTART.md) - Getting started guide
-272
View File
@@ -1,272 +0,0 @@
# Library Functions
Documentation for library functions available in m3ta-nixpkgs.
## Overview
The library provides helper functions for your NixOS and Home Manager configurations.
## Available Libraries
### `m3ta-lib.ports`
Port management utilities for managing service ports across hosts.
## Port Management Functions
### `mkPortHelpers`
Create port helper functions from a ports configuration.
#### Signature
```nix
mkPortHelpers :: portsConfig -> portHelpers
```
#### Arguments
`portsConfig` - An attribute set with structure:
```nix
{
ports = { service-name = port-number; ... };
hostPorts = { hostname = { service-name = port-number; ... }; ... };
}
```
#### Returns
An attribute set containing helper functions:
```nix
{
getPort = service: host -> port-number-or-null;
getHostPorts = host -> ports-attrs;
listServices = -> [string];
}
```
#### Usage
```nix
{config, inputs, ...}: let
m3taLib = inputs.m3ta-nixpkgs.lib.${config.system};
myPorts = {
ports = {
nginx = 80;
grafana = 3000;
};
hostPorts = {
laptop = {
nginx = 8080;
};
};
};
portHelpers = m3taLib.ports.mkPortHelpers myPorts;
in {
# Get port with host override
services.nginx.port = portHelpers.getPort "nginx" config.networking.hostName;
# Get all ports for host
laptopPorts = portHelpers.getHostPorts "laptop";
# List all services
allServices = portHelpers.listServices;
}
```
### `getPort` (from portHelpers)
Get port for a service, with optional host-specific override.
#### Signature
```nix
getPort :: string -> string -> int-or-null
```
#### Arguments
1. `service` - The service name (string)
2. `host` - The hostname (string), or `null` for default
#### Returns
Port number (int) or `null` if service not found.
#### Usage
```nix
services.nginx = {
port = portHelpers.getPort "nginx" "laptop"; # Returns host-specific port
# or
port = portHelpers.getPort "nginx" null; # Returns default port
};
```
### `getHostPorts` (from portHelpers)
Get all ports for a specific host (merges defaults with host overrides).
#### Signature
```nix
getHostPorts :: string -> attrs
```
#### Arguments
1. `host` - The hostname (string)
#### Returns
Attribute set of all ports for the host.
#### Usage
```nix
laptopPorts = portHelpers.getHostPorts "laptop";
# Returns: { nginx = 8080; grafana = 3000; prometheus = 9090; ... }
```
### `listServices` (from portHelpers)
List all defined service names.
#### Signature
```nix
listServices :: -> [string]
```
#### Returns
List of service names (strings).
#### Usage
```nix
allServices = portHelpers.listServices;
# Returns: ["nginx" "grafana" "prometheus" "homepage"]
```
### `getDefaultPort`
Simple helper to get a port without host override.
#### Signature
```nix
getDefaultPort :: portsConfig -> string -> int-or-null
```
#### Arguments
1. `portsConfig` - Same structure as `mkPortHelpers`
2. `service` - The service name (string)
#### Returns
Port number (int) or `null` if service not found.
#### Usage
```nix
services.my-service = {
port = m3taLib.ports.getDefaultPort myPorts "my-service";
};
```
## Using Library Functions
### Importing
```nix
{config, inputs, ...}: let
# Import library
m3taLib = inputs.m3ta-nixpkgs.lib.${config.system};
in {
# Use library functions
}
```
### Example: Custom Port Management
```nix
{config, inputs, ...}: let
m3taLib = inputs.m3ta-nixpkgs.lib.${config.system};
myPorts = {
ports = {
web = 80;
api = 8080;
db = 5432;
};
hostPorts = {
dev = {
web = 8080;
api = 8081;
};
};
};
portHelpers = m3taLib.ports.mkPortHelpers myPorts;
hostname = config.networking.hostName;
in {
services.nginx = {
enable = true;
virtualHosts.${hostname} = {
locations."/" = {
proxyPass = "http://localhost:${toString (portHelpers.getPort "api" hostname)}";
};
};
};
services.postgresql = {
enable = true;
port = portHelpers.getPort "db" hostname;
};
}
```
### Example: Generate Config Files
```nix
{inputs, ...}: let
m3taLib = inputs.m3ta-nixpkgs.lib.${system};
myPorts = {
ports = {
service1 = 3000;
service2 = 3001;
};
};
portHelpers = m3taLib.ports.mkPortHelpers myPorts;
in {
environment.etc."ports.toml".text = generators.toTOML {} {
services = portHelpers.getHostPorts "desktop";
};
}
```
## Function Reference Summary
| Function | Purpose | Return Type |
|----------|---------|------------|
| `mkPortHelpers` | Create port helper functions | `portHelpers` attrs |
| `getPort` | Get port with optional host override | `int or null` |
| `getHostPorts` | Get all ports for host | `attrs` |
| `listServices` | List all service names | `[string]` |
| `getDefaultPort` | Get default port only | `int or null` |
## Related
- [Port Management Guide](../guides/port-management.md) - Detailed usage guide
- [NixOS Ports Module](../modules/nixos/ports.md) - Port management module
- [Home Manager Ports Module](../modules/home-manager/ports.md) - User-level port management
- [Architecture](../ARCHITECTURE.md) - Understanding library functions
-498
View File
@@ -1,498 +0,0 @@
# 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.cli.tool1.enable {...})
(mkIf config.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 for m3ta modules, `cli.*` namespace for CLI modules
```nix
m3ta.ports.enable = true;
cli.zellij-ps.enable = true;
```
**Bad**: Flat namespace
```nix
ports.enable = true; # Potential conflict
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
-193
View File
@@ -1,193 +0,0 @@
# Example Standalone Home Manager Configuration using m3ta-nixpkgs
# This file demonstrates how to use m3ta-nixpkgs with standalone Home Manager
# (without NixOS)
{
description = "Example Home Manager configuration with m3ta-nixpkgs";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
# Add m3ta-nixpkgs as an input
m3ta-nixpkgs = {
url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
# Or use a local path during development:
# url = "path:/home/user/projects/m3ta-nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
home-manager,
m3ta-nixpkgs,
...
} @ inputs: let
system = "x86_64-linux"; # Change to your system: aarch64-linux, x86_64-darwin, aarch64-darwin
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
# Apply m3ta-nixpkgs overlays
overlays = [
m3ta-nixpkgs.overlays.default
];
};
in {
homeConfigurations = {
# Replace 'm3tam3re' with your actual username
m3tam3re = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
# Pass inputs as extra special args
extraSpecialArgs = {inherit inputs;};
modules = [
# Import m3ta's Home Manager modules
m3ta-nixpkgs.homeManagerModules.default
# Main Home Manager configuration
{
# ============================================
# User Information
# ============================================
home.username = "m3tam3re";
home.homeDirectory = "/home/m3tam3re";
home.stateVersion = "24.05";
# ============================================
# Packages from m3ta-nixpkgs
# ============================================
# Since we applied the overlay above, packages are available directly
home.packages = with pkgs; [
# Custom packages from m3ta-nixpkgs
code2prompt
hyprpaper-random
launch-webapp
msty-studio
pomodoro-timer
zellij-ps
# Regular packages from nixpkgs
git
vim
htop
fzf
ripgrep
];
# ============================================
# Custom Home Manager Modules
# ============================================
# If you've defined custom Home Manager modules
# programs.myProgram = {
# enable = true;
# package = pkgs.myProgram;
# settings = {
# theme = "dark";
# };
# };
# ============================================
# Shell Configuration
# ============================================
programs.bash = {
enable = true;
shellAliases = {
ll = "ls -l";
".." = "cd ..";
};
};
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
};
# ============================================
# Git Configuration
# ============================================
programs.git = {
enable = true;
userName = "Your Name";
userEmail = "your.email@example.com";
extraConfig = {
init.defaultBranch = "main";
pull.rebase = false;
};
};
# ============================================
# Additional Programs
# ============================================
programs.direnv = {
enable = true;
nix-direnv.enable = true;
};
programs.fzf = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
};
# ============================================
# Environment Variables
# ============================================
home.sessionVariables = {
EDITOR = "vim";
VISUAL = "vim";
};
# ============================================
# File Management
# ============================================
# Create custom config files
home.file.".config/my-app/config.json".text = ''
{
"setting": "value"
}
'';
# ============================================
# Allow Home Manager to manage itself
# ============================================
programs.home-manager.enable = true;
}
];
};
# ============================================
# Minimal Example Configuration
# ============================================
minimal = home-manager.lib.homeManagerConfiguration {
pkgs = import nixpkgs {
inherit system;
overlays = [m3ta-nixpkgs.overlays.default];
};
modules = [
{
home.username = "m3tam3re";
home.homeDirectory = "/home/m3tam3re";
home.stateVersion = "24.05";
# Just use a couple of custom packages
home.packages = with pkgs; [
code2prompt
zellij-ps
];
programs.home-manager.enable = true;
}
];
};
};
};
}
-153
View File
@@ -1,153 +0,0 @@
# Example NixOS Configuration using m3ta-nixpkgs
# This file demonstrates how to integrate m3ta-nixpkgs into your NixOS system
{
description = "Example NixOS configuration with m3ta-nixpkgs";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# Add m3ta-nixpkgs as an input
m3ta-nixpkgs = {
url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
# Or use a local path during development:
# url = "path:/home/user/projects/m3ta-nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
m3ta-nixpkgs,
home-manager,
...
} @ inputs: {
nixosConfigurations = {
# Replace 'hostname' with your actual hostname
hostname = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = {inherit inputs;};
modules = [
# Your hardware configuration
./hardware-configuration.nix
# Import m3ta's NixOS modules (if any are defined)
m3ta-nixpkgs.nixosModules.default
# Main configuration
({pkgs, ...}: {
# ============================================
# METHOD 1: Using Overlays (Recommended)
# ============================================
# This makes custom packages available as if they were in nixpkgs
nixpkgs.overlays = [
m3ta-nixpkgs.overlays.default
# Or use individual overlays for more control:
# m3ta-nixpkgs.overlays.additions
# m3ta-nixpkgs.overlays.modifications
];
# Now you can use packages normally
environment.systemPackages = with pkgs; [
# Custom packages from m3ta-nixpkgs
code2prompt
hyprpaper-random
msty-studio
pomodoro-timer
tuxedo-backlight
zellij-ps
# Regular nixpkgs packages
vim
git
htop
];
# ============================================
# METHOD 2: Direct Package Reference
# ============================================
# Use this if you don't want to use overlays
# environment.systemPackages = [
# inputs.m3ta-nixpkgs.packages.${pkgs.system}.code2prompt
# inputs.m3ta-nixpkgs.packages.${pkgs.system}.zellij-ps
# ];
# ============================================
# Using Custom NixOS Modules
# ============================================
# If you've defined custom NixOS modules, configure them here
# m3ta.myModule = {
# enable = true;
# # module-specific options
# };
# ============================================
# System Configuration
# ============================================
system.stateVersion = "24.05";
networking.hostName = "hostname";
# Enable flakes
nix.settings.experimental-features = ["nix-command" "flakes"];
})
# ============================================
# Home Manager Integration
# ============================================
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.m3tam3re = {pkgs, ...}: {
# Import m3ta's Home Manager modules
imports = [
m3ta-nixpkgs.homeManagerModules.default
# Or import specific modules:
# m3ta-nixpkgs.homeManagerModules.zellij-ps
];
# Home Manager packages with overlay
home.packages = with pkgs; [
launch-webapp
# Other packages...
];
# Configure custom Home Manager modules
# programs.myProgram = {
# enable = true;
# # options...
# };
home.stateVersion = "24.05";
};
}
];
};
# ============================================
# Alternative: Minimal Configuration
# ============================================
minimal = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({pkgs, ...}: {
nixpkgs.overlays = [m3ta-nixpkgs.overlays.default];
environment.systemPackages = with pkgs; [
code2prompt
];
system.stateVersion = "24.05";
})
];
};
};
};
}
Generated
-63
View File
@@ -1,63 +0,0 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1770562336,
"narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d6c71932130818840fc8fe9509cf50be8c64634f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1770073757,
"narHash": "sha256-Vy+G+F+3E/Tl+GMNgiHl9Pah2DgShmIUBJXmbiQPHbI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "47472570b1e607482890801aeaf29bfb749884f6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"opencode": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1770761545,
"narHash": "sha256-IHN7Rh/Wb4TKdT1rkJYgkI0CLBXCcrM0OpCkIlycW+Y=",
"owner": "anomalyco",
"repo": "opencode",
"rev": "1bbbd51d48f38014674eebe1588f556da95b7b1f",
"type": "github"
},
"original": {
"owner": "anomalyco",
"ref": "v1.1.56",
"repo": "opencode",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"opencode": "opencode"
}
}
},
"root": "root",
"version": 7
}
-118
View File
@@ -1,118 +0,0 @@
{
description = "m3ta's personal Nix repository - Custom packages, overlays, and modules";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
opencode.url = "github:anomalyco/opencode/v1.1.56";
# Optional: Add stable channel if needed
# nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.05";
};
outputs = {
self,
nixpkgs,
...
} @ inputs: let
# Supported systems
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
# Helper function to generate an attrset for each of the systems
forAllSystems = nixpkgs.lib.genAttrs systems;
# Helper to create pkgs for a given system
pkgsFor = system:
import nixpkgs {
inherit system;
config.allowUnfree = true;
};
in {
# Custom packages - accessible via 'nix build .#package-name'
packages = forAllSystems (
system: let
pkgs = pkgsFor system;
in
import ./pkgs {inherit pkgs inputs;}
);
# Overlays - can be imported in your system configuration
overlays = {
# Default overlay: adds all custom packages
default = final: prev:
import ./pkgs {
pkgs = final;
inputs = inputs;
};
# Individual overlays for more granular control
additions = final: prev:
import ./pkgs {
pkgs = final;
inputs = inputs;
};
modifications = final: prev:
import ./overlays/mods {inherit prev;};
};
# NixOS modules - for system-level configuration
nixosModules = {
default = ./modules/nixos;
# Individual modules for selective imports
ports = ./modules/nixos/ports.nix;
mem0 = ./modules/nixos/mem0.nix;
};
# Home Manager modules - for user-level configuration
homeManagerModules = {
default = import ./modules/home-manager;
ports = import ./modules/home-manager/ports.nix;
zellij-ps = import ./modules/home-manager/zellij-ps.nix;
};
# Library functions - helper utilities for your configuration
lib = forAllSystems (
system: let
pkgs = pkgsFor system;
in
import ./lib {lib = pkgs.lib;}
);
# Development shells for various programming environments
# Usage: nix develop .#<shell-name>
# Available shells: default, python, devops
devShells = forAllSystems (
system: let
pkgs = pkgsFor system;
in
import ./shells {inherit pkgs;}
);
# Formatter for 'nix fmt'
formatter = forAllSystems (
system:
(pkgsFor system).alejandra
);
# Templates for creating new packages/modules
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";
};
};
};
}
-12
View File
@@ -1,12 +0,0 @@
# Library of helper functions for m3ta-nixpkgs
# Usage in your configuration:
# let
# m3taLib = inputs.m3ta-nixpkgs.lib.${system};
# in ...
{lib}: {
# Port management utilities
ports = import ./ports.nix {inherit lib;};
# Add more helper modules here as needed
# example = import ./example.nix { inherit lib; };
}
-113
View File
@@ -1,113 +0,0 @@
# Port management utilities
#
# This module provides functions to manage service ports across multiple hosts
# in a centralized way. Ports are defined in your configuration and can have
# host-specific overrides.
#
# Usage in your configuration:
#
# # In your flake or configuration, define your ports:
# let
# m3taLib = inputs.m3ta-nixpkgs.lib.${system};
#
# myPorts = {
# ports = {
# nginx = 80;
# grafana = 3000;
# prometheus = 9090;
# homepage = 8080;
# };
# hostPorts = {
# laptop = {
# nginx = 8080; # Override nginx port on laptop
# };
# server = {
# homepage = 3001; # Override homepage port on server
# };
# };
# };
#
# portHelpers = m3taLib.ports.mkPortHelpers myPorts;
# in {
# # Use in your config:
# services.nginx.port = portHelpers.getPort "nginx" "laptop";
# # Returns: 8080 (host-specific override)
#
# services.grafana.port = portHelpers.getPort "grafana" "laptop";
# # Returns: 3000 (default port)
#
# # Get all ports for a specific host (defaults + overrides):
# allLaptopPorts = portHelpers.getHostPorts "laptop";
# # Returns: { nginx = 8080; grafana = 3000; prometheus = 9090; homepage = 8080; }
# }
{lib}: {
# Create port helper functions from a ports configuration
#
# Args:
# portsConfig: An attribute set with structure:
# {
# ports = { service-name = port-number; ... };
# hostPorts = { hostname = { service-name = port-number; ... }; ... };
# }
#
# Returns:
# An attribute set containing helper functions:
# - getPort: Get port for a service with optional host override
# - getHostPorts: Get all ports for a specific host
# - listServices: List all defined services
mkPortHelpers = portsConfig: let
ports = portsConfig.ports or {};
hostPorts = portsConfig.hostPorts or {};
in {
# Get port for a service, with optional host-specific override
#
# Args:
# service: The service name (string)
# host: The hostname (string)
#
# Returns:
# Port number (int) or null if service not found
#
# Example:
# getPort "nginx" "laptop" # Returns host-specific port if defined
# getPort "nginx" null # Returns default port
getPort = service: host:
if host != null && hostPorts ? ${host} && hostPorts.${host} ? ${service}
then hostPorts.${host}.${service}
else ports.${service} or null;
# Get all ports for a specific host (merges defaults with host overrides)
#
# Args:
# host: The hostname (string)
#
# Returns:
# Attribute set of all ports for the host
#
# Example:
# getHostPorts "laptop" # { nginx = 8080; grafana = 3000; ... }
getHostPorts = host:
ports // (hostPorts.${host} or {});
# List all defined service names
#
# Returns:
# List of service names (strings)
listServices = lib.attrNames ports;
};
# Simple helper to get a port without host override
# Useful when you don't need host-specific ports
#
# Args:
# portsConfig: Same structure as mkPortHelpers
# service: The service name (string)
#
# Returns:
# Port number (int) or null if service not found
#
# Example:
# getDefaultPort myPorts "nginx" # Returns default port only
getDefaultPort = portsConfig: service:
portsConfig.ports.${service} or null;
}
-74
View File
@@ -1,74 +0,0 @@
# Home Manager Modules
User-level configuration modules organized by functional category.
## Structure
```
home-manager/
├── default.nix # Aggregator: imports all categories + ports.nix
├── ports.nix # Port management (HM-specific: generateEnvVars)
├── cli/ # Terminal/CLI tools
│ ├── default.nix # Category aggregator
│ └── zellij-ps.nix
└── coding/ # Development tools
├── default.nix # Category aggregator
└── editors.nix # Neovim + Zed configs
```
## Where to Look
| Task | Location |
|------|----------|
| Add CLI module | `cli/<name>.nix`, import in `cli/default.nix` |
| Add coding module | `coding/<name>.nix`, import in `coding/default.nix` |
| Add new category | Create `<category>/default.nix`, import in root `default.nix` |
| Module with host ports | Import `../../lib/ports.nix`, use `mkPortHelpers` |
## Option Namespaces
- `cli.*` - CLI tools (e.g., `cli.zellij-ps.enable`)
- `coding.editors.*` - Editor configs (e.g., `coding.editors.neovim.enable`)
- `m3ta.ports.*` - Port management (shared with NixOS)
## Patterns
**Category aggregator** (`cli/default.nix`):
```nix
{
imports = [
./zellij-ps.nix
# Add new modules here
];
}
```
**Simple module** (zellij-ps):
```nix
options.cli.zellij-ps = {
enable = mkEnableOption "...";
projectFolders = mkOption { type = types.listOf types.path; ... };
};
config = mkIf cfg.enable {
home.packages = [ pkgs.zellij-ps ];
home.sessionVariables.PROJECT_FOLDERS = ...;
};
```
**Multi-config module** (editors.nix):
```nix
config = mkMerge [
(mkIf cfg.neovim.enable { programs.neovim = {...}; })
(mkIf cfg.zed.enable { programs.zed-editor = {...}; })
(mkIf (cfg.neovim.enable || cfg.zed.enable) { home.packages = [...]; })
];
```
## HM vs NixOS Differences
| Feature | Home Manager | NixOS |
|---------|--------------|-------|
| `currentHost` default | `null` (must set) | `config.networking.hostName` |
| `generateEnvVars` | Available | Not available |
| Output file | `~/.config/m3ta/ports.json` | `/etc/m3ta/ports.json` |
| Package access | `pkgs.*` via overlay | `pkgs.*` via overlay |
-8
View File
@@ -1,8 +0,0 @@
# CLI/Terminal-related Home Manager modules
{
imports = [
./rofi-project-opener.nix
./stt-ptt.nix
./zellij-ps.nix
];
}
@@ -1,134 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.cli.rofi-project-opener;
# Project directory submodule type
projectDirType = types.submodule {
options = {
path = mkOption {
type = types.str;
description = "Base directory path to scan for project subdirectories.";
example = "~/dev";
};
args = mkOption {
type = types.str;
default = "";
description = "Additional arguments to pass to opencode when launching projects from this directory.";
example = "--agent Planner-Sisyphus";
};
};
};
# Convert projectDirs attrset to JSON for config file
projectDirsJson = builtins.toJSON (
mapAttrs (name: value: {
path = value.path;
args = value.args;
})
cfg.projectDirs
);
in {
options.cli.rofi-project-opener = {
enable = mkEnableOption "Rofi-based project directory launcher";
projectDirs = mkOption {
type = types.attrsOf projectDirType;
default = {
dev = {path = "~/dev";};
projects = {path = "~/projects";};
};
description = ''
Attribute set of base directories to scan for project subdirectories.
Each directory will be scanned for immediate subdirectories (non-hidden).
Projects are displayed as "base_dir/project_name" in rofi.
Each entry can specify:
- path: Base directory path (supports ~ for home directory)
- args: Optional arguments to pass to opencode for projects in this directory
'';
example = literalExpression ''
{
nixpkgs = { path = "~/p/NIX/nixpkgs"; args = "--agent Planner-Sisyphus"; };
dev = { path = "~/dev"; };
work = { path = "~/work"; args = "--agent work-agent"; };
}
'';
};
terminal = mkOption {
type = types.either types.str types.package;
default = "kitty";
description = "Terminal emulator to use for launching opencode. Can be a string or package.";
example = literalExpression "pkgs.alacritty";
};
terminalCommand = mkOption {
type = types.str;
default = "";
description = ''
Custom command to run in the terminal.
Placeholders:
- %s = project path
- %a = project args (from projectDirs.<name>.args)
If empty, defaults to: cd to project, run "opencode %a"
Examples:
- "" (empty) - Uses default: cd to project, run opencode with args
- "opencode %a" - Run opencode with project-specific args
- "nvim" - Open editor (no args)
- "myapp %s %a" - Custom app with path and args
'';
example = literalExpression ''"opencode %a"'';
};
rofiPrompt = mkOption {
type = types.str;
default = "Select project";
description = "Prompt text displayed in rofi.";
example = "Open project:";
};
rofiArgs = mkOption {
type = types.listOf types.str;
default = ["-dmenu" "-i"];
description = ''
Arguments to pass to rofi.
Common options:
- "-dmenu" - Enable dmenu mode (required)
- "-i" - Case-insensitive matching
- "-theme <theme>" - Use specific rofi theme
- "-width <percentage>" - Window width
- "-lines <number>" - Number of visible lines
'';
example = literalExpression ''["-dmenu" "-i" "-theme gruvbox"]'';
};
};
config = mkIf cfg.enable {
home.packages = [pkgs.rofi-project-opener];
# Write JSON config file for project directories
xdg.configFile."rofi-project-opener/projects.json".text = projectDirsJson;
# Write shell config file for other settings
xdg.configFile."rofi-project-opener/config".text = ''
# rofi-project-opener configuration
TERMINAL="${
if isDerivation cfg.terminal
then "${cfg.terminal}/bin/${cfg.terminal.pname or (builtins.baseNameOf (toString cfg.terminal))}"
else cfg.terminal
}"
${optionalString (cfg.terminalCommand != "") ''TERMINAL_CMD="${cfg.terminalCommand}"''}
ROFI_PROMPT="${cfg.rofiPrompt}"
ROFI_ARGS="${escapeShellArgs cfg.rofiArgs}"
'';
};
}
-158
View File
@@ -1,158 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.cli.stt-ptt;
# Build stt-ptt package with the selected whisper package
sttPttPackage = pkgs.stt-ptt.override {
whisper-cpp = cfg.whisperPackage;
};
modelDir = "${config.xdg.dataHome}/stt-ptt/models";
modelPath = "${modelDir}/${cfg.model}.bin";
# HuggingFace URL for whisper.cpp models
modelUrl = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/${cfg.model}.bin";
in {
options.cli.stt-ptt = {
enable = mkEnableOption "Push to Talk Speech to Text using Whisper";
whisperPackage = mkOption {
type = types.package;
default = pkgs.whisper-cpp;
description = ''
The whisper-cpp package to use. Available options:
Pre-built variants:
- `pkgs.whisper-cpp` - CPU-based inference (default)
- `pkgs.whisper-cpp-vulkan` - Vulkan GPU acceleration
Override options (can be combined):
- `cudaSupport` - NVIDIA CUDA support
- `rocmSupport` - AMD ROCm support
- `vulkanSupport` - Vulkan support
- `coreMLSupport` - Apple CoreML (macOS only)
- `metalSupport` - Apple Metal (macOS ARM only)
Example overrides:
- `pkgs.whisper-cpp.override { cudaSupport = true; }` - NVIDIA GPU
- `pkgs.whisper-cpp.override { rocmSupport = true; }` - AMD GPU
- `pkgs.whisper-cpp.override { vulkanSupport = true; }` - Vulkan
'';
example = literalExpression "pkgs.whisper-cpp.override { cudaSupport = true; }";
};
model = mkOption {
type = types.str;
default = "ggml-large-v3-turbo";
description = ''
The Whisper model to use. Models are downloaded from HuggingFace.
Available models (sorted by size/quality):
- `ggml-tiny` / `ggml-tiny.en` - 75MB, fastest, lowest quality
- `ggml-base` / `ggml-base.en` - 142MB, fast, basic quality
- `ggml-small` / `ggml-small.en` - 466MB, balanced
- `ggml-medium` / `ggml-medium.en` - 1.5GB, good quality
- `ggml-large-v1` - 2.9GB, high quality (original)
- `ggml-large-v2` - 2.9GB, high quality (improved)
- `ggml-large-v3` - 2.9GB, highest quality
- `ggml-large-v3-turbo` - 1.6GB, high quality, optimized speed (recommended)
Models ending in `.en` are English-only and slightly faster for English.
Quantized versions (q5_0, q5_1, q8_0) are also available for reduced size.
'';
example = "ggml-base.en";
};
notifyTimeout = mkOption {
type = types.int;
default = 3000;
description = ''
Notification timeout in milliseconds for the recording indicator.
Set to 0 for persistent notifications.
'';
example = 5000;
};
language = mkOption {
type = types.enum [
"auto"
"en"
"es"
"fr"
"de"
"it"
"pt"
"ru"
"zh"
"ja"
"ko"
"ar"
"hi"
"tr"
"pl"
"nl"
"sv"
"da"
"fi"
"no"
"vi"
"th"
"id"
"uk"
"cs"
];
default = "auto";
description = ''
Language for speech recognition. Use "auto" for automatic language detection,
or specify a language code (ISO 639-1 standard) for better accuracy.
Auto-detection analyzes the audio to determine the spoken language automatically.
Specifying a language can improve accuracy if you know the language in advance.
Common language codes:
- en: English
- es: Spanish
- fr: French
- de: German
- zh: Chinese
- ja: Japanese
- ko: Korean
whisper.cpp supports 100+ languages. See whisper.cpp documentation for the full list.
'';
example = "en";
};
};
config = mkIf cfg.enable {
home.packages = [sttPttPackage];
home.sessionVariables = {
STT_MODEL = modelPath;
STT_LANGUAGE = cfg.language;
STT_NOTIFY_TIMEOUT = toString cfg.notifyTimeout;
};
# Create model directory and download model if not present
home.activation.downloadWhisperModel = lib.hm.dag.entryAfter ["writeBoundary"] ''
MODEL_DIR="${modelDir}"
MODEL_PATH="${modelPath}"
MODEL_URL="${modelUrl}"
$DRY_RUN_CMD mkdir -p "$MODEL_DIR"
if [ ! -f "$MODEL_PATH" ]; then
echo "Downloading Whisper model: ${cfg.model}..."
$DRY_RUN_CMD ${pkgs.curl}/bin/curl -L -o "$MODEL_PATH" "$MODEL_URL" || {
echo "Failed to download model from $MODEL_URL"
echo "Please download manually and place at: $MODEL_PATH"
}
fi
'';
};
}
-45
View File
@@ -1,45 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.cli.zellij-ps;
in {
options.cli.zellij-ps = {
enable = mkEnableOption "Zellij Project Selector";
projectFolders = mkOption {
type = types.listOf types.path;
description = "List of project folders for zellij-ps.";
default = ["${config.home.homeDirectory}/projects"];
};
layout = mkOption {
type = types.str;
description = "Layout for zellij";
default = ''
layout {
pane size=1 borderless=true {
plugin location="zellij:tab-bar"
}
pane
pane split_direction="vertical" {
pane
pane command="htop"
}
pane size=2 borderless=true {
plugin location="zellij:status-bar"
}
}
'';
};
};
config = mkIf cfg.enable {
home.packages = [pkgs.zellij-ps];
home.sessionVariables.PROJECT_FOLDERS = lib.concatStringsSep ":" cfg.projectFolders;
home.file.".config/zellij/layouts/zellij-ps.kdl".text = cfg.layout;
};
}
-6
View File
@@ -1,6 +0,0 @@
# Coding-related Home Manager modules
{
imports = [
./editors.nix
];
}
-199
View File
@@ -1,199 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.coding.editors;
in {
options.coding.editors = {
neovim = {
enable = mkEnableOption "neovim with LazyVim configuration";
};
zed = {
enable = mkEnableOption "zed editor with custom configuration";
};
};
config = mkMerge [
# Neovim configuration
(mkIf cfg.neovim.enable {
programs.neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
vimdiffAlias = true;
withNodeJs = true;
withPython3 = true;
# This is your init.lua content (extraLuaConfig for compatibility with older home-manager)
extraLuaConfig = ''
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- Bootstrap LazyVim via lazy.nvim
-- Docs: https://github.com/folke/lazy.nvim and https://www.lazyvim.org/
require("lazy").setup({
spec = {
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
{ import = "lazyvim.plugins.extras.lang.typescript" },
{ import = "lazyvim.plugins.extras.lang.python" },
{ import = "lazyvim.plugins.extras.lang.go" },
{ import = "lazyvim.plugins.extras.lang.nix" },
{ import = "lazyvim.plugins.extras.lang.rust" },
{ import = "lazyvim.plugins.extras.lang.nushell" },
{ "Mofiqul/dracula.nvim" },
},
defaults = { lazy = false, version = false },
install = { colorscheme = { "dracula", "tokyonight", "habamax" } },
checker = { enabled = false },
performance = {
rtp = {
disabled_plugins = {
"gzip", "tarPlugin", "tohtml", "tutor", "zipPlugin",
},
},
},
})
vim.o.termguicolors = true
vim.cmd.colorscheme("dracula")
'';
};
})
# Zed editor configuration
(mkIf cfg.zed.enable {
programs.zed-editor = {
enable = true;
userSettings = {
# UI and Theme
theme = "Dracula";
ui_font_size = 16;
buffer_font_size = 16;
buffer_font_family = "FiraCode Nerd Font";
# Editor Behavior
vim_mode = true;
auto_update = false;
format_on_save = "on";
load_direnv = "shell_hook";
# AI Features
features = {
edit_prediction_provider = "zed";
};
edit_predictions = {
mode = "subtle";
};
show_edit_predictions = true;
agent = {
default_model = {
provider = "zed.dev";
model = "claude-sonnet-4";
};
};
assistant = {
version = "2";
default_model = {
provider = "anthropic";
model = "claude-4";
};
};
# Language Models
language_models = {
anthropic = {
api_url = "https://api.anthropic.com";
};
openai = {
api_url = "https://api.openai.com/v1";
};
ollama = {
api_url = "http://localhost:11434";
};
};
# Languages Configuration
languages = {
Nix = {
language_servers = ["nixd"];
formatter = {
external = {
command = "alejandra";
arguments = [
"-q"
"-"
];
};
};
};
Python = {
language_servers = ["pyrefly"];
formatter = {
external = {
command = "black";
arguments = ["-"];
};
};
};
};
# LSP Configuration
lsp = {
rust-analyzer = {
initialization_options = {
check = {
command = "clippy";
};
};
};
pyrefly = {
binary = {
arguments = ["--lsp"];
};
};
};
# Context Servers
context_servers = {
some-context-server = {
source = "custom";
command = "some-command";
args = [
"arg-1"
"arg-2"
];
env = {};
};
};
# Privacy
telemetry = {
metrics = false;
};
};
};
})
# Common packages (always installed if either editor is enabled)
(mkIf (cfg.neovim.enable || cfg.zed.enable) {
home.packages = with pkgs; [zig];
})
];
}
-8
View File
@@ -1,8 +0,0 @@
# Home Manager modules organized by category
{
imports = [
./cli
./coding
./ports.nix
];
}
-159
View File
@@ -1,159 +0,0 @@
# Home Manager Module for Port Management
#
# This module provides centralized port management for Home Manager configurations.
# Define ports once and use them consistently across user services, with support
# for host-specific overrides.
#
# Usage in your Home Manager configuration:
#
# # In your home.nix or flake:
# imports = [ inputs.m3ta-nixpkgs.homeManagerModules.default ];
#
# m3ta.ports = {
# enable = true;
#
# # Define your default ports
# definitions = {
# vscodium = 8080;
# jupyter = 8888;
# dev-server = 3000;
# local-api = 8000;
# docs-preview = 4000;
# };
#
# # Define host-specific overrides
# hostOverrides = {
# laptop = {
# dev-server = 3001;
# vscodium = 8081;
# };
# desktop = {
# jupyter = 9999;
# };
# };
#
# # Set the current hostname
# currentHost = "laptop"; # Or use config.networking.hostName if available
# };
#
# # Use ports in your configuration:
# home.file.".config/myapp/config.json".text = builtins.toJSON {
# port = config.m3ta.ports.get "dev-server";
# };
#
# # Generate environment variables:
# home.sessionVariables = {
# DEV_SERVER_PORT = toString (config.m3ta.ports.get "dev-server");
# JUPYTER_PORT = toString (config.m3ta.ports.get "jupyter");
# };
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.m3ta.ports;
portsLib = import ../../lib/ports.nix {inherit lib;};
portHelpers =
if cfg.enable
then
portsLib.mkPortHelpers {
ports = cfg.definitions;
hostPorts = cfg.hostOverrides;
}
else null;
in {
options.m3ta.ports = {
enable = mkEnableOption "centralized port management for Home Manager";
definitions = mkOption {
type = types.attrsOf types.port;
default = {};
description = "Default port definitions for user services.";
};
hostOverrides = mkOption {
type = types.attrsOf (types.attrsOf types.port);
default = {};
description = "Host-specific port overrides.";
};
currentHost = mkOption {
type = types.nullOr types.str;
default = null;
description = "Hostname to use for port resolution.";
};
# Internal computed options
get = mkOption {
type = types.raw;
readOnly = true;
internal = true;
};
getForHost = mkOption {
type = types.raw;
readOnly = true;
internal = true;
};
all = mkOption {
type = types.attrsOf types.port;
readOnly = true;
internal = true;
};
allForHost = mkOption {
type = types.raw;
readOnly = true;
internal = true;
};
services = mkOption {
type = types.listOf types.str;
readOnly = true;
internal = true;
};
# Env var generation
generateEnvVars = mkOption {
type = types.bool;
default = false;
description = "Generate environment variables for all ports.";
};
envVarPrefix = mkOption {
type = types.str;
default = "PORT_";
description = "Prefix for generated environment variables.";
};
};
config = mkIf cfg.enable {
m3ta.ports.get = service: portHelpers.getPort service cfg.currentHost;
m3ta.ports.getForHost = host: service: portHelpers.getPort service host;
m3ta.ports.all = portHelpers.getHostPorts cfg.currentHost;
m3ta.ports.allForHost = portHelpers.getHostPorts;
m3ta.ports.services = portHelpers.listServices;
home.sessionVariables = mkIf cfg.generateEnvVars (
let
toEnvVarName = service:
cfg.envVarPrefix + (lib.toUpper (builtins.replaceStrings ["-"] ["_"] service));
in
builtins.listToAttrs (
map (service: {
name = toEnvVarName service;
value = toString (cfg.get service);
})
cfg.services
)
);
home.file.".config/m3ta/ports.json".text = builtins.toJSON {
hostname = cfg.currentHost;
ports = cfg.all;
allDefinitions = cfg.definitions;
hostOverrides = cfg.hostOverrides;
};
};
}
-30
View File
@@ -1,30 +0,0 @@
# NixOS Modules
# Import this in your NixOS configuration with:
# imports = [ inputs.m3ta-nixpkgs.nixosModules.default ];
{
config,
lib,
pkgs,
...
}: {
# This is the main entry point for all custom NixOS modules
# Add your custom modules here as imports or inline definitions
imports = [
./mem0.nix
./ports.nix
# Example: ./my-service.nix
# Add more module files here as you create them
];
# You can also define inline options here
# options = {
# m3ta = {
# # Your custom options
# };
# };
# config = {
# # Your custom configuration
# };
}
-363
View File
@@ -1,363 +0,0 @@
# NixOS Module for Mem0 REST API Server
#
# This module provides a systemd service for the Mem0 REST API server,
# allowing you to run mem0 as a system service with configurable vector storage.
#
# Usage in your NixOS configuration:
#
# # In your flake.nix or configuration.nix:
# imports = [ inputs.m3ta-nixpkgs.nixosModules.default ];
#
# m3ta.mem0 = {
# enable = true;
# port = 8000;
# host = "127.0.0.1";
#
# # LLM Configuration
# llm = {
# provider = "openai";
# apiKeyFile = "/run/secrets/openai-api-key"; # Use agenix or sops-nix
# model = "gpt-4";
# };
#
# # Vector Storage Configuration
# vectorStore = {
# provider = "qdrant"; # or "chroma", "pinecone", etc.
# config = {
# host = "localhost";
# port = 6333;
# };
# };
#
# # Optional: Environment variables
# environmentFile = "/etc/mem0/environment";
# };
#
# Using with m3ta.ports (recommended):
#
# m3ta.ports = {
# enable = true;
# definitions = { mem0 = 8000; };
# hostOverrides.laptop = { mem0 = 8080; };
# currentHost = config.networking.hostName;
# };
#
# m3ta.mem0 = {
# enable = true;
# port = config.m3ta.ports.get "mem0"; # Automatically uses host-specific port
# };
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.m3ta.mem0;
# Python environment with mem0
pythonEnv = pkgs.python3.withPackages (ps:
with ps; [
cfg.package
]);
# Convert vector store config to environment variables
vectorStoreEnv =
if cfg.vectorStore.provider == "qdrant"
then {
MEM0_VECTOR_PROVIDER = "qdrant";
QDRANT_HOST = cfg.vectorStore.config.host or "localhost";
QDRANT_PORT = toString (cfg.vectorStore.config.port or 6333);
QDRANT_COLLECTION = cfg.vectorStore.config.collection_name or "mem0_memories";
}
else if cfg.vectorStore.provider == "pgvector"
then {
MEM0_VECTOR_PROVIDER = "pgvector";
POSTGRES_HOST = cfg.vectorStore.config.host or "localhost";
POSTGRES_PORT = toString (cfg.vectorStore.config.port or 5432);
POSTGRES_DB = cfg.vectorStore.config.dbname or "postgres";
POSTGRES_USER = cfg.vectorStore.config.user or "postgres";
POSTGRES_PASSWORD = cfg.vectorStore.config.password or "postgres";
POSTGRES_COLLECTION = cfg.vectorStore.config.collection_name or "mem0_memories";
}
else if cfg.vectorStore.provider == "chroma"
then {
MEM0_VECTOR_PROVIDER = "chroma";
CHROMA_HOST = cfg.vectorStore.config.host or "localhost";
CHROMA_PORT = toString (cfg.vectorStore.config.port or 8000);
CHROMA_COLLECTION = cfg.vectorStore.config.collection_name or "mem0_memories";
}
else {};
# Start script that sets up environment and runs the server
startScript = pkgs.writeShellScript "mem0-start" ''
set -e
# Load environment file if specified
${optionalString (cfg.environmentFile != null) ''
if [ -f "${cfg.environmentFile}" ]; then
set -a
source "${cfg.environmentFile}"
set +a
fi
''}
# Load API key from file if specified
${optionalString (cfg.llm.apiKeyFile != null) ''
if [ -f "${cfg.llm.apiKeyFile}" ]; then
export OPENAI_API_KEY="$(cat ${cfg.llm.apiKeyFile})"
fi
''}
# Create state directory
mkdir -p ${cfg.stateDir}
cd ${cfg.stateDir}
# Run the server
exec ${pythonEnv}/bin/mem0-server
'';
in {
options.m3ta.mem0 = {
enable = mkEnableOption "Mem0 REST API server";
package = mkOption {
type = types.package;
default = pkgs.mem0;
defaultText = literalExpression "pkgs.mem0";
description = "The mem0 package to use.";
};
host = mkOption {
type = types.str;
default = "127.0.0.1";
description = "Host address to bind the server to.";
};
port = mkOption {
type = types.port;
default = 8000;
description = "Port to run the REST API server on.";
};
workers = mkOption {
type = types.int;
default = 1;
description = "Number of worker processes.";
};
logLevel = mkOption {
type = types.enum ["critical" "error" "warning" "info" "debug" "trace"];
default = "info";
description = "Logging level for the server.";
};
stateDir = mkOption {
type = types.path;
default = "/var/lib/mem0";
description = "Directory to store mem0 data and state.";
};
user = mkOption {
type = types.str;
default = "mem0";
description = "User account under which mem0 runs.";
};
group = mkOption {
type = types.str;
default = "mem0";
description = "Group under which mem0 runs.";
};
environmentFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Environment file containing additional configuration.
This file should contain KEY=value pairs, one per line.
Useful for secrets that shouldn't be in the Nix store.
'';
example = "/etc/mem0/environment";
};
# LLM Configuration
llm = {
provider = mkOption {
type = types.enum ["openai" "anthropic" "azure" "groq" "together" "ollama" "litellm"];
default = "openai";
description = "LLM provider to use for memory operations.";
};
model = mkOption {
type = types.str;
default = "gpt-4o-mini";
description = "Model name to use for the LLM.";
};
apiKeyFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Path to file containing the API key for the LLM provider.
The file should contain only the API key.
This is more secure than putting the key in the Nix store.
'';
example = "/run/secrets/openai-api-key";
};
temperature = mkOption {
type = types.nullOr types.float;
default = null;
description = "Temperature parameter for LLM generation.";
};
maxTokens = mkOption {
type = types.nullOr types.int;
default = null;
description = "Maximum tokens for LLM generation.";
};
extraConfig = mkOption {
type = types.attrs;
default = {};
description = "Additional LLM configuration options.";
example = {
top_p = 1.0;
frequency_penalty = 0.0;
};
};
};
# Vector Store Configuration
vectorStore = {
provider = mkOption {
type = types.enum [
"qdrant"
"chroma"
"pinecone"
"weaviate"
"faiss"
"pgvector"
"redis"
"elasticsearch"
"milvus"
];
default = "qdrant";
description = "Vector database provider to use.";
};
config = mkOption {
type = types.attrs;
default = {};
description = ''
Configuration for the vector store.
The structure depends on the provider.
'';
example = literalExpression ''
{
host = "localhost";
port = 6333;
collection_name = "mem0_memories";
}
'';
};
};
# Embedder Configuration
embedder = {
provider = mkOption {
type = types.nullOr (types.enum ["openai" "huggingface" "ollama" "vertexai"]);
default = null;
description = "Embedding model provider. If null, uses default.";
};
model = mkOption {
type = types.nullOr types.str;
default = null;
description = "Embedding model name to use.";
example = "text-embedding-3-small";
};
config = mkOption {
type = types.attrs;
default = {};
description = "Configuration for the embedder.";
example = {
model = "text-embedding-3-small";
};
};
};
};
config = mkIf cfg.enable {
# Create user and group
users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
description = "Mem0 service user";
home = cfg.stateDir;
createHome = true;
};
users.groups.${cfg.group} = {};
# Systemd service
systemd.services.mem0 = {
description = "Mem0 REST API Server";
after = ["network.target"];
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "simple";
User = cfg.user;
Group = cfg.group;
ExecStart = startScript;
Restart = "on-failure";
RestartSec = "5s";
# Security hardening
NoNewPrivileges = true;
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
ReadWritePaths = [cfg.stateDir];
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
RestrictRealtime = true;
RestrictNamespaces = true;
LockPersonality = true;
MemoryDenyWriteExecute = false; # Python needs this
RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
};
environment =
{
PYTHONUNBUFFERED = "1";
MEM0_HOST = cfg.host;
MEM0_PORT = toString cfg.port;
MEM0_LLM_PROVIDER = cfg.llm.provider;
MEM0_LLM_MODEL = cfg.llm.model;
MEM0_HISTORY_DB_PATH = "${cfg.stateDir}/history.db";
MEM0_WORKERS = toString cfg.workers;
MEM0_LOG_LEVEL = cfg.logLevel;
}
// optionalAttrs (cfg.llm.temperature != null) {
MEM0_LLM_TEMPERATURE = toString cfg.llm.temperature;
}
// optionalAttrs (cfg.llm.extraConfig != {}) {
MEM0_LLM_EXTRA_CONFIG = builtins.toJSON cfg.llm.extraConfig;
}
// optionalAttrs (cfg.embedder.provider != null) {
MEM0_EMBEDDER_PROVIDER = cfg.embedder.provider;
}
// optionalAttrs (cfg.embedder.model != null) {
MEM0_EMBEDDER_MODEL = cfg.embedder.model;
}
// vectorStoreEnv;
};
# Open firewall port if binding to non-localhost
networking.firewall.allowedTCPPorts = mkIf (cfg.host != "127.0.0.1" && cfg.host != "localhost") [cfg.port];
};
}
-124
View File
@@ -1,124 +0,0 @@
# NixOS Module for Port Management
#
# This module provides centralized port management across your NixOS systems.
# Define ports once and use them consistently across all services, with
# support for host-specific overrides.
#
# Usage in your NixOS configuration:
#
# # In your flake.nix or configuration.nix:
# imports = [ inputs.m3ta-nixpkgs.nixosModules.default ];
#
# m3ta.ports = {
# enable = true;
#
# # Define your default ports
# definitions = {
# nginx = 80;
# grafana = 3000;
# prometheus = 9090;
# homepage = 8080;
# ssh = 22;
# };
#
# # Define host-specific overrides
# hostOverrides = {
# laptop = {
# nginx = 8080; # Use non-privileged port on laptop
# ssh = 2222;
# };
# server = {
# homepage = 3001;
# };
# };
#
# # Optionally set the current hostname for automatic port resolution
# currentHost = config.networking.hostName;
# };
#
# # Use ports in your configuration:
# services.nginx.defaultHTTPListenPort = config.m3ta.ports.get "nginx";
# services.grafana.settings.server.http_port = config.m3ta.ports.get "grafana";
#
# # Or access all ports for the current host:
# environment.etc."my-ports.json".text = builtins.toJSON config.m3ta.ports.all;
{
config,
lib,
...
}:
with lib; let
cfg = config.m3ta.ports;
portsLib = import ../../lib/ports.nix {inherit lib;};
portHelpers =
if cfg.enable
then
portsLib.mkPortHelpers {
ports = cfg.definitions;
hostPorts = cfg.hostOverrides;
}
else null;
in {
options.m3ta.ports = {
enable = mkEnableOption "centralized port management";
definitions = mkOption {
type = types.attrsOf types.port;
default = {};
description = "Default port definitions for services.";
};
hostOverrides = mkOption {
type = types.attrsOf (types.attrsOf types.port);
default = {};
description = "Host-specific port overrides.";
};
currentHost = mkOption {
type = types.str;
default = config.networking.hostName;
description = "Hostname to use for port resolution.";
};
# Internal computed options
get = mkOption {
type = types.raw;
readOnly = true;
internal = true;
};
getForHost = mkOption {
type = types.raw;
readOnly = true;
internal = true;
};
all = mkOption {
type = types.attrsOf types.port;
readOnly = true;
internal = true;
};
allForHost = mkOption {
type = types.raw;
readOnly = true;
internal = true;
};
services = mkOption {
type = types.listOf types.str;
readOnly = true;
internal = true;
};
};
config = mkIf cfg.enable {
m3ta.ports.get = service: portHelpers.getPort service cfg.currentHost;
m3ta.ports.getForHost = host: service: portHelpers.getPort service host;
m3ta.ports.all = portHelpers.getHostPorts cfg.currentHost;
m3ta.ports.allForHost = portHelpers.getHostPorts;
m3ta.ports.services = portHelpers.listServices;
};
}
-70
View File
@@ -1,70 +0,0 @@
{inputs, ...}: {
# This one brings our custom packages from the 'pkgs' directory
additions = final: prev:
(import ../pkgs {pkgs = final;})
# // (inputs.hyprpanel.overlay final prev)
// {rose-pine-hyprcursor = inputs.rose-pine-hyprcursor.packages.${prev.system}.default;};
# This one contains whatever you want to overlay
# You can change versions, add patches, set compilation flags, anything really.
# https://nixos.wiki/wiki/Overlays
modifications = final: prev:
# Import all package modifications from mods directory
(import ./mods/default.nix {inherit prev;})
// {
# Direct configuration overrides
brave = prev.brave.override {
commandLineArgs = "--password-store=gnome-libsecret";
};
# nodejs_24 = inputs.nixpkgs-stable.legacyPackages.${prev.system}.nodejs_24;
# paperless-ngx = inputs.nixpkgs-45570c2.legacyPackages.${prev.system}.paperless-ngx;
# anytype-heart = inputs.nixpkgs-9e58ed7.legacyPackages.${prev.system}.anytype-heart;
# trezord = inputs.nixpkgs-2744d98.legacyPackages.${prev.system}.trezord;
# mesa = inputs.nixpkgs-master.legacyPackages.${prev.system}.mesa;
# hyprpanel = inputs.hyprpanel.packages.${prev.system}.default.overrideAttrs (prev: {
# version = "latest"; # or whatever version you want
# src = final.fetchFromGitHub {
# owner = "Jas-SinghFSU";
# repo = "HyprPanel";
# rev = "master"; # or a specific commit hash
# hash = "sha256-l623fIVhVCU/ylbBmohAtQNbK0YrWlEny0sC/vBJ+dU=";
# };
# });
};
temp-packages = final: _prev: {
temp = import inputs.nixpkgs-9e9486b {
system = final.system;
config.allowUnfree = true;
};
};
stable-packages = final: _prev: {
stable = import inputs.nixpkgs-stable {
system = final.system;
config.allowUnfree = true;
};
};
pinned-packages = final: _prev: {
pinned = import inputs.nixpkgs-9472de4 {
system = final.system;
config.allowUnfree = true;
};
};
locked-packages = final: _prev: {
locked = import inputs.nixpkgs-locked {
system = final.system;
config.allowUnfree = true;
};
};
master-packages = final: _prev: {
master = import inputs.nixpkgs-master {
system = final.system;
config.allowUnfree = true;
};
};
}
-16
View File
@@ -1,16 +0,0 @@
{prev}:
prev.beads.overrideAttrs (oldAttrs: rec {
version = "0.47.1";
src = prev.fetchFromGitHub {
owner = "steveyegge";
repo = "beads";
tag = "v${version}";
hash = "sha256-DwIR/r1TJnpVd/CT1E2OTkAjU7k9/KHbcVwg5zziFVg=";
};
vendorHash = "sha256-pY5m5ODRgqghyELRwwxOr+xlW41gtJWLXaW53GlLaFw=";
# Tests require git worktree operations that fail in Nix sandbox
doCheck = false;
})
-10
View File
@@ -1,10 +0,0 @@
{prev}: {
# Package modifications
# This overlay contains package overrides and modifications
# n8n = import ./n8n.nix {inherit prev;};
# beads = import ./beads.nix {inherit prev;};
# Add more modifications here as needed
# example-package = prev.example-package.override { ... };
}
-18
View File
@@ -1,18 +0,0 @@
{prev}:
prev.n8n.overrideAttrs (oldAttrs: rec {
version = "2.4.1";
src = prev.fetchFromGitHub {
owner = "n8n-io";
repo = "n8n";
rev = "n8n@${version}";
hash = "sha256-EQP9ZI8kt30SUYE1+/UUpxQXpavzKqDu8qE24zsNifg=";
};
pnpmDeps = prev.pnpm_10.fetchDeps {
pname = oldAttrs.pname;
inherit version src;
fetcherVersion = 1;
hash = "sha256-Q30IuFEQD3896Hg0HCLd38YE2i8fJn74JY0o95LKJis=";
};
})
-33
View File
@@ -1,33 +0,0 @@
# pkgs/ AGENTS.md
## OVERVIEW
Custom package registry using `callPackage` pattern for flake-wide availability.
## STRUCTURE
- `default.nix`: Central registry (entry point for overlays)
- `code2prompt/`: Rust package
- `hyprpaper-random/`: Bash script
- `launch-webapp/`: Webapp wrapper
- `mem0/`: Python package + custom `server.py`
- `msty-studio/`: AppImage wrapper
- `pomodoro-timer/`: Timer utility
- `tuxedo-backlight/`: Hardware control
- `zellij-ps/`: Gitea-hosted package
## WHERE TO LOOK
- **Register new pkg**: Add entry to `pkgs/default.nix` attribute set
- **Modify pkg**: Edit `pkgs/<name>/default.nix` (version, hash, deps)
- **Check visibility**: `nix flake show` (uses `pkgs/default.nix` via `overlays/default.nix`)
- **Add scripts**: Place alongside `default.nix` in package folder (e.g., `mem0/server.py`)
## CONVENTIONS
- **CallPackage**: Always use `pkgs.callPackage ./dir {}` in registry
- **Dir == Attr**: Package directory name MUST match its registry attribute
- **Path literals**: Reference local assets using `./file` within derivations
- **Self-contained**: Keep all package-specific files in their own directory
## ANTI-PATTERNS
- **Orphaned dirs**: Creating `pkgs/new-pkg/` without updating `pkgs/default.nix`
- **Direct flake imports**: Importing packages in `flake.nix` instead of through the registry
- **Implicit deps**: Not declaring dependencies in the package function arguments
- **Non-derivations**: Placing NixOS/HM modules here (use `modules/` instead)
-64
View File
@@ -1,64 +0,0 @@
{
lib,
stdenv,
buildGoModule,
fetchFromGitHub,
gitMinimal,
installShellFiles,
nix-update-script,
versionCheckHook,
writableTmpDirAsHomeHook,
}:
buildGoModule (finalAttrs: {
pname = "beads";
version = "0.49.1";
src = fetchFromGitHub {
owner = "steveyegge";
repo = "beads";
tag = "v${finalAttrs.version}";
hash = "sha256-roOyTMy9nKxH2Bk8MnP4h2CDjStwK6z0ThQhFcM64QI=";
};
vendorHash = "sha256-YU+bRLVlWtHzJ1QPzcKJ70f+ynp8lMoIeFlm+29BNPE=";
subPackages = ["cmd/bd"];
ldflags = ["-s" "-w"];
nativeBuildInputs = [installShellFiles];
nativeCheckInputs = [gitMinimal writableTmpDirAsHomeHook];
# Skip security tests on Darwin - they check for /etc/passwd which isn't available in sandbox
checkFlags =
lib.optionals stdenv.hostPlatform.isDarwin
["-skip=TestCleanupMergeArtifacts_CommandInjectionPrevention"];
preCheck = ''
export PATH="$out/bin:$PATH"
'';
postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
installShellCompletion --cmd bd \
--bash <($out/bin/bd completion bash) \
--fish <($out/bin/bd completion fish) \
--zsh <($out/bin/bd completion zsh)
'';
nativeInstallCheckInputs = [versionCheckHook writableTmpDirAsHomeHook];
versionCheckProgramArg = "version";
doInstallCheck = true;
doCheck = false;
passthru.updateScript = nix-update-script {};
meta = {
description = "Lightweight memory system for AI coding agents with graph-based issue tracking";
homepage = "https://github.com/steveyegge/beads";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [kedry];
mainProgram = "bd";
};
})
-40
View File
@@ -1,40 +0,0 @@
{
lib,
fetchFromGitHub,
nix-update-script,
rustPlatform,
pkg-config,
perl,
openssl,
}:
rustPlatform.buildRustPackage rec {
pname = "code2prompt";
version = "4.2.0";
src = fetchFromGitHub {
owner = "mufeedvh";
repo = "code2prompt";
rev = "v${version}";
hash = "sha256-Gh8SsSTZW7QlyyC3SWJ5pOK2x85/GT7+LPJn2Jeczpc=";
};
cargoLock = {
lockFile = src + "/Cargo.lock";
};
buildAndTestSubdir = "crates/code2prompt";
nativeBuildInputs = [pkg-config perl];
buildInputs = [openssl];
passthru.updateScript = nix-update-script {};
meta = with lib; {
description = "A CLI tool that converts your codebase into a single LLM prompt with a source tree, prompt templating, and token counting";
homepage = "https://github.com/mufeedvh/code2prompt";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "code2prompt";
};
}
-26
View File
@@ -1,26 +0,0 @@
{
pkgs,
inputs ? null,
...
}: {
# Custom packages registry
# Each package is defined in its own directory under pkgs/
beads = pkgs.callPackage ./beads {};
sidecar = pkgs.callPackage ./sidecar {};
td = pkgs.callPackage ./td {};
code2prompt = pkgs.callPackage ./code2prompt {};
hyprpaper-random = pkgs.callPackage ./hyprpaper-random {};
launch-webapp = pkgs.callPackage ./launch-webapp {};
mem0 = pkgs.callPackage ./mem0 {};
msty-studio = pkgs.callPackage ./msty-studio {};
n8n = pkgs.callPackage ./n8n {};
pomodoro-timer = pkgs.callPackage ./pomodoro-timer {};
rofi-project-opener = pkgs.callPackage ./rofi-project-opener {};
stt-ptt = pkgs.callPackage ./stt-ptt {};
tuxedo-backlight = pkgs.callPackage ./tuxedo-backlight {};
zellij-ps = pkgs.callPackage ./zellij-ps {};
# Imported from flake inputs
opencode = inputs.opencode.packages.${pkgs.system}.opencode;
# opencode-desktop = pkgs.callPackage ./opencode-desktop { inherit inputs; };
}
-72
View File
@@ -1,72 +0,0 @@
{
lib,
stdenv,
writeShellScriptBin,
fd,
hyprland,
coreutils,
gawk,
}: let
script = writeShellScriptBin "hyprpaper-random" ''
#!/usr/bin/env bash
set -euo pipefail
# Directory (override with WALLPAPER_DIR)
DIR="''${WALLPAPER_DIR:-''${XDG_CONFIG_HOME:-$HOME/.config}/hypr/wallpapers}"
HYPRCTL="${hyprland}/bin/hyprctl"
FD="${fd}/bin/fd"
SHUF="${coreutils}/bin/shuf"
TR="${coreutils}/bin/tr"
AWK="${gawk}/bin/awk"
# Pick one random image (null-safe)
WALLPAPER="$(
"$FD" . "$DIR" -t f -e jpg -e jpeg -e png -e webp -e avif -0 --follow --hidden \
| "$SHUF" -z -n1 \
| "$TR" -d '\0'
)"
if [[ -z "''${WALLPAPER:-}" ]]; then
echo "No wallpapers found in: $DIR" >&2
exit 1
fi
# Preload so hyprpaper can use it
"$HYPRCTL" hyprpaper preload "$WALLPAPER" >/dev/null 2>&1 || true
# Apply to all monitors
"$HYPRCTL" monitors \
| "$AWK" '/^Monitor /{print $2}' \
| while IFS= read -r mon; do
[ -n "$mon" ] && "$HYPRCTL" hyprpaper wallpaper "$mon,$WALLPAPER"
done
exit 0
'';
in
stdenv.mkDerivation {
pname = "hyprpaper-random";
version = "0.1.1";
dontUnpack = true;
buildInputs = [
fd
hyprland
coreutils
gawk
];
installPhase = ''
mkdir -p "$out/bin"
ln -s ${script}/bin/hyprpaper-random "$out/bin/hyprpaper-random"
'';
meta = {
description = "Minimal random wallpaper setter for Hyprpaper";
license = lib.licenses.mit;
platforms = lib.platforms.linux;
mainProgram = "hyprpaper-random";
};
}
-41
View File
@@ -1,41 +0,0 @@
{
lib,
stdenv,
writeShellScriptBin,
}: let
launcher = writeShellScriptBin "launch-webapp" ''
#!/usr/bin/env bash
browser=$(xdg-settings get default-web-browser)
case "$browser" in
google-chrome*) browser_bin="google-chrome" ;;
brave-browser*) browser_bin="brave-browser" ;;
microsoft-edge*) browser_bin="microsoft-edge" ;;
opera*) browser_bin="opera" ;;
vivaldi*) browser_bin="vivaldi" ;;
*) browser_bin="chromium" ;;
esac
exec_cmd="/etc/profiles/per-user/$USER/bin/$browser_bin"
exec setsid uwsm app -- "$exec_cmd" --app="$1" ''${@:2}
'';
in
stdenv.mkDerivation {
pname = "launch-webapp";
version = "0.1.0";
dontUnpack = true;
installPhase = ''
mkdir -p $out/bin
ln -s ${launcher}/bin/launch-webapp $out/bin/launch-webapp
'';
meta = {
description = "Launches a web app using your default browser in app mode.";
license = lib.licenses.mit;
platforms = lib.platforms.linux;
mainProgram = "launch-webapp";
};
}
-102
View File
@@ -1,102 +0,0 @@
{
lib,
nix-update-script,
python3,
fetchFromGitHub,
}:
python3.pkgs.buildPythonPackage rec {
pname = "mem0ai";
version = "1.0.3";
pyproject = true;
src = fetchFromGitHub {
owner = "mem0ai";
repo = "mem0";
rev = "v${version}";
hash = "sha256-OIiInnXSE4Q+d+Hwb/cPD29aCYNQjPDshPVv/MsLy5Y=";
};
# Relax Python dependency version constraints
# mem0 has strict version pins that may not match nixpkgs versions
pythonRelaxDeps = true;
build-system = with python3.pkgs; [
hatchling
];
dependencies = with python3.pkgs; [
litellm
qdrant-client
pydantic
openai
posthog
pytz
sqlalchemy
protobuf
uvicorn
fastapi
];
optional-dependencies = with python3.pkgs; {
graph = [
# Note: some graph dependencies may not be available in nixpkgs
# neo4j is available, others will need to be packaged separately
];
vector_stores = [
# chromadb # available in nixpkgs
# pinecone-client # may need packaging
# weaviate-client # may need packaging
# faiss # available as faiss-cpu
psycopg
pymongo
pymysql
redis
elasticsearch
];
llms = [
groq
openai
# together # may need packaging
# litellm # may need packaging
# ollama # may need packaging
# google-generativeai # may need packaging
];
extras = [
boto3
# langchain-community # may need packaging
# sentence-transformers # may need packaging
elasticsearch
# fastembed # may need packaging
];
};
# Skip tests for now since they require additional test dependencies
doCheck = false;
# Disable imports check because mem0 tries to create directories at import time
# which fails in the Nix sandbox (/homeless-shelter)
pythonImportsCheck = [];
postInstall = ''
install -Dm755 ${./server.py} $out/bin/mem0-server
'';
passthru.updateScript = nix-update-script {};
meta = with lib; {
description = "Long-term memory layer for AI agents with REST API support";
longDescription = ''
Mem0 provides a sophisticated memory layer for AI applications, offering:
- Memory management for AI agents (add, search, update, delete)
- REST API server for easy integration
- Support for multiple vector storage backends (Qdrant, Chroma, etc.)
- Graph memory capabilities
- Multi-modal support
- Configurable LLM and embedding models
'';
homepage = "https://github.com/mem0ai/mem0";
changelog = "https://github.com/mem0ai/mem0/releases/tag/v${version}";
license = licenses.asl20;
platforms = platforms.linux;
};
}
-301
View File
@@ -1,301 +0,0 @@
#!/usr/bin/env python3
"""
Mem0 REST API Server
A FastAPI-based REST server for mem0 memory operations.
"""
import logging
import os
import sys
from typing import Any, Dict, List, Optional
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse, RedirectResponse
from pydantic import BaseModel, Field
from mem0 import Memory
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
# Configuration from environment variables
def get_config_from_env() -> Dict[str, Any]:
"""Build mem0 configuration from environment variables."""
config = {"version": "v1.1"}
# Vector store configuration
vector_provider = os.environ.get("MEM0_VECTOR_PROVIDER", "qdrant")
config["vector_store"] = {"provider": vector_provider}
if vector_provider == "qdrant":
config["vector_store"]["config"] = {
"host": os.environ.get("QDRANT_HOST", "localhost"),
"port": int(os.environ.get("QDRANT_PORT", "6333")),
"collection_name": os.environ.get("QDRANT_COLLECTION", "mem0_memories"),
}
elif vector_provider == "pgvector":
config["vector_store"]["config"] = {
"host": os.environ.get("POSTGRES_HOST", "localhost"),
"port": int(os.environ.get("POSTGRES_PORT", "5432")),
"dbname": os.environ.get("POSTGRES_DB", "postgres"),
"user": os.environ.get("POSTGRES_USER", "postgres"),
"password": os.environ.get("POSTGRES_PASSWORD", "postgres"),
"collection_name": os.environ.get("POSTGRES_COLLECTION", "mem0_memories"),
}
elif vector_provider == "chroma":
config["vector_store"]["config"] = {
"host": os.environ.get("CHROMA_HOST", "localhost"),
"port": int(os.environ.get("CHROMA_PORT", "8000")),
"collection_name": os.environ.get("CHROMA_COLLECTION", "mem0_memories"),
}
# LLM configuration
llm_provider = os.environ.get("MEM0_LLM_PROVIDER", "openai")
config["llm"] = {
"provider": llm_provider,
"config": {
"model": os.environ.get("MEM0_LLM_MODEL", "gpt-4o-mini"),
}
}
# Temperature: only include if set (null means use provider default)
temperature = os.environ.get("MEM0_LLM_TEMPERATURE")
if temperature is not None:
config["llm"]["config"]["temperature"] = float(temperature)
# Extra config: merge JSON env var if provided
extra_config_json = os.environ.get("MEM0_LLM_EXTRA_CONFIG")
if extra_config_json:
import json
try:
extra_config = json.loads(extra_config_json)
config["llm"]["config"].update(extra_config)
except json.JSONDecodeError:
logging.warning(f"Failed to parse MEM0_LLM_EXTRA_CONFIG: {extra_config_json}")
# Add API key if available
if llm_provider == "openai":
api_key = os.environ.get("OPENAI_API_KEY")
if api_key:
config["llm"]["config"]["api_key"] = api_key
# Embedder configuration
embedder_provider = os.environ.get("MEM0_EMBEDDER_PROVIDER", "openai")
config["embedder"] = {
"provider": embedder_provider,
}
# Embedder model: only include if provider is set
if embedder_provider:
embedder_config = {}
embedder_model = os.environ.get("MEM0_EMBEDDER_MODEL")
if embedder_model:
embedder_config["model"] = embedder_model
config["embedder"]["config"] = embedder_config
if embedder_provider == "openai":
api_key = os.environ.get("OPENAI_API_KEY")
if api_key:
config["embedder"]["config"]["api_key"] = api_key
# History DB path
history_db_path = os.environ.get("MEM0_HISTORY_DB_PATH", "/var/lib/mem0/history.db")
config["history_db_path"] = history_db_path
return config
# Initialize Memory instance
try:
config = get_config_from_env()
logging.info(f"Initializing mem0 with config: {config}")
# Validate API key is set for OpenAI provider
if config.get("llm", {}).get("provider") == "openai":
if not config.get("llm", {}).get("config", {}).get("api_key"):
logging.error("OPENAI_API_KEY environment variable is required but not set.")
logging.error("Please set OPENAI_API_KEY environment variable or configure apiKeyFile in NixOS module.")
sys.exit(1)
MEMORY_INSTANCE = Memory.from_config(config)
logging.info("Memory instance initialized successfully")
except Exception as e:
logging.error(f"Failed to initialize Memory: {e}")
logging.error("Please check your configuration and ensure all required services are running.")
sys.exit(1)
app = FastAPI(
title="Mem0 REST API",
description="A REST API for managing and searching memories for your AI Agents and Apps.",
version="1.0.0",
)
class Message(BaseModel):
role: str = Field(..., description="Role of the message (user or assistant).")
content: str = Field(..., description="Message content.")
class MemoryCreate(BaseModel):
messages: List[Message] = Field(..., description="List of messages to store.")
user_id: Optional[str] = None
agent_id: Optional[str] = None
run_id: Optional[str] = None
metadata: Optional[Dict[str, Any]] = None
class SearchRequest(BaseModel):
query: str = Field(..., description="Search query.")
user_id: Optional[str] = None
run_id: Optional[str] = None
agent_id: Optional[str] = None
filters: Optional[Dict[str, Any]] = None
@app.get("/", summary="Redirect to documentation", include_in_schema=False)
def home():
"""Redirect to the OpenAPI documentation."""
return RedirectResponse(url="/docs")
@app.get("/health", summary="Health check")
def health():
"""Check if the server is running."""
return {"status": "healthy", "service": "mem0-api"}
@app.post("/configure", summary="Configure Mem0")
def set_config(config: Dict[str, Any]):
"""Set memory configuration."""
global MEMORY_INSTANCE
MEMORY_INSTANCE = Memory.from_config(config)
return {"message": "Configuration set successfully"}
@app.post("/memories", summary="Create memories")
def add_memory(memory_create: MemoryCreate):
"""Store new memories."""
if not any([memory_create.user_id, memory_create.agent_id, memory_create.run_id]):
raise HTTPException(status_code=400, detail="At least one identifier (user_id, agent_id, run_id) is required.")
params = {k: v for k, v in memory_create.model_dump().items() if v is not None and k != "messages"}
try:
response = MEMORY_INSTANCE.add(messages=[m.model_dump() for m in memory_create.messages], **params)
return JSONResponse(content=response)
except Exception as e:
logging.exception("Error in add_memory:")
raise HTTPException(status_code=500, detail=str(e))
@app.get("/memories", summary="Get memories")
def get_all_memories(
user_id: Optional[str] = None,
run_id: Optional[str] = None,
agent_id: Optional[str] = None,
):
"""Retrieve stored memories."""
if not any([user_id, run_id, agent_id]):
raise HTTPException(status_code=400, detail="At least one identifier is required.")
try:
params = {
k: v for k, v in {"user_id": user_id, "run_id": run_id, "agent_id": agent_id}.items() if v is not None
}
return MEMORY_INSTANCE.get_all(**params)
except Exception as e:
logging.exception("Error in get_all_memories:")
raise HTTPException(status_code=500, detail=str(e))
@app.get("/memories/{memory_id}", summary="Get a memory")
def get_memory(memory_id: str):
"""Retrieve a specific memory by ID."""
try:
return MEMORY_INSTANCE.get(memory_id)
except Exception as e:
logging.exception("Error in get_memory:")
raise HTTPException(status_code=500, detail=str(e))
@app.post("/search", summary="Search memories")
def search_memories(search_req: SearchRequest):
"""Search for memories based on a query."""
try:
params = {k: v for k, v in search_req.model_dump().items() if v is not None and k != "query"}
return MEMORY_INSTANCE.search(query=search_req.query, **params)
except Exception as e:
logging.exception("Error in search_memories:")
raise HTTPException(status_code=500, detail=str(e))
@app.put("/memories/{memory_id}", summary="Update a memory")
def update_memory(memory_id: str, updated_memory: Dict[str, Any]):
"""Update an existing memory with new content."""
try:
return MEMORY_INSTANCE.update(memory_id=memory_id, data=updated_memory)
except Exception as e:
logging.exception("Error in update_memory:")
raise HTTPException(status_code=500, detail=str(e))
@app.get("/memories/{memory_id}/history", summary="Get memory history")
def memory_history(memory_id: str):
"""Retrieve memory history."""
try:
return MEMORY_INSTANCE.history(memory_id=memory_id)
except Exception as e:
logging.exception("Error in memory_history:")
raise HTTPException(status_code=500, detail=str(e))
@app.delete("/memories/{memory_id}", summary="Delete a memory")
def delete_memory(memory_id: str):
"""Delete a specific memory by ID."""
try:
MEMORY_INSTANCE.delete(memory_id=memory_id)
return {"message": "Memory deleted successfully"}
except Exception as e:
logging.exception("Error in delete_memory:")
raise HTTPException(status_code=500, detail=str(e))
@app.delete("/memories", summary="Delete all memories")
def delete_all_memories(
user_id: Optional[str] = None,
run_id: Optional[str] = None,
agent_id: Optional[str] = None,
):
"""Delete all memories for a given identifier."""
if not any([user_id, run_id, agent_id]):
raise HTTPException(status_code=400, detail="At least one identifier is required.")
try:
params = {
k: v for k, v in {"user_id": user_id, "run_id": run_id, "agent_id": agent_id}.items() if v is not None
}
MEMORY_INSTANCE.delete_all(**params)
return {"message": "All relevant memories deleted"}
except Exception as e:
logging.exception("Error in delete_all_memories:")
raise HTTPException(status_code=500, detail=str(e))
@app.post("/reset", summary="Reset all memories")
def reset_memory():
"""Completely reset stored memories."""
try:
MEMORY_INSTANCE.reset()
return {"message": "All memories reset"}
except Exception as e:
logging.exception("Error in reset_memory:")
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
host = os.environ.get("MEM0_HOST", "127.0.0.1")
port = int(os.environ.get("MEM0_PORT", "8000"))
workers = int(os.environ.get("MEM0_WORKERS", "1"))
log_level = os.environ.get("MEM0_LOG_LEVEL", "info")
uvicorn.run(app, host=host, port=port, workers=workers, log_level=log_level)
-45
View File
@@ -1,45 +0,0 @@
{
appimageTools,
fetchurl,
lib,
nodejs,
nodePackages,
uv,
python3,
makeWrapper,
}: let
pname = "msty-studio";
version = "2.0.0-beta.4";
src = fetchurl {
url = "https://next-assets.msty.studio/app/alpha/linux/MstyStudio_x86_64.AppImage";
sha256 = "sha256-zJcGK7QEL3ROgVJy13mMdY/437H3Zx8EwSXy7rEhV9w=";
};
appimageContents = appimageTools.extractType2 {inherit pname version src;};
in
appimageTools.wrapType2 {
inherit pname version src;
nativeBuildInputs = [makeWrapper];
extraPkgs = pkgs: [
nodejs
nodePackages.npm
uv
python3
];
extraInstallCommands = ''
install -m 444 -D ${appimageContents}/MstyStudio.desktop -t $out/share/applications
substituteInPlace $out/share/applications/MstyStudio.desktop \
--replace 'Exec=AppRun' 'Exec=${pname}'
install -m 444 -D ${appimageContents}/MstyStudio.png \
$out/share/icons/hicolor/256x256/apps/MstyStudio.png
wrapProgram $out/bin/${pname} \
--prefix PATH : ${nodejs}/bin:${nodePackages.npm}/bin:${uv}/bin:${python3}/bin
'';
meta = {
description = "Msty Studio enables advanced, privacypreserving AI workflows entirely on your local machine.";
license = lib.licenses.unfree;
platforms = lib.platforms.linux;
mainProgram = "msty-studio";
};
}
-114
View File
@@ -1,114 +0,0 @@
{
stdenv,
lib,
nixosTests,
fetchFromGitHub,
nodejs,
pnpm_10,
fetchPnpmDeps,
pnpmConfigHook,
python3,
node-gyp,
cctools,
xcbuild,
libkrb5,
libmongocrypt,
libpq,
makeWrapper,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "n8n";
version = "n8n@2.6.4";
src = fetchFromGitHub {
owner = "n8n-io";
repo = "n8n";
tag = finalAttrs.version;
hash = "sha256-t3zwxyjiocVoq7wbH4WYiUggaZFHlV9/vzrIorH7jPc=";
};
pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
pnpm = pnpm_10;
fetcherVersion = 3;
hash = "sha256-vjgteuMd+lkEL9vT1Ngndk8G3Ad1esa1NBPpEHBFmDg=";
};
nativeBuildInputs =
[
pnpmConfigHook
pnpm_10
python3 # required to build sqlite3 bindings
node-gyp # required to build sqlite3 bindings
makeWrapper
]
++ lib.optional stdenv.hostPlatform.isDarwin [cctools xcbuild];
buildInputs = [nodejs libkrb5 libmongocrypt libpq];
buildPhase = ''
runHook preBuild
pushd node_modules/sqlite3
node-gyp rebuild
popd
# TODO: use deploy after resolved https://github.com/pnpm/pnpm/issues/5315
pnpm build --filter=n8n
runHook postBuild
'';
preInstall = ''
echo "Removing non-deterministic and unnecessary files"
find -type d -name .turbo -exec rm -rf {} +
rm node_modules/.modules.yaml
rm packages/nodes-base/dist/types/nodes.json
CI=true pnpm --ignore-scripts prune --prod
find -type f \( -name "*.ts" -o -name "*.map" \) -exec rm -rf {} +
rm -rf node_modules/.pnpm/{typescript*,prettier*}
shopt -s globstar
# https://github.com/pnpm/pnpm/issues/3645
find node_modules packages/**/node_modules -xtype l -delete
echo "Removed non-deterministic and unnecessary files"
'';
installPhase = ''
runHook preInstall
mkdir -p $out/{bin,lib/n8n}
mv {packages,node_modules} $out/lib/n8n
makeWrapper $out/lib/n8n/packages/cli/bin/n8n $out/bin/n8n \
--set N8N_RELEASE_TYPE "stable"
runHook postInstall
'';
passthru = {
tests = nixosTests.n8n;
updateScript = ./update.sh;
};
# this package has ~80000 files, these take too long and seem to be unnecessary
dontStrip = true;
dontPatchELF = true;
dontRewriteSymlinks = true;
meta = {
description = "Free and source-available fair-code licensed workflow automation tool";
longDescription = ''
Free and source-available fair-code licensed workflow automation tool.
Easily automate tasks across different services.
'';
homepage = "https://n8n.io";
changelog = "https://github.com/n8n-io/n8n/releases/tag/n8n@${finalAttrs.version}";
maintainers = with lib.maintainers; [gepbird AdrienLemaire sweenu];
license = lib.licenses.sustainableUse;
mainProgram = "n8n";
platforms = lib.platforms.unix;
};
})
-6
View File
@@ -1,6 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell --pure -i bash -p bash curl jq nix-update cacert git
set -euo pipefail
new_version="$(curl -s "https://api.github.com/repos/n8n-io/n8n/releases/latest" | jq --raw-output '.tag_name | ltrimstr("n8n@")')"
nix-update n8n --version "$new_version"
-23
View File
@@ -1,23 +0,0 @@
{ lib, stdenv, symlinkJoin, makeWrapper, inputs ? null, }:
let
opencode-desktop =
inputs.opencode.packages.${stdenv.hostPlatform.system}.desktop;
in symlinkJoin {
name = "opencode-desktop";
paths = [ opencode-desktop ];
nativeBuildInputs = [ makeWrapper ];
postBuild = ''
wrapProgram $out/bin/opencode-desktop \
--run 'if [[ "$NIXOS_OZONE_WL" == "1" ]]; then export OC_ALLOW_WAYLAND=1; fi'
'';
meta = {
description = "OpenCode Desktop App with Wayland support";
homepage = "https://opencode.ai";
license = lib.licenses.mit;
platforms = lib.platforms.linux;
mainProgram = "opencode-desktop";
};
}
-92
View File
@@ -1,92 +0,0 @@
{
lib,
stdenv,
writeShellScriptBin,
timer,
kitty,
rofi,
libnotify,
speechd,
}: let
launcher = writeShellScriptBin "launch-timer" ''
#!/bin/bash
validate_time() {
local input=$1
if [[ $input =~ ^[0-9]+[mhs]$ ]]; then
return 0
else
return 1
fi
}
notify_end() {
local session_name=$1
${libnotify}/bin/notify-send "Pomodoro" "$session_name session ended!"
${speechd}/bin/spd-say "$session_name session ended"
}
start_timer() {
local duration=$1
local session_name=$2
kitty \
--class="floating-pomodoro" \
--title="floating-pomodoro" \
${timer}/bin/timer $duration
notify_end "$session_name"
}
# Show rofi menu with options
selected=$(printf "work\nbreak\ncustom" | rofi -dmenu -p "Work Timer:" -l 3)
# Exit if no selection was made
[ -z "$selected" ] && exit
case $selected in
"work")
start_timer "45m" "work"
;;
"break")
start_timer "10m" "break"
;;
"custom")
# Show input dialog for custom time
custom_time=$(rofi -dmenu -p "Enter time (e.g., 25m, 1h, 30s):" -l 0)
# Validate input and start timer
if [ ! -z "$custom_time" ] && validate_time "$custom_time"; then
start_timer "$custom_time" "custom"
else
${libnotify}/bin/notify-send "Invalid time format" "Please use format: 30s, 25m, or 1h"
exit 1
fi
;;
esac
'';
in
stdenv.mkDerivation {
pname = "work-timer";
version = "0.1.0";
dontUnpack = true;
buildInputs = [
timer
kitty
rofi
libnotify
speechd
];
installPhase = ''
mkdir -p $out/bin
ln -s ${launcher}/bin/launch-timer $out/bin/launch-timer
'';
meta = {
description = "A Work timer.";
license = lib.licenses.mit;
platforms = lib.platforms.linux;
mainProgram = "launch-timer";
};
}
-181
View File
@@ -1,181 +0,0 @@
{
writeShellScriptBin,
rofi,
libnotify,
coreutils,
gnugrep,
gnused,
jq,
}:
writeShellScriptBin "rofi-project-opener" ''
#!/usr/bin/env bash
# rofi-project-opener - Rofi-based project directory launcher
set -euo pipefail
# Core utilities
NOTIFY="${libnotify}/bin/notify-send"
ROFI="${rofi}/bin/rofi"
MKDIR="${coreutils}/bin/mkdir"
RM="${coreutils}/bin/rm"
SORT="${coreutils}/bin/sort"
CUT="${coreutils}/bin/cut"
DIRNAME="${coreutils}/bin/dirname"
BASENAME="${coreutils}/bin/basename"
GREP="${gnugrep}/bin/grep"
SED="${gnused}/bin/sed"
JQ="${jq}/bin/jq"
# Configuration files
CONFIG_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/rofi-project-opener"
CONFIG_FILE="$CONFIG_DIR/config"
PROJECTS_JSON="$CONFIG_DIR/projects.json"
if [[ -f "$CONFIG_FILE" ]]; then
# shellcheck disable=SC1090
source "$CONFIG_FILE"
fi
# Fallback to environment variables or defaults
TERMINAL="''${TERMINAL:-kitty}"
TERMINAL_CMD="''${TERMINAL_CMD:-}"
ROFI_PROMPT="''${ROFI_PROMPT:-Select project}"
ROFI_ARGS="''${ROFI_ARGS:--dmenu -i}"
# Check for projects.json
if [[ ! -f "$PROJECTS_JSON" ]]; then
echo "[rofi-project-opener] Error: No projects.json found at $PROJECTS_JSON" >&2
"$NOTIFY" -u critical -a "rofi-project-opener" "No projects.json configuration found"
exit 1
fi
PROJECTS_JSON_DATA="$(cat "$PROJECTS_JSON")"
# Temporary file for project list
PROJECTS_LIST="''${XDG_RUNTIME_DIR:-/tmp}/rofi-project-opener.$$"
# Cleanup on exit
cleanup() {
[[ -f "$PROJECTS_LIST" ]] && "$RM" -f "$PROJECTS_LIST"
}
trap cleanup EXIT
# Ensure runtime directory exists
"$MKDIR" -p "$("$DIRNAME" "$PROJECTS_LIST")"
# Show error notification
show_error() {
local message="$1"
echo "[rofi-project-opener] Error: $message" >&2
"$NOTIFY" -u critical -a "rofi-project-opener" "$message"
}
# Build list of projects from JSON config
# Format: display_name|full_path|args
build_project_list() {
> "$PROJECTS_LIST"
# Parse JSON and iterate over each base directory entry
local keys
keys=$(echo "$PROJECTS_JSON_DATA" | "$JQ" -r 'keys[]')
for key in $keys; do
local base_path base_args
base_path=$(echo "$PROJECTS_JSON_DATA" | "$JQ" -r --arg k "$key" '.[$k].path')
base_args=$(echo "$PROJECTS_JSON_DATA" | "$JQ" -r --arg k "$key" '.[$k].args // ""')
# Expand ~ to $HOME
base_path="''${base_path/#\~/$HOME}"
# Expand $HOME variable (allows both ~ and $HOME in config)
base_path="$(eval echo "$base_path")"
# Skip if directory doesn't exist
if [[ ! -d "$base_path" ]]; then
echo "[rofi-project-opener] Warning: Directory does not exist: $base_path" >&2
continue
fi
# Find 1st level subdirectories (non-hidden)
for project in "$base_path"/*/; do
if [[ -d "$project" ]]; then
# Get directory name without trailing slash
project_path="''${project%/}"
project_name="$("$BASENAME" "$project_path")"
# Skip hidden directories
if [[ "$project_name" == .* ]]; then
continue
fi
# Use key as display prefix (e.g., "dev/myproject")
echo "$key/$project_name|$project_path|$base_args" >> "$PROJECTS_LIST"
fi
done
done
# Check if we found any projects
[[ -s "$PROJECTS_LIST" ]]
}
# Build project list
if ! build_project_list; then
show_error "No projects found in configured directories"
exit 1
fi
# Deduplicate and sort
"$SORT" -t '|' -k1 -u "$PROJECTS_LIST" -o "$PROJECTS_LIST"
# Display in rofi and get selection
# shellcheck disable=SC2086
selection=$("$CUT" -d '|' -f1 "$PROJECTS_LIST" | "$ROFI" $ROFI_ARGS -p "$ROFI_PROMPT") || true
# Exit if cancelled
if [[ -z "$selection" ]]; then
exit 0
fi
# Get the full path and args from selection
selected_line=$("$GREP" "^$selection|" "$PROJECTS_LIST")
project_path=$(echo "$selected_line" | "$CUT" -d '|' -f2)
project_args=$(echo "$selected_line" | "$CUT" -d '|' -f3)
# Exit if path not found (shouldn't happen)
if [[ -z "$project_path" ]]; then
show_error "Could not find project path for: $selection"
exit 1
fi
# Verify directory still exists
if [[ ! -d "$project_path" ]]; then
show_error "Project directory no longer exists: $project_path"
exit 1
fi
# Build terminal command
# Placeholders: %s = project path, %a = project args
if [[ -n "$TERMINAL_CMD" ]]; then
# Substitute placeholders
final_cmd="$TERMINAL_CMD"
final_cmd="''${final_cmd//%s/$project_path}"
final_cmd="''${final_cmd//%a/$project_args}"
# Source /etc/profile (base PATH) and HM session vars (sessionPath) for NixOS
exec "$TERMINAL" --hold -e bash --login -c "
unset __HM_SESS_VARS_SOURCED
for f in ~/.nix-profile/etc/profile.d/hm-session-vars.sh /etc/profiles/per-user/\$USER/etc/profile.d/hm-session-vars.sh; do
[ -f \"\$f\" ] && . \"\$f\"
done
cd '$project_path' && exec $final_cmd
"
else
# Default: open terminal, cd to project, run opencode with args
# Source /etc/profile (base PATH) and HM session vars (sessionPath) for NixOS
exec "$TERMINAL" --hold -e bash --login -c "
unset __HM_SESS_VARS_SOURCED
for f in ~/.nix-profile/etc/profile.d/hm-session-vars.sh /etc/profiles/per-user/\$USER/etc/profile.d/hm-session-vars.sh; do
[ -f \"\$f\" ] && . \"\$f\"
done
cd '$project_path' && opencode $project_args
"
fi
''
-66
View File
@@ -1,66 +0,0 @@
{
lib,
buildGoModule,
fetchFromGitHub,
gitMinimal,
makeWrapper, # Add this
nix-update-script,
td, # Add this - the td package
versionCheckHook,
writableTmpDirAsHomeHook,
}:
buildGoModule (finalAttrs: {
pname = "sidecar";
version = "0.71.1";
src = fetchFromGitHub {
owner = "marcus";
repo = "sidecar";
tag = "v${finalAttrs.version}";
hash = "sha256-LqpqNQ56tKXqEKbUrMxBkiGOzklGaqx8SCTEGIwE43k=";
};
vendorHash = "sha256-R/AjNJ4x4t1zXXzT+21cjY+9pxs4DVXU4xs88BQvHx4=";
subPackages = ["cmd/sidecar"];
ldflags = [
"-s"
"-w"
"-X main.Version=v${finalAttrs.version}" # Can combine these
];
nativeBuildInputs = [makeWrapper]; # Add this
nativeCheckInputs = [
gitMinimal
writableTmpDirAsHomeHook
];
nativeInstallCheckInputs = [
versionCheckHook
writableTmpDirAsHomeHook
];
versionCheckProgramArg = "--version";
doInstallCheck = true;
doCheck = false;
postInstall = ''
wrapProgram $out/bin/sidecar \
--prefix PATH : ${lib.makeBinPath [td]}
'';
passthru = {
updateScript = nix-update-script {};
};
meta = {
description = "Use sidecar next to CLI agents for diffs, file trees, conversation history, and task management with td";
homepage = "https://github.com/marcus/sidecar";
changelog = "https://github.com/marcus/sidecar/releases/tag/v${finalAttrs.version}";
license = lib.licenses.mit;
mainProgram = "sidecar";
platforms = lib.platforms.unix;
};
})
-98
View File
@@ -1,98 +0,0 @@
{
lib,
stdenv,
writeShellScriptBin,
whisper-cpp,
wtype,
libnotify,
pipewire,
procps,
busybox,
}: let
script = writeShellScriptBin "stt-ptt" ''
#!/usr/bin/env bash
# stt-ptt - Push to Talk Speech to Text
CACHE_DIR="''${XDG_CACHE_HOME:-$HOME/.cache}/stt-ptt"
MODEL_DIR="''${XDG_DATA_HOME:-$HOME/.local/share}/stt-ptt/models"
AUDIO="$CACHE_DIR/stt.wav"
# Configurable via environment
STT_MODEL="''${STT_MODEL:-$MODEL_DIR/ggml-large-v3-turbo.bin}"
STT_LANGUAGE="''${STT_LANGUAGE:-auto}"
STT_NOTIFY_TIMEOUT="''${STT_NOTIFY_TIMEOUT:-3000}"
NOTIFY="${libnotify}/bin/notify-send"
PW_RECORD="${pipewire}/bin/pw-record"
WHISPER="${whisper-cpp}/bin/whisper-cli"
WTYPE="${wtype}/bin/wtype"
PKILL="${procps}/bin/pkill"
MKDIR="${busybox}/bin/mkdir"
RM="${busybox}/bin/rm"
TR="${busybox}/bin/tr"
SED="${busybox}/bin/sed"
SLEEP="${busybox}/bin/sleep"
# Ensure cache directory exists
"$MKDIR" -p "$CACHE_DIR"
# Kill any existing pw-record for this audio file (prevents orphan nodes)
kill_existing() {
"$PKILL" -f "pw-record.*$AUDIO" 2>/dev/null
"$SLEEP" 0.1
}
case "''${1:-}" in
start)
kill_existing
"$RM" -f "$AUDIO"
"$NOTIFY" -t "$STT_NOTIFY_TIMEOUT" -a "stt-ptt" "Recording..."
"$PW_RECORD" --rate=16000 --channels=1 "$AUDIO" &
;;
stop)
kill_existing
if [[ -f "$AUDIO" ]]; then
if [[ ! -f "$STT_MODEL" ]]; then
"$NOTIFY" -t "$STT_NOTIFY_TIMEOUT" -a "stt-ptt" "Error: Model not found at $STT_MODEL"
"$RM" -f "$AUDIO"
exit 1
fi
text=$("$WHISPER" -m "$STT_MODEL" -f "$AUDIO" -l "$STT_LANGUAGE" -np -nt 2>/dev/null | "$TR" -d '\n' | "$SED" 's/^[[:space:]]*//;s/[[:space:]]*$//')
"$RM" -f "$AUDIO"
[[ -n "$text" ]] && "$WTYPE" -- "$text"
fi
;;
*)
echo "Usage: stt-ptt {start|stop}"
echo ""
echo "Environment variables:"
echo " STT_MODEL - Path to whisper model (default: \$XDG_DATA_HOME/stt-ptt/models/ggml-large-v3-turbo.bin)"
echo " STT_LANGUAGE - Language code or 'auto' for auto-detection (default: auto)"
echo " STT_NOTIFY_TIMEOUT - Notification timeout in ms (default: 3000)"
exit 1
;;
esac
'';
in
stdenv.mkDerivation {
pname = "stt-ptt";
version = "0.1.0";
dontUnpack = true;
# No buildInputs needed - all runtime deps are hardcoded with full nix store paths in the script
installPhase = ''
mkdir -p "$out/bin"
ln -s ${script}/bin/stt-ptt "$out/bin/stt-ptt"
'';
meta = with lib; {
description = "Push to Talk Speech to Text using Whisper";
homepage = "https://code.m3ta.dev/m3tam3re/nixpkgs";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "stt-ptt";
};
}
-47
View File
@@ -1,47 +0,0 @@
{
lib,
buildGoModule,
fetchFromGitHub,
gitMinimal,
nix-update-script,
versionCheckHook,
writableTmpDirAsHomeHook,
}:
buildGoModule (finalAttrs: {
pname = "td";
version = "0.33.0";
src = fetchFromGitHub {
owner = "marcus";
repo = "td";
tag = "v${finalAttrs.version}";
hash = "sha256-gci4B83x/0UMawy+fncArF9zO1aHRE/zXj91e5h6yi8=";
};
vendorHash = "sha256-Rp0lhnBLJx+exX7VLql3RfthTVk3LLftD6n6SsSWzVY=";
ldflags = [
"-s"
"-w"
"-X"
"main.Version=v${finalAttrs.version}"
];
nativeCheckInputs = [gitMinimal writableTmpDirAsHomeHook];
nativeInstallCheckInputs = [versionCheckHook writableTmpDirAsHomeHook];
versionCheckProgramArg = "version";
doInstallCheck = true;
doCheck = false;
passthru.updateScript = nix-update-script {};
meta = with lib; {
description = "Minimalist CLI for tracking tasks across AI coding sessions";
homepage = "https://github.com/marcus/td";
license = licenses.mit;
mainProgram = "td";
platforms = platforms.unix;
};
})
-26
View File
@@ -1,26 +0,0 @@
{writeShellScriptBin}:
writeShellScriptBin "tuxedo-backlight" ''
# all keys
echo '0 150 255' | tee /sys/class/leds/rgb:kbd_backlight*/multi_intensity
# DEL key
echo '255 0 155' | tee /sys/class/leds/rgb:kbd_backlight_15/multi_intensity
# ESC key
echo '255 0 155' | tee /sys/class/leds/rgb:kbd_backlight/multi_intensity
# function and Fn keys
for i in {1..12} 102; do
echo '0 255 80' | tee /sys/class/leds/rgb:kbd_backlight_$i/multi_intensity
done
# complete numblock and keys above
for i in {16..19} {36..39} {56..59} {76..79} {96..99} {117..119}; do
echo '255 150 0' | tee /sys/class/leds/rgb:kbd_backlight_$i/multi_intensity
done
# arrow keys
for i in 95 {114..116}; do
echo '0 255 80' | tee /sys/class/leds/rgb:kbd_backlight_$i/multi_intensity
done
''
-42
View File
@@ -1,42 +0,0 @@
{
lib,
stdenv,
fetchFromGitea,
fish,
fd,
fzf,
zellij,
}:
with lib;
stdenv.mkDerivation {
pname = "zellij-ps";
version = "0.1.0";
src = fetchFromGitea {
domain = "code.m3ta.dev";
owner = "m3tam3re";
repo = "helper-scripts";
rev = "08a3217b83391c1110545c1ee3161eecd5dbe5e9";
sha256 = "1sc4i58mwcg3qsq0wwl5rvk08ykbxc497bq7mrxiirndsarskby7";
};
propagatedBuildInputs = [fish fd fzf zellij];
nativeBuildInputs = [];
installPhase = ''
mkdir -p $out/bin
substitute zellij-ps.fish $out/bin/zellij-ps \
--replace-fail 'fd --type' '${fd}/bin/fd --type' \
--replace-fail 'fzf --preview' '${fzf}/bin/fzf --preview' \
--replace-fail 'zellij --layout' '${zellij}/bin/zellij --layout' \
--replace-fail 'pgrep -c zellij' 'pgrep -c ${zellij}/bin/zellij'
chmod +x $out/bin/zellij-ps
'';
meta = {
description = "Zellij project switcher - quickly switch between project folders";
license = lib.licenses.mit;
platforms = platforms.unix;
mainProgram = "zellij-ps";
};
}
-32
View File
@@ -1,32 +0,0 @@
# Development shells for various programming environments
# Each shell can be accessed via: nix develop .#<shell-name>
# Or used in home-manager/system configs
{pkgs}: {
# Default shell for working on this repository
default = pkgs.mkShell {
name = "m3ta-nixpkgs-dev";
buildInputs = with pkgs; [
nil # Nix LSP
alejandra # Nix formatter
nix-tree # Explore dependency trees
statix # Nix linter
deadnix # Find dead Nix code
];
shellHook = ''
echo "🚀 m3ta-nixpkgs development environment"
echo "Available commands:"
echo " nix flake check - Check flake validity"
echo " nix flake show - Show flake outputs"
echo " nix build .#<pkg> - Build a package"
echo " nix fmt . - Format Nix files"
echo " statix check . - Lint Nix files"
echo " deadnix . - Find dead code"
'';
};
# Import all individual shell environments
python = import ./python.nix {inherit pkgs;};
devops = import ./devops.nix {inherit pkgs;};
}
-144
View File
@@ -1,144 +0,0 @@
# DevOps development environment
# Usage: nix develop .#devops
{pkgs}:
pkgs.mkShell {
name = "devops-dev";
buildInputs = with pkgs; [
# Container tools
docker
docker-compose
podman
buildah
skopeo
dive # Docker image explorer
# Kubernetes tools
kubectl
kubectx # Includes kubens
k9s # TUI for Kubernetes
kubernetes-helm
helmfile
kustomize
stern # Multi-pod log tailing
kubeseal # Sealed secrets
# Infrastructure as Code
terraform
opentofu # Open-source Terraform fork
terragrunt
terraform-docs
tflint
infracost # Cost estimates for Terraform
# Configuration management
ansible
ansible-lint
# CI/CD tools
github-cli
gitlab-runner
act # Run GitHub Actions locally
# Cloud CLIs
awscli2
google-cloud-sdk
azure-cli
doctl # DigitalOcean CLI
# Monitoring and observability
prometheus
grafana
# Note: promtool is included in prometheus package
# Service mesh
istioctl
linkerd
# Security and secrets
vault
sops
age # Encryption tool
trivy # Security scanner
# Scripting and automation
python3
jq
yq-go
jo # JSON output from shell
# Network tools
curl
wget
httpie
netcat
nmap
tcpdump
wireshark-cli
# System utilities
htop
btop
lsof
tmux
git
gnumake
# Linters and formatters
shellcheck
shfmt
yamllint
];
# Environment variables
DOCKER_BUILDKIT = "1";
COMPOSE_DOCKER_CLI_BUILD = "1";
shellHook = ''
echo "🚀 DevOps Development Environment"
echo ""
echo "Container tools:"
echo " docker / podman - Container runtime"
echo " docker-compose - Multi-container applications"
echo " dive - Explore Docker images"
echo " buildah / skopeo - Build and manage containers"
echo ""
echo "Kubernetes:"
echo " kubectl - Kubernetes CLI"
echo " k9s - Kubernetes TUI"
echo " helm - Package manager"
echo " kubectx / kubens - Switch contexts/namespaces (kubens included in kubectx)"
echo " stern <pod> - Multi-pod logs"
echo ""
echo "Infrastructure as Code:"
echo " terraform / opentofu - Infrastructure provisioning"
echo " terragrunt - Terraform wrapper"
echo " ansible - Configuration management"
echo " tflint - Terraform linter"
echo ""
echo "Cloud CLIs:"
echo " aws - AWS CLI"
echo " gcloud - Google Cloud CLI"
echo " az - Azure CLI"
echo " doctl - DigitalOcean CLI"
echo ""
echo "Security & Secrets:"
echo " vault - HashiCorp Vault"
echo " sops - Secrets management"
echo " trivy - Security scanner"
echo " kubeseal - Sealed secrets"
echo ""
echo "CI/CD:"
echo " gh - GitHub CLI"
echo " act - Run GitHub Actions locally"
echo " gitlab-runner - GitLab CI runner"
echo ""
echo "Utilities:"
echo " jq / yq - JSON/YAML processors"
echo " httpie / curl - HTTP clients"
echo " shellcheck - Shell script linter"
echo ""
echo "💡 Tip: Use 'kubectx' and 'kubens' to quickly switch contexts"
echo ""
'';
}
-82
View File
@@ -1,82 +0,0 @@
# Modern Python development environment with marimo and uv — Nushell version
# Usage: nix develop .#python (drops into Nushell)
{pkgs}: let
# Use the latest Python available in nixpkgs
python = pkgs.python313;
in
pkgs.mkShell {
name = "python-marimo-dev";
buildInputs = with pkgs; [
# Python interpreter
python
# Tooling
black
pyrefly
# Modern package manager
uv
# Essential system dependencies for numpy and scientific packages
stdenv.cc.cc.lib
zlib
gfortran
openblas
lapack
# Nushell itself
nushell
];
# Environment variables for proper library linking
LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath [
pkgs.stdenv.cc.cc.lib
pkgs.zlib
pkgs.gfortran.cc.lib
]}";
# Bash shellHook that sets up the environment and launches Nushell
shellHook = ''
echo "🐍 Python + Marimo Development Environment"
echo ""
echo "Python version: $(python --version)"
echo "uv version: $(uv --version)"
echo ""
# Create venv if it doesn't exist
if [ ! -d ".venv" ]; then
echo "Creating virtual environment..."
uv venv
fi
# Activate the virtual environment
source .venv/bin/activate
# Install marimo if not present
if ! python -c "import marimo" 2>/dev/null; then
echo "Installing marimo..."
uv pip install marimo
fi
# Install numpy if not present
if ! python -c "import numpy" 2>/dev/null; then
echo "Installing numpy..."
uv pip install numpy
fi
echo ""
echo " Environment ready!"
echo ""
echo "Quick start:"
echo " marimo edit - Start marimo notebook"
echo " uv pip install <package> - Install packages"
echo " python script.py - Run Python scripts"
echo ""
echo "💡 Popular packages: uv pip install pandas matplotlib scipy scikit-learn"
echo ""
# Launch Nushell
exec nu
'';
}
-144
View File
@@ -1,144 +0,0 @@
# Home Manager Module Template
# This is a template for creating new Home Manager modules in m3ta-nixpkgs
# Copy this template and modify it for your specific module
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.programs.myProgram; # Replace 'myProgram' with your program/module name
# Common locations: config.programs.*, config.services.*, config.m3ta.*
in {
# Define options that users can set in their Home Manager configuration
options.programs.myProgram = {
enable = mkEnableOption "my custom program"; # Replace with your program description
# Example: Package option
package = mkOption {
type = types.package;
default = pkgs.hello; # Replace with your package
defaultText = literalExpression "pkgs.hello";
description = "The package to use";
};
# Example: String option
configDir = mkOption {
type = types.str;
default = "${config.xdg.configHome}/myprogram";
defaultText = literalExpression ''"''${config.xdg.configHome}/myprogram"'';
description = "Directory to store configuration";
};
# Example: Boolean option
enableBashIntegration = mkOption {
type = types.bool;
default = true;
description = "Whether to enable Bash integration";
};
# Example: Attribute set for settings
settings = mkOption {
type = types.attrs;
default = {};
example = literalExpression ''
{
theme = "dark";
fontSize = 12;
}
'';
description = "Configuration settings written to config file";
};
# Example: Lines of text (for config files)
extraConfig = mkOption {
type = types.lines;
default = "";
example = ''
# Custom configuration
option = value
'';
description = "Extra configuration to append to the config file";
};
# Example: Environment variables
environmentVariables = mkOption {
type = types.attrsOf types.str;
default = {};
example = {MY_VAR = "value";};
description = "Environment variables to set";
};
};
# Define what happens when the module is enabled
config = mkIf cfg.enable {
# Add package to user profile
home.packages = [cfg.package];
# Set environment variables
home.sessionVariables = cfg.environmentVariables;
# Create configuration file
# Method 1: Using xdg.configFile
xdg.configFile."myprogram/config.conf" = {
text = ''
# Generated by Home Manager
${builtins.toJSON cfg.settings}
${cfg.extraConfig}
'';
};
# Method 2: Using home.file for non-XDG locations
# home.file.".myprogramrc".text = ''
# # Configuration here
# '';
# Example: Bash integration
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
# My program bash integration
eval "$(${cfg.package}/bin/myprogram init bash)"
'';
# Example: Zsh integration
programs.zsh.initExtra = mkIf cfg.enableBashIntegration ''
# My program zsh integration
eval "$(${cfg.package}/bin/myprogram init zsh)"
'';
# Example: Fish integration
# programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
# ${cfg.package}/bin/myprogram init fish | source
# '';
# Example: Systemd user service
systemd.user.services.myprogram = {
Unit = {
Description = "My Program Service";
After = ["graphical-session.target"];
};
Service = {
Type = "simple";
ExecStart = "${cfg.package}/bin/myprogram daemon";
Restart = "on-failure";
RestartSec = 5;
};
Install = {
WantedBy = ["default.target"];
};
};
# Example: Create directories
# home.file."${cfg.configDir}/.keep".text = "";
# Example: Manage symlinks
# home.file."bin/myprogram".source = "${cfg.package}/bin/myprogram";
};
# Module metadata (optional)
meta = {
maintainers = with lib.maintainers; []; # Add your name if in nixpkgs
};
}
-136
View File
@@ -1,136 +0,0 @@
# NixOS Module Template
# This is a template for creating new NixOS modules in m3ta-nixpkgs
# Copy this template and modify it for your specific module
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.m3ta.myModule; # Replace 'myModule' with your module name
in {
# Define options that users can set in their configuration
options.m3ta.myModule = {
enable = mkEnableOption "my custom module"; # Replace with your module description
# Example: String option
package = mkOption {
type = types.package;
default = pkgs.hello; # Replace with your default package
defaultText = literalExpression "pkgs.hello";
description = "The package to use for this module";
};
# Example: String option
dataDir = mkOption {
type = types.path;
default = "/var/lib/mymodule";
description = "Directory where data will be stored";
};
# Example: Port number
port = mkOption {
type = types.port;
default = 8080;
description = "Port to listen on";
};
# Example: String option
user = mkOption {
type = types.str;
default = "mymodule";
description = "User account under which the service runs";
};
# Example: Group option
group = mkOption {
type = types.str;
default = "mymodule";
description = "Group under which the service runs";
};
# Example: Boolean option
openFirewall = mkOption {
type = types.bool;
default = false;
description = "Whether to open the firewall for the service port";
};
# Example: List of strings
extraArgs = mkOption {
type = types.listOf types.str;
default = [];
example = ["--verbose" "--debug"];
description = "Additional command-line arguments to pass";
};
# Example: Attribute set (key-value pairs)
settings = mkOption {
type = types.attrs;
default = {};
example = literalExpression ''
{
logLevel = "info";
timeout = 30;
}
'';
description = "Configuration settings as attribute set";
};
};
# Define what happens when the module is enabled
config = mkIf cfg.enable {
# Create a system user
users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
home = cfg.dataDir;
createHome = true;
description = "My module service user";
};
users.groups.${cfg.group} = {};
# Define a systemd service
systemd.services.mymodule = {
description = "My Custom Module Service";
wantedBy = ["multi-user.target"];
after = ["network.target"];
serviceConfig = {
Type = "simple";
User = cfg.user;
Group = cfg.group;
WorkingDirectory = cfg.dataDir;
ExecStart = "${cfg.package}/bin/myprogram ${concatStringsSep " " cfg.extraArgs}";
Restart = "on-failure";
RestartSec = 5;
# Security hardening
PrivateTmp = true;
NoNewPrivileges = true;
ProtectSystem = "strict";
ProtectHome = true;
ReadWritePaths = [cfg.dataDir];
};
};
# Open firewall if requested
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [cfg.port];
};
# Add package to system packages (optional)
environment.systemPackages = [cfg.package];
# Example: Create configuration file
# environment.etc."mymodule/config.json".text = builtins.toJSON cfg.settings;
};
# Module metadata
meta = {
maintainers = with lib.maintainers; []; # Add your name if in nixpkgs
doc = ./default.md; # Optional: Link to documentation
};
}
-85
View File
@@ -1,85 +0,0 @@
# Package Template
# This is a template for creating new packages in m3ta-nixpkgs
# Copy this template and modify it for your specific package
{
lib,
stdenv,
fetchFromGitHub,
# Add build dependencies here
# pkg-config,
# cmake,
# rustPlatform,
# python3,
# nodejs,
# Add runtime dependencies here
# openssl,
# libxml2,
}:
stdenv.mkDerivation rec {
pname = "package-name"; # Replace with your package name
version = "0.1.0"; # Replace with actual version
# Source fetching - choose one method:
# Method 1: From GitHub
src = fetchFromGitHub {
owner = "owner-name";
repo = "repo-name";
rev = "v${version}"; # or use a specific commit hash
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
# To get the correct hash, first set it to lib.fakeHash, then run:
# nix build .#package-name
# The error message will show the correct hash
};
# Method 2: From URL
# src = fetchurl {
# url = "https://example.com/package-${version}.tar.gz";
# hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
# };
# Build-time dependencies (tools needed to build the package)
nativeBuildInputs = [
# pkg-config
# cmake
# makeWrapper
];
# Runtime dependencies (libraries needed at runtime)
buildInputs = [
# openssl
# libxml2
];
# Build phase (optional, only if you need custom build steps)
# buildPhase = ''
# make
# '';
# Install phase (optional, only if you need custom install steps)
# installPhase = ''
# mkdir -p $out/bin
# cp binary $out/bin/
# '';
# Post-install hook (optional, for wrapping binaries, etc.)
# postInstall = ''
# wrapProgram $out/bin/program \
# --prefix PATH : ${lib.makeBinPath [ dependency ]}
# '';
# Metadata - REQUIRED
meta = with lib; {
description = "A short description of the package";
longDescription = ''
A longer, more detailed description of what the package does.
This can span multiple lines.
'';
homepage = "https://github.com/owner/repo";
changelog = "https://github.com/owner/repo/releases/tag/v${version}";
license = licenses.mit; # Change to appropriate license
maintainers = with maintainers; []; # Add your name if you're in nixpkgs
platforms = platforms.linux; # or platforms.unix, platforms.all, etc.
mainProgram = "program-name"; # The main executable name
};
}