Compare commits
13
Commits
3f48c0400b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d9d0ccf9f | ||
|
|
027b366d32 | ||
|
|
6c637b7d2a | ||
|
|
ec01840c03 | ||
|
|
d4025b39f6 | ||
|
|
cb27d06be3 | ||
|
|
db61ca7b28 | ||
|
|
39156b44f6 | ||
|
|
0a90261623 | ||
|
|
329f9855a6 | ||
|
|
2e93c57b37 | ||
|
|
2f88d5567e | ||
|
|
b725bb37c2 |
@@ -0,0 +1,164 @@
|
|||||||
|
# Homepage Widgets 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:** Add a `my.homepage.widgets` NixOS option so widgets can be declared in the homepage module and contributed from other modules, mirroring how `my.homepage.services` works today.
|
||||||
|
|
||||||
|
**Architecture:** Add a `my.homepage.widgets` option (typed `listOf attrs` since widget shapes vary by type) to the homepage module, import a `manual-widgets.nix` for ad-hoc definitions, merge both and pass to `services.homepage-dashboard.widgets`. Add starter widgets in `machines/jupiter/environments.nix` to confirm the wiring works end-to-end.
|
||||||
|
|
||||||
|
**Tech Stack:** Nix, NixOS module system, gethomepage.dev (`services.homepage-dashboard`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Map
|
||||||
|
|
||||||
|
| Action | File | Responsibility |
|
||||||
|
|--------|------|----------------|
|
||||||
|
| Modify | `modules/environments/homepage/default.nix` | Add `my.homepage.widgets` option + wire to dashboard |
|
||||||
|
| Create | `modules/environments/homepage/manual-widgets.nix` | Empty list for ad-hoc widgets (parallel to `manual-services.nix`) |
|
||||||
|
| Modify | `machines/jupiter/environments.nix` | Declare starter widgets to verify the feature end-to-end |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Add `my.homepage.widgets` option to the homepage module
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `modules/environments/homepage/default.nix`
|
||||||
|
- Create: `modules/environments/homepage/manual-widgets.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Create `manual-widgets.nix`** — empty list, same pattern as `manual-services.nix`
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# modules/environments/homepage/manual-widgets.nix
|
||||||
|
[ ]
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Add `manualWidgets` import in the `let` block of `default.nix`**
|
||||||
|
|
||||||
|
Current `let` block (lines 7–42) ends with `homepageServices`. Add one line after `manualServices`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
manualServices = import ./manual-services.nix;
|
||||||
|
manualWidgets = import ./manual-widgets.nix;
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Add the `my.homepage.widgets` option**
|
||||||
|
|
||||||
|
After the closing brace of `options.my.homepage.services` (line 80), add:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
options.my.homepage.widgets = with lib; mkOption {
|
||||||
|
type = types.listOf types.attrs;
|
||||||
|
default = [ ];
|
||||||
|
description = "Widget definitions passed directly to services.homepage-dashboard.widgets. Each entry is an attrset like { resources = { cpu = true; memory = true; }; }.";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Wire widgets to the dashboard in the `config` block**
|
||||||
|
|
||||||
|
The `config` block currently sets `services = homepageServices ++ manualServices;`. Add `widgets`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.homepage-dashboard = {
|
||||||
|
enable = true;
|
||||||
|
listenPort = dashboardPort;
|
||||||
|
allowedHosts = "${dashboardHost}:${toString dashboardPort},localhost:${toString dashboardPort},127.0.0.1:${toString dashboardPort},jupiter.solar.internal:${toString dashboardPort}";
|
||||||
|
bookmarks = import ./bookmarks.nix;
|
||||||
|
services = homepageServices ++ manualServices;
|
||||||
|
widgets = config.my.homepage.widgets ++ manualWidgets;
|
||||||
|
};
|
||||||
|
# ... rest of config unchanged
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 5: Build to check for eval errors (no switch yet)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nixos-rebuild build --flake /Users/finnmarkwitz/development/nixos#jupiter 2>&1 | tail -20
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: build succeeds with no errors (widgets list is empty, so no visible change yet).
|
||||||
|
|
||||||
|
- [ ] **Step 6: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/finnmarkwitz/development/nixos
|
||||||
|
git add modules/environments/homepage/default.nix modules/environments/homepage/manual-widgets.nix
|
||||||
|
git commit -m "feat: add my.homepage.widgets option to homepage module"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 2: Add starter widgets in `environments.nix`
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `machines/jupiter/environments.nix`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Add `my.homepage.widgets` to `environments.nix`**
|
||||||
|
|
||||||
|
Add the following after the `my.profiles` block (e.g. after line 39, before the `my.hardware` block):
|
||||||
|
|
||||||
|
```nix
|
||||||
|
my.homepage.widgets = [
|
||||||
|
{
|
||||||
|
search = {
|
||||||
|
provider = "google";
|
||||||
|
target = "_blank";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
resources = {
|
||||||
|
cpu = true;
|
||||||
|
memory = true;
|
||||||
|
disk = "/";
|
||||||
|
cacheInterval = 5000;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
datetime = {
|
||||||
|
text_size = "xl";
|
||||||
|
format = {
|
||||||
|
timeStyle = "short";
|
||||||
|
dateStyle = "short";
|
||||||
|
hour12 = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Build to confirm eval**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nixos-rebuild build --flake /Users/finnmarkwitz/development/nixos#jupiter 2>&1 | tail -20
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: build succeeds.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Switch and verify visually**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo nixos-rebuild switch --flake /Users/finnmarkwitz/development/nixos#jupiter
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `http://jupiter.solar.internal:8082` (or `http://localhost:8082`) in a browser.
|
||||||
|
|
||||||
|
Expected: search bar, CPU/memory/disk resource monitor, and date/time widget appear at the top of the dashboard.
|
||||||
|
|
||||||
|
- [ ] **Step 4: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/finnmarkwitz/development/nixos
|
||||||
|
git add machines/jupiter/environments.nix
|
||||||
|
git commit -m "feat: add starter homepage widgets (search, resources, datetime)"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification Checklist
|
||||||
|
|
||||||
|
- [ ] `nixos-rebuild build` passes with no eval errors
|
||||||
|
- [ ] Dashboard at `:8082` shows widgets at top of page
|
||||||
|
- [ ] Existing services and bookmarks are unchanged
|
||||||
|
- [ ] Other modules can now contribute widgets via `my.homepage.widgets = [ ... ];` in their `config` block
|
||||||
Generated
+26
-26
@@ -63,11 +63,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1788450739,
|
"lastModified": 1790898470,
|
||||||
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
|
"narHash": "sha256-zTwuwezD0w3hpga6a6P8emidzAZFyWqlNeRBlpWOOl8=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
|
"rev": "024633cd702b10285db5cb19b40ad48d2399ba60",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -87,11 +87,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1788267358,
|
"lastModified": 1790500375,
|
||||||
"narHash": "sha256-nt+lUqYVpc9Y6JeMd2WmXzCDojasdadKo0mWcluvY2Y=",
|
"narHash": "sha256-XN3sDtn8TU9hAc9xqZ+SqRB/HHm2wjxM6aSWYLJU+oo=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "git-hooks.nix",
|
"repo": "git-hooks.nix",
|
||||||
"rev": "27555e2624241fb116b49095df4caaee85a25691",
|
"rev": "a0e4241b51206fbcbf52fd322eb5f0cd80f153c4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -113,11 +113,11 @@
|
|||||||
"uv2nix": "uv2nix"
|
"uv2nix": "uv2nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791121781,
|
"lastModified": 1792650380,
|
||||||
"narHash": "sha256-39vzOiYTAwECDMfJAv/b+OxpHPXHfJle0Gx5x+WjPW0=",
|
"narHash": "sha256-4l8C4z7K4VQDq2ExP6v9NUdCpSFagB1hbt4gh/Y6YSw=",
|
||||||
"owner": "NousResearch",
|
"owner": "NousResearch",
|
||||||
"repo": "hermes-agent",
|
"repo": "hermes-agent",
|
||||||
"rev": "af90026aa09949579bd423d24def3d38f743cde0",
|
"rev": "81a55437f3f31a9f12a30c53b6c5d49d420898aa",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -157,11 +157,11 @@
|
|||||||
"nixpkgs-regression": "nixpkgs-regression"
|
"nixpkgs-regression": "nixpkgs-regression"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791067591,
|
"lastModified": 1792618091,
|
||||||
"narHash": "sha256-SGcfVVSS3DLO+ES4J+SrLxKGP11yvTWXgiAqku1L+Sk=",
|
"narHash": "sha256-sDmJ6tgPjlSk9P2jCXXjV2l0Ewe7K9CwclMcAvpEyR0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nix",
|
"repo": "nix",
|
||||||
"rev": "e8280775f307a94ca82cea193cfcc14c0d56232a",
|
"rev": "42d96171bbef8a8073106dd93ca68878d7339abd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -211,11 +211,11 @@
|
|||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791128201,
|
"lastModified": 1792491056,
|
||||||
"narHash": "sha256-rlsYY/Dg/LhbIj51Aa6TLvRpZeb3KZgUTd7llQ5XcJE=",
|
"narHash": "sha256-6n1Dn+WYtD8lprnSi+0k4FjbKfIVNG8lblpJ5MiiqXs=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "31cc5f4d9b9ba601071e8b8504601b9b176e2756",
|
"rev": "efb6d0d5e2394c3c5416a18652808aba206c0988",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -286,11 +286,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791048980,
|
"lastModified": 1792502884,
|
||||||
"narHash": "sha256-u3KCLxsnf1622GdFccg8hmkEIutOZ1h4pvia5ERjIuI=",
|
"narHash": "sha256-ij8QUxzTOHovLrNOxVRx+RAhGQFOMsJbji0veiatH5k=",
|
||||||
"rev": "a7868a727837f3c09cee2ce0ca671c76b1589fed",
|
"rev": "02c087f3fe673c9e317f206a627cb6b910336dbe",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1084968.a7868a727837/nixexprs.tar.zst"
|
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1097682.02c087f3fe67/nixexprs.tar.zst"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"id": "nixpkgs",
|
"id": "nixpkgs",
|
||||||
@@ -313,11 +313,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
"nixpkgs_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791031588,
|
"lastModified": 1792615934,
|
||||||
"narHash": "sha256-4XF6NXFWmQPM0xHuxTw+iQEA6mUtmDQNJoVd4u9GkLw=",
|
"narHash": "sha256-q1ku4ygV7tdmv5Q9QYwhVDsNMZRJcRYjVczoX5+XWBo=",
|
||||||
"rev": "825e2028c29b702a4a5f085f08095d12099784f2",
|
"rev": "da6dc0e7b26060f2f71ce3ef7088fb56ee44fa36",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://releases.nixos.org/nixos/26.05/nixos-26.05.11150.825e2028c29b/nixexprs.tar.zst"
|
"url": "https://releases.nixos.org/nixos/26.05/nixos-26.05.12400.da6dc0e7b260/nixexprs.tar.zst"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"id": "nixpkgs",
|
"id": "nixpkgs",
|
||||||
@@ -415,11 +415,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791103873,
|
"lastModified": 1792056300,
|
||||||
"narHash": "sha256-nFxM+pKoZ8LJAEnUXARyCaOAloWgaW9kZQOSjWzKcTE=",
|
"narHash": "sha256-YU1LjDe1o2Ymg5zEiCHbmMXLkDCtxHQRiVqZ3nC5GGk=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "dcd241ba97088c22569d1573286e1b9daad340c0",
|
"rev": "44931708c62937c2b1bf7953902989fa5bb9ee1b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ _: {
|
|||||||
kde-desktop.enable = true;
|
kde-desktop.enable = true;
|
||||||
zsh.enable = true;
|
zsh.enable = true;
|
||||||
apps = {
|
apps = {
|
||||||
desktop_apps = true;
|
desktop_apps = false;
|
||||||
dev_apps = true;
|
dev_apps = false;
|
||||||
};
|
};
|
||||||
development.enable = true;
|
development.enable = true;
|
||||||
docker.enable = true;
|
docker.enable = true;
|
||||||
@@ -19,7 +19,7 @@ _: {
|
|||||||
nvidia.enable = false;
|
nvidia.enable = false;
|
||||||
};
|
};
|
||||||
my.services = {
|
my.services = {
|
||||||
vpn.enable = true;
|
vpn.enable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,13 @@ in
|
|||||||
spotify
|
spotify
|
||||||
keepassxc
|
keepassxc
|
||||||
moonlight-qt
|
moonlight-qt
|
||||||
|
# jetbrains.idea-ultimate
|
||||||
nextcloud-client
|
nextcloud-client
|
||||||
pipewire
|
pipewire
|
||||||
wireplumber
|
wireplumber
|
||||||
vlc
|
vlc
|
||||||
ghostty
|
ghostty
|
||||||
|
zed-editor
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,7 @@ in
|
|||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
users.users.finn.packages = with pkgs; [
|
users.users.finn.packages = with pkgs; [
|
||||||
google-chrome
|
|
||||||
vscode
|
|
||||||
zed-editor
|
|
||||||
neovim
|
neovim
|
||||||
# jetbrains.idea-ultimate
|
|
||||||
go
|
go
|
||||||
nodejs # bundles npm
|
nodejs # bundles npm
|
||||||
(python3.withPackages (
|
(python3.withPackages (
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ in
|
|||||||
services.hermes-agent = {
|
services.hermes-agent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# Deliberate pin, matches the approved design — bump on purpose, not by drift.
|
# Deliberate pin, matches the approved design — bump on purpose, not by drift.
|
||||||
settings.model.default = "anthropic/claude-sonnet-4-5";
|
settings.model.default = "anthropic/claude-sonnet-5-5";
|
||||||
# The Nix flake input is the source of truth for hermes's version here; its
|
# The Nix flake input is the source of truth for hermes's version here; its
|
||||||
# built-in self-updater polling GitHub independently just burns API quota.
|
# built-in self-updater polling GitHub independently just burns API quota.
|
||||||
settings.updates.check = false;
|
settings.updates.check = false;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
{
|
{
|
||||||
icon = "reddit.png";
|
icon = "reddit.png";
|
||||||
href = "https://reddit.com/";
|
href = "https://reddit.com/";
|
||||||
description = "The front page of the internet";
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -17,7 +16,7 @@
|
|||||||
{
|
{
|
||||||
YouTube = [
|
YouTube = [
|
||||||
{
|
{
|
||||||
abbr = "YT";
|
icon = "youtube.png";
|
||||||
href = "https://youtube.com/";
|
href = "https://youtube.com/";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -32,4 +32,40 @@
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
"Gaming" = [
|
||||||
|
{
|
||||||
|
"Talon" = {
|
||||||
|
href = "https://ethraldos.online";
|
||||||
|
description = "Kunst der Täuschung";
|
||||||
|
icon = "foundry-vtt.png";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"Tyranny of Dragons" = {
|
||||||
|
href = "https://hotdq.smoothcloud.de";
|
||||||
|
description = "Tyranny of Dragons (D&D)";
|
||||||
|
icon = "foundry-vtt.png";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"Beholder D&D" = {
|
||||||
|
href = "https://beholder.ethraldos.online";
|
||||||
|
description = "Andrey FoundryVTT Server";
|
||||||
|
icon = "foundry-vtt.png";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"Minecraft" = {
|
||||||
|
href = "https://rechberg.online";
|
||||||
|
description = "Java Minecraft Server";
|
||||||
|
icon = "minecraft.png";
|
||||||
|
widget = {
|
||||||
|
type = "minecraft";
|
||||||
|
url = "tcp://rechberg.online:25565";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user