Skip to content

feat: add logo/branding, WOL network-host suggestions, favicons, and … - #41

Merged
JuanCF merged 3 commits into
mainfrom
feat/wol-mac-network-discovery
Jun 14, 2026
Merged

feat: add logo/branding, WOL network-host suggestions, favicons, and …#41
JuanCF merged 3 commits into
mainfrom
feat/wol-mac-network-discovery

Conversation

@JuanCF

@JuanCF JuanCF commented Jun 14, 2026

Copy link
Copy Markdown
Owner

…auto-load logs

  • Add logo marks (light/dark/mark SVGs) to sidebar and README, replacing the simple accent dot
  • Add favicons (16x16, 32x32, .ico), apple-touch-icon, and PWA webmanifest with 192x192/512x512 icons
  • Add GET /api/wol/network-hosts endpoint that parses the ARP cache (ip neigh show), resolves hostnames via threaded reverse DNS, and returns discovered hosts so the WOL target form can offer MAC-address dropdown suggestions from the local network
  • Auto-fill target name from reverse-DNS hostname on MAC selection
  • Remove manual "Load Recent" button; logs now auto-load recent entries on component mount
  • Bump version references from v1.1.0 to v1.1.1
  • Add frontend & backend tests for all new functionality

Summary by CodeRabbit

  • New Features

    • Network host discovery now provides MAC address suggestions with optional hostnames in Wake on LAN.
    • Device names auto-fill from discovered hostnames when selecting a MAC address.
    • Recent logs automatically load on application startup.
  • Chores

    • Updated application version to 1.1.1.
    • Added web app manifest and favicon assets for improved branding and app installation support.

…auto-load logs

- Add logo marks (light/dark/mark SVGs) to sidebar and README,
  replacing the simple accent dot
- Add favicons (16x16, 32x32, .ico), apple-touch-icon, and
  PWA webmanifest with 192x192/512x512 icons
- Add GET /api/wol/network-hosts endpoint that parses the ARP
  cache (ip neigh show), resolves hostnames via threaded reverse
  DNS, and returns discovered hosts so the WOL target form can
  offer MAC-address dropdown suggestions from the local network
- Auto-fill target name from reverse-DNS hostname on MAC selection
- Remove manual "Load Recent" button; logs now auto-load recent
  entries on component mount
- Bump version references from v1.1.0 to v1.1.1
- Add frontend & backend tests for all new functionality
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@JuanCF, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 11 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ca2520a8-ffcb-4b91-a65d-f682bea75b0e

📥 Commits

Reviewing files that changed from the base of the PR and between fc5091b and d8c4a74.

📒 Files selected for processing (5)
  • src/backend/services/wol.py
  • src/backend/tests/test_services_wol.py
  • src/frontend/public/site.webmanifest
  • src/frontend/src/components/Logs.tsx
  • src/frontend/src/styles/components.css
📝 Walkthrough

Walkthrough

This PR adds ARP-cache-based MAC address suggestions with optional reverse-DNS hostname auto-fill to the WakeOnLan target modal, backed by a new scan_network_hosts() backend service and GET /api/wol/network-hosts route. It also bumps the release to v1.1.1, adds a sidebar SVG logo mark, introduces favicon and PWA manifest assets, and fixes the Logs component to auto-load recent entries on mount.

Changes

WOL Network Host Discovery & MAC Suggestions

Layer / File(s) Summary
scan_network_hosts backend service
src/backend/services/wol.py
New imports (socket, subprocess, ThreadPoolExecutor) and scan_network_hosts() function: runs ip neigh show, parses IP/MAC pairs via regex, normalizes MACs to uppercase, and resolves hostnames concurrently with per-future timeout and error swallowing.
GET /api/wol/network-hosts route and backend tests
src/backend/routes/wol.py, src/backend/tests/test_routes.py, src/backend/tests/test_services_wol.py
Admin-protected list_network_hosts route delegating to wol_service.scan_network_hosts(); route tests for non-empty and empty results; service unit tests covering ARP parsing, FAILED/INCOMPLETE filtering, empty output, subprocess errors, and DNS failure resilience.
Frontend WakeOnLan MAC datalist and auto-fill
src/frontend/src/constants/index.ts, src/frontend/src/components/WakeOnLan.tsx, src/frontend/src/__tests__/components/WakeOnLan.test.tsx
WOL_NETWORK_HOSTS API constant added; TargetModal gains NetworkHost type, MAC_REGEX/IDENT_START constants, networkHosts state with fetch-on-open effect, handleMacChange for name auto-fill from matched hostname, and a datalist rendering MAC suggestions; full Vitest suite covers datalist population, auto-fill guard conditions, validation errors, and fetch-failure handling.

