Skip to content

Latest commit

 

History

History
120 lines (81 loc) · 11 KB

File metadata and controls

120 lines (81 loc) · 11 KB

AGENTS.md

This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.

Project overview

Static personal website ("This is Eytle") — no build step, no package manager, no framework. Served directly as HTML/CSS/JS. GitHub (origin) stores the source; production eytle.cn is served by Nginx on Tencent Cloud and deployed through the tencent Git remote. See CODEx_DEPLOY_GUIDE.md before deployment.

The museum additionally uses a Python/SQLite guestbook API. Its code, database, secret and backups live outside the public web root. Production service templates are in scripts/production/; see docs/maintenance/museum-guestbook-service.md. A Git push deploys static assets only: backend changes require a separate service update and verification.

Restored local workspace (2026-09-12)

The current Linux workspace is /home/yeom/Documents/ChatGPT/thisIsEytle, restored from the PSSD backup of D:\eyt_web. Read docs/maintenance/2026-09-12-recovery.md for the verified baseline, local commands, preserved drafts, and remaining deployment-access checks. The ignored eyt_web_repo/, deploy/, and .claude/worktrees/pensive-robinson/ directories contain historical copies or drafts; continue website work at the repository root.

For server commands, use ssh eytle-server. This machine's ~/.ssh/config provides a dedicated Ed25519 key, a direct network interface to bypass Mihomo, and optional connection sharing. Fresh key authentication and git ls-remote tencent were verified on 2026-09-12. If the active network interface changes from wlp0s20f3, update BindInterface in the local SSH config.

Collaboration and release workflow (2026-09-18)

Use one isolated Git worktree (or branch) for each feature task. A feature task may edit, test, and commit only its own scope; it must not publish to origin or tencent. Do not run multiple feature tasks in the repository root at the same time.

The Codex thread titled “Eytle 网站发布会话” is the release thread. It works at the repository root and is the sole owner of the following steps:

  1. Inspect every completed feature commit and merge or cherry-pick it into main.
  2. Run the complete test suite and relevant local checks.
  3. Create the integration/release commit after confirming the worktree is clean.
  4. Push main to GitHub first, then push the identical commit to tencent.
  5. Verify local, GitHub, Tencent bare repository, server worktree, and production files all match; keep release verification records outside the public web root.

Before starting a new feature, create its worktree from current main. If a feature needs files changed by another unfinished task, pause that dependent change until the prerequisite commit is available. Keep deployment configuration and internal maintenance files out of the public site using scripts/deploy-excludes.txt.

Architecture

The site uses sticky top navigation + a rendered stage (index.html + css/style.css + js/main.js), with cinematic birch-forest artwork. Night uses deep blue and amber; day uses ivory and sage. Responsive images/forest-{night,day}[-mobile].webp backgrounds have an optional WebGL2 pond/fog enhancement in js/forest-scene.js.

