Updates every repo doc to reflect the simplified install model:
- Local install is just a download from /releases/.
- Server install is just running zddc-server (current-stable HTMLs
embedded at compile time).
- Customize via .zddc apps: cascade entries (channel/version/URL/path,
with default + per-app composition); editor at /.profile/zddc/.
Removes references to the old install scripts, level-1/level-2 stubs,
admin UI at /.profile/apps, SHA-256 verification, TOFU writes, refresh
worker, and ZDDC_APPS_* env vars.
zddc/README.md: replaces "Landing Page and Tool Install" section with
"Apps: virtual tool HTMLs" — covers the folder-name availability rules,
the resolution chain (real-file override / cascade / embedded), spec
syntax cheat sheet, cache layout under <ZDDC_ROOT>/_app/, the ?v=
cache-only override, and the X-ZDDC-Source response header.
ARCHITECTURE.md: install-distribution-model section rewritten to
describe the embed-first / cascade-override model with one canonical
example.
AGENTS.md, CLAUDE.md: short-form summaries pointing at the same model.
README.md: install bullet rewritten.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.1 KiB
7.1 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. Stable releases ship as cross-compiled binaries on 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,build-lib.sh(POSIX sh helpers sourced by every tool'sbuild.sh), andpublish-codeberg-release.sh(used byzddc/release.shto upload zddc-server binaries — HTML tools no longer use it).website/— 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/index.html(regenerated bybuild.sh). 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 # build all five HTML tools (dist/ only) + regen website/releases/index.html
sh tool/build.sh # build one (archive|transmittal|classifier|mdedit|landing)
sh tool/build.sh --release [version] # cut stable; write website/releases/<tool>_v<X.Y.Z>.html, refresh 5 symlinks, tag <tool>-vX.Y.Z
sh tool/build.sh --release alpha|beta # cut channel; overwrite website/releases/<tool>_<channel>.html in place. No tag (channel URLs are stable URLs by design)
./freshen-channel <tool> <channel> # rebuild alpha/beta from current stable tag (run after every stable release if you want to advance the channel mirror)
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 (separate sub-project, not part of sh build.sh)
(cd zddc && go test ./...) # unit tests (Go 1.24+)
sh zddc/release.sh [<version>] # cut stable zddc-server release; tags + cross-compiles binaries + uploads to Codeberg. Stable-only (no alpha/beta channel for binaries).
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.website/releases/is committed. Per-version files (<tool>_v<X.Y.Z>.html) are real immutable files; partial-version pins (<tool>_v<X.Y>.html,<tool>_v<X>.html) and channels (<tool>_<channel>.html) are checked-in symlinks. Stable cuts write the new versioned file + refresh the 5 symlinks (cascade rule: stable cut → beta + alpha both reset to the new stable). Beta/alpha cuts overwrite their channel mirror in place; on a beta cut, alpha cascades to point at 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 still get clean<tool>-vX.Y.Ztags. - 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 (patch+1 from latest clean<tool>-vX.Y.Ztag). Plain dev adds a full timestamp +-dirtymarker;--release alpha|betais date-only. - Plain
sh tool/build.shis a dev build. Writesdist/<tool>.htmlonly; nowebsite/releases/side-effect. To publish, re-run with--release alpha. - 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.