dev_arc_aws/.kiro/steering/project-guide.md
Samuel James 4422840dd3
Some checks failed
Deploy to racknerd1 / validate (push) Successful in 2m26s
Deploy to racknerd1 / deploy (push) Failing after 4s
the
2026-06-23 15:55:31 -04:00

4 KiB

ArchNest — Project Guide for Kiro

Steering file for AI sessions working on this repo. Covers architecture decisions, workflow rules, and patterns to follow. Read alongside design-rules.md (visual conventions) which is injected separately.


Quick Context

ArchNest is a self-hosted ops dashboard — live infrastructure monitoring, SSH terminal/tunnels/files, Docker container management, remote desktop, and bookmarks. Deployed at archnest.snsnetlabs.com via Docker Compose on racknerd1. Private Forgejo repo (never public).

Tech Stack (exact versions matter)

Layer Tech
Frontend React 19, Vite 8, TypeScript 6, Tailwind CSS v4, React Router 7
Charts Recharts 3
Icons Lucide React (verify exports exist at runtime, not just TS types)
Terminal xterm.js 6 (@xterm/xterm + @xterm/addon-fit)
Backend Fastify 5, TypeScript 5.7, ESM (tsx dev, tsc -b build)
DB better-sqlite3 (SQLite)
Auth @fastify/jwt + bcryptjs + server-tracked sessions
Validation zod
SSH ssh2 library
AWS @aws-sdk/client-ec2, @aws-sdk/client-sts
Deploy Docker Compose (Alpine images), GitHub Actions → racknerd1

Git Workflow

  • Remote: origin → private Forgejo instance (SSH via ProxyJump)
  • Never commit on main. Always create kiro/<feature> branches.
  • Commit style: imperative title + body explaining why, with trailers:
    Co-authored-by: Samuel James <ssamjame@amazon.com>
    Co-authored-by: Kiro <noreply@kiro.dev>
    
  • Before committing: npm run build (frontend) + cd backend && npx tsc --noEmit (backend)
  • Stage specific files — never git add -A blindly
  • PR flow: git push -u origin <branch>gh pr create → squash-merge

Code Patterns to Follow

Frontend

  • One page component per route in src/pages/
  • All backend calls go through src/lib/api.ts (typed apiFetch wrapper)
  • No global state library — plain React state + localStorage for prefs
  • Auth via src/lib/AuthContext.tsx (JWT in localStorage)
  • New pages need: route in App.tsx, entry in api.ts, sidebar link

Backend

  • One route file per feature in backend/src/routes/
  • Integration adapters in backend/src/integrations/ (must implement testConnection())
  • SSH-based features use backend/src/ssh/connect.ts shared transport
  • Request validation with zod schemas
  • Audit logging via logEvent() from db/index.ts
  • Secrets encrypted at rest (AES-256-GCM via db/crypto.ts)
  • Never expose secret values to frontend — only secretKeys: string[]

Adding a New Integration

  1. Create adapter in backend/src/integrations/<name>.ts
  2. Register in backend/src/integrations/registry.ts
  3. Add type to IntegrationType union
  4. Add route if needed in backend/src/routes/
  5. Add api.ts functions + TS interfaces on frontend
  6. Add card in Settings integrations section

Policies

  • Zero mock data — every number comes from a live API/SSH/DB call
  • Design-first for big features — write a docs/<feature>.md before coding
  • No footer on any page
  • Primary target: 1920px+ viewport, should feel spacious
  • Mesh gate defaults OFF — never lock the live instance
  • OpenSSL legacy provider in backend Dockerfile — don't remove (needed for old PEM keys)

Environment

  • Required env vars: ARCHNEST_SECRET_KEY, ARCHNEST_JWT_SECRET
  • Optional: ARCHNEST_DB_PATH, PORT, ARCHNEST_GUAC_CRYPT_KEY, ARCHNEST_CORS_ORIGIN, ARCHNEST_AGENT_TOKEN, ARCHNEST_AGENT_STALE_MS
  • Frontend dev proxies /apihttp://localhost:4000

Key Files to Read First

  1. README.md — architecture overview
  2. HANDOFF.md — current state + standing rules
  3. design-decisions.md — visual conventions + per-page implementation notes
  4. ROADMAP.md — deferred/tiered work
  5. docs/ — subsystem design documents

SSH Config (for reference)

  • ssh forgejo → Git operations (User: forgejo, via ProxyJump linode)
  • ssh forgejo-admin → root shell on Forgejo host (for admin tasks)
  • ssh linode → jump host at 172.238.163.85