Region Role
.rail (sticky top header; legacy class name) Brand/logo, language switcher, nav (each .nav-i has data-section), lamp (theme); contact links live in the footer
.stage (#stage) Main panel — go(section) re-renders it on every nav click
#overlay-root Patch-log reader + gallery lightbox mount here (mountOverlay), close on ✕ / backdrop / Esc

The home section (about) is a custom overview: hero + a two-column grid (latest real patch-log entry + message form | gallery preview). Other sections render generic lists/grids into the stage. Shareable routes use /, /projects, /tools, /patchlog, /gallery and /downloads, with History API back/forward support. Legacy hashes are normalized on arrival. Nginx routes only these known paths to index.html; keep missing assets and unknown pages as 404. Use python3 scripts/preview.py for local static preview with clean URLs.

Main-site UI state lives in main.js; forest-scene.js independently manages the optional background animation. There is no framework or build step. Forest and particle rendering stop off the hero, on other sections, in hidden tabs, or under reduced motion; retain the static CSS fallback.

Content repositories (2026-09-26)

Personal content is no longer tracked here. Eytle-Patch-Log owns logs/ and its index generator; Eytle-Museum owns images/gallery/, images/gallery-preview/, audio/museum.mp3, their maintenance scripts and content tests. Website code and interface assets remain here; files/730.zip is intentionally retained by the user. content-sources.json pins both repositories to full commit SHAs. Do not add personal content back to this repository.

Read docs/maintenance/content-repositories.md before content updates or deployment. Use python3 scripts/assemble-site.py --output /tmp/NEW-PREVIEW with sibling content clones (or explicit --logs-repo/--museum-repo paths), then python3 scripts/preview.py --root /tmp/NEW-PREVIEW --port 8000 for a complete preview. Assembly preserves the public URLs below. A plain source preview has no logs/artwork. The release thread must seed the server's private content repositories and install scripts/production/post-receive before publishing the first split version. The previous static-only rsync hook is insufficient. Historical Git content is not rewritten.

Data flow

DATA (top of main.js) is the single source of truth for static content (projects, tools, downloads, about). Dynamic sections load their data at render time:

  • Patch Log — loadLogs() fetches ./logs/index.json (newest-first list of YYYY-MM-DD) then fetches individual ./logs/YYYY-MM-DD.txt when a calendar day or the home "read more" is clicked. The home overview shows the most recent entry's real first lines.
  • Gallery — loadGallery() fetches ./images/gallery/index.json (list of original filenames) plus ./images/gallery-preview/index.json (generated lightweight WebP mapping), then builds DATA.gallery. Grid/home cards use previews; the lightbox keeps the originals. Both loaders cache after first call.

The log, gallery, and gallery-preview index.json files are generated in their owning content repositories — never edit them by hand. These paths exist in assembled previews and production, not in this source tree.

Local automation

Script / hook Repository Role
scripts/update-index.py Eytle-Patch-Log regenerate the newest-first log index
scripts/gallery-renamer.js Eytle-Museum normalize image names and gallery index
scripts/gallery-previews.py Eytle-Museum generate WebP previews and manifest
.githooks/pre-commit this website reject personal content accidentally staged here
scripts/assemble-site.py this website validate pinned content and compose a separate public directory

Trilingual support

Trilingual (中文 / English / 한국어). t(zh, en, ko) returns the appropriate string based on lang; pick(obj, base) reads localized fields (name/nameEn/nameKo) off DATA entries. Nav buttons carry data-zh/data-en/data-ko; applyLang() updates labels, persists lang to localStorage, and re-renders the active section. All dynamic text goes through escapeHtml().

Theme

data-theme="night|day" is set on <html> ("lights off / on"). Switching swaps the background painting and the whole token set, and updates the lamp button's action label. Theme persists to localStorage. (mc-calc.html is independent and unaffected.)

Message form

Home overview has a "给 Eytle 留言" box (140-char limit + live count, fixed height, honeypot anti-spam). Backend is MSG_CONFIG.web3formsKey near the top of main.js: paste a free Web3Forms public submit key to relay messages to the inbox; leave '' and the form explains that sending is unavailable and preserves the draft. This is separate from the museum guestbook. No secret key ever belongs in this file.

Adding content

  • New project: add an entry to DATA.projects in main.js. Set sub: [] for direct GitHub link, or populate sub for a sub-project list.
  • New tool: add to DATA.tools. Set external: false for internal pages (e.g. mc-calc.html). icon (e.g. the Eye of Ender) is shown only on the tool row — keep that image scoped to tools.
  • New download: add to DATA.downloads.
  • New gallery image: use the scripts and images/gallery/ in Eytle-Museum, then commit originals, previews and generated indexes there.
  • New patch log entry: create logs/YYYY-MM-DD.txt in Eytle-Patch-Log, run its index generator and commit there.
  • Publish content changes: update content-sources.json to the desired content commits; the release thread publishes content before the site. Do not copy material into the website repository.

mc-calc.html

Self-contained Minecraft stronghold finder tool. Separate page, no shared JS with main.js.

museum.html

Self-contained first-person 3D museum (Three.js via jsDelivr importmap, pinned to 0.186.0). Reads images/gallery/index.json for order and the generated images/gallery-preview/index.json for lightweight textures. On the gallery nav click, main.js routes WebGL2-capable devices here via isMuseumCapable(); coarse pointers use js/museum-touch.js and css/museum-touch.css for joystick / drag controls without pointer lock, using the same render quality as desktop. The first entry click requests fullscreen; entrance and touch HUD buttons allow retry and exit. Unsupported browsers keep the grid + lightbox; /gallery is also the explicit lightweight fallback. The museum is a fixed dark dramatic hall — it does NOT follow the night/day theme. Exit returns to / (never /gallery, to avoid a relaunch loop). The public URL is /museum; /museum.html redirects there. No shared JS with main.js. Interaction and streaming live in js/museum.js; procedural architecture, materials and planar reflections in js/museum-architecture.js; projector light volumes and dust in js/museum-atmosphere.js; instanced lamp rendering in js/museum-fixture-batch.js; styling in css/museum.css.

The Nocturne art direction uses a 6.7 m vaulted hall, champagne metal and dark stone. Keep the half-width at 3 m and structural projections within the existing 0.4 m collision margin. Fog ends at 82 m before the 88 m hidden-retarget boundary. Reflection cameras must have their cloned AudioListener children cleared. Ceiling projectors, their light volumes and floor pools share js/museum-lighting-layout.js; opaque bloom occlusion lives in js/museum-bloom-occlusion.js. Keep pier/intrados light channels centered on each rib and stop longitudinal rails before the 0.45 m plinths. Use museum.html?perf=walk for automatic visual/performance verification; the entrance is hidden in this diagnostic mode.