The earlier symlink approach (commit 03f83ad) broke under the canonical
deployment shape. The Caddy systemd unit at
/etc/containers/systemd/caddy.container mounts only
/home/user/src/zddc/website:/usr/share/caddy/zddc:ro
into the Caddy container, so a symlink at
website/releases/landing_alpha.html → ../../landing/dist/index.html
resolves to /usr/share/caddy/landing/dist/index.html inside the
container — a path that simply doesn't exist there. Result:
GET https://zddc.varasys.io/releases/landing_alpha.html → 404, and
the dev cluster's level-2 stub failed to load.
Revert update_alpha() to a plain copy. Trade-off goes back to: every
dev build dirties the corresponding _alpha.html in git. Commit
alongside source changes (alpha is mutable channel anyway) or
git checkout to discard. cp follows symlinks at the destination, so
the helper now `rm -f`s the dest before copying — handles the
symlink-to-file transition cleanly.
Updates AGENTS.md and CLAUDE.md to describe the copy semantics and
the volume-mount constraint that motivates them. Five _alpha.html
files convert from symlinks back to regular files (typechange).
End-to-end verified: curl https://zddc.varasys.io/releases/landing_alpha.html
returns 200 (30177 bytes) after the rebuild.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 KiB
5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Authoritative docs — read these first
This repo already has two thorough agent-facing references. Always consult them before working — they cover details intentionally omitted here:
AGENTS.md— commands, build-system rules, per-tool parser quirks, testing gotchas, git/worktree workflow, release process, zddc-server notesARCHITECTURE.md— single-file HTML pattern rationale, JS module/state patterns, per-tool architecture, security model
If something in this CLAUDE.md conflicts with those, those win — and please update them rather than letting drift accumulate.
Repo shape
This is a monorepo of independent tools, not one application:
archive/,transmittal/,classifier/,mdedit/,landing/— five self-contained HTML tools, each compiled to a single inlined HTML file in its owndist/. Naming: the first four outputdist/tool.html;landing/outputsdist/index.html(it's the project picker served at the root ofzddc-server).zddc/— Go HTTP server (separate sub-project, podman/podman-compose; Go 1.24+). ServesZDDC_ROOT/index.htmlatGET /as the landing page;Accept: application/jsonon/returns the ACL-filtered project list.shared/—base.cssplus shared JS modules (zddc.js,hash.js,zddc-filter.js,theme.js,help.js) included by every tool's build, andbuild-lib.sh(POSIX sh helpers sourced by every tool'sbuild.sh)website/— published artifacts:index.html(root URL),releases/<tool>_v<X.Y.Z>.html(immutable stable archives),releases/<tool>_stable.html(symlink to current stable),releases/<tool>_{alpha,beta}.html(mutable channel files), plus bootstrap zips (install.zip,track-{alpha,beta,stable}.zip).--releaseis the only path to publishing — there is nowebsite/dev/.tests/— Playwright specs (Chromium only, requires File System Access API).tests/schema.spec.jsvalidatestransmittal.schema.jsonagainst canonical fixtures viaajv(only dev dep besides Playwright)
Most-used commands
sh build.sh # build all five HTML tools (dist/ only)
sh tool/build.sh # build one (archive|transmittal|classifier|mdedit|landing)
sh tool/build.sh --release [version] # cut stable; tag, write website/releases/<tool>_v<ver>.html, refresh _stable symlink
sh tool/build.sh --release alpha|beta # cut channel build; overwrites website/releases/<tool>_<channel>.html (mutable, no tag)
npm test # all Playwright specs (build first!)
npx playwright test <tool> # one spec
./dev-server start # ./dev-server stop # cache-busting HTTP on :8000
No lint/typecheck/format commands exist — vanilla JS + POSIX sh by design.
Things that bite if you forget
dist/is gitignored but force-committed (git add -f tool/dist/tool.html). Never hand-edit adist/file.- Never write to
website/index.html,website/releases/<tool>_v*.html,website/releases/<tool>_stable.html, orwebsite/releases/<tool>_beta.htmldirectly — promote viash tool/build.sh --release [version|alpha|beta]. Stable releases writewebsite/releases/<tool>_v<ver>.html(immutable) and refresh<tool>_stable.html; alpha/beta overwrite<tool>_<channel>.htmlin place. Exception:<tool>_alpha.htmlfiles — every plaintool/build.shmirrors the dist file there as a real copy (not symlink — the canonical Caddy serves onlywebsite/and can't follow../paths). Side-effect: dev builds dirty those files; commit alongside the source change orgit checkoutto discard. - Always build before running tests — Playwright opens
dist/tool.htmlviafile://. </in JS string/template literals breaks inline<script>embedding.shared/build-lib.shprovidesescape_js_close_tags; every tool'sbuild.shruns JS through it before inlining.- All ZDDC parsing/formatting/hashing goes through
window.zddc(fromshared/zddc.js+shared/hash.js+shared/zddc-filter.js). API:parseFilename,parseFolder,parseRevision,formatFilename,formatFolder,compareRevisions,isValidStatus,splitExtension,joinExtension,crypto.{sha256Hex, sha256String, sha256File, bytesToHex},filter.{parse, matches}. File objects across tools usetrackingNumber(string) andextension(string, no leading dot — usezddc.joinExtension(name, ext)to build a filename). Add edge cases totests/zddc.spec.js, not per-tool tests. - Two globals only:
window.app(per-tool app state + modules) andwindow.zddc(shared library). No others — anything that crosses tool boundaries goes through one of these. - Worktrees live at
~/src/zddc-<branch>. Checkgit worktree listbefore starting a feature branch; nevergit checkout/switchinside a worktree another agent might be using. - Build scripts are POSIX
shwithset -eu, not bash.concat_filestakes positional args only.