Commit graph

11 commits

Author SHA1 Message Date
Samuel James
07116a0475
Docker setup-script hint + expanded Help page (#35)
* Add mesh prerequisite gate (NetBird verification before app config)

Implements the design in docs/mesh-prerequisite-gate.md per the user's
DECIDE A-D answers: a permanent admin override, B1 (reachable) verification
with host mesh IP shown informationally, members allowed in with a notice
instead of being blocked, and mesh.required defaulting off so the live
production instance is unaffected.

- system_config kv table + getConfig/setConfig helpers
- /api/system/mesh-status, /mesh/verify, /mesh/override, /mesh/required
- AuthContext gains a 'needs-mesh' status (admins only) and exposes
  meshStatus for a member-facing banner
- MeshGate page reuses the integration create+test flow to connect NetBird

* Make mesh verification universal (CIDR check, not NetBird-specific)

Replace the NetBird-adapter-based "reachable" check with a vendor-agnostic
one: the admin supplies the mesh's IP range (CIDR), and verification just
confirms this host has an address inside it. Works identically for
NetBird, WireGuard, ZeroTier, Tailscale, or any other mesh tech, with no
integration record or vendor API call required.

* Add reachability fallback for routed meshes (VPC peering, etc.)

A host can be on the mesh's "side" of a routed network (e.g. a VPC peered
into a NetBird/WireGuard mesh) without holding a local IP in the mesh's
own CIDR. Local-IP-in-CIDR stays the primary check; if it fails, the admin
can supply a known peer/gateway IP on the mesh and we verify by pinging
it instead. Adds iputils to the backend image for the ping binary.

* Add Mesh section to Settings for configuring/testing the mesh gate

Admins can now toggle mesh.required, run verify/override, and see
current mesh status entirely from the app, without hitting the API
directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hu9pZvJY4BgmcQeAw2ugk

* Show a host-specific Docker remote-API setup script in Settings

When adding/editing a Docker integration with a tcp:// or http:// remote
URL, display a copyable systemd override + curl verification script
scoped to the entered host:port, so enabling the daemon's API doesn't
require looking up the steps separately.

* Expand Help page with quick-start guide and real-world examples

Adds a quick-start ordering card and per-feature example callouts (with icons) so first-time users see concrete use cases, not just descriptions.

* Update HANDOFF/README for handoff: mesh gate shipped, Docker UX work, no feature queued

Corrects the stale 'mesh gate not built' framing (it shipped across 4 commits, all merged) and documents the Docker setup-script hint + Help page expansion done this session. Leaves a clear next-task list for the picking-up agent: decide on merging claude/youthful-cerf-ibvxfb, then check with the user for the next priority.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-21 04:34:59 -04:00
Samuel James
cdd93f204e
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
Samuel James
b836ac1a02
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
Samuel James
b2600e2577
docs: fix conflicting Kiro steering/spec files (#25)
* 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: fix conflicting Kiro steering/spec files missed in prior cleanup

The earlier doc-cleanup pass only checked root-level markdown files and
missed .kiro/, a dotdir holding Kiro IDE spec-driven-dev artifacts. Two
files there directly contradicted the real app and design-decisions.md:

- .kiro/steering/design-rules.md is auto-injected into every Kiro
  session, but stated an 80px/50px sidebar and Zustand state management
  — both wrong (real app: 200px/64px sidebar, plain React state +
  localStorage, no Zustand). Rewrote it to match design-decisions.md so
  Kiro doesn't steer future sessions on stale info.
- .kiro/specs/archnest-dashboard/requirements.md was an abandoned
  requirements-only spec (no design.md/tasks.md ever followed) for the
  original 6-page/Network-page/CDN-asset vision, same vintage as the
  already-deleted archnest-blueprint.md. Removed the whole spec
  directory since nothing references it and it never matured past
  requirements.

Documented both files (and why they were removed/rewritten) in the
README's documentation map.

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:51:11 -04:00
Samuel James
d8286ac42b
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
Samuel James
ae5142769d
Update handoff docs for deployed state and auth roadmap (#22)
* 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.

* Update handoff docs for deployed state and auth-system work-in-progress

HANDOFF.md and README.md still described deployment as the open task;
the app has been live on racknerd1 for several sessions now. Rewrites
both to reflect current state and lay out the 4-phase auth/SSO plan
(menu fix done, password/sessions/login-log/multi-user/SSO pending) so
the next session can pick up at Phase 2 without re-deriving context.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 09:50:06 -04:00
Claude
3d9c4c65c2
Update docs: mark feature work complete, document deploy setup as the only remaining task
HANDOFF.md and TERMIX_MIGRATION.md were stale (pre-dated the full Termix migration). Rewrote HANDOFF.md to reflect the current feature-complete state and point straight at deployment setup. Expanded README's Deployment section into concrete steps (host provisioning, secrets, .env, DNS) since the workflow/compose files already exist and just need configuring. Added a top-level .env.example for the server-side .env that docker-compose.yml expects.
2026-06-19 16:41:32 +00:00
Claude
70b2ef8a69
Update README and add HANDOFF.md for session handoff
Documents the real backend, all 8 completed integration adapters, known
caveats (Proxmox TLS, fast-jwt vuln, SSH key textarea UX, the
IntegrationType/integrationTypes enum duplication footgun), and what's
explicitly on hold (Terminal/Termix), so another AI session can resume
work with full context.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
2026-06-18 21:12:50 +00:00
Claude
f24edb74b2
Add avatar upload to Settings, document Settings page, update README
- Profile section: click avatar to upload a personal photo (FileReader
  preview, hover camera icon overlay), replacing static initials
- README.md rewritten with project-specific page status table, dev
  setup, tech stack, and deployment notes
- design-decisions.md: add Settings Page subsection documenting layout,
  section-switching, and the avatar upload technique

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
2026-06-18 18:50:43 +00:00
Samuel James
dd535827ae update 2026-06-18 08:14:00 -04:00
Samuel James
a562f801de
Add README with project title and description 2026-06-11 20:02:04 -04:00