Skip to content

Repository files navigation

HUMAN x AGENT - Personal Lab

English | 简体中文

An interactive personal lab by Xiaoran Tang: a motion-led portfolio where AI agents, developer tools, and human context meet.

Next.js React TypeScript License: MIT

Hero view of the personal lab

What this project is

This is more than a static resume page. It is a small, self-contained product surface with four connected layers:

  1. A cinematic, chapter-based personal story.
  2. A case-study archive for experiments in agents, developer tools, and speech-first learning.
  3. An operating-system-style LUMEN workspace with windows, apps, memory, and a knowledge base.
  4. An optional server-side bridge to a separate AI agent service, with a local mock provider for offline development.

The design language treats the site as a Human-AI Lab. Xiaoran is the creator, observer, and system designer; LUMEN is a supporting guide; projects are experiments that make the relationship between people and machines tangible.

Highlights

  • Motion-led narrative: the home page moves through Entry, Hero, Human Context, Selected Work, LUMEN, System Blueprint, Capabilities, and Contact chapters.
  • Scroll-driven hero: desktop and mobile portrait sequences, mouse parallax, signal paths, progress feedback, and a maple-leaf handoff are orchestrated with GSAP and ScrollTrigger.
  • Three case studies: SOLUM, AGENT PLATFORM, and ENGLISH ROOM are defined in content/projects.ts and rendered as archive cards and full project stages.
  • LUMEN OS: /workspace provides a responsive desktop metaphor with a dock, shortcuts, draggable windows, minimize/maximize/close states, and apps for LUMEN, Projects, Notes, Terminal, Memory, Contact, Settings, and Trash.
  • Agent-ready chat: /api/lumen/chat streams token and tool events from an optional sidecar over SSE, while the built-in mock provider keeps the site usable without another service.
  • Consent-based memory: long-term visitor memory is opt-in, visitor-scoped, and manageable through pause and forget-all controls.
  • Honest contact delivery: the contact route only sends to a webhook when CONTACT_WEBHOOK_URL is configured; otherwise it falls back to a visible mail link.
  • Security-conscious defaults: server-only service tokens, same-origin checks, request limits, lightweight rate limiting, CSP, frame denial, and privacy-preserving observability are part of the implementation.

Screenshots

The following images were captured from the current local build at 1440x900 and 390x844 with a real Chromium browser. They show the actual public UI, not a mockup.

Selected work archive LUMEN guidance console
Selected work archive LUMEN guidance console

LUMEN OS on a 390 by 844 mobile viewport

Route map

Route Purpose
/ Motion-led personal lab and chapter narrative
/projects Selected work archive
/projects/[slug] Overview, highlights, stack, milestones, and next-project navigation
/workspace LUMEN OS desktop and applications
/about Personal story and design position
/resume Printable resume document
/api/lumen/chat SSE chat proxy with provider selection and request limits
/api/lumen/memory Visitor-scoped memory controls
/api/internal/agent/rag/index Authenticated knowledge indexing endpoint
/api/internal/agent/rag/retrieve Authenticated knowledge retrieval endpoint

Architecture

flowchart LR
  Browser["Browser UI<br/>Portfolio + LUMEN OS"] --> Next["Next.js App Router"]
  Next --> Chat["/api/lumen/chat<br/>SSE proxy"]
  Chat --> Provider{"Provider"}
  Provider -->|mock| Mock["Built-in mock provider"]
  Provider -->|container| Agent["Optional agent-website sidecar"]
  Next --> Memory["Visitor memory<br/>SQLite + WAL"]
  Next --> Knowledge["Site knowledge<br/>RAG index/retrieve"]
  Agent --> Knowledge
Loading

The external agent is intentionally a separate repository and deployment boundary. The website never exposes the service token to the browser. Each request gets a request ID; server observability records route, character counts, timing, and error type without storing message content.

LUMEN provider modes

Setting Behavior Use case
LUMEN_PROVIDER=mock Uses the local deterministic provider Default development and public code review
LUMEN_PROVIDER=container Proxies to LUMEN_CONTAINER_URL over the sidecar contract A connected deployment with agent-website

