fix: code review fixes
- Fix hardcoded user path in webapps.nix (use homeDirectory) - Normalize wallpapers option to use .enable suffix - Remove duplicate FZF keybind declaration - Update comments to match actual implementation
This commit is contained in:
727
docs/plans/2026-04-26-home-profile-restructuring.md
Normal file
727
docs/plans/2026-04-26-home-profile-restructuring.md
Normal file
@@ -0,0 +1,727 @@
|
|||||||
|
# Home Profile Restructuring Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Restructure nixos-config/home/ from host-based to profile-based organization with clear separation between base, coding, profiles, desktop, and server layers.
|
||||||
|
|
||||||
|
**Architecture:** Three-layer model: Base (always loaded) → Coding (profile-independent) → Profiles/Context (freely combinable with constraints). Desktop and Server contexts are mutually exclusive.
|
||||||
|
|
||||||
|
**Tech Stack:** NixOS, Home Manager, Nix flakes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
home/
|
||||||
|
├── base/ # IMMER geladen
|
||||||
|
│ ├── default.nix
|
||||||
|
│ ├── shell/
|
||||||
|
│ │ ├── default.nix
|
||||||
|
│ │ ├── nushell.nix # PRIMARY Shell
|
||||||
|
│ │ └── starship.nix
|
||||||
|
│ ├── cli-tools/
|
||||||
|
│ │ ├── default.nix
|
||||||
|
│ │ ├── fzf.nix
|
||||||
|
│ │ ├── zellij.nix
|
||||||
|
│ │ ├── nitch.nix
|
||||||
|
│ │ └── television.nix
|
||||||
|
│ └── secrets/
|
||||||
|
│ └── secrets.nix
|
||||||
|
│
|
||||||
|
├── coding/ # Profil-unabhängig
|
||||||
|
│ ├── default.nix
|
||||||
|
│ ├── editor/
|
||||||
|
│ │ ├── default.nix
|
||||||
|
│ │ └── neovim.nix # Basis NeoVim (aus nixpkgs referenziert)
|
||||||
|
│ ├── lsp/
|
||||||
|
│ │ ├── default.nix
|
||||||
|
│ │ └── servers.nix
|
||||||
|
│ ├── git/
|
||||||
|
│ │ └── git.nix
|
||||||
|
│ └── agents/
|
||||||
|
│ └── agents.nix # Agent-System (aus nixpkgs referenziert)
|
||||||
|
│
|
||||||
|
├── profiles/ # FREI KOMBINIERBAR
|
||||||
|
│ ├── gaming/
|
||||||
|
│ │ ├── default.nix
|
||||||
|
│ │ ├── steam.nix
|
||||||
|
│ │ └── gamescope.nix
|
||||||
|
│ │
|
||||||
|
│ └── media/
|
||||||
|
│ ├── default.nix
|
||||||
|
│ ├── obs.nix
|
||||||
|
│ ├── ffmpeg.nix
|
||||||
|
│ ├── yt-dlp.nix
|
||||||
|
│ ├── kdenlive.nix
|
||||||
|
│ └── handbrake.nix
|
||||||
|
│
|
||||||
|
├── desktop/ # NUR wenn context=desktop
|
||||||
|
│ ├── default.nix
|
||||||
|
│ ├── wm/
|
||||||
|
│ │ ├── default.nix
|
||||||
|
│ │ ├── hyprland.nix
|
||||||
|
│ │ ├── wayland.nix
|
||||||
|
│ │ └── rofi.nix
|
||||||
|
│ ├── apps/
|
||||||
|
│ │ ├── default.nix
|
||||||
|
│ │ ├── obsidian.nix
|
||||||
|
│ │ ├── office.nix
|
||||||
|
│ │ ├── webapps.nix
|
||||||
|
│ │ └── crypto.nix
|
||||||
|
│ └── theme/
|
||||||
|
│ ├── default.nix
|
||||||
|
│ ├── fonts.nix
|
||||||
|
│ ├── theme.nix
|
||||||
|
│ └── wallpapers.nix
|
||||||
|
│
|
||||||
|
└── server/
|
||||||
|
└── default.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Integration Points:**
|
||||||
|
|
||||||
|
| Component | Source | Notes |
|
||||||
|
|-----------|--------|-------|
|
||||||
|
| NeoVim Config | `inputs.m3ta-nixpkgs.pkgs.neovim-config` | Custom package in nixpkgs |
|
||||||
|
| OpenCode Desktop | `inputs.m3ta-nixpkgs.pkgs.opencode-desktop` | Custom package |
|
||||||
|
| Agent-System | `inputs.m3ta-nixpkgs.homeModules.coding.agents` | OpenCode, Claude Code, Pi |
|
||||||
|
| Zed Editor | `inputs.m3ta-nixpkgs.homeModules.coding.editors` | Desktop-only via Zed Remote |
|
||||||
|
| Editor Module | `inputs.m3ta-nixpkgs.homeModules.coding.editors` | NeoVim (base) + Zed (desktop) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Create New Structure
|
||||||
|
|
||||||
|
### Task 1: Create Directory Structure
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `home/base/default.nix`
|
||||||
|
- Create: `home/base/shell/default.nix`
|
||||||
|
- Create: `home/base/shell/nushell.nix`
|
||||||
|
- Create: `home/base/shell/starship.nix`
|
||||||
|
- Create: `home/base/cli-tools/default.nix`
|
||||||
|
- Create: `home/base/cli-tools/fzf.nix`
|
||||||
|
- Create: `home/base/cli-tools/zellij.nix`
|
||||||
|
- Create: `home/base/cli-tools/nitch.nix`
|
||||||
|
- Create: `home/base/cli-tools/television.nix`
|
||||||
|
- Create: `home/base/secrets/secrets.nix`
|
||||||
|
- Create: `home/coding/default.nix`
|
||||||
|
- Create: `home/coding/editor/default.nix`
|
||||||
|
- Create: `home/coding/editor/neovim.nix`
|
||||||
|
- Create: `home/coding/lsp/default.nix`
|
||||||
|
- Create: `home/coding/lsp/servers.nix`
|
||||||
|
- Create: `home/coding/git/git.nix`
|
||||||
|
- Create: `home/coding/agents/agents.nix`
|
||||||
|
- Create: `home/profiles/gaming/default.nix`
|
||||||
|
- Create: `home/profiles/gaming/steam.nix`
|
||||||
|
- Create: `home/profiles/gaming/gamescope.nix`
|
||||||
|
- Create: `home/profiles/media/default.nix`
|
||||||
|
- Create: `home/profiles/media/obs.nix`
|
||||||
|
- Create: `home/profiles/media/ffmpeg.nix`
|
||||||
|
- Create: `home/profiles/media/yt-dlp.nix`
|
||||||
|
- Create: `home/profiles/media/kdenlive.nix`
|
||||||
|
- Create: `home/profiles/media/handbrake.nix`
|
||||||
|
- Create: `home/desktop/default.nix`
|
||||||
|
- Create: `home/desktop/wm/default.nix`
|
||||||
|
- Create: `home/desktop/wm/hyprland.nix`
|
||||||
|
- Create: `home/desktop/wm/wayland.nix`
|
||||||
|
- Create: `home/desktop/wm/rofi.nix`
|
||||||
|
- Create: `home/desktop/apps/default.nix`
|
||||||
|
- Create: `home/desktop/apps/obsidian.nix`
|
||||||
|
- Create: `home/desktop/apps/office.nix`
|
||||||
|
- Create: `home/desktop/apps/webapps.nix`
|
||||||
|
- Create: `home/desktop/apps/crypto.nix`
|
||||||
|
- Create: `home/desktop/theme/default.nix`
|
||||||
|
- Create: `home/desktop/theme/fonts.nix`
|
||||||
|
- Create: `home/desktop/theme/theme.nix`
|
||||||
|
- Create: `home/desktop/theme/wallpapers.nix`
|
||||||
|
- Create: `home/server/default.nix`
|
||||||
|
- Modify: `home/default.nix` (Hauptaggregator)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Create home/base/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/base/default.nix
|
||||||
|
# Basis-Konfiguration: Shell + CLI-Tools + Secrets
|
||||||
|
# Wird IMMER geladen (kein enable-Flag)
|
||||||
|
|
||||||
|
{ inputs, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./shell
|
||||||
|
./cli-tools
|
||||||
|
./secrets
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Create home/base/shell/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/base/shell/default.nix
|
||||||
|
{ inputs, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./nushell.nix
|
||||||
|
./starship.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Create home/base/shell/nushell.nix**
|
||||||
|
|
||||||
|
Migrated from: `home/features/cli/nushell.nix`
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/base/shell/nushell.nix
|
||||||
|
# Primary shell - Nushell
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.nushell = {
|
||||||
|
enable = true;
|
||||||
|
configFile = ...;
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
nushell
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Create home/base/shell/starship.nix**
|
||||||
|
|
||||||
|
Migrated from: `home/features/cli/starship.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 5: Create home/base/cli-tools/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/base/cli-tools/default.nix
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./fzf.nix
|
||||||
|
./zellij.nix
|
||||||
|
./nitch.nix
|
||||||
|
./television.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 6: Create CLI tool modules**
|
||||||
|
|
||||||
|
Migrate from `home/features/cli/`:
|
||||||
|
- `fzf.nix` → `home/base/cli-tools/fzf.nix`
|
||||||
|
- `zellij.nix` → `home/base/cli-tools/zellij.nix`
|
||||||
|
- `nitch.nix` → `home/base/cli-tools/nitch.nix`
|
||||||
|
- `television.nix` → `home/base/cli-tools/television.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 7: Create home/base/secrets/secrets.nix**
|
||||||
|
|
||||||
|
Migrated from: `home/features/cli/secrets.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 8: Create home/coding/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/coding/default.nix
|
||||||
|
# Coding-Konfiguration: Editor + LSP + Git + Agents
|
||||||
|
# Wird geladen wenn coding Profil aktiviert
|
||||||
|
|
||||||
|
{ inputs, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./editor
|
||||||
|
./lsp
|
||||||
|
./git
|
||||||
|
./agents
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 9: Create home/coding/editor/default.nix**
|
||||||
|
|
||||||
|
References: `inputs.m3ta-nixpkgs.homeModules.coding.editors`
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/coding/editor/default.nix
|
||||||
|
{ inputs, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Importiert NeoVim (immer) + Zed (desktop)
|
||||||
|
imports = [
|
||||||
|
inputs.m3ta-nixpkgs.homeModules.coding.editors
|
||||||
|
];
|
||||||
|
|
||||||
|
# NeoVim Config Package
|
||||||
|
home.packages = [ inputs.m3ta-nixpkgs.packages.${pkgs.system}.neovim-config ];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 10: Create home/coding/lsp/default.nix + servers.nix**
|
||||||
|
|
||||||
|
Migrate LSP configuration from existing setup
|
||||||
|
|
||||||
|
- [ ] **Step 11: Create home/coding/git/git.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/coding/git/git.nix
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
# Git configuration
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 12: Create home/coding/agents/agents.nix**
|
||||||
|
|
||||||
|
References: `inputs.m3ta-nixpkgs.homeModules.coding.agents`
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/coding/agents/agents.nix
|
||||||
|
{ inputs, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
inputs.m3ta-nixpkgs.homeModules.coding.agents
|
||||||
|
];
|
||||||
|
|
||||||
|
# Agent-Konfiguration
|
||||||
|
coding.agents.opencode = {
|
||||||
|
enable = true;
|
||||||
|
agentsInput = inputs.agents;
|
||||||
|
# modelOverrides...
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 13: Create home/profiles/gaming/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/profiles/gaming/default.nix
|
||||||
|
# Gaming Profile - frei kombinierbar
|
||||||
|
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./steam.nix
|
||||||
|
./gamescope.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 14: Create gaming profile modules**
|
||||||
|
|
||||||
|
- `steam.nix` - Steam + Steam Deck Tools
|
||||||
|
- `gamescope.nix` - Gamescope Session
|
||||||
|
|
||||||
|
- [ ] **Step 15: Create home/profiles/media/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/profiles/media/default.nix
|
||||||
|
# Media Profile - Content Creation / Streaming
|
||||||
|
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./obs.nix
|
||||||
|
./ffmpeg.nix
|
||||||
|
./yt-dlp.nix
|
||||||
|
./kdenlive.nix
|
||||||
|
./handbrake.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 16: Create media profile modules**
|
||||||
|
|
||||||
|
Migrate from `home/features/desktop/media.nix`:
|
||||||
|
- `obs.nix` - OBS Studio
|
||||||
|
- `ffmpeg.nix` - FFmpeg + Tools
|
||||||
|
- `yt-dlp.nix` - YouTube Downloader
|
||||||
|
- `kdenlive.nix` - Kdenlive Video Editor
|
||||||
|
- `handbrake.nix` - HandBrake
|
||||||
|
|
||||||
|
- [ ] **Step 17: Create home/desktop/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/desktop/default.nix
|
||||||
|
# Desktop-Konfiguration - nur wenn context=desktop
|
||||||
|
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Zed Remote: Server-Zugriff via SSH
|
||||||
|
programs.zed-editor = {
|
||||||
|
enable = true;
|
||||||
|
# Remote Connections Config
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./wm
|
||||||
|
./apps
|
||||||
|
./theme
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 18: Create home/desktop/wm modules**
|
||||||
|
|
||||||
|
Migrate from `home/features/desktop/`:
|
||||||
|
- `hyprland.nix` → `home/desktop/wm/hyprland.nix`
|
||||||
|
- `wayland.nix` → `home/desktop/wm/wayland.nix`
|
||||||
|
- `rofi.nix` → `home/desktop/wm/rofi.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 19: Create home/desktop/apps modules**
|
||||||
|
|
||||||
|
Migrate from `home/features/desktop/`:
|
||||||
|
- `obsidian.nix` → `home/desktop/apps/obsidian.nix`
|
||||||
|
- `office.nix` → `home/desktop/apps/office.nix`
|
||||||
|
- `webapps.nix` → `home/desktop/apps/webapps.nix`
|
||||||
|
- `crypto.nix` → `home/desktop/apps/crypto.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 20: Create home/desktop/theme modules**
|
||||||
|
|
||||||
|
Migrate from `home/features/desktop/`:
|
||||||
|
- `fonts.nix` → `home/desktop/theme/fonts.nix`
|
||||||
|
- `theme.nix` → `home/desktop/theme/theme.nix`
|
||||||
|
- `wallpapers.nix` → `home/desktop/theme/wallpapers.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 21: Create home/server/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/server/default.nix
|
||||||
|
# Server-Konfiguration - nur wenn context=server
|
||||||
|
# Minimal da primär via Zed Remote gearbeitet wird
|
||||||
|
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Server-spezifische Konfiguration falls nötig
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 22: Commit Phase 1**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add home/
|
||||||
|
git commit -m "feat(home): create new directory structure
|
||||||
|
|
||||||
|
- Add base/ with shell, cli-tools, secrets
|
||||||
|
- Add coding/ with editor, lsp, git, agents
|
||||||
|
- Add profiles/ with gaming, media
|
||||||
|
- Add desktop/ with wm, apps, theme
|
||||||
|
- Add server/ minimal config
|
||||||
|
- Reference m3ta-nixpkgs modules where appropriate"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Create Profile System with Constraints
|
||||||
|
|
||||||
|
### Task 2: Implement Profile Loader with Mutual Exclusion
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Create: `home/lib/default.nix` (Profile loading utilities)
|
||||||
|
- Modify: `flake.nix` (Host-spezifische Home-Config)
|
||||||
|
- Modify: `hosts/common/users/home.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Create home/lib/default.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home/lib/default.nix
|
||||||
|
# Profile loading utilities
|
||||||
|
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Generiert Home-Manager Konfiguration basierend auf Profilen
|
||||||
|
mkHomeConfig = {
|
||||||
|
profiles ? [],
|
||||||
|
context ? null, # "desktop" | "server" | null
|
||||||
|
}: let
|
||||||
|
inherit (lib) optionalAttrs mkIf;
|
||||||
|
|
||||||
|
# Profile die immer geladen werden
|
||||||
|
baseModules = [ ./base ];
|
||||||
|
|
||||||
|
# Profile die optional geladen werden
|
||||||
|
profileModules = optionalAttrs (builtins.elem "coding" profiles) [ ./coding ];
|
||||||
|
|
||||||
|
# Context-spezifische Module
|
||||||
|
contextModules = {
|
||||||
|
desktop = [ ./desktop ];
|
||||||
|
server = [ ./server ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Profile-spezifische Module
|
||||||
|
profileSpecific = {
|
||||||
|
gaming = [ ./profiles/gaming ];
|
||||||
|
media = [ ./profiles/media ];
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
imports = baseModules ++ profileModules
|
||||||
|
++ (contextModules.${context} or [])
|
||||||
|
++ (builtins.map (p: ./profiles.${p})
|
||||||
|
(builtins.filter (p: builtins.hasAttr p profileSpecific) profiles));
|
||||||
|
};
|
||||||
|
|
||||||
|
# Assertion: desktop und server schließen sich aus
|
||||||
|
mutualExclusiveContexts = builtins.hasAttr "desktop" && builtins.hasAttr "server";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Update flake.nix for m3-ares (Desktop)**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# hosts/m3-ares/ (Desktop Beispiel)
|
||||||
|
{ inputs, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Home-Manager für m3tam3re auf m3-ares
|
||||||
|
home-manager.users.m3tam3re = { config, ... }: {
|
||||||
|
# NEU: Profile-System
|
||||||
|
m3ta.profiles = [ "coding" "gaming" "media" ]; # Freie Kombination
|
||||||
|
m3ta.context = "desktop"; # Schließt "server" aus
|
||||||
|
|
||||||
|
# Alternativ: Legacy-Kompatibilität
|
||||||
|
# imports = [ ./home ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Update flake.nix for m3-atlas (Server)**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# hosts/m3-atlas/ (Server Beispiel)
|
||||||
|
{ inputs, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
home-manager.users.m3tam3re = { config, ... }: {
|
||||||
|
m3ta.profiles = [ "coding" ]; # Nur Coding auf Server
|
||||||
|
m3ta.context = "server"; # Schließt "desktop" aus
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Add assertions in flake.nix**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# Validation: Context constraints
|
||||||
|
assertion = hostConfig.m3ta.context != "desktop" || hostConfig.m3ta.context != "server"
|
||||||
|
|| (hostConfig.m3ta.context == null); # Mutually exclusive
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 5: Commit Phase 2**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add flake.nix hosts/
|
||||||
|
git commit -m "feat: implement profile system with constraints
|
||||||
|
|
||||||
|
- Add home/lib for profile loading utilities
|
||||||
|
- Add m3ta.profiles option (list of profiles)
|
||||||
|
- Add m3ta.context option (desktop|server|null)
|
||||||
|
- Add mutual exclusion assertion
|
||||||
|
- Update m3-ares and m3-atlas as examples"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: Migrate Existing Configuration
|
||||||
|
|
||||||
|
### Task 3: Migrate home/features to new Structure
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Modify: Multiple files in `home/features/` (move content, update paths)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Map existing features to new structure**
|
||||||
|
|
||||||
|
| Old Location | New Location | Notes |
|
||||||
|
|--------------|--------------|-------|
|
||||||
|
| `home/features/cli/nushell.nix` | `home/base/shell/nushell.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/cli/starship.nix` | `home/base/shell/starship.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/cli/fzf.nix` | `home/base/cli-tools/fzf.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/cli/zellij.nix` | `home/base/cli-tools/zellij.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/cli/nitch.nix` | `home/base/cli-tools/nitch.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/cli/television.nix` | `home/base/cli-tools/television.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/cli/secrets.nix` | `home/base/secrets/secrets.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/coding/opencode.nix` | Reference via `m3ta-nixpkgs` | Update import |
|
||||||
|
| `home/features/coding/pi.nix` | Reference via `m3ta-nixpkgs` | Update import |
|
||||||
|
| `home/features/desktop/hyprland.nix` | `home/desktop/wm/hyprland.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/wayland.nix` | `home/desktop/wm/wayland.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/rofi.nix` | `home/desktop/wm/rofi.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/obsidian.nix` | `home/desktop/apps/obsidian.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/office.nix` | `home/desktop/apps/office.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/webapps.nix` | `home/desktop/apps/webapps.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/crypto.nix` | `home/desktop/apps/crypto.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/fonts.nix` | `home/desktop/theme/fonts.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/theme.nix` | `home/desktop/theme/theme.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/wallpapers.nix` | `home/desktop/theme/wallpapers.nix` | ✓ Done in Task 1 |
|
||||||
|
| `home/features/desktop/media.nix` | `home/profiles/media/*.nix` | Split into modules |
|
||||||
|
| `home/features/desktop/gaming.nix` | `home/profiles/gaming/*.nix` | Split into modules |
|
||||||
|
|
||||||
|
- [ ] **Step 2: Archive old structure**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# After migration, archive old features/
|
||||||
|
git mv home/features home/features.old
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Verify all configurations are imported**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check that all features are accessible in new structure
|
||||||
|
nix flake check
|
||||||
|
home-manager dry-activate
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Commit Phase 3**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git commit -m "chore: migrate features to profile structure
|
||||||
|
|
||||||
|
- Move all cli features to base/shell and base/cli-tools
|
||||||
|
- Move desktop features to desktop/* subdirectories
|
||||||
|
- Split media into individual profile modules
|
||||||
|
- Split gaming into individual profile modules
|
||||||
|
- Archive old features/ directory"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: Test and Validate
|
||||||
|
|
||||||
|
### Task 4: Test Profile Combinations
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Test: Manual testing on m3-ares (Desktop)
|
||||||
|
- Test: Manual testing on m3-atlas (Server)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Test m3-ares (Desktop with all profiles)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and test on m3-ares
|
||||||
|
nixos-rebuild dry-build --flake .#m3-ares
|
||||||
|
home-manager dry-activate --flake .#m3tam3re@m3-ares
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: Loads base + coding + desktop + gaming + media
|
||||||
|
|
||||||
|
- [ ] **Step 2: Test m3-atlas (Server with coding only)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and test on m3-atlas
|
||||||
|
nixos-rebuild dry-build --flake .#m3-atlas
|
||||||
|
home-manager dry-activate --flake .#m3tam3re@m3-atlas
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: Loads base + coding + server (no desktop modules)
|
||||||
|
|
||||||
|
- [ ] **Step 3: Test assertion (should fail)**
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# This SHOULD fail - desktop and server together
|
||||||
|
m3ta.context = "desktop";
|
||||||
|
m3ta.profiles = [ "coding" ];
|
||||||
|
# Nix should throw assertion error
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Commit Phase 4**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit -m "test: validate profile combinations on all hosts
|
||||||
|
|
||||||
|
- m3-ares: base + coding + desktop + gaming + media ✓
|
||||||
|
- m3-atlas: base + coding + server ✓
|
||||||
|
- Constraint assertion working ✓"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 5: Cleanup
|
||||||
|
|
||||||
|
### Task 5: Remove Old Structure
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
|
||||||
|
- Delete: `home/features.old/` (after verification)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Verify no broken imports**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Search for any references to old paths
|
||||||
|
grep -r "home/features" --include="*.nix"
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: No results
|
||||||
|
|
||||||
|
- [ ] **Step 2: Delete old directory**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git rm -rf home/features.old
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Final format and check**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix fmt
|
||||||
|
nix flake check
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Final commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit -m "chore: remove old features directory
|
||||||
|
|
||||||
|
Cleanup complete. New structure:
|
||||||
|
- home/base/ (always loaded)
|
||||||
|
- home/coding/ (profile-independent)
|
||||||
|
- home/profiles/ (gaming, media)
|
||||||
|
- home/desktop/ (context=desktop)
|
||||||
|
- home/server/ (context=server)"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
| Phase | Tasks | Description |
|
||||||
|
|-------|-------|-------------|
|
||||||
|
| 1 | 1 | Create new directory structure |
|
||||||
|
| 2 | 2 | Implement profile system with constraints |
|
||||||
|
| 3 | 3 | Migrate existing features |
|
||||||
|
| 4 | 4 | Test profile combinations |
|
||||||
|
| 5 | 5 | Remove old structure |
|
||||||
|
|
||||||
|
**Total:** 5 tasks, ~22 steps
|
||||||
|
|
||||||
|
**Expected Duration:** 2-4 hours (depending on migration complexity)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration Notes
|
||||||
|
|
||||||
|
1. **NeoVim Config**: Already in nixpkgs, reference via `inputs.m3ta-nixpkgs.packages.neovim-config`
|
||||||
|
|
||||||
|
2. **Agent-System**: Already in nixpkgs, reference via `inputs.m3ta-nixpkgs.homeModules.coding.agents`
|
||||||
|
|
||||||
|
3. **Zed Remote**: Desktop-only feature, works via SSH. No server-side installation needed.
|
||||||
|
|
||||||
|
4. **Fish Shell**: Removed from base (Nushell is primary). Can be added as optional profile if needed.
|
||||||
|
|
||||||
|
5. **Feature Flags**: Old `features.*.enable` options → New profile lists `m3ta.profiles = [ "gaming" "media" ]`
|
||||||
17
flake.lock
generated
17
flake.lock
generated
@@ -969,6 +969,7 @@
|
|||||||
"skills-anthropic": "skills-anthropic",
|
"skills-anthropic": "skills-anthropic",
|
||||||
"skills-basecamp": "skills-basecamp",
|
"skills-basecamp": "skills-basecamp",
|
||||||
"skills-kestra": "skills-kestra",
|
"skills-kestra": "skills-kestra",
|
||||||
|
"skills-superpowers": "skills-superpowers",
|
||||||
"skills-vercel": "skills-vercel"
|
"skills-vercel": "skills-vercel"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1040,6 +1041,22 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"skills-superpowers": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1776996157,
|
||||||
|
"narHash": "sha256-0WupTacT1jIwVBloj1i0RF7wIllVtP8eMPRl7VrXdbE=",
|
||||||
|
"owner": "obra",
|
||||||
|
"repo": "superpowers",
|
||||||
|
"rev": "6efe32c9e2dd002d0c394e861e0529675d1ab32e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "obra",
|
||||||
|
"repo": "superpowers",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"skills-vercel": {
|
"skills-vercel": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
|
|||||||
@@ -61,6 +61,10 @@
|
|||||||
url = "github:kestra-io/agent-skills";
|
url = "github:kestra-io/agent-skills";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
|
skills-superpowers = {
|
||||||
|
url = "github:obra/superpowers";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
skills-vercel = {
|
skills-vercel = {
|
||||||
url = "github:vercel-labs/skills";
|
url = "github:vercel-labs/skills";
|
||||||
flake = false;
|
flake = false;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ in {
|
|||||||
src = inputs.skills-anthropic;
|
src = inputs.skills-anthropic;
|
||||||
selectSkills = ["pdf" "docx" "frontend-design"];
|
selectSkills = ["pdf" "docx" "frontend-design"];
|
||||||
}
|
}
|
||||||
|
{src = inputs.skills-superpowers;}
|
||||||
{src = inputs.skills-vercel;}
|
{src = inputs.skills-vercel;}
|
||||||
{src = inputs.skills-basecamp;}
|
{src = inputs.skills-basecamp;}
|
||||||
{src = inputs.skills-kestra;}
|
{src = inputs.skills-kestra;}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
neovim
|
neovim
|
||||||
git
|
git
|
||||||
|
tea
|
||||||
ghostty.terminfo
|
ghostty.terminfo
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
extraServices = {
|
extraServices = {
|
||||||
flatpak.enable = false;
|
flatpak.enable = false;
|
||||||
ollama.enable = false;
|
ollama.enable = false;
|
||||||
podman.enable = true;
|
podman.enable = false;
|
||||||
virtualisation.enable = false;
|
virtualisation.enable = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,35 @@
|
|||||||
venvSitePackages = "/home/hermes/.venv/lib/python3.11/site-packages";
|
venvSitePackages = "/home/hermes/.venv/lib/python3.11/site-packages";
|
||||||
gccLibPath = "${pkgs.stdenv.cc.cc.lib}/lib";
|
gccLibPath = "${pkgs.stdenv.cc.cc.lib}/lib";
|
||||||
in {
|
in {
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /home/hermes/.config 0755 hermes hermes -"
|
||||||
|
"d /home/hermes/.config/tea 0755 hermes hermes -"
|
||||||
|
"L+ /home/hermes/.config/tea/yml - - - - ${pkgs.writeText "tea-yml" ''
|
||||||
|
logins:
|
||||||
|
- name: m3ta
|
||||||
|
url: https://code.m3ta.dev
|
||||||
|
token:
|
||||||
|
ssh_host: code.m3ta.dev
|
||||||
|
user: m3ta-chiron
|
||||||
|
default: true
|
||||||
|
''}"
|
||||||
|
"f /home/hermes/.gitconfig 0644 hermes hermes - ${pkgs.writeText "gitconfig" ''
|
||||||
|
[user]
|
||||||
|
name = m3ta-chiron
|
||||||
|
email = m3ta-chiron@agentmail.to
|
||||||
|
[init]
|
||||||
|
defaultBranch = main
|
||||||
|
''}"
|
||||||
|
];
|
||||||
|
|
||||||
services.hermes-agent = {
|
services.hermes-agent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
addToSystemPackages = true;
|
addToSystemPackages = true;
|
||||||
|
|
||||||
|
extraPackages = with pkgs; [docker git tea];
|
||||||
|
|
||||||
# Secrets via agenix
|
# Secrets via agenix
|
||||||
environmentFiles = [
|
environmentFiles = [
|
||||||
config.age.secrets."hermes-env".path
|
config.age.secrets."hermes-env".path
|
||||||
@@ -26,11 +51,15 @@ in {
|
|||||||
# Non-secret environment variables
|
# Non-secret environment variables
|
||||||
environment = {
|
environment = {
|
||||||
GLM_BASE_URL = "https://api.z.ai/api/coding/paas/v4/";
|
GLM_BASE_URL = "https://api.z.ai/api/coding/paas/v4/";
|
||||||
|
GIT_AUTHOR_NAME = "m3ta-chiron";
|
||||||
|
GIT_AUTHOR_EMAIL = "m3ta-chiron@agentmail.to";
|
||||||
|
GIT_COMMITTER_NAME = "m3ta-chiron";
|
||||||
|
GIT_COMMITTER_EMAIL = "m3ta-chiron@agentmail.to";
|
||||||
};
|
};
|
||||||
|
|
||||||
# ── Container mode (podman) ──────────────────────────────────────────
|
# ── Container mode (podman) ──────────────────────────────────────────
|
||||||
container = {
|
container = {
|
||||||
enable = true;
|
enable = false;
|
||||||
backend = "podman";
|
backend = "podman";
|
||||||
extraVolumes = ["/home/m3tam3re/p:/projects:rw"];
|
extraVolumes = ["/home/m3tam3re/p:/projects:rw"];
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
@@ -63,7 +92,7 @@ in {
|
|||||||
|
|
||||||
# ── Terminal ───────────────────────────────────────────────────────
|
# ── Terminal ───────────────────────────────────────────────────────
|
||||||
terminal = {
|
terminal = {
|
||||||
backend = "docker";
|
backend = "local";
|
||||||
modal_mode = "auto";
|
modal_mode = "auto";
|
||||||
cwd = ".";
|
cwd = ".";
|
||||||
timeout = 180;
|
timeout = 180;
|
||||||
@@ -127,6 +156,7 @@ in {
|
|||||||
|
|
||||||
# ── Memory ─────────────────────────────────────────────────────────
|
# ── Memory ─────────────────────────────────────────────────────────
|
||||||
memory = {
|
memory = {
|
||||||
|
provider = "honcho";
|
||||||
memory_enabled = true;
|
memory_enabled = true;
|
||||||
user_profile_enabled = true;
|
user_profile_enabled = true;
|
||||||
memory_char_limit = 2200;
|
memory_char_limit = 2200;
|
||||||
@@ -169,44 +199,6 @@ in {
|
|||||||
|
|
||||||
# ── Web ────────────────────────────────────────────────────────────
|
# ── Web ────────────────────────────────────────────────────────────
|
||||||
web = {backend = "exa";};
|
web = {backend = "exa";};
|
||||||
|
|
||||||
# ── Platform Toolsets ──────────────────────────────────────────────
|
|
||||||
platform_toolsets = {
|
|
||||||
cli = [
|
|
||||||
"browser"
|
|
||||||
"clarify"
|
|
||||||
"code_execution"
|
|
||||||
"cronjob"
|
|
||||||
"delegation"
|
|
||||||
"file"
|
|
||||||
"image_gen"
|
|
||||||
"memory"
|
|
||||||
"session_search"
|
|
||||||
"skills"
|
|
||||||
"terminal"
|
|
||||||
"todo"
|
|
||||||
"tts"
|
|
||||||
"vision"
|
|
||||||
"web"
|
|
||||||
];
|
|
||||||
telegram = [
|
|
||||||
"browser"
|
|
||||||
"clarify"
|
|
||||||
"code_execution"
|
|
||||||
"cronjob"
|
|
||||||
"delegation"
|
|
||||||
"file"
|
|
||||||
"image_gen"
|
|
||||||
"memory"
|
|
||||||
"session_search"
|
|
||||||
"skills"
|
|
||||||
"terminal"
|
|
||||||
"todo"
|
|
||||||
"tts"
|
|
||||||
"vision"
|
|
||||||
"web"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -50,5 +50,6 @@ in {
|
|||||||
"secrets/honcho-key.age".publicKeys = systems ++ users;
|
"secrets/honcho-key.age".publicKeys = systems ++ users;
|
||||||
"secrets/hermes-env.age".publicKeys = systems ++ users;
|
"secrets/hermes-env.age".publicKeys = systems ++ users;
|
||||||
"secrets/hermes-cloud-env.age".publicKeys = systems ++ users;
|
"secrets/hermes-cloud-env.age".publicKeys = systems ++ users;
|
||||||
|
"secrets/hermes-gitea-token.age".publicKeys = systems ++ users;
|
||||||
"secrets/tuwunel-registration-token.age".publicKeys = systems ++ users;
|
"secrets/tuwunel-registration-token.age".publicKeys = systems ++ users;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
25
secrets/hermes-gitea-token.age
Normal file
25
secrets/hermes-gitea-token.age
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 4NLKrw j+zQu+BGTMVhIEzhqECFLMqs8tK7P8zDF/0fumWTrSY
|
||||||
|
RqemJfrS6bf6r/Owh38FNV14JNqTP2ZtN8diUqJ0NTU
|
||||||
|
-> ssh-ed25519 5kwcsA gYZEiF1oFwd7kddSzmmvFC7umpaD0y4DL2LAOHmmkkI
|
||||||
|
KcOSW/aExT0wJl2Fs97mVSj64CYGL8DsHbKZca3BdTo
|
||||||
|
-> ssh-ed25519 9d4YIQ 41Mx+hpizRKeW4lu1gMcHVI4p5PqN202F/dJl0n9oTw
|
||||||
|
G9zr0kdbswSifyHzqlWNyYB1TEaQjxFyxs7mz9XM7Ko
|
||||||
|
-> ssh-ed25519 3Bcr1w 3FnDPnyWym3Pv70DBEg+tewH6GNM3S/mbbYPGjb1LiY
|
||||||
|
TOpFTHq5XDoJoqfsDnProGUlXKwuGJQhYJf/f23bgKE
|
||||||
|
-> ssh-ed25519 c4NQlA mpZuWGlXdmhqkta3SxcDcm/4dw017Zn9KS29WBznnzg
|
||||||
|
3LjR5O5uezXy3toWAEAEPU4nVx69GYpbYQwQygoIwf4
|
||||||
|
-> ssh-rsa DQlE7w
|
||||||
|
iK5n9EFFD3apn6eJJiAB6dom/llqgneXeSYWNN44Xm0Qez5H3slpn4779BiQwMrI
|
||||||
|
863iJj91E7KSgANfm3yP3JP8veuuwATk1lRjnk/Xx5AbIQjhlANK7SoNB938unKc
|
||||||
|
Syd5sA4NX/SRy5rlJUXmc1ZtJex1sc880xj9xEOrclhd1pMD7zPE647SUDz8FcEU
|
||||||
|
BsHckU3+dKvlLcUVbFJCVfH9LBQezVRE2ajRQRy6FygwTkgrXpD9peTCXLBOacye
|
||||||
|
IOzPCJUsDB0Ats5osq/xdYb23Qz5RaiztBhNuurI6gWkAim17f8sGIdlWirjQOvH
|
||||||
|
NwTIArMT8vexBJsLtiYW0ZbLYPX+byidLRpuk2RXT1pfUMkeVWA2g1CgKCHKJbQG
|
||||||
|
ef4EMFRPhRZ5Knd6279dXalbE2FTbt1uWpxhvjOF8E5O4lM6+3ApWf5d7c0qM6on
|
||||||
|
jP4+Bn/sOIkVsiB1fjd6YqcXdyORNLqlwOsaCtvfLJ5t0EfebpP5Rigk13f2xddf
|
||||||
|
|
||||||
|
-> ssh-ed25519 CSMyhg M6Nc06Maem8c92oFktCHl/FeNdevn8fazYJjxLygxSc
|
||||||
|
h6E9GHEO8l9cKVEO6RlpzVJovuo7aOmKYXVDYHVBs1s
|
||||||
|
--- RlUihZA7p0luD4sv9EY73wq9qIFWMHNnoNmxxVMO8OI
|
||||||
|
¸å¿Ür
|
||||||
Reference in New Issue
Block a user