v1.1.1 Release Housekeeping and UI Polish

Layer / File(s) Summary
v1.1.1 version bump across all release artifacts
scripts/setup.sh, vm/nut-vm.sh, README.md, src/frontend/src/constants/index.ts, src/frontend/package.json
NUTWATCH_REF default and help text updated to v1.1.1 in setup scripts and VM script; APP_VERSION and package version bumped; README install tables updated.
Sidebar SVG logo, favicon assets, and web manifest
src/frontend/src/components/Sidebar.tsx, src/frontend/src/styles/components.css, src/frontend/index.html, src/frontend/public/site.webmanifest, README.md
LogoMark SVG component replaces brand-dot element in sidebar; .brand-dot CSS replaced with .brand-logo (44×44px flex); favicon <link> tags added to index.html; site.webmanifest created with app identity, icon paths, and #0a0c10 theme color; README title updated with logo image and WOL description expanded.
Logs auto-load on mount
src/frontend/src/components/Logs.tsx
loadRecent() is called during the initial mount effect before the EventSource starts; the manual "Load Recent" toolbar button is removed.

Sequence Diagram(s)

sequenceDiagram
  participant Browser as Browser (WakeOnLan Modal)
  participant FrontendAPI as Frontend API Layer
  participant WolRoute as GET /api/wol/network-hosts
  participant WolService as wol_service.scan_network_hosts()
  participant IpNeigh as ip neigh show
  participant DNS as socket.gethostbyaddr

  Browser->>FrontendAPI: fetch(API.WOL_NETWORK_HOSTS)
  FrontendAPI->>WolRoute: GET /api/wol/network-hosts
  WolRoute->>WolService: scan_network_hosts()
  WolService->>IpNeigh: subprocess run
  IpNeigh-->>WolService: ARP neighbor lines
  WolService->>DNS: concurrent reverse DNS per IP
  DNS-->>WolService: hostname or OSError → ""
  WolService-->>WolRoute: [{ip, mac, hostname}, ...]
  WolRoute-->>FrontendAPI: {"hosts": [...]}
  FrontendAPI-->>Browser: networkHosts list
  Browser->>Browser: render datalist options, auto-fill Name from hostname
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • JuanCF/nutwatch#38: Modifies the same versioning variables (NUTWATCH_REF in scripts/setup.sh, APP_VERSION in src/frontend/src/constants/index.ts, and src/frontend/package.json) — directly the previous version bump this PR supersedes.
  • JuanCF/nutwatch#32: Introduced the WOL backend integration in src/backend/services/wol.py and src/backend/routes/wol.py that this PR extends with scan_network_hosts() and the new /api/wol/network-hosts route.

Poem

