GET /api/data/export serializes all integrations (with decrypted secrets, for
cross-instance portability), bookmark categories, bookmarks, and tunnels;
POST /api/data/import restores them additively in a transaction with old->new
id remapping. Wires the Settings "Data & Backup" section to download/upload the
backup file. Verified end-to-end including cross-instance portability under a
different ARCHNEST_SECRET_KEY, plus browser verification of the Settings UI.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
Ports the core of Termix's host-transfer feature: stream files/directories
between two SSH hosts through the backend via SFTP (read source -> write dest),
with up-front scan for progress totals, recursive directory support, optional
move, and cooperative cancellation. Leaves behind Termix's parallel-segment
workers, tar heuristics, watchdogs and retry orchestration as unjustified at
this scale.
Exposed via REST (start/list/status/cancel) with an in-memory transfer registry,
and surfaced in the Files page as a per-entry "send to another host" action plus
a live transfers progress panel. Verified end-to-end against two real SSH
endpoints: recursive copy (binary md5 match), move (source deleted), error
handling, and mid-stream cancel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
Ports Termix's per-host metrics collector logic onto ArchNest's own SSH
connection helpers (not its multi-user/cache/session scaffolding), exposed via
a new authenticated REST endpoint and a dedicated /host-metrics page with
client-side polling.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
Extends the existing Engine-API-based docker integration adapter rather than
porting Termix's SSH+CLI approach, since ArchNest's docker integrations only
ever configure a baseUrl. Adds backend/src/docker/{client,exec}.ts and
backend/src/routes/docker.ts (REST + websocket exec-terminal via raw socket
hijack), and a new Containers page wired into the sidebar/router.
Verified end-to-end against a real dockerd instance and a real container in
this sandbox, which caught and fixed a genuine bug: calling /exec/{id}/resize
before starting the exec hangs the daemon indefinitely; fixed by setting the
initial size via ConsoleSize at exec-create time instead.
Ephemeral per-request SFTP connections, whole-file-in-memory view/edit
with a 50MB cap and binary detection, streaming download for files of
any size, multipart upload. No sudo/permission-elevation or
server-to-server transfer in this pass (documented gaps, matching
Termix's own scope for the latter).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
- backend/src/ssh/connect.ts: extracted shared SSH-connect logic
(jump-host chaining, TOFU host-key verification) out of terminal.ts
so tunnels can reuse it.
- backend/src/tunnels/manager.ts + socks5.ts: in-memory tunnel
runtime manager supporting local forward (forwardOut), remote
forward (forwardIn), and dynamic SOCKS5 proxying, with automatic
reconnect/retry and an auto-start-on-boot option. New `tunnels`
table persists configs as the saved presets.
- backend/src/routes/tunnels.ts: REST CRUD + connect/disconnect.
- src/pages/Tunnels.tsx: new /tunnels page (sidebar entry added) to
create, start/stop, and delete tunnels with live status polling.
- Verified end-to-end against a real ssh2 test server handling real
forwardOut/forwardIn requests and a real upstream TCP echo server -
all three tunnel modes moved real data, and disconnect correctly
tore down the local listener.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
TopBar, Sidebar, and the Settings profile form previously showed a hardcoded
"ArchNest Ops" identity, a fake unread-notification count, and a static "All
Systems Operational" indicator. These now use the real logged-in user (with
a new PUT /api/auth/me endpoint to edit display name/email/avatar) and real
integration health for the sidebar status dot.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
Adds an events table + logEvent helper for a genuine activity log, and
a /api/integrations/resources aggregate endpoint backed by a new optional
listResources adapter method (implemented for Docker via its containers API).
StatusCards, MiddleRow, BottomRow, and Infrastructure now render real
integration/resource/event data instead of hardcoded numbers, with empty
states where no data source exists yet (AWS cost, historical trends).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
Bookmarks, categories, favorites, quick access, recently added, link
health, and category breakdown are now all derived from real backend
data instead of hardcoded arrays. Adds an Add Bookmark modal (with
inline new-category creation) and a working favorite toggle, both
backed by the existing /api/bookmarks endpoints. Adds
createBookmarkCategory/updateBookmark to the API client.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
Replaces mock integration data in Settings.tsx with live calls to
api.listIntegrations/createIntegration/updateIntegration/testIntegration.
Also fixes apiFetch sending Content-Type: application/json on bodyless
requests, which made Fastify reject Test Connection calls with 400.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
- New AuthContext drives app state (loading/needs-setup/enrolling/
logged-out/logged-in) by checking GET /api/system/setup-status and
GET /api/auth/me on load; JWT stored in localStorage
- Enrollment page: step 1 creates the admin account via POST /api/setup,
step 2 lets you connect integrations (or skip) before entering the app
- Login page for returning sessions; TopBar's Sign Out now calls
logout() instead of being a dead link
- Verified end-to-end in a browser: fresh setup -> connect/skip ->
dashboard, reload persists the session, sign out -> login -> back in
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF