Moves website source + release artifacts off `main` and into a new
orphan branch named `website` in this same Codeberg repo. A `git worktree`
of that branch — typically at ~/src/zddc-website/ — is what the system
Caddy now bind-mounts and serves at zddc.varasys.io. Decoupling source
from the live site means editing source can no longer accidentally
affect what's published.
Layout going forward:
- ~/src/zddc/ — main worktree (this branch, source only).
- ~/src/zddc-website/ — git worktree of the `website` branch:
hand-edited content + LFS-tracked release
artifacts (server binaries) + regular-git
HTML tool releases + symlinks.
- Caddy bind-mount swapped: ~/src/zddc/website → ~/src/zddc-website
(quadlet at /etc/containers/systemd/caddy.container, restarted).
Build pipeline now writes releases to
${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}.
- build.sh: RELEASES_DIR points at the env var
- shared/build-lib.sh: promote_release honors the env var, falls
back to the legacy in-repo path so any
standalone single-tool release on a checkout
that still has website/ keeps working
- freshen-channel: passes ZDDC_DEPLOY_RELEASES_DIR through to
the worktree-based build
Docs (CLAUDE.md, AGENTS.md, ARCHITECTURE.md, .gitignore) updated for
the new layout. The 51 MB of website/ blobs stays in main's history
(no force-push); over time Codeberg's GC will pack them down.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8.9 KiB
8.9 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; Go 1.24+). ServesZDDC_ROOT/index.htmlatGET /as the landing page;Accept: application/jsonon/returns the ACL-filtered project list. Cross-compiled binaries are committed to thewebsiteorphan branch (LFS-tracked) and served fromzddc.varasys.io/releases/(no Codeberg release assets); thehelm/charts in this repo build from source at deploy time.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.shAND by the top-levelbuild.shfor lockstep release helpers).websiteorphan branch (same Codeberg repo) — committed static site:index.html(root URL, hand-edited intro),releases/<tool>_v<X.Y.Z>.html(immutable per-version archives),releases/<tool>_v<X.Y>.htmland_v<X>.html(symlinks),releases/<tool>_{stable,beta,alpha}.html(channel mirrors),releases/zddc-server_v<X.Y.Z>_<platform>(per-version cross-compiled binaries; LFS-tracked),releases/zddc-server_<channel>_<platform>(binary symlinks following the same cascade),releases/zddc-server_<X>.html(per-version / per-channel stub pages that fan out the four platform downloads in one matrix-cell link),releases/index.html(matrix table regenerated bybuild.sh). Working dir:~/src/zddc-website/(agit worktreeof thewebsitebranch —git -C ~/src/zddc worktree add ~/src/zddc-website website). Caddy: thezddc.varasys.io:8443vhost bind-mounts~/src/zddc-websiteand serves from there. Install model: local use is a download from/releases/. Server use iszddc-server, which has the current-stable build of all five tools baked in via//go:embed(compile-time default). Tools auto-served at folder-name-driven paths:archiveeverywhere,classifierinIncoming/Working/Stagingsubtrees,mdeditinWorkingsubtrees,transmittalinStagingsubtrees,landingonly at root. Override via.zddc apps:cascade entry (channel/version/URL/path) — fetched once, cached at<ZDDC_ROOT>/_app/. Drop a real.htmlfile at any path to override.helm/— example Helm charts for zddc-server (zddc-server-prod/,zddc-server-dev/). Both compile from source via init container. Operators copyvalues.yaml.exampleand customize. No secrets in repo.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 # dev build: 5 HTML tools + cross-compile zddc-server binaries + regen releases/index.html
sh tool/build.sh # build one HTML tool (archive|transmittal|classifier|mdedit|landing)
# Lockstep releases — every cut bumps ALL tools (5 HTML + zddc-server) to the same version
sh build.sh --release # stable, coordinated next-version (max(latest tag) + 1)
sh build.sh --release X.Y.Z # stable, explicit version
sh build.sh --release alpha # alpha channel cut for everything
sh build.sh --release beta # beta channel cut for everything
sh tool/build.sh --release [version|alpha|beta] # single-tool release (rare; prefer the lockstep top-level cut)
./freshen-channel <tool> <channel> # rebuild a single tool's alpha/beta from its current stable 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
# zddc/ Go server (sub-project)
(cd zddc && go test ./...) # unit tests (Go 1.24+)
No lint/typecheck/format commands exist for the HTML tools — vanilla JS + POSIX sh by design.
Things that bite if you forget
dist/is gitignored.tool/dist/<tool>.htmlis the canonical built artifact for testing and as the source for--releasewrites. Never hand-edit adist/file.- Lockstep releases. Every release cut bumps all six artifacts (5 HTML tools + zddc-server) to the same version, even if a tool didn't change. The coordinated next-stable target is
max(latest tag across all tools) + 1. Per-tool independent versions are no longer the norm —sh build.sh --releaseis the canonical path. Workflow: alpha = active dev, beta = ready for general testing, stable = ready to ship. - Release artifacts live on the
websiteorphan branch. The build pipeline writes them to${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}— a git worktree of that branch, served by Caddy directly. HTML tools: per-version<tool>_v<X.Y.Z>.html(real immutable files) + partial-version pins + channel mirrors (symlinks). zddc-server:zddc-server_v<X.Y.Z>_<platform>per-version binaries (LFS),zddc-server_v<X.Y>_<platform>/_v<X>_<platform>/_<channel>_<platform>symlinks, pluszddc-server_<X>.htmlstub pages that surface the four platform downloads in one matrix-cell link. Same cascade rule for both: stable cut → beta + alpha both reset to stable; beta cut → alpha cascades to beta. - No tags for alpha/beta. Channel URLs are stable URLs by design — appending counter tags would defeat the purpose. The on-page label encodes
<date> · <sha>for traceability. Stable cuts get clean<tool>-vX.Y.Ztags for every tool (six tags per cut, all sharing the same X.Y.Z). - Pre-release semver in the on-page label. Plain dev builds and
--release alpha|betacuts embedvX.Y.Z-{alpha,beta}in{{BUILD_LABEL}}where X.Y.Z is the next-stable target. Plain dev adds a full timestamp +-dirtymarker;--release alpha|betais date-only. - Channel-link verifier. Every
sh build.shends with a check that every<tool>_{stable,beta,alpha}.html(and zddc-server's per-platform binary mirrors + stub pages) resolves. Bootstrap-friendly: skips zddc-server checks until the first--releasecut materializes the binaries. - Plain
sh tool/build.shis a dev build. Writesdist/<tool>.htmlonly; no new per-version files / symlink updates in the website worktree. To publish, re-run withsh build.sh --release alphato cut all six tools' alpha mirrors together. The release writes go to thewebsiteworktree at${ZDDC_DEPLOY_RELEASES_DIR:-~/src/zddc-website/releases}, which is then committed + pushed on that branch separately frommain. - 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.