When the remote provider is unavailable before a response begins, the client can fall back to the mock provider. Streaming tool actions are allowlisted to navigation, scrolling, and opening an app.

Privacy and security

  • Long-term memory is off until a visitor explicitly opts in.
  • Anonymous visitors receive a random, HttpOnly, SameSite cookie; production enables Secure.
  • Memory is isolated per visitor and stored in a SQLite database under SITE_DATA_DIR with WAL enabled.
  • The Memory app supports pause and Forget all; destructive requests require same-origin validation.
  • Chat requests are capped at 8 KB and 2,000 characters, with a lightweight per-visitor rate limit.
  • Logs carry request IDs, route names, character counts, and timings, but not message bodies.
  • next.config.ts sets CSP, X-Frame-Options, nosniff, COOP, Referrer Policy, and Permissions Policy headers.

Tech stack

  • Next.js 16.3 App Router and React 19
  • TypeScript 5.7
  • Tailwind CSS 4
  • GSAP, ScrollTrigger, and @gsap/react
  • Lenis smooth scrolling
  • Canvas 2D, HTML video, Web Audio, and IntersectionObserver
  • ESLint and TypeScript static analysis
  • Node.js 22 and Docker for the standalone production image
  • SQLite for visitor memory persistence

Getting started

Prerequisites

  • Node.js 22 (the production image is built on node:22-alpine)
  • npm 10 or newer
  • Optional: Docker and a running 1panel-network only for the deployment compose file

Local development

git clone https://github.com/xiaoran7/Resume.git
cd Resume
npm ci
cp .env.example .env.local
npm run dev

Open http://localhost:3000. The default LUMEN_PROVIDER=mock keeps the project independent from the optional agent sidecar.

Environment variables

Variable Default Description
LUMEN_PROVIDER mock mock or container
LUMEN_CONTAINER_URL http://agent-website:8100 Internal URL of the optional agent sidecar
LUMEN_SERVICE_TOKEN empty Server-only shared token for the sidecar and internal RAG routes
SITE_DATA_DIR ./data Directory for the SQLite memory database
CONTACT_WEBHOOK_URL empty Optional HTTPS endpoint for validated contact form JSON

Quality checks

npm run lint
npm run typecheck
npm run check
npm run build

npm run check runs linting, TypeScript validation, and the production build used by Docker.

Media and asset policy

Personal portrait art, character videos, project covers, and background media are intentionally excluded from Git by .gitignore and .dockerignore. This keeps private or large media out of the public source snapshot and leaves the visual identity replaceable.

To reproduce the full visual presentation locally, provide your own licensed files at the paths used by the components, for example:

public/assets/portrait/hero-frames/{desktop,mobile}/frame-01.webp ... frame-40.webp
public/assets/lumen/mahiru-*.mp4
public/assets/lumen/*-poster.webp
public/assets/projects/<slug>/cover.webp
public/assets/projects/<slug>/showcase.mp4
public/assets/bg/*.mp4

The screenshots in docs/screenshots/ are documentation captures of the current presentation. They do not grant rights to the underlying personal or third-party imagery.

Docker and deployment

Dockerfile builds a minimal Next.js standalone image on Node 22. docker-compose.yml binds the app to 127.0.0.1:3102, mounts ./assets for late-bound media, persists LUMEN memory in a named volume, and expects an external 1panel-network plus an optional agent-website service. It is therefore a deployment-oriented compose file, not a zero-configuration local stack.

Project structure

app/                  App Router pages and server routes
components/           UI, motion, media, LUMEN, and workspace components
content/              Owner profile, projects, and site knowledge
lib/lumen/            Provider protocol, tools, consent, and server storage
lib/lumen-os/         Window-manager state machine
public/assets/        Runtime visual-media locations
docs/screenshots/     Public README captures
Dockerfile            Node 22 standalone production image
docker-compose.yml    Loopback deployment with assets and data volumes

License

The source code is released under the MIT License. The personal name, brand, screenshots, and any excluded or third-party media remain subject to their own rights and are not a blanket grant of trademark or image rights.

Credits

Built and maintained by Xiaoran Tang. The project is an ongoing study of the boundary between people and machines: observe, model, make, listen, revise.

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages