docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
# ArchNest — Design Decisions & Page Reference
2026-06-18 08:14:00 -04:00
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
> Living reference for visual/UX conventions and what's actually built on each page.
> Apply the Global Rules consistently to any new page. The Page Notes section
> describes the **real, deployed** implementation — not a mockup. If you change a
> page's layout or data source, update its section here in the same PR.
>
> This file replaces the old `archnest-blueprint.md` (original 6-page mockup
> pitch, since deleted — superseded by the real 11-page app below) and
> `glance.md` (original Glance spec with fictional config files like
> `systems.config`/`infra.config` that were never built — also deleted). Anything
> from those files still true (color palette, typography, card style, dropdown
> menu shape) has been folded in below.
2026-06-18 08:14:00 -04:00
---
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
## Global Rules (apply to every page)
2026-06-18 08:14:00 -04:00
### Sidebar
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- Expanded width: 200px. Collapsed width: 64px (icons only).
- User can manually collapse/expand via a toggle button (not just responsive breakpoints).
- Main content `margin-left` must match the sidebar width exactly.
- Bottom of sidebar: live "System Status" widget — green dot + "All Systems
Operational" or "X Issue(s) Detected", driven by polling integration status
(not the fictional ping-sweep config described in the old spec).
2026-06-18 08:14:00 -04:00
### Page Title (Top Bar)
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- Color: gold `#C8A434` — not white. Use inline `style={{ color: '#C8A434' }}`
if a Tailwind class doesn't apply.
- Font: 18px, bold, uppercase, tracking-wide.
- No border on the top bar — it blends into the page background.
- Pages with a `pageSubtitles` entry (currently only BookNest) render a larger
28px title + subtitle line instead, and the top bar grows from 56px → 72px —
see `TopBar.tsx` 's `pageSubtitles` map and `App.tsx` 's `topBarHeight` lookup,
which must be kept in sync or the layout clips/gaps.
2026-06-18 08:14:00 -04:00
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
### Colors
2026-06-24 12:27:04 -04:00
#### Dark Mode (Default — Shipped)
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
| Role | Value |
|------|-------|
| Background (page) | `#0D0E10` |
| Background (cards) | `#141518` |
| Background (sidebar) | `#0A0B0D` |
| Border (cards) | `#1E2025` |
| Border/accent (hover/active) | `#C8A434` (gold) |
| Success | `#2ECC71` |
| Warning | `#E67E22` |
| Danger | `#E74C3C` |
| Text (primary) | `#E8E6E0` |
| Text (secondary) | `#7A7D85` |
2026-06-18 08:14:00 -04:00
2026-06-24 12:27:04 -04:00
#### Light Mode (Planned — Palette Documented)
| Role | Value |
|------|-------|
| Background (page) | `#F7F6F3` (warm off-white) |
| Background (cards) | `#FFFFFF` (pure white) |
| Background (sidebar) | `#FAF9F7` (very light warm gray) |
| Border (cards) | `#E8E5DF` (soft warm border) |
| Border/accent (hover/active) | `#C8A434` (gold — same as dark) |
| Success | `#2ECC71` |
| Warning | `#E67E22` |
| Danger | `#E74C3C` |
| Text (primary) | `#1A1A1A` (near-black) |
| Text (secondary) | `#6B6560` (warm gray) |
Hero banners per mode:
- Dark: `assets/themes/archnest-default/archnest-default-dark.png` — dark sci-fi cityscape with neon arches
- Light: `assets/themes/archnest-default/archnest-default-light.png` — luminous white/gold cityscape, bright sky
Geometric/card backgrounds per mode:
- Dark: textured black slate with angular gold-lit geometric cuts (top-left and bottom-right diagonal slashes with warm gold edge lighting). Dominant colors: near-black slate `#1A1815` , charcoal `#0F0E0C` , gold edge glow `#C8A434` → `#8B6914` .
- Light: cream marble with matching diagonal geometric cuts and warm gold edge lighting. Dominant colors: warm cream `#F0EDE6` , gold highlights `#C8A434` .
---
### Forest Theme
A second theme with dark and light modes. Same structural layout as the default
but with a different visual identity — mountainous alien landscapes with amber/gold
point lights and a massive planet in the sky.
#### Forest — Dark Mode
| Role | Value | Notes |
|------|-------|-------|
| Page background | `#080806` | Near-black with warm brown undertone |
| Card background | `#121210` | Dark charcoal-brown |
| Sidebar background | `#0A0A08` | Deepest surface |
| Border | `#1E1C18` | Warm dark border |
| Accent | `#D4A850` | Warm amber/gold (slightly warmer than default) |
| Success | `#2ECC71` | |
| Warning | `#E67E22` | |
| Danger | `#E74C3C` | |
| Text primary | `#E8E4DC` | Warm off-white |
| Text secondary | `#7A7568` | Warm gray-brown |
Hero banner: dark alien mountain landscape with massive planet, amber point lights on a grid floor, warm gold highlights on peaks. Deep blacks with scattered amber/gold sparks.
Asset: `assets/themes/forest/forest-dark.png`
#### Forest — Light Mode
| Role | Value | Notes |
|------|-------|-------|
| Page background | `#F5F2ED` | Warm ivory |
| Card background | `#FFFFFF` | Pure white |
| Sidebar background | `#FAF8F4` | Lightest warm tone |
| Border | `#E5E0D8` | Soft warm border |
| Accent | `#D4A850` | Same amber/gold as dark mode |
| Success | `#2ECC71` | |
| Warning | `#E67E22` | |
| Danger | `#E74C3C` | |
| Text primary | `#1A1810` | Warm near-black |
| Text secondary | `#6B6558` | Warm brown-gray |
Hero banner: luminous white/ivory mountain landscape with massive planet, golden sparkle points on a marble-like floor, peaks dusted in white with gold vein highlights. Ethereal, bright, airy.
Asset: `assets/themes/forest/forest-light.png`
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
Tailwind v4 `@theme` custom colors (`text-gold` , `bg-card` , etc.) don't always
apply reliably — fall back to inline `style={{ color: '#C8A434' }}` when a
color isn't rendering, and verify visually after changes.
2026-06-18 08:14:00 -04:00
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
### Typography
- Card titles: 10-11px, uppercase, tracking-[1.5px], secondary color, font-medium.
- Large numbers: 24-28px, bold, primary color.
- Subtitles/labels: 10-11px, secondary color.
- Body text in lists: 13px, primary color.
- Timestamps: 11px, secondary color.
2026-06-18 08:14:00 -04:00
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
### Card Style
- Border radius: 12px. Background `#141518` . Border 1px solid `#1E2025` .
- Padding: 16-24px depending on density. No shadows (flat design).
- Hover: border transitions to gold, 0.2s ease.
### Content Alignment
- All rows in a page share the same horizontal padding (`px-6` at the parent
container level) so the hero banner, status cards, and content rows line up
left/right.
2026-06-18 08:14:00 -04:00
### Animations
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- Card hover: border → gold, 0.2s ease.
- Progress ring / sparkline: animate from 0 on load, ~1s.
- Progress bars: fill animation ~0.8s.
2026-06-18 08:14:00 -04:00
### Icons
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- Lucide React, 14-18px depending on context. Gold for active/accent, secondary
color for inactive. Gold glow on active sidebar items:
`shadow-[0_0_6px_rgba(200,164,52,0.5)]` .
- **Gotcha**: the installed lucide-react version's TypeScript types list some
brand/wordmark icons (`Github` , `Gitlab` , `Linkedin` , `Youtube` ) that aren't
actually exported at runtime — `tsc --noEmit` stays clean while the page
renders blank with a runtime `SyntaxError` only visible in the Vite dev log.
Verify icon names against the package's actual exports before importing
anything brand-flavored.
### No Footer
- No page has a fixed footer/status bar. Don't add one unless explicitly requested.
### Target Display
- Primary design target: 16-inch / 1920px-wide screen. Don't constrain content
width unnecessarily — design should feel spacious.
### User Avatar & Dropdown (TopBar, every page)
- 36px circle, gold border + glow, shows uploaded avatar image or initials.
- Adjacent: display name + "Administrator" role label, chevron (rotates on open).
- Dropdown menu: header (name + email) → **Profile** (`/settings?tab=profile` )
→ **Appearance** (`/settings?tab=appearance` ) → **Security**
(`/settings?tab=security` ) → **Help & Support** (`/help` ) → divider →
**Sign Out** (red, danger styling). See `TopBar.tsx` .
2026-06-18 08:14:00 -04:00
---
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
## Page Notes (what's actually built, page by page)
All pages below consume real backend data via `src/lib/api.ts` — **zero mock
data anywhere in the app.** Where a section says "real backend data," it means
an actual SQL-backed or live-polled endpoint, not a config file or static array.
### Glance (`/`)
- Hero banner (image with radial-gradient fade mask) + KPI cards overlapping
the bottom edge via negative margin.
- 4 status cards: **System Status** (% of integrations reachable),
**Infrastructure** (resource count + health breakdown from
`api.listResources()` ), **Integrations** (connected/total from
`api.listIntegrations()` ), **Bookmarks** (total + favorites from
`api.listBookmarks()` ).
- Middle row (3 columns): Resource Overview (top 6 resources + status),
Recent Activity (5 latest from `api.listEvents(5)` ), problem/critical
resources widget.
- Bottom row: Connected Integrations grid + 4 Shortcuts buttons (to Settings,
BookNest, Infrastructure).
- No footer. Hides the hero gracefully if the banner image fails to load.
- There is **no** `systems.config` /`infra.config` /ping-sweep/fail2ban
machinery — that was speculative spec from before the backend existed.
Health figures are derived directly from each integration adapter's
`testConnection()` result, polled by the existing `/api/integrations` list.
### Infrastructure (`/infrastructure`)
- Hero banner at the `App.tsx` layout level (`showHero` includes this route),
extending behind the sticky, transparent-on-hero-routes TopBar.
- Sub-tabs: **Overview** (only enabled tab) and **Network** (disabled,
"Coming soon" — intentional, leave alone unless asked).
- 4 status cards: Total Resources, Healthy, Warnings, Critical — from
`api.listResources()` .
- Middle row: Resource Distribution (donut by integration type) + Node Status
(4-col tile grid, one tile per resource — replaced an earlier world-map
concept since a map doesn't make sense for a small/single-site setup).
- Bottom row: Integration Health list + Recent Activity (`api.listEvents(4)` ).
- Card backgrounds use a `cardDim` + `cardVignette` (radial-gradient,
`closest-side` keyword — a fixed `%` leaves a visible hard edge on straight
sides) combo on the middle row only, per explicit visual preference; bottom
row stays plain/regular.
### BookNest (`/booknest`)
- Hero banner reused at layout level with page-specific tuning
(`heroPaddingTop` /`heroObjectPosition` lookup maps in `App.tsx` ).
- Large 28px title + "Your Digital Library" subtitle (the one page using
`pageSubtitles` ), header grows to 72px.
- Page stats row (Links / Categories / Favorites) + "Delete All" bulk action.
- Main column: Quick Access (top 5 categories) + bookmark groups grid (4 cols,
full CRUD with hover edit/delete/star).
- Right sidebar (spans both grid rows via `gridRow: '1 / span 2'` ): Favorites,
Recently Added (5 newest), Link Health donut, Category Breakdown donut.
- Add/edit bookmark modal supports auto-detected favicons via
`guessServiceIconUrl()` or manual icon entry.
- All data from `api.listBookmarks()` / `api.listBookmarkCategories()` with
real create/update/delete calls — no local-only state.
### Terminal (`/terminal`)
- Left sidebar: SSH hosts (integrations of type `ssh` ), click to connect.
- Tab bar + 1/2/4-pane split layout, each pane an independent xterm instance.
docs: sync HANDOFF/README/design-decisions; add mesh-gate design (#32)
Bring the docs in line with what shipped since the auth phases, and hand
off the next planned feature cleanly for another agent to pick up.
- HANDOFF.md: new TL;DR (auth complete; persistent terminals + Docker
three-ways shipped); prominent "next task = Mesh Prerequisite Gate"
callout warning not to code before the open decisions are answered;
corrected standing rules (kiro/<feature> branches, gh-based workflow,
npm run build over plain tsc, Co-authored-by trailers); architecture
sections updated for TerminalSessionContext, dockerSsh/agents routes,
docker_agent_reports table, ssh/docker.ts, and the new agent env vars;
new "Docker: three ways" section.
- README.md: Containers/Terminal page rows, route-group list, SSH layer,
agent/ dir, ARCHNEST_AGENT_TOKEN/ARCHNEST_AGENT_STALE_MS, current-state
paragraph, and doc reading order.
- design-decisions.md: Terminal (persistence) and Containers (three
sources + detail tab) page notes; backend Docker-transport note; mesh
gate flagged under Future Integration Notes.
- docs/mesh-prerequisite-gate.md (new): full design with lockout-safety
invariants and the open decisions (A-D) needed before implementation.
Docs only; no code changed.
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
2026-06-20 16:42:47 -04:00
- **Sessions persist across in-app navigation**: the xterm instances +
WebSockets are owned by `src/lib/TerminalSessionContext.tsx` (mounted above
the router), and their DOM nodes are re-parented into the page on mount /
moved to a hidden root on unmount rather than disposed. Closing a tab/pane or
logging out tears a session down; a full browser reload still drops them.
(Self-hosted caps the grid at 4 panes; "as many as fit" is a paid-tier
roadmap item.)
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- Preferences panel (theme: ArchNest Dark/Matrix/Solarized/Midnight Blue, font
size 11-16px, font family) — stored in `localStorage`
(`archnest-terminal-prefs` ), not synced server-side.
- WebSocket to `/api/terminal` : `connect` /`input` /`resize` /`list_tmux` /`disconnect`
messages; supports attaching to an existing tmux session or starting a new one.
- Certificate auth (OPKSSH) shells out to the system `ssh` binary under a pty
rather than using the JS SSH client.
- Session logging to `ARCHNEST_SESSION_LOG_DIR` is backend-supported but has
no dedicated viewer UI yet.
### Tunnels (`/tunnels`)
- List + create form for local/remote/dynamic (SOCKS5) SSH tunnels.
- Create form fields conditionally show/hide based on mode (no endpoint
host/port fields for dynamic mode).
- Status color map: stopped `#7A7D85` , connecting `#C8A434` , retrying
`#E0A030` , connected `#2ECC71` , error `#E74C3C` . Polls every 3s.
- Backed by `api.listTunnels()/createTunnel()/connectTunnel()/disconnectTunnel()/deleteTunnel()` .
### Files (`/files`)
- SSH host selector + breadcrumb-navigable SFTP directory browser.
- File editor modal: plain textarea, files up to 50MB (anything larger is
download-only). Heuristic binary detection (null bytes/control chars) decides
base64 vs. text encoding.
- Inline directory creation, rename, delete, upload, download.
- Host-to-host transfer modal: pick source file + destination host/path,
copy-or-move toggle, live progress bar fed by `api.getTransfer(id)` polling.
### Containers (`/containers`)
docs: sync HANDOFF/README/design-decisions; add mesh-gate design (#32)
Bring the docs in line with what shipped since the auth phases, and hand
off the next planned feature cleanly for another agent to pick up.
- HANDOFF.md: new TL;DR (auth complete; persistent terminals + Docker
three-ways shipped); prominent "next task = Mesh Prerequisite Gate"
callout warning not to code before the open decisions are answered;
corrected standing rules (kiro/<feature> branches, gh-based workflow,
npm run build over plain tsc, Co-authored-by trailers); architecture
sections updated for TerminalSessionContext, dockerSsh/agents routes,
docker_agent_reports table, ssh/docker.ts, and the new agent env vars;
new "Docker: three ways" section.
- README.md: Containers/Terminal page rows, route-group list, SSH layer,
agent/ dir, ARCHNEST_AGENT_TOKEN/ARCHNEST_AGENT_STALE_MS, current-state
paragraph, and doc reading order.
- design-decisions.md: Terminal (persistence) and Containers (three
sources + detail tab) page notes; backend Docker-transport note; mesh
gate flagged under Future Integration Notes.
- docs/mesh-prerequisite-gate.md (new): full design with lockout-safety
invariants and the open decisions (A-D) needed before implementation.
Docs only; no code changed.
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
2026-06-20 16:42:47 -04:00
- Host selector spans **three sources** : Docker Engine TCP API (integrations of
type `docker` ), Docker-over-SSH (integrations of type `ssh` , runs the `docker`
CLI on the host), and read-only push **agents** (hosts that POST reports).
- **Intra-page tabs**: tab 1 is the container spreadsheet
(Name/Image/State/CPU/Memory/Ports/Actions); clicking a container name opens a
closeable per-container **detail tab** (overview/state+health/stats/ports/
networks/mounts/env-with-secrets-masked/labels). Detail is richest for agent
hosts (full `docker inspect` ); docker/ssh sources degrade gracefully.
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- Per-container state badge (running/paused/exited/dead) with context-aware
action buttons (Start/Stop/Restart/Pause/Unpause/Remove) — buttons disable
docs: sync HANDOFF/README/design-decisions; add mesh-gate design (#32)
Bring the docs in line with what shipped since the auth phases, and hand
off the next planned feature cleanly for another agent to pick up.
- HANDOFF.md: new TL;DR (auth complete; persistent terminals + Docker
three-ways shipped); prominent "next task = Mesh Prerequisite Gate"
callout warning not to code before the open decisions are answered;
corrected standing rules (kiro/<feature> branches, gh-based workflow,
npm run build over plain tsc, Co-authored-by trailers); architecture
sections updated for TerminalSessionContext, dockerSsh/agents routes,
docker_agent_reports table, ssh/docker.ts, and the new agent env vars;
new "Docker: three ways" section.
- README.md: Containers/Terminal page rows, route-group list, SSH layer,
agent/ dir, ARCHNEST_AGENT_TOKEN/ARCHNEST_AGENT_STALE_MS, current-state
paragraph, and doc reading order.
- design-decisions.md: Terminal (persistence) and Containers (three
sources + detail tab) page notes; backend Docker-transport note; mesh
gate flagged under Future Integration Notes.
- docs/mesh-prerequisite-gate.md (new): full design with lockout-safety
invariants and the open decisions (A-D) needed before implementation.
Docs only; no code changed.
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
2026-06-20 16:42:47 -04:00
themselves for invalid transitions. **Agent rows are read-only** (no actions).
- Live CPU/memory stats: polled for Docker-API running containers; embedded in
the report for agent hosts; not available for the SSH list view.
- Logs modal (configurable tail) and exec modal (interactive shell) for
docker/ssh sources, via `/api/docker/exec` (base64-framed) or
`/api/docker-ssh/exec` (plain UTF-8). See `docs/docker-agent-monitoring.md` .
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
### Remote Desktop (`/remote-desktop`)
- Left sidebar: hosts from integrations of type `remote_desktop` .
- Main area is a Guacamole canvas tunneled over WebSocket to `/api/guacamole` ,
proxying to the `guacd` sidecar container (RDP/VNC/Telnet).
- Requires `ARCHNEST_GUAC_CRYPT_KEY` — sessions fail without it (the backend
warns on startup if it's missing).
### Host Metrics (`/host-metrics`)
- Left sidebar: SSH hosts. Selecting one starts a 5-second polling loop against
`api.getHostMetrics(integrationId)` , cleared on deselect.
- Cards: CPU/Memory/Disk gauges (color thresholds: green < 75 %, yellow 75-90 %,
red ≥90%) + Uptime, then Network Interfaces, Processes (top 10),
Listening Ports, Firewall Rules (UFW/iptables), Login Activity.
- Backed by 10 sequential SSH-exec collectors under `backend/src/ssh/metrics/`
(cpu, memory, disk, uptime, network, system, processes, ports, firewall,
login-stats) — sequential on purpose, to avoid exceeding OpenSSH's
`MaxSessions` limit per host.
### Settings (`/settings`)
- Fixed 200px left nav, 7 sections: Profile, Appearance, Security,
Integrations, Notifications, Data & Backup, About. URL-deep-linkable via
`?tab=` (`useSearchParams` ) — use this pattern for any future section.
- **Profile**: display name, email, avatar upload (`FileReader.readAsDataURL`
→ base64 data URL, persisted via `api.updateMe()` — this one *is* a real
backend round-trip, unlike the rest of the page below).
- **Appearance**: accent color swatches — **local-state only, doesn't persist
or apply anywhere** (see Known Stubs in `HANDOFF.md` ).
- **Security**: password-change form + 2FA toggle — currently placeholder UI
pending the Phase 2 auth work in `HANDOFF.md` .
- **Integrations**: one card per type (Proxmox/Docker/NetBird/Cloudflare/AWS/
Uptime Kuma/Weather/Remote Desktop/SSH), each with type-specific fields
(secrets masked, eye-toggle to reveal, "Test Connection" button). Real CRUD
via `api.createIntegration()/updateIntegration()/deleteIntegration()/testIntegration()` .
- **Notifications**: toggles — placeholder, no delivery mechanism (see
Known Stubs in `HANDOFF.md` ).
- **Data & Backup**: full JSON export/import of integrations + secrets +
bookmarks + tunnels via `backend/src/routes/data.ts` — this is the one
endpoint that intentionally round-trips decrypted secrets, by design, for
backup portability.
- **About**: static version/license/links info.
### Help (`/help`)
- Fully static — no backend calls. 11 guide cards (one per real page) with a
short description and tips. Update this page whenever a new page ships.
### Login (`/login`) / Enrollment (`/enrollment`)
- `Login.tsx` : username/password form → `api.login()` → `AuthContext` .
- `Enrollment.tsx` : two-step first-run flow — (1) create the admin account via
`api.setup()` , gated to only work while the `users` table is empty; (2)
optional "Connect Your Services" integration onboarding grid (skippable,
same integration form as Settings). Routed to based on
`GET /api/system/setup-status` .
2026-06-18 18:50:43 +00:00
2026-06-18 17:49:34 +00:00
---
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
## Backend Architecture (current, not aspirational)
Add backend skeleton: Fastify + SQLite API with auth and integrations
- Single-user JWT auth with a first-run /api/setup endpoint, gated by
GET /api/system/setup-status, to back an upcoming enrollment page
- SQLite schema for users, integrations, secrets (AES-256-GCM encrypted),
bookmarks, and bookmark categories
- Integration adapter registry with real health-check adapters for
Uptime Kuma and Docker, stubs for the rest, wired to
POST /api/integrations/:id/test
- CRUD routes for integrations and bookmarks
- backend/ as its own Docker service in docker-compose.yml, Vite dev
proxy for /api, .env.example for required secrets
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
2026-06-18 19:04:48 +00:00
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- `backend/` — Fastify 5 + TypeScript (ESM, `tsx` dev / `tsc -b` build),
`better-sqlite3` for storage, deployed as its own Docker container alongside
the frontend and a `guacd` sidecar.
Keep SSH terminal sessions connected across page navigation (#30)
The Terminal page held all session state (xterm instances and their
WebSockets) in component-local React state. Because it renders as a
`<Route element={<Terminal />}>`, navigating away unmounted it and ran
the xterm cleanup (`term.dispose()` + `ws.close()`), tearing down every
SSH session. Returning to the page reconnected from scratch, losing
scrollback and any running work.
Lift terminal sessions into a `TerminalSessionProvider` mounted above the
router (in `main.tsx`, inside `AuthProvider`). The provider owns each
pane's xterm instance, fit addon, WebSocket, and a persistent wrapper DOM
node. Wrappers live in a hidden container at the app root; the Terminal
page re-parents them into its grid on mount and moves them back to the
hidden root on unmount instead of disposing — so the xterm + WebSocket
keep running in the background across route changes.
Disconnect semantics: closing a tab/pane (or shrinking the 1/2/4 grid)
destroys those sessions; logout tears down all sessions. A full browser
reload still drops connections (the WebSocket dies with the page) — this
persists across in-app navigation only.
Shared terminal constants/types/prefs are split into a non-component
module (`src/lib/terminalPrefs.ts`) so the context file stays a clean
component module.
Also document the terminal window grid-view tiering in ROADMAP.md
(self-hosted = 4-window cap, current; paid = as many as fit on screen,
planned for the AWS deployment), and realign HANDOFF/README/design-docs
to reflect that auth Phase 3 (multi-user) shipped and Phase 4 (SSO) is
deferred to a paid AWS add-on.
Verified with a clean `tsc -b && vite build` (frontend) and
`tsc --noEmit -p .` (backend).
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
2026-06-20 15:02:50 -04:00
- Auth: JWT (`@fastify/jwt` ) with server-tracked sessions and a multi-user
schema (admin/member roles, 10-seat cap). Authentik SSO is deferred to a
paid AWS add-on — see `ROADMAP.md` .
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- Integration credentials split across `integrations` (non-secret config) and
`secrets` (AES-256-GCM-encrypted, keyed by `ARCHNEST_SECRET_KEY` ) tables —
secrets never appear in a generic "list integrations" response by
construction, not by remembering to redact a field.
- Every integration type has an adapter in `backend/src/integrations/`
implementing `testConnection()` (required) and `listResources()` (optional);
`registry.ts` maps `IntegrationType` → adapter. All 9 types
(proxmox/docker/netbird/cloudflare/aws/uptime_kuma/weather/ssh/remote_desktop)
are real, working adapters — none are stubs anymore.
- `backend/src/ssh/` is the shared SSH transport layer powering Terminal,
Files, Tunnels, Transfers, and Host Metrics: `connect.ts` (jump-host
chaining, host-key verification, cert auth), `sftp.ts` (ephemeral SFTP),
docs: sync HANDOFF/README/design-decisions; add mesh-gate design (#32)
Bring the docs in line with what shipped since the auth phases, and hand
off the next planned feature cleanly for another agent to pick up.
- HANDOFF.md: new TL;DR (auth complete; persistent terminals + Docker
three-ways shipped); prominent "next task = Mesh Prerequisite Gate"
callout warning not to code before the open decisions are answered;
corrected standing rules (kiro/<feature> branches, gh-based workflow,
npm run build over plain tsc, Co-authored-by trailers); architecture
sections updated for TerminalSessionContext, dockerSsh/agents routes,
docker_agent_reports table, ssh/docker.ts, and the new agent env vars;
new "Docker: three ways" section.
- README.md: Containers/Terminal page rows, route-group list, SSH layer,
agent/ dir, ARCHNEST_AGENT_TOKEN/ARCHNEST_AGENT_STALE_MS, current-state
paragraph, and doc reading order.
- design-decisions.md: Terminal (persistence) and Containers (three
sources + detail tab) page notes; backend Docker-transport note; mesh
gate flagged under Future Integration Notes.
- docs/mesh-prerequisite-gate.md (new): full design with lockout-safety
invariants and the open decisions (A-D) needed before implementation.
Docs only; no code changed.
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
2026-06-20 16:42:47 -04:00
`transfer.ts` (host-to-host streamed copy/move with progress + cancel),
`docker.ts` (runs the `docker` CLI over SSH for the Containers page —
injection-safe ref validation), and `metrics/` (the 10 collectors listed
above).
- Docker container data has three transports: `backend/src/docker/` +
`routes/docker.ts` (Engine TCP API), `ssh/docker.ts` + `routes/dockerSsh.ts`
(CLI over SSH), and `routes/agents.ts` (token-gated push-agent ingest into
the `docker_agent_reports` table, read-only). See
`docs/docker-agent-monitoring.md` .
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
- Vite dev server proxies `/api` → `http://localhost:4000` ; prod routes `/api`
to the backend container via Nginx Proxy Manager.
2026-06-18 17:49:34 +00:00
docs: realign design docs with deployed app, consolidate, rewrite README (#24)
* Add editable display-name field to generic integrations
Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Surface the new-integration name field as a labeled input
The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
* Add file upload for SSH private key and certificate fields
Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.
* Fix SSH private key paste corrupting multi-line PEM format
Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.
* Add JSON-converted bookmark import file for Archnest data import
Converts homarr-bookmarks.md into the format expected by /api/data/import.
* Auto-populate bookmark icons via favicon service in import JSON
Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.
* docs: realign design docs with the deployed app, consolidate, rewrite README
README.md was badly stale (listed Terminal as "pending/on hold" and only
5 pages, when all 11 pages are built and live). Rewrote it as a detailed,
accurate map of the architecture, every page, every backend route,
every integration adapter, and the SSH subsystem, written explicitly for
this repo's actual audience (the owner + future AI sessions, never the
public).
Deleted archnest-blueprint.md and glance.md: both were pre-backend mockup
specs describing fictional config files (systems.config, infra.config,
fail2ban-driven security scoring) and placeholder data that never matched
the real implementation, and conflicted with the deployed app's actual
page count/nav/data sources. Their still-true content (color palette,
dropdown menu shape, card styling) was folded into design-decisions.md.
Rewrote design-decisions.md's "Page-Specific Notes" into a full "Page
Notes" section covering all 11 pages plus Login/Enrollment (previously
only 4 pages had notes, and those didn't reflect later changes like
Files/Tunnels/Containers/Host Metrics/Remote Desktop shipping). Each
section now states the real data source per page so it can't drift from
the code silently again.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:22:04 -04:00
## Future Integration Notes
- AWS/Cloudflare/NetBird/Proxmox/Uptime Kuma adapters are real but currently
surface basic resource inventory + health only — deeper cost/pricing/budget
data (mentioned in the old blueprint) is not implemented and not currently
planned; revisit only if explicitly requested.
docs: sync HANDOFF/README/design-decisions; add mesh-gate design (#32)
Bring the docs in line with what shipped since the auth phases, and hand
off the next planned feature cleanly for another agent to pick up.
- HANDOFF.md: new TL;DR (auth complete; persistent terminals + Docker
three-ways shipped); prominent "next task = Mesh Prerequisite Gate"
callout warning not to code before the open decisions are answered;
corrected standing rules (kiro/<feature> branches, gh-based workflow,
npm run build over plain tsc, Co-authored-by trailers); architecture
sections updated for TerminalSessionContext, dockerSsh/agents routes,
docker_agent_reports table, ssh/docker.ts, and the new agent env vars;
new "Docker: three ways" section.
- README.md: Containers/Terminal page rows, route-group list, SSH layer,
agent/ dir, ARCHNEST_AGENT_TOKEN/ARCHNEST_AGENT_STALE_MS, current-state
paragraph, and doc reading order.
- design-decisions.md: Terminal (persistence) and Containers (three
sources + detail tab) page notes; backend Docker-transport note; mesh
gate flagged under Future Integration Notes.
- docs/mesh-prerequisite-gate.md (new): full design with lockout-safety
invariants and the open decisions (A-D) needed before implementation.
Docs only; no code changed.
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
2026-06-20 16:42:47 -04:00
- **Mesh prerequisite gate** (require a verified NetBird mesh before the app
can be configured) is designed in `docs/mesh-prerequisite-gate.md` but not
built — it has open decisions pending user sign-off, and must default OFF so
it can't lock the live instance.