lnbits-extensions/CLAUDE.md
2026-09-14 15:34:56 +02:00

4.3 KiB

CLAUDE.md

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

What this repo is

A single-file catalog: extensions.json is the manifest LNbits hosts read via LNBITS_EXTENSIONS_MANIFESTS. No server code, no build, no tests, no tags. Every commit on main is live for every host that pulls the raw URL (…/aiolabs/lnbits-extensions/raw/branch/main/extensions.json), including bohm's native lnbits and the regtest compose stack. Hosts pick up changes on lnbits restart, then upgrade via the admin UI. Audit trail is git log; rollback is git revert.

This is an infra repo: commit straight to main, no PR. The release procedure that leads up to a catalog commit (merge PRs in the extension repo, chore(release) bump, test on dev lnbits, tag, hash) lives in ~/dev/CLAUDE.md under "Extension release procedure". This file only covers the catalog side.

Manifest shape

{ "featured": [<id>, …], "extensions": [<entry>, …] }

Required entry fields: id, repo, name, version, short_description, archive, hash (sha256 of the archive zip). Optional: icon, min_lnbits_version, max_lnbits_version, details_link. Many entries omit min_lnbits_version entirely; copy the previous entry for the same id and change only version, archive, hash.

Entries are grouped by id in the file. Insert a new version directly after the last existing entry for that id, not at the end of the array.

Rules that bite

  • Add, never overwrite. A new version is a new object alongside the old ones; installs on the previous version must still resolve it. The one historical exception (lnurlp: replace v1.3.0-aio.1 with v1.3.0-aio.2) was a same-day fix of a broken tag.
  • Keep 4-space indent and ensure_ascii=False. A 2-space re-serialise once turned a one-entry bump into a whole-file diff and needed a follow-up chore: restore 4-space JSON formatting commit. Hand-edit the block, or round-trip with the snippet below (verified byte-identical).
  • Aio forks point at git.atitlan.io/aiolabs/<ext>, never GitHub. The three github.com/lnbits/lnurlp entries (1.1.3, 1.2.0, 1.3.0) predate the fork and stay only for installs that still run them. Don't add new upstream entries for any extension that has an aio fork; production only sees this manifest, so an upstream URL here bypasses our vetting.
  • Aio semver must outrank the upstream tag (v1.3.0-aio.2 > v1.3.0). Dev instances also see LNbits's built-in catalog; if upstream wins the semver comparison, clicking Upgrade overwrites the git checkout under ~/dev/shared/extensions/.
  • hash is the integrity gate. LNbits refuses to install when the downloaded archive's sha256 differs. Always recompute from the tag's archive URL; never copy a hash from a previous entry.

Commands

Compute the hash for a tagged release (Forgejo archive URL form):

curl -sL https://git.atitlan.io/aiolabs/<ext>/archive/v<version>.zip | sha256sum

Validate the manifest before committing (parse, required fields, duplicate id+version, and that the archive URL's tag matches version):

python3 - <<'EOF'
import json, sys
d = json.load(open("extensions.json"))
req = {"id","repo","name","version","short_description","archive","hash"}
seen = set(); bad = 0
for e in d["extensions"]:
    key = (e.get("id"), e.get("version"))
    for m in (req - e.keys(), ["dup"] if key in seen else [], ["archive!=version"] if f"v{e.get('version')}.zip" not in e.get("archive","") else []):
        if m: print(key, m); bad += 1
    seen.add(key)
sys.exit(bad)
EOF

Re-serialise without formatting drift (only if editing programmatically):

python3 -c "
import json
d = json.load(open('extensions.json'))
open('extensions.json','w').write(json.dumps(d, indent=4, ensure_ascii=False) + '\n')"

Verify a committed entry matches the live archive:

git diff -U0 HEAD~1 | grep -oE '"(archive|hash)": "[^"]+"'

Commit message convention

One entry per commit, subject <ext>: add v<version> (<one-line what changed>), e.g. events: add v1.6.1-aio.15 (promo codes enforced). The parenthetical is the only human-readable changelog the catalog has, so name the user-visible change, not "bump". Formatting-only fixes use chore:.