Replace the build-counter version scheme (every alpha push monotonically
bumps the patch number, producing immutable :0.0.X tags that look
indistinguishable from stable releases) with proper semver pre-release
suffixes. Stable owns clean vX.Y.Z; alpha and beta carry
vX.Y.Z-{alpha,beta}[.N] indicating the next-stable target.
The next-stable target is the patch-bump of the latest clean
<prefix>-vX.Y.Z tag. Counter N is per-channel (alpha and beta count
separately) and resets when a new stable advances next-patch. Used
only for zddc-server image tags, where every release is git-tagged;
HTML tools omit the counter since alpha/beta cuts there don't tag.
release-image.sh:
- New CLI: sh release-image.sh [alpha|beta|stable] [<version>].
- Default channel alpha. Version arg only valid (and only optional)
for stable.
- Auto-derives the version via next_prerelease for alpha/beta, and
patch-bump for unspecified stable.
- Now creates the git tag itself (the auto-derived version is no
longer something the operator can predict in advance), but does
not push — operator finishes with `git push --tags`.
shared/build-lib.sh:
- Add next_prerelease(channel, tag_prefix) helper.
- compute_build_label embeds v<next-stable>-{alpha,beta} in the
on-page label for plain and --release alpha|beta builds.
- Plain builds: v<next-stable>-alpha · <ts> · <sha>[-dirty]
--release alpha: v<next-stable>-alpha · <date> · <sha>
--release beta: v<next-stable>-beta · <date> · <sha>
--release [<version>]: v<X.Y.Z> (clean stable, unchanged shape).
Pre-release semver ordering (vX.Y.Z-alpha.1 < vX.Y.Z-alpha.2 <
vX.Y.Z-beta.1 < vX.Y.Z) is honored by registry tag sorting,
git tag --sort=-v:refname, sort -V, npm, cargo — so consumers can
pin or compare versions without surprises.
Existing zddc-server-v0.0.{3..7} git tags and registry tags are
audit history; not rewritten. Going forward, alpha/beta cuts produce
v0.0.8-{alpha,beta}.N format, and clean v0.0.8 is reserved for a
deliberate stable promotion.
freshen-channel needs no code change. It runs --release <channel>
inside a worktree at the latest stable tag, where the build-lib.sh
at that tag is still the old version producing old-format labels;
the first stable cut after this commit will propagate the new format
to subsequent freshens (per the existing "build pipeline at the tag"
reproducibility policy).
AGENTS.md and CLAUDE.md updated.
55 lines
6.2 KiB
Markdown
55 lines
6.2 KiB
Markdown
# 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 notes
|
|
- **`ARCHITECTURE.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 own `dist/`. Naming: the first four output `dist/tool.html`; **`landing/` outputs `dist/index.html`** (it's the project picker served at the root of `zddc-server`).
|
|
- `zddc/` — Go HTTP server (separate sub-project, podman/podman-compose; Go 1.24+). Serves `ZDDC_ROOT/index.html` at `GET /` as the landing page; `Accept: application/json` on `/` returns the ACL-filtered project list.
|
|
- `shared/` — `base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, and `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.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), and `bootstrap/{level1,track-stable,track-beta,track-alpha}/<tool>.html` (per-channel level-2 stubs + same-origin level-1 stubs that the home-page install snippets curl into the operator's deployment dir). `--release` is the only path to publishing `releases/`; `bootstrap/` is regenerated by every plain `sh build.sh`. There is no `website/dev/`.
|
|
- `tests/` — Playwright specs (Chromium only, requires File System Access API). `tests/schema.spec.js` validates `transmittal.schema.json` against canonical fixtures via `ajv` (only dev dep besides Playwright)
|
|
|
|
## Most-used commands
|
|
|
|
```bash
|
|
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)
|
|
./freshen-channel <tool> <channel> # rebuild alpha/beta from current stable tag (run after every stable release)
|
|
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+)
|
|
podman build -t zddc-server zddc/ # build container image
|
|
sh release-image.sh [alpha|beta|stable] [<version>] # canonical image release; alpha/beta auto-derive version (default: alpha)
|
|
```
|
|
|
|
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 but force-committed** (`git add -f tool/dist/tool.html`). Never hand-edit a `dist/` file.
|
|
- **Never write to `website/index.html`, `website/releases/<tool>_v*.html`, `website/releases/<tool>_stable.html`, or `website/releases/<tool>_beta.html` directly** — promote via `sh tool/build.sh --release [version|alpha|beta]`. Stable releases write `website/releases/<tool>_v<ver>.html` (immutable) and refresh `<tool>_stable.html`; alpha/beta overwrite `<tool>_<channel>.html` in place.
|
|
- **Pre-release semver for alpha/beta.** On-page label embeds `vX.Y.Z-{alpha,beta}` where X.Y.Z is the next-stable target (patch+1 from latest clean `<tool>-vX.Y.Z` tag). zddc-server image tags additionally carry a `.N` counter (`v0.0.8-alpha.1`, `.2`, …) since every release is tagged; HTML tools omit the counter (alpha/beta cuts aren't tagged). Stable tags are clean `vX.Y.Z`.
|
|
- **Alpha exception — every plain build dirties `website/releases/<tool>_alpha.html`.** Every `tool/build.sh` (no flags) mirrors the just-built dist file into `<tool>_alpha.html` as a real copy (not symlink — the canonical Caddy serves only `website/` and can't follow `../` paths). Side-effect: dev builds dirty those files; commit alongside the source change or `git checkout` to discard.
|
|
- **Always build before running tests** — Playwright opens `dist/tool.html` via `file://`.
|
|
- **`</` in JS string/template literals breaks inline `<script>`** embedding. `shared/build-lib.sh` provides `escape_js_close_tags`; every tool's `build.sh` runs JS through it before inlining.
|
|
- **All ZDDC parsing/formatting/hashing goes through `window.zddc`** (from `shared/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 use `trackingNumber` (string) and `extension` (string, **no leading dot** — use `zddc.joinExtension(name, ext)` to build a filename). Add edge cases to `tests/zddc.spec.js`, not per-tool tests.
|
|
- **Two globals only**: `window.app` (per-tool app state + modules) and `window.zddc` (shared library). No others — anything that crosses tool boundaries goes through one of these.
|
|
- **Worktrees live at `~/src/zddc-<branch>`.** Check `git worktree list` before starting a feature branch; never `git checkout`/`switch` inside a worktree another agent might be using.
|
|
- **Build scripts are POSIX `sh` with `set -eu`**, not bash. `concat_files` takes positional args only.
|