🐇 Hoppity-hop through the network I go,
Sniffing the ARP cache, row by row,
A MAC here, a hostname there,
No more blank fields — names fill the air!
v1.1.1 — the burrow's brand new,
With a logo that shines and a manifest too! 🌰

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is truncated (ends with 'and …') and doesn't fully convey all major changes; it references logos, WOL suggestions, and favicons but obscures the complete scope of the changeset. Complete the title to clearly describe all major additions: e.g., 'feat: add branding assets, WOL network-host suggestions, favicons, and auto-load logs' or provide the full untruncated title.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/wol-mac-network-discovery

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/backend/services/wol.py`:
- Around line 191-194: The subprocess.run call in the wol.py file bypasses the
project's required command wrapper. Replace the direct subprocess.run invocation
(which calls the "ip neigh show" command with a 5-second timeout and text
output) with a call to run_cmd from utils.py, ensuring you pass the command list
and timeout parameter appropriately to the wrapper function. Make sure to import
run_cmd from utils.py if not already imported in the file.
- Around line 204-214: The ThreadPoolExecutor context manager calls
shutdown(wait=True) on exit, which blocks until all submitted futures complete.
Even though as_completed() with timeout=2.0 raises FutureTimeoutError after 2
seconds, the pending hostname resolution futures continue running and the
context manager exit waits for them to finish, defeating the timeout purpose.
Fix this by canceling any remaining futures after the timeout exception is
caught. Within the FutureTimeoutError except block, iterate through the futures
dictionary and call cancel() on each future that is still running to prevent the
context manager from blocking on slow DNS queries. This ensures the timeout is
truly respected and slow hostname resolutions don't block the request beyond 2
seconds.

In `@src/frontend/public/site.webmanifest`:
- Line 16: The `start_url` property in the web manifest is currently set to
"/static/" which points to the static asset directory, but PWAs should launch at
the actual application entry route. Change the `start_url` value from "/static/"
to "/" to match the main app route served by the backend (`@app.route("/")`).
This ensures PWA installations correctly open the application at the correct URL
instead of the static assets directory.

In `@src/frontend/src/components/Logs.tsx`:
- Line 24: The `loadRecent()` function is being called before it is declared,
which causes a CI lint failure. Move the `loadRecent` function definition to
appear before the line where it is invoked at line 24, or define it as a
callback using useCallback before the effect that calls it. Ensure the
declaration of `loadRecent` precedes its usage in the effect.

In `@src/frontend/src/components/Sidebar.tsx`:
- Around line 89-99: The LogoMark SVG component has hardcoded dimensions of
50x50 pixels, but its container (.brand-logo) is 44x44 pixels, which can cause
clipping or overflow. Modify the LogoMark function to remove the hardcoded width
and height attributes or adjust them to match the container's 44x44 size, making
the SVG responsive to its parent container's dimensions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ce56ca84-585c-49eb-ad42-d115251d5fb7

📥 Commits

Reviewing files that changed from the base of the PR and between 7248b41 and fc5091b.

⛔ Files ignored due to path filters (20)
  • assets/icons/apple-touch-icon.png is excluded by !**/*.png
  • assets/icons/favicon-16x16.png is excluded by !**/*.png
  • assets/icons/favicon-32x32.png is excluded by !**/*.png
  • assets/icons/favicon.ico is excluded by !**/*.ico
  • assets/icons/icon-192.png is excluded by !**/*.png
  • assets/icons/icon-48.png is excluded by !**/*.png
  • assets/icons/icon-512.png is excluded by !**/*.png
  • assets/icons/logo-dark.svg is excluded by !**/*.svg
  • assets/icons/logo-light.svg is excluded by !**/*.svg
  • assets/icons/logo-mark.svg is excluded by !**/*.svg
  • src/frontend/public/apple-touch-icon.png is excluded by !**/*.png
  • src/frontend/public/favicon-16x16.png is excluded by !**/*.png
  • src/frontend/public/favicon-32x32.png is excluded by !**/*.png
  • src/frontend/public/favicon.ico is excluded by !**/*.ico
  • src/frontend/public/icon-192.png is excluded by !**/*.png
  • src/frontend/public/icon-48.png is excluded by !**/*.png
  • src/frontend/public/icon-512.png is excluded by !**/*.png
  • src/frontend/public/logo-dark.svg is excluded by !**/*.svg
  • src/frontend/public/logo-light.svg is excluded by !**/*.svg
  • src/frontend/public/logo-mark.svg is excluded by !**/*.svg
📒 Files selected for processing (16)
  • README.md
  • scripts/setup.sh
  • src/backend/routes/wol.py
  • src/backend/services/wol.py
  • src/backend/tests/test_routes.py
  • src/backend/tests/test_services_wol.py
  • src/frontend/index.html
  • src/frontend/package.json
  • src/frontend/public/site.webmanifest
  • src/frontend/src/__tests__/components/WakeOnLan.test.tsx
  • src/frontend/src/components/Logs.tsx
  • src/frontend/src/components/Sidebar.tsx
  • src/frontend/src/components/WakeOnLan.tsx
  • src/frontend/src/constants/index.ts
  • src/frontend/src/styles/components.css
  • vm/nut-vm.sh

Comment thread src/backend/services/wol.py Outdated
Comment thread src/backend/services/wol.py Outdated
Comment thread src/frontend/public/site.webmanifest Outdated
Comment thread src/frontend/src/components/Logs.tsx
Comment thread src/frontend/src/components/Sidebar.tsx
The loadRecent function was defined after the useEffect that calls it, relying on hoisting which works for function declarations but not for the assigned arrow function. Moving it above the useEffect ensures the function is defined before it is referenced, improving readability and avoiding any temporal dead zone confusion for future readers.
Replace subprocess.run with run_cmd in WOL ARP scanning, and cancel
non-completed futures on timeout to prevent resource leaks. Update tests
to mock run_cmd instead of monkey-patching subprocess.

Fix PWA start_url from /static/ to / for correct installed-app launch.
Enlarge brand logo from 44px to 50px for visual polish.
@JuanCF
JuanCF merged commit bbf184e into main Jun 14, 2026
4 checks passed
@JuanCF
JuanCF deleted the feat/wol-mac-network-discovery branch June 14, 2026 07:26
@coderabbitai coderabbitai Bot mentioned this pull request Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants