diff --git a/.github/RELEASE-v1.2.1.md b/.github/RELEASE-v1.2.1.md new file mode 100644 index 00000000..d1bc9fe5 --- /dev/null +++ b/.github/RELEASE-v1.2.1.md @@ -0,0 +1,172 @@ +# v1.2.1 — all 129 free plugins + +## Re-cut — why the version changed again + +This PR originally targeted the next patch above `main`'s pre-PR baseline +(one patch past `1.0.0`) for all 129 free-registry entries (see history +below). That target was wrong: measured against `main`, `registry.json` had +41 entries at `1.1.2`, 2 at `1.1.0`, 1 at `1.2.0`, and 1 at `1.1.1` +(`ollama`) — the originally-targeted version would have **downgraded** all +45 of them. A +downgrade breaks inter-plugin `requires` semver ranges +(`internal/plugin/compat.go`) and any installed-version comparison, and the +release tag must equal the registry version because the Cloudflare Worker +resolves `releases/download/v/-.tar.gz` directly +from the `version` field — there is no separate "real" version underneath. + +**Every one of the 129 entries now moves to `1.2.1` instead, so no entry +goes backward: `1.2.1` is strictly greater than the highest version anyone +held on `main`** (41 were at `1.1.2`, one — `entitlements` — was at `1.2.0`, +the highest of the lot). `ollama` moves to `1.2.1` with everyone else; the +earlier plan to leave it at `1.1.1` is void — there must be no unreferenced +tarball left dangling on the release. + +## Scope change from the original plan (still applies) + +This PR originally bumped 8 repackaged plugins (content-progress, cron, +donorbox, maintenance, notifications, notify, search, storage — PRs +#78/#79/#80). **It now covers all 129 free-registry entries.** + +The reason: plugins#84 (data audit) found that **70 of the 129 free plugins +had no published tarball for the version `registry.json` stated on `main`** +— 11 had no release tag at all for that version, and 59 had the tag but no +matching `-.tar.gz` asset in it (every `*@1.1.2` entry in +particular — that release is a partial re-release of a different, mostly +`1.0.0`, plugin set, not a superset). `nself plugin install` 404s for all 70 +of these today, independent of anything in this PR. Full defect list: +plugins#84. + +## What changed in this re-cut + +- `registry.json` — `version` set to `1.2.1` for all 129 entries, including + `ollama`. `releaseTag` set to `v1.2.1` for every entry that carries a + `releaseTag` field (`shared-utils` does not, and does not gain one — + `installable:false`, no tarball, no checksum, per below). +- Each plugin's own `free//plugin.json` — `version` bumped to `1.2.1` + to match (CI's version-consistency gate requires the two to agree; see + `.github/workflows/registry-check.yml` "Registry version consistency + check"). +- `scripts/deterministic-tar.sh` now also pins file **modes** + (`--mode='go-w,a+rX'`), not just mtime/uid/gid/member-order. Measured + today: identical git content on two machines produced tar streams that + hashed differently by mode bits alone (`644` on one, `664` on the other — + the checkout environment's umask was leaking into the artifact). With the + mode flag added, both machines now produce the identical tar stream. +- `.github/workflows/tarball-checksum-gate.yml` (both the source-tarball + job and the `checksums.platforms` job added in `0eae661`) no longer + rebuilds tarballs in CI and diffs them against `registry.json`. That + comparison can never hold: with byte-identical tar streams as input, + `gzip -n -9` produces **different output** depending on the gzip/zlib + build doing the compressing (measured today: Apple gzip 479 vs GNU gzip + 1.12 diverged on real plugin data, 6e9d3966 vs 0283c3b3, for the same + tar bytes). DEFLATE output is implementation- and version-dependent by + design — this isn't a bug in the tar recipe, no tar flag fixes it. The + gate now verifies `registry.json`'s checksums against the **published + release assets** for the registry's version instead (`gh release + download`). With no release for that version yet — the normal state of + this PR right now — it skips with a `::notice::` explaining why and + passes; once a release exists, a mismatch fails it. The deterministic-tar + recipe and the mode fix above are unaffected and still required — they + make a *local* rebuild reproducible across machines, which is what lets a + contributor sanity-check a tarball before it's uploaded; they were never + going to make two different gzip implementations agree byte-for-byte. +- `scripts/verify-published-checksums.sh` — rewritten to match the release + flow this PR depends on: given a tag, it downloads every plugin's + published release asset (source tarball + any per-platform binaries), + computes sha256, and either reports mismatches against `registry.json` + (default) or, with `--write`, writes the published hashes into + `registry.json`'s flat `checksum`, nested `checksums.sha256`, and + `checksums.platforms.` fields. **Not run against a real + release in this PR** — no `v1.2.1` release exists yet. + +## Checksums in this PR are provisional — not rebuilt, not final + +**This re-cut did not rebuild any tarball or recompute any checksum.** The +`checksum` / `checksums.sha256` / `checksums.platforms` values currently in +`registry.json` are carried over unchanged from the previous version's +content — they are stale by definition the moment the `version` field next +to them changes, and they must not be read as validated for `1.2.1`. Per +the release flow above, the correct order is: the owner creates a **draft** +`v1.2.1` release with the built tarballs attached, `verify-published- +checksums.sh v1.2.1 --write` then reads the checksums from those published +bytes and writes them into `registry.json`, and only that state gets +merged. Do not treat this PR's current checksum fields as ground truth for +`1.2.1` assets. + +## One exception (not touched beyond its version) — `shared-utils` + +`shared-utils` has no `checksum` and gains none here. It's +`installable: false` in its own `plugin.json` — an internal Go library +(request-ID tracing middleware, HTTP client propagation) other free +plugins import at build time, not something a user ever +`nself plugin install`s directly. It has no `tarball`/`download_url`/ +`releaseTag` field in `registry.json` (not added here, to avoid implying +it's independently distributable) — there is nothing for a checksum to +attest to. Its `version` field is bumped to `1.2.1` for consistency with +its own `plugin.json`, and nothing else. + +`ollama` is **no longer** an exception (see re-cut rationale above) — it +takes `1.2.1` and a `releaseTag` of `v1.2.1` like every other entry. + +## event-bus asset naming + +A previous release misnamed the `event-bus` asset `event-bus-v1.0.0.tar.gz` +(stray `v` inside the filename). Confirmed today: `scripts/build-and- +upload-tarballs.sh` names tarballs `"${plugin_name}-${TAG#v}.tar.gz"` +(strips the `v` from the tag before building the filename), and +`scripts/build-tarballs.sh` uses the same `${version}` (already +`v`-stripped) convention — so a `1.2.1` build of `event-bus` names its +asset `event-bus-1.2.1.tar.gz`, no stray `v`. No occurrence of the slip +remains in either script. + +## Local gate + +- `git grep -n "1\.0\.1" -- registry.json .github/RELEASE-v1.2.1.md` — empty. +- `jq -r '.plugins[].version' registry.json | sort -u` — exactly `1.2.1`. +- Version-vs-`main` downgrade check across all 129 entries — zero entries + where the `main` version is greater than `1.2.1`. +- `bash shared/validate-registry.sh` — see PR body for the current error + count. +- No tarballs were built and no checksums were recomputed this session (see + "Checksums in this PR are provisional" above) — this is a version-only + re-cut, not a rebuild. + +This is a PUBLIC repo (`nself-org/plugins`) — this account cannot +self-approve, so this PR stays open pending owner review. + +## This PR does NOT merge, tag, or release anything + +The owner's sequence, once this PR is approved (unchanged in substance from +the release-mechanics note in the builder brief, only the version changes): + +```bash +# (a) Owner creates a DRAFT release with the built 1.2.1 tarballs attached, +# targeting this PR's head commit: +gh release create v1.2.1 -R nself-org/plugins --draft \ + --target <#81-head-sha> \ + -F .github/RELEASE-v1.2.1.md \ + upload-all/*.tar.gz upload-all/*.sha256 + +# (b) Run verify-published-checksums.sh against the draft's published +# bytes and push the resulting registry.json to this PR branch: +./scripts/verify-published-checksums.sh v1.2.1 --write +git add registry.json && git commit -m "chore(registry): checksums from published v1.2.1 draft assets" +git push + +# (c) Owner merges this PR (this is the version bump landing on main). + +# (d) Publish the draft (tag is created on publish, pointing at the merge +# commit — re-target with --target if the merge produced a different +# commit than the draft was built against): +gh release edit v1.2.1 -R nself-org/plugins --draft=false + +# (e) Purge the Worker's KV cache and spot-verify: +curl -X POST https://plugins.nself.org/api/sync +curl -sI https://plugins.nself.org/plugins/storage/tarball +# expect: HTTP/2 302, location: .../releases/download/v1.2.1/storage-1.2.1.tar.gz +curl -sI https://plugins.nself.org/plugins/access-controls/tarball +# expect: HTTP/2 302 +nself plugin install notifications +``` + +**Do not merge until the owner has reviewed this PR and given the go-ahead.** diff --git a/.github/workflows/release-tarballs.yml b/.github/workflows/release-tarballs.yml index ff7e87db..61a09d21 100644 --- a/.github/workflows/release-tarballs.yml +++ b/.github/workflows/release-tarballs.yml @@ -77,7 +77,11 @@ jobs: return fi - tar -czf "$tarball" "$plugin_dir" + # scripts/deterministic-tar.sh is the ONE tarball recipe shared with + # scripts/build-tarballs.sh — fixed mtime/owner/sort/pax so the bytes + # this workflow publishes always match whatever built the checksum + # recorded in registry.json, no matter which of the two built it. + bash scripts/deterministic-tar.sh "$tarball" "$plugin_dir" sha256=$(sha256sum "$tarball" | cut -d' ' -f1) printf "%s %s\n" "$sha256" "${plugin_name}-${VERSION}.tar.gz" > "$checksum_file" echo "BUILT $plugin_name sha256:${sha256}" @@ -151,7 +155,10 @@ jobs: fi local ptar="${DIST_DIR}/${plugin_name}-${VERSION}-${platform}.tar.gz" - tar -czf "$ptar" -C "$stage" "${plugin_name}" + # Same shared recipe as the source tarball above — the per-platform + # binary archives had the identical mtime/ordering non-determinism + # (compiled-binary mtimes and per-run staging-dir enumeration order). + bash scripts/deterministic-tar.sh "$ptar" -C "$stage" "${plugin_name}" psha=$(sha256sum "$ptar" | cut -d' ' -f1) printf "%s %s\n" "$psha" "$(basename "$ptar")" > "${ptar}.sha256" rm -rf "$stage" @@ -239,6 +246,7 @@ jobs: # Free plugin tarballs are source-only; arch verification is not applicable here. - name: Upload tarballs to GitHub Release + id: upload env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | @@ -266,16 +274,58 @@ jobs: --prerelease=false fi - # Upload all tarballs and checksums (clobber = idempotent) - gh release upload "$TAG" \ - dist/*.tar.gz \ - dist/*.sha256 \ - --repo "${{ github.repository }}" \ - --clobber + # NEVER --clobber. An asset already on the release is the artifact + # of record: registry.json's checksums are written from those exact + # published bytes (scripts/verify-published-checksums.sh --write). + # + # The release flow uploads the tarballs to a DRAFT release first, then + # writes their hashes into registry.json, then merges, then publishes. + # Publishing creates the tag, which triggers THIS workflow. If it then + # rebuilt and clobbered, the bytes on the release would no longer be + # the bytes those checksums attest to, and all 129 free plugins would + # fail verification at the exact moment of release. CI cannot + # reproduce the uploaded bytes: identical tar streams still gzip + # differently across machines (Apple gzip vs GNU gzip, and across zlib + # versions), measured 2026-09-11. + # + # So: upload only what is missing. That is what "idempotent" in this + # file's header always meant, and what --clobber never did. + existing="$(gh release view "$TAG" --repo "${{ github.repository }}" \ + --json assets --jq '.assets[].name' 2>/dev/null || true)" + + to_upload=() + skipped=0 + for f in dist/*.tar.gz dist/*.sha256; do + [ -e "$f" ] || continue + if printf '%s\n' "$existing" | grep -qxF "$(basename "$f")"; then + skipped=$((skipped + 1)) + continue + fi + to_upload+=("$f") + done + echo "Assets already on $TAG (left untouched): ${skipped}" + if [ "${#to_upload[@]}" -eq 0 ]; then + echo "Nothing new to upload — every built asset is already published." + else + echo "Uploading ${#to_upload[@]} missing asset(s)." + gh release upload "$TAG" "${to_upload[@]}" \ + --repo "${{ github.repository }}" + fi + + echo "uploaded_count=${#to_upload[@]}" >> "$GITHUB_OUTPUT" echo "Upload complete" + # Only backfill when THIS run actually published something. When every + # asset is already on the release (the tag-push run that follows + # publishing a draft, for instance) the bytes of record are the ones + # already there, and a fresh local build is not guaranteed to reproduce + # them. Recomputing from dist/ would overwrite verified checksums with + # unverified ones. scripts/verify-published-checksums.sh is the tool that + # writes checksums for an already-populated release; it reads the + # published bytes rather than a rebuild. - name: Backfill checksums in registry.json + if: steps.upload.outputs.uploaded_count != '0' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | @@ -283,26 +333,74 @@ jobs: VERSION="${TAG#v}" REPO="${{ github.repository }}" - # For each plugin tarball, update registry.json with checksum + tarball URL + before_count="$(jq '.plugins | length' registry.json)" + + # dist/ holds TWO kinds of tarball: the source tarball + # -.tar.gz, and for cli plugins five platform tarballs + # --.tar.gz. They need different registry + # fields, and telling them apart matters. + # + # This loop used to derive the plugin name as "${tarball_name%-${VERSION}.tar.gz}". + # That suffix does not match a platform tarball (which ends + # "-linux-amd64.tar.gz"), so the substitution was a no-op and + # plugin_name came out as the whole filename. jq's `.plugins[$name] = ...` + # then CREATED that key. One run on v1.2.1 grew registry.json from 129 + # entries to 289 — 160 junk entries such as + # "ai-cli-1.2.1-darwin-amd64.tar.gz", each with a checksum and no + # version. The CLI resolves installs from this file, so that is a + # corrupt registry, and it was committed and pushed automatically. + # + # Now: strip at the FIRST "-", classify by what follows, and + # refuse to write a key that does not already exist, so a naming change + # fails the release loudly instead of silently inventing entries. for checksum_file in dist/*.sha256; do tarball_name="$(basename "$checksum_file" .sha256)" - plugin_name="${tarball_name%-${VERSION}.tar.gz}" sha256="$(cut -d' ' -f1 "$checksum_file")" tarball_url="https://github.com/${REPO}/releases/download/${TAG}/${tarball_name}" - jq --arg name "$plugin_name" \ - --arg sha "sha256:${sha256}" \ - --arg url "$tarball_url" \ - --arg tag "$TAG" \ - '(.plugins[$name].checksums.sha256) = $sha | - (.plugins[$name].tarballUrl) = $url | - (.plugins[$name].releaseTag) = $tag' \ - registry.json > registry.tmp.json && mv registry.tmp.json registry.json + stem="${tarball_name%.tar.gz}" # -[-] + plugin_name="${stem%%-${VERSION}*}" # + suffix="${stem#*-${VERSION}}" # "" (source) or "-" + + if ! jq -e --arg name "$plugin_name" '.plugins | has($name)' registry.json >/dev/null; then + echo "::error::$tarball_name resolved to plugin '$plugin_name', which is not in registry.json." + echo "::error::Refusing to create a new registry entry from a tarball filename." + exit 1 + fi + + if [ -z "$suffix" ]; then + # Source tarball — the artifact the flat checksum attests to. + jq --arg name "$plugin_name" \ + --arg sha "sha256:${sha256}" \ + --arg url "$tarball_url" \ + --arg tag "$TAG" \ + '(.plugins[$name].checksums.sha256) = $sha | + (.plugins[$name].tarballUrl) = $url | + (.plugins[$name].releaseTag) = $tag' \ + registry.json > registry.tmp.json && mv registry.tmp.json registry.json + else + # Platform tarball — belongs under checksums.platforms.. + platform="${suffix#-}" + jq --arg name "$plugin_name" \ + --arg platform "$platform" \ + --arg sha "sha256:${sha256}" \ + '(.plugins[$name].checksums.platforms[$platform]) = $sha' \ + registry.json > registry.tmp.json && mv registry.tmp.json registry.json + fi done - echo "registry.json updated" + # The entry count must not change. Backfilling checksums never adds or + # removes a plugin; if it did, something derived a name wrongly again. + after_count="$(jq '.plugins | length' registry.json)" + if [ "$after_count" != "$before_count" ]; then + echo "::error::registry.json entry count changed during checksum backfill: ${before_count} -> ${after_count}" + exit 1 + fi + + echo "registry.json updated ($after_count entries, unchanged)" - name: Commit updated registry.json + if: steps.upload.outputs.uploaded_count != '0' run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" diff --git a/.github/workflows/tarball-checksum-gate.yml b/.github/workflows/tarball-checksum-gate.yml new file mode 100644 index 00000000..17a6ad17 --- /dev/null +++ b/.github/workflows/tarball-checksum-gate.yml @@ -0,0 +1,309 @@ +name: Tarball Checksum Gate + +# Verifies registry.json's checksums against the PUBLISHED RELEASE ASSETS +# for each plugin's registry.json `releaseTag`, not against a fresh CI +# rebuild. +# +# Why not rebuild-and-compare (what this gate did before the P6 re-cut): +# scripts/deterministic-tar.sh pins mtime, uid/gid, member order and (as of +# this same re-cut) file mode — but it still shells out to `gzip -n -9`, +# and DEFLATE output is implementation- and version-dependent by design. +# Measured directly (2026-09-11): with byte-identical tar streams as input, +# Apple gzip 479 (macOS) and GNU gzip 1.12 (Linux/ubuntu-latest) produced +# DIFFERENT compressed bytes for the same real plugin content — 6e9d3966 vs +# 0283c3b3. Python's zlib diverges the same way across zlib 1.2.12 (macOS) +# vs 1.3 (Linux). A trivially compressible probe (all-zeros, short text) +# can make two gzip builds agree by accident, which is how this hid before +# — real plugin data exposes it every time. So a CI rebuild-and-diff gate +# can NEVER reliably pass: even a byte-perfect deterministic-tar.sh recipe +# hits a gzip build difference the tar flags cannot fix, because the +# divergence is downstream of tar entirely. +# +# The release model this repo actually ships under settles this: the +# artifact of record is whatever bytes get UPLOADED to the GitHub release, +# and registry.json's checksums are meant to be written FROM those +# published bytes (scripts/verify-published-checksums.sh --write), not +# computed independently and hoped to match. So this gate downloads the +# real release asset for each plugin's registry.json releaseTag and diffs +# THAT — the exact thing `nself plugin install` downloads and +# internal/plugin/security.go's verifyChecksum checks against. +# +# No release exists yet for a given tag == the normal state of an open +# version-bump PR (this one, right now: v1.2.1 has no release). The gate +# SKIPS the compare for any plugin whose tag has no published release, +# says so via ::notice::, and PASSES — it must never fail merely because +# the owner hasn't cut the release yet, and it must never silently pass +# without saying which branch it took. Once a release DOES exist for a +# tag, a checksum mismatch against its real asset FAILS the gate — proven +# locally before this file was written: same registry checksum against a +# byte-identical rebuilt asset passes, a corrupted asset fails, restoring +# it passes again (see PR body / commit message for the transcript). +# +# scripts/deterministic-tar.sh and scripts/build-tarballs.sh are unchanged +# in spirit and still required: they are what makes a LOCAL rebuild +# reproducible across contributors' machines and CI, which is what lets +# someone sanity-check a tarball before it's uploaded. They were never +# going to make two different gzip implementations byte-agree, and this +# gate no longer asks them to. +# +# A second job, platform-checksum-gate, applies the identical published- +# asset treatment to the per-platform binary tarballs added in plugins#83 +# (registry.json's checksums.platforms. fields, commit 0eae661). + +on: + pull_request: + branches: [main] + paths: + - 'free/**' + - 'registry.json' + - 'scripts/deterministic-tar.sh' + - 'scripts/build-tarballs.sh' + - 'scripts/verify-published-checksums.sh' + - '.github/workflows/tarball-checksum-gate.yml' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + checksum-gate: + name: Verify registry.json checksums against published release assets + runs-on: ubuntu-latest + timeout-minutes: 15 + env: + GH_TOKEN: ${{ github.token }} + + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Install jq + run: sudo apt-get install -y jq + + - name: Diff registry.json checksums against each plugin's published release asset + run: | + set -euo pipefail + + REPO="nself-org/plugins" + WORK="$(mktemp -d)" + FAIL=0 + CHECKED=0 + SKIPPED_NO_RELEASE=0 + SKIPPED_NO_CHECKSUM=0 + declare -A RELEASE_EXISTS + + while IFS= read -r plugin_dir; do + name="$(basename "$plugin_dir")" + + entry="$(jq -c --arg n "$name" '.plugins[$n] // empty' registry.json)" + if [ -z "$entry" ]; then + # registry-check.yml's concern (presence parity), not this gate's. + continue + fi + + expected_checksum="$(printf '%s' "$entry" | jq -r '.checksum // empty')" + expected_nested="$(printf '%s' "$entry" | jq -r '.checksums.sha256 // empty')" + + if [ -z "$expected_checksum" ] && [ -z "$expected_nested" ]; then + # e.g. shared-utils: installable:false, no tarball/download_url, + # nothing for a checksum to attest to. + SKIPPED_NO_CHECKSUM=$((SKIPPED_NO_CHECKSUM + 1)) + continue + fi + + tag="$(printf '%s' "$entry" | jq -r '.releaseTag // empty')" + version="$(printf '%s' "$entry" | jq -r '.version // empty')" + + if [ -z "$tag" ] || [ -z "$version" ]; then + echo "::warning::$name has a checksum recorded but no releaseTag/version — cannot resolve a published asset to verify against" + SKIPPED_NO_RELEASE=$((SKIPPED_NO_RELEASE + 1)) + continue + fi + + if [ -z "${RELEASE_EXISTS[$tag]+x}" ]; then + if gh release view "$tag" --repo "$REPO" >/dev/null 2>&1; then + RELEASE_EXISTS["$tag"]=1 + else + RELEASE_EXISTS["$tag"]=0 + fi + fi + + if [ "${RELEASE_EXISTS[$tag]}" = "0" ]; then + echo "::notice::No published release $tag yet — skipping the published-bytes checksum compare for $name (registry version=$version). This is the normal state before the owner cuts the release; it is NOT a pass on the checksum itself." + SKIPPED_NO_RELEASE=$((SKIPPED_NO_RELEASE + 1)) + continue + fi + + tarball_name="${name}-${version}.tar.gz" + if ! gh release download "$tag" --repo "$REPO" --pattern "$tarball_name" --dir "$WORK" --clobber >/dev/null 2>&1; then + echo "MISSING $name: release $tag exists but has no asset named $tarball_name" + FAIL=1 + continue + fi + + asset_path="${WORK}/${tarball_name}" + actual="$(sha256sum "$asset_path" | cut -d' ' -f1)" + CHECKED=$((CHECKED + 1)) + rm -f "$asset_path" + + # Case-insensitive compare, matching internal/plugin/security.go's + # verifyChecksum (strings.EqualFold) — the actual install-time check. + if [ -n "$expected_checksum" ]; then + lhs="$(printf '%s' "$expected_checksum" | tr '[:upper:]' '[:lower:]')" + rhs="$(printf '%s' "$actual" | tr '[:upper:]' '[:lower:]')" + if [ "$lhs" != "$rhs" ]; then + echo "MISMATCH $name: registry .checksum=$expected_checksum published=$actual" + FAIL=1 + fi + fi + + # checksums.sha256 may carry a "sha256:" prefix; strip before comparing. + if [ -n "$expected_nested" ]; then + nested_hex="${expected_nested#sha256:}" + lhs="$(printf '%s' "$nested_hex" | tr '[:upper:]' '[:lower:]')" + rhs="$(printf '%s' "$actual" | tr '[:upper:]' '[:lower:]')" + if [ "$lhs" != "$rhs" ]; then + echo "MISMATCH $name: registry .checksums.sha256=$expected_nested published=$actual" + FAIL=1 + fi + fi + done < <(find free -maxdepth 1 -mindepth 1 -type d | sort) + + echo "" + echo "Checked against a published release asset: $CHECKED" + echo "Skipped (no release published yet for that tag): $SKIPPED_NO_RELEASE" + echo "Skipped (no checksum recorded): $SKIPPED_NO_CHECKSUM" + + rm -rf "$WORK" + + if [ "$FAIL" -ne 0 ]; then + echo "" + echo "::error::one or more registry.json checksums do not match the corresponding published release asset" + echo "Rebuild locally with scripts/build-tarballs.sh , upload it to the" >&2 + echo "release, then re-run scripts/verify-published-checksums.sh --write" >&2 + echo "to bring registry.json back in sync with what is actually published." >&2 + exit 1 + fi + + if [ "$CHECKED" -eq 0 ]; then + echo "::notice::No plugin's releaseTag currently has a published GitHub release — this gate had nothing to compare against and is passing vacuously, not because any checksum was verified. It will start actually checking bytes once a release exists for these tags." + fi + + echo "OK: every checksum that could be checked against a published release asset matches" + + platform-checksum-gate: + name: Verify registry.json checksums.platforms against published release assets + runs-on: ubuntu-latest + timeout-minutes: 15 + env: + GH_TOKEN: ${{ github.token }} + + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Install jq + run: sudo apt-get install -y jq + + - name: Diff registry.json checksums.platforms against each plugin's published per-platform assets + run: | + set -euo pipefail + + REPO="nself-org/plugins" + WORK="$(mktemp -d)" + FAIL=0 + CHECKED=0 + SKIPPED_NO_RELEASE=0 + SKIPPED_NO_BINARY=0 + declare -A RELEASE_EXISTS + + # Matches internal/plugin/arch.go's PlatformArch() — the same list + # scripts/build-tarballs.sh cross-compiles for a binaryName plugin. + PLATFORMS="darwin-arm64 darwin-amd64 linux-amd64 linux-arm64 windows-amd64" + + while IFS= read -r plugin_dir; do + name="$(basename "$plugin_dir")" + + bin_name="$(jq -r '.binaryName // .implementation.binaryName // ""' "${plugin_dir}/plugin.json" 2>/dev/null || printf '')" + if [ -z "$bin_name" ]; then + SKIPPED_NO_BINARY=$((SKIPPED_NO_BINARY + 1)) + continue + fi + + entry="$(jq -c --arg n "$name" '.plugins[$n] // empty' registry.json)" + [ -z "$entry" ] && continue + + tag="$(printf '%s' "$entry" | jq -r '.releaseTag // empty')" + version="$(printf '%s' "$entry" | jq -r '.version // empty')" + if [ -z "$tag" ] || [ -z "$version" ]; then + echo "::warning::$name declares binaryName but registry entry has no releaseTag/version — cannot resolve platform assets" + SKIPPED_NO_RELEASE=$((SKIPPED_NO_RELEASE + 1)) + continue + fi + + if [ -z "${RELEASE_EXISTS[$tag]+x}" ]; then + if gh release view "$tag" --repo "$REPO" >/dev/null 2>&1; then + RELEASE_EXISTS["$tag"]=1 + else + RELEASE_EXISTS["$tag"]=0 + fi + fi + + if [ "${RELEASE_EXISTS[$tag]}" = "0" ]; then + echo "::notice::No published release $tag yet — skipping the published-bytes platform-checksum compare for $name. This is the normal state before the owner cuts the release." + SKIPPED_NO_RELEASE=$((SKIPPED_NO_RELEASE + 1)) + continue + fi + + for platform in $PLATFORMS; do + ptar_name="${name}-${version}-${platform}.tar.gz" + expected="$(printf '%s' "$entry" | jq -r --arg p "$platform" '.checksums.platforms[$p] // empty')" + + if [ -z "$expected" ]; then + echo "MISSING $name/$platform: no registry checksums.platforms.$platform recorded (install-time verification refuses this unconditionally)" + FAIL=1 + continue + fi + + if ! gh release download "$tag" --repo "$REPO" --pattern "$ptar_name" --dir "$WORK" --clobber >/dev/null 2>&1; then + echo "MISSING-ASSET $name/$platform: release $tag exists but has no asset named $ptar_name" + FAIL=1 + continue + fi + + ptar="${WORK}/${ptar_name}" + actual="$(sha256sum "$ptar" | cut -d' ' -f1)" + CHECKED=$((CHECKED + 1)) + rm -f "$ptar" + + lhs="$(printf '%s' "$expected" | tr '[:upper:]' '[:lower:]')" + rhs="$(printf '%s' "$actual" | tr '[:upper:]' '[:lower:]')" + if [ "$lhs" != "$rhs" ]; then + echo "MISMATCH $name/$platform: registry .checksums.platforms.$platform=$expected published=$actual" + FAIL=1 + fi + done + done < <(find free -maxdepth 1 -mindepth 1 -type d | sort) + + echo "" + echo "Checked against a published platform asset: $CHECKED" + echo "Skipped (no release published yet for that tag): $SKIPPED_NO_RELEASE" + echo "Skipped (no binaryName): $SKIPPED_NO_BINARY" + + rm -rf "$WORK" + + if [ "$FAIL" -ne 0 ]; then + echo "" + echo "::error::one or more registry.json checksums.platforms entries are missing, or do not match a published per-platform release asset" + exit 1 + fi + + if [ "$CHECKED" -eq 0 ]; then + echo "::notice::No binaryName plugin's releaseTag currently has a published GitHub release — this gate had nothing to compare against and is passing vacuously, not because any platform checksum was verified." + fi + + echo "OK: every checksums.platforms entry that could be checked against a published asset matches" diff --git a/free/access-controls/plugin.json b/free/access-controls/plugin.json index c43e1dd9..8387cccc 100644 --- a/free/access-controls/plugin.json +++ b/free/access-controls/plugin.json @@ -1,6 +1,6 @@ { "name": "access-controls", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Role-based and attribute-based access control (RBAC + ABAC) with policy engine", "author": "nself", diff --git a/free/admin-api/plugin.json b/free/admin-api/plugin.json index 185fdd80..6f19385c 100644 --- a/free/admin-api/plugin.json +++ b/free/admin-api/plugin.json @@ -1,6 +1,6 @@ { "name": "admin-api", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Admin API service providing aggregated metrics, system health, session counts, storage breakdown, and real-time dashboard endpoints", "author": "nself", diff --git a/free/ai-cli/plugin.json b/free/ai-cli/plugin.json index 142aca50..d9df3855 100644 --- a/free/ai-cli/plugin.json +++ b/free/ai-cli/plugin.json @@ -1,6 +1,6 @@ { "name": "ai-cli", - "version": "1.0.0", + "version": "1.2.1", "description": "AI operations for nSelf: chat, local Ollama model management, and Gemini API key pool provisioning and rotation.", "author": "nself", "license": "MIT", diff --git a/free/ai-studio/plugin.json b/free/ai-studio/plugin.json index 13d5ec45..f3cec435 100644 --- a/free/ai-studio/plugin.json +++ b/free/ai-studio/plugin.json @@ -1,6 +1,6 @@ { "name": "ai-studio", - "version": "1.0.0", + "version": "1.2.1", "description": "Google AI Studio integration for local nSelf instances: secure Cloudflare Tunnel bridge with schema-context injection and read-only enforcement.", "author": "nself", "license": "MIT", diff --git a/free/alerts/plugin.json b/free/alerts/plugin.json index 3c917e96..d86ce0ad 100644 --- a/free/alerts/plugin.json +++ b/free/alerts/plugin.json @@ -1,6 +1,6 @@ { "name": "alerts", - "version": "1.0.0", + "version": "1.2.1", "description": "Manage Prometheus alert rules and Alertmanager silences: list, silence, and send synthetic test alerts.", "author": "nself", "license": "MIT", @@ -45,5 +45,5 @@ "required": [], "optional": [] }, - "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install alerts` must place the built nself-alerts binary at ~/.nself/plugins/bin/nself-alerts, where internal/plugin/router.go's ProxyCommand execs it for `nself alerts ` with stdio inherited. Extracted from cli/cmd/commands/alerts.go and cli/internal/alerts/ under CLI-R11 \u2014 internal/alerts was self-contained (stdlib only, plus exec of amtool/curl) and moved wholesale unchanged. The only core-side change was decoupling internal/admin/alerts.go, which used the same package purely to describe two static admin alert rules \u2014 it now defines its own minimal type." + "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install alerts` must place the built nself-alerts binary at ~/.nself/plugins/bin/nself-alerts, where internal/plugin/router.go's ProxyCommand execs it for `nself alerts ` with stdio inherited. Extracted from cli/cmd/commands/alerts.go and cli/internal/alerts/ under CLI-R11 — internal/alerts was self-contained (stdlib only, plus exec of amtool/curl) and moved wholesale unchanged. The only core-side change was decoupling internal/admin/alerts.go, which used the same package purely to describe two static admin alert rules — it now defines its own minimal type." } diff --git a/free/analytics/plugin.json b/free/analytics/plugin.json index 77e94db0..2969713f 100644 --- a/free/analytics/plugin.json +++ b/free/analytics/plugin.json @@ -1,6 +1,6 @@ { "name": "analytics", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Event tracking, counters, funnels, and quota management analytics engine", "author": "nself", diff --git a/free/api/plugin.json b/free/api/plugin.json index eefa6fc1..2f7bab73 100644 --- a/free/api/plugin.json +++ b/free/api/plugin.json @@ -1,6 +1,6 @@ { "name": "api", - "version": "1.0.0", + "version": "1.2.1", "description": "Inspect the nSelf plugin API surface: endpoint probes, deprecation calendar, and the API changelog.", "author": "nself", "license": "MIT", diff --git a/free/audit-analytics/plugin.json b/free/audit-analytics/plugin.json index b6a6f0ae..cd4470e6 100644 --- a/free/audit-analytics/plugin.json +++ b/free/audit-analytics/plugin.json @@ -1,6 +1,6 @@ { "name": "audit-analytics", - "version": "1.0.0", + "version": "1.2.1", "api_version": "1.0.0", "description": "Advanced audit analytics over np_audit_log: anomaly detection (z-score baseline), user behaviour heatmaps, privileged-action review queue, and webhook/email alerts.", "author": "nself", diff --git a/free/audit-log/plugin.json b/free/audit-log/plugin.json index a7b9b6e4..eee87088 100644 --- a/free/audit-log/plugin.json +++ b/free/audit-log/plugin.json @@ -1,6 +1,6 @@ { "name": "audit-log", - "version": "1.0.0", + "version": "1.2.1", "description": "Append-only audit log for security-relevant events: auth, privilege change, secret access, plugin install/uninstall. Queryable from Admin with filters by event type, actor, severity, and time range.", "author": "nself", "license": "MIT", diff --git a/free/audit/plugin.json b/free/audit/plugin.json index 438ee6b3..9df36590 100644 --- a/free/audit/plugin.json +++ b/free/audit/plugin.json @@ -1,6 +1,6 @@ { "name": "audit", - "version": "1.0.0", + "version": "1.2.1", "description": "Ecosystem documentation audit: banned words, dead links, and missing anchors across READMEs, wiki, docs, SPORT, PPI, and PRI.", "author": "nself", "license": "MIT", diff --git a/free/auth-enterprise/plugin.json b/free/auth-enterprise/plugin.json index b713392b..84e8415c 100644 --- a/free/auth-enterprise/plugin.json +++ b/free/auth-enterprise/plugin.json @@ -1,6 +1,6 @@ { "name": "auth-enterprise", - "version": "1.1.2", + "version": "1.2.1", "description": "MFA enforcement (TOTP + WebAuthn policy) and SSO via SAML 2.0 and OIDC for Google Workspace, Okta, and Microsoft Entra ID.", "category": "authentication", "isCommercial": false, diff --git a/free/backup/plugin.json b/free/backup/plugin.json index 27002ab3..b4e612f2 100644 --- a/free/backup/plugin.json +++ b/free/backup/plugin.json @@ -1,6 +1,6 @@ { "name": "backup", - "version": "1.0.0", + "version": "1.2.1", "description": "PostgreSQL backup and restore automation with scheduling", "author": "nself", "license": "MIT", diff --git a/free/byok/plugin.json b/free/byok/plugin.json index bba1f072..82a33646 100644 --- a/free/byok/plugin.json +++ b/free/byok/plugin.json @@ -1,6 +1,6 @@ { "name": "byok", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Bring Your Own Key (BYOK) per-tenant encryption. Envelope encryption with customer-managed keys (CMK) via AWS KMS, GCP Cloud KMS, or HashiCorp Vault Transit. DEK wrapped by CMK. Satisfies HIPAA, FedRAMP High, FFIEC, and DORA key-control requirements. Enterprise-only.", "author": "nself", @@ -59,7 +59,7 @@ "kms.configured": "KMS provider configured for tenant", "kms.verified": "KMS connectivity verified", "key.rotated": "Key rotation job completed", - "key.revoked": "CMK revoked \u2014 data access blocked", + "key.revoked": "CMK revoked — data access blocked", "rotation.started": "Key rotation job started", "rotation.failed": "Key rotation job failed" }, diff --git a/free/cdc/plugin.json b/free/cdc/plugin.json index 428f315c..6c4ac855 100644 --- a/free/cdc/plugin.json +++ b/free/cdc/plugin.json @@ -1,8 +1,8 @@ { "name": "cdc", - "version": "1.0.0", + "version": "1.2.1", "api_version": "1.0.0", - "description": "Change Data Capture \u2014 streams Postgres WAL events to downstream consumers via webhooks or message queues.", + "description": "Change Data Capture — streams Postgres WAL events to downstream consumers via webhooks or message queues.", "author": "nself", "license": "MIT", "isCommercial": false, diff --git a/free/cdn/plugin.json b/free/cdn/plugin.json index d06fac77..5bcdcc6c 100644 --- a/free/cdn/plugin.json +++ b/free/cdn/plugin.json @@ -1,6 +1,6 @@ { "name": "cdn", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "CDN management and integration plugin - cache purging, signed URLs. Planned: analytics sync from Cloudflare/BunnyCDN", "author": "nself", diff --git a/free/ci/plugin.json b/free/ci/plugin.json index 9bd4a113..8004a672 100644 --- a/free/ci/plugin.json +++ b/free/ci/plugin.json @@ -1,6 +1,6 @@ { "name": "ci", - "version": "1.0.1", + "version": "1.2.1", "description": "Local CI gate runner: detects repo stack (Go/Node/Flutter/Dart), runs lint+test+build, scans secrets with gitleaks, then posts a GitHub commit status (nself-ci) via gh OAuth. Replaces billing-blocked GitHub Actions as the merge gate.", "author": "nself", "license": "MIT", diff --git a/free/claw-cli/plugin.json b/free/claw-cli/plugin.json index 386e8958..12fe5d16 100644 --- a/free/claw-cli/plugin.json +++ b/free/claw-cli/plugin.json @@ -1,6 +1,6 @@ { "name": "claw-cli", - "version": "1.0.0", + "version": "1.2.1", "description": "CLI client for the nClaw AI assistant: prompt, chat, pairing, keys, memories, topics, sessions, MCP server, OpenAI-compatible proxy, and schema migrations.", "author": "nself", "license": "MIT", diff --git a/free/cloudflare/plugin.json b/free/cloudflare/plugin.json index a28e5a1f..5d6ce58e 100644 --- a/free/cloudflare/plugin.json +++ b/free/cloudflare/plugin.json @@ -1,6 +1,6 @@ { "name": "cloudflare", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Cloudflare zone, DNS, R2, cache, and analytics management", "author": "nself", diff --git a/free/compliance/plugin.json b/free/compliance/plugin.json index 761ae5b3..38c8b663 100644 --- a/free/compliance/plugin.json +++ b/free/compliance/plugin.json @@ -1,6 +1,6 @@ { "name": "compliance", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Comprehensive compliance and audit platform with GDPR/CCPA/HIPAA/SOC2/PCI management, DSARs, consent tracking, data retention, breach notification, immutable audit logging, SIEM integration, and compliance reporting", "author": "nself", diff --git a/free/content-acquisition/plugin.json b/free/content-acquisition/plugin.json index 9d8f5951..c74e4de4 100644 --- a/free/content-acquisition/plugin.json +++ b/free/content-acquisition/plugin.json @@ -1,6 +1,6 @@ { "name": "content-acquisition", - "version": "1.0.0", + "version": "1.2.1", "description": "Content acquisition with download rules engine. Planned: RSS feed monitoring, release calendar integration, automated download orchestration", "author": "nself", "license": "MIT", diff --git a/free/content-progress/plugin.json b/free/content-progress/plugin.json index 94cb69d3..49119959 100644 --- a/free/content-progress/plugin.json +++ b/free/content-progress/plugin.json @@ -1,6 +1,6 @@ { "name": "content-progress", - "version": "1.0.0", + "version": "1.2.1", "description": "Track video, audio, and content playback progress with continue watching, watchlists, and favorites", "author": "nself", "license": "MIT", diff --git a/free/content-safety/plugin.json b/free/content-safety/plugin.json index f7cf5a5b..7d89a3f9 100644 --- a/free/content-safety/plugin.json +++ b/free/content-safety/plugin.json @@ -1,7 +1,7 @@ { "name": "content-safety", "displayName": "ɳSelf Content Safety", - "version": "1.0.0", + "version": "1.2.1", "description": "Trust-safety evidence, legal holds, spam detection, raid protection, and abuse scoring", "author": "nSelf", "license": "MIT", diff --git a/free/costs/plugin.json b/free/costs/plugin.json index f795013b..dc395c42 100644 --- a/free/costs/plugin.json +++ b/free/costs/plugin.json @@ -1,6 +1,6 @@ { "name": "costs", - "version": "1.0.0", + "version": "1.2.1", "description": "Show estimated per-install operational costs: Hetzner VPS, Cloudflare, Vercel, Stripe fees, and installed paid plugin licenses.", "author": "nself", "license": "MIT", @@ -44,5 +44,5 @@ "required": [], "optional": [] }, - "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install costs` must place the built nself-costs binary at ~/.nself/plugins/bin/nself-costs, where internal/plugin/router.go's ProxyCommand execs it for `nself costs ` with stdio inherited. Extracted from cli/cmd/commands/costs.go under CLI-R11. The core CLI's internal/plugin.ListInstalled() is unreachable across the module boundary, so this plugin's internal/plugininfo package reimplements only the narrow read it needs (plugin.json's tier/requires_license/licenseType fields) rather than the full manifest validation internal/plugin performs at install time \u2014 see that package's doc comment for the exact scope of the simplification." + "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install costs` must place the built nself-costs binary at ~/.nself/plugins/bin/nself-costs, where internal/plugin/router.go's ProxyCommand execs it for `nself costs ` with stdio inherited. Extracted from cli/cmd/commands/costs.go under CLI-R11. The core CLI's internal/plugin.ListInstalled() is unreachable across the module boundary, so this plugin's internal/plugininfo package reimplements only the narrow read it needs (plugin.json's tier/requires_license/licenseType fields) rather than the full manifest validation internal/plugin performs at install time — see that package's doc comment for the exact scope of the simplification." } diff --git a/free/crdt/plugin.json b/free/crdt/plugin.json index 2f656d66..1a9d86c6 100644 --- a/free/crdt/plugin.json +++ b/free/crdt/plugin.json @@ -1,6 +1,6 @@ { "name": "crdt", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.3.0", "description": "CRDT offline-first primitives. Self-hosted Yjs (y-websocket protocol) and automerge sync server with Postgres persistence. Drop-in replacement for Liveblocks/PartyKit with zero extra infra.", "author": "nself", diff --git a/free/cron/plugin.json b/free/cron/plugin.json index e59d856f..8bc6ac5f 100644 --- a/free/cron/plugin.json +++ b/free/cron/plugin.json @@ -1,6 +1,6 @@ { "name": "cron", - "version": "1.0.0", + "version": "1.2.1", "description": "Cron job scheduler. Register jobs with standard cron syntax, execute via HTTP callbacks, track run history.", "author": "nself", "license": "MIT", diff --git a/free/ddns/plugin.json b/free/ddns/plugin.json index 990457ef..4fc48e7f 100644 --- a/free/ddns/plugin.json +++ b/free/ddns/plugin.json @@ -1,6 +1,6 @@ { "name": "ddns", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Dynamic DNS plugin with external IP monitoring. Planned: DNS provider API integration (Cloudflare, Route53) for automated record updates", "author": "nself", diff --git a/free/devices/plugin.json b/free/devices/plugin.json index d2a6ee39..a6d8492f 100644 --- a/free/devices/plugin.json +++ b/free/devices/plugin.json @@ -1,6 +1,6 @@ { "name": "devices", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "IoT device enrollment, trust management, and command dispatch service.", "author": "nself", diff --git a/free/dlq/plugin.json b/free/dlq/plugin.json index 925b59da..086a9b5f 100644 --- a/free/dlq/plugin.json +++ b/free/dlq/plugin.json @@ -1,6 +1,6 @@ { "name": "dlq", - "version": "1.0.0", + "version": "1.2.1", "description": "Manage dead-letter queues for nSelf plugins: re-enqueue rows that failed processing back to the work queue, with safe row limits and dry-run preview.", "author": "nself", "license": "MIT", @@ -46,5 +46,5 @@ "required": [], "optional": [] }, - "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables of its own \u2014 it calls the running stack's REST API (default http://localhost:8080) to fetch and replay a named plugin's DLQ rows. `nself plugin install dlq` must place the built nself-dlq binary at ~/.nself/plugins/bin/nself-dlq, where internal/plugin/router.go's ProxyCommand execs it for `nself dlq ` with stdio inherited. Extracted from cli/cmd/commands/dlq_replay.go under CLI-R11 \u2014 a straight file move, since the command had zero github.com/nself-org/cli/internal/* dependencies beyond internal/dlq itself." + "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables of its own — it calls the running stack's REST API (default http://localhost:8080) to fetch and replay a named plugin's DLQ rows. `nself plugin install dlq` must place the built nself-dlq binary at ~/.nself/plugins/bin/nself-dlq, where internal/plugin/router.go's ProxyCommand execs it for `nself dlq ` with stdio inherited. Extracted from cli/cmd/commands/dlq_replay.go under CLI-R11 — a straight file move, since the command had zero github.com/nself-org/cli/internal/* dependencies beyond internal/dlq itself." } diff --git a/free/documents/plugin.json b/free/documents/plugin.json index 8c5c62d7..c143763d 100644 --- a/free/documents/plugin.json +++ b/free/documents/plugin.json @@ -1,6 +1,6 @@ { "name": "documents", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Document management and generation service with templates, versioning, and sharing", "author": "nself", diff --git a/free/dogfood/plugin.json b/free/dogfood/plugin.json index a1fdef61..4463d58e 100644 --- a/free/dogfood/plugin.json +++ b/free/dogfood/plugin.json @@ -1,6 +1,6 @@ { "name": "dogfood", - "version": "1.0.0", + "version": "1.2.1", "description": "Production dogfood audit and reporting: 21 read-only checks covering backups, DR, tenancy, licensing, secrets, migrations, monitoring, security, watchdog, and queue health.", "author": "nself", "license": "MIT", diff --git a/free/donorbox/plugin.json b/free/donorbox/plugin.json index 3244af80..935e11e2 100644 --- a/free/donorbox/plugin.json +++ b/free/donorbox/plugin.json @@ -1,6 +1,6 @@ { "name": "donorbox", - "version": "1.0.0", + "version": "1.2.1", "description": "Donorbox donation data sync with webhook handling", "author": "nself", "license": "MIT", diff --git a/free/dr/plugin.json b/free/dr/plugin.json index 6c099427..189ac13e 100644 --- a/free/dr/plugin.json +++ b/free/dr/plugin.json @@ -1,6 +1,6 @@ { "name": "dr", - "version": "1.0.0", + "version": "1.2.1", "description": "Disaster recovery: promote a standby, fence the old primary, run drills, and install the systemd units DR needs.", "author": "nself", "license": "MIT", diff --git a/free/e2ee/plugin.json b/free/e2ee/plugin.json index 830e59e3..8ecc7ae0 100644 --- a/free/e2ee/plugin.json +++ b/free/e2ee/plugin.json @@ -1,6 +1,6 @@ { "name": "e2ee", - "version": "1.0.0", + "version": "1.2.1", "description": "End-to-end encryption key directory: X3DH prekey distribution + Kyber-1024 (ML-KEM-1024) post-quantum prekeys for nchat. Server stores PUBLIC keys only; private keys never leave the client.", "author": "nself", "license": "MIT", diff --git a/free/email/plugin.json b/free/email/plugin.json index 21d5386a..a80efce1 100644 --- a/free/email/plugin.json +++ b/free/email/plugin.json @@ -1,6 +1,6 @@ { "name": "email", - "version": "1.0.0", + "version": "1.2.1", "displayName": "plugin-email", "description": "Transactional email via Elastic Email. Send, template, and track emails.", "port": 9008, diff --git a/free/encryption/plugin.json b/free/encryption/plugin.json index 491bda30..eb16383c 100644 --- a/free/encryption/plugin.json +++ b/free/encryption/plugin.json @@ -1,6 +1,6 @@ { "name": "encryption", - "version": "1.0.0", + "version": "1.2.1", "description": "Bring Your Own Key (BYOK) per-tenant envelope encryption for nSelf Cloud: AWS KMS, GCP Cloud KMS, and HashiCorp Vault Transit, with key rotation and an audit trail.", "author": "nself", "license": "MIT", @@ -51,5 +51,5 @@ "required": [], "optional": [] }, - "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables of its own \u2014 it calls the BYOK plugin's own HTTP API (default http://localhost:3741). `nself plugin install encryption` must place the built nself-encryption binary at ~/.nself/plugins/bin/nself-encryption, where internal/plugin/router.go's ProxyCommand execs it for `nself encryption ` with stdio inherited. Extracted from cli/cmd/commands/encryption.go under CLI-R11 \u2014 a straight file move, since the command had zero github.com/nself-org/cli/internal/* dependencies before extraction." + "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables of its own — it calls the BYOK plugin's own HTTP API (default http://localhost:3741). `nself plugin install encryption` must place the built nself-encryption binary at ~/.nself/plugins/bin/nself-encryption, where internal/plugin/router.go's ProxyCommand execs it for `nself encryption ` with stdio inherited. Extracted from cli/cmd/commands/encryption.go under CLI-R11 — a straight file move, since the command had zero github.com/nself-org/cli/internal/* dependencies before extraction." } diff --git a/free/entitlements/plugin.json b/free/entitlements/plugin.json index b5cca850..bb0e141c 100644 --- a/free/entitlements/plugin.json +++ b/free/entitlements/plugin.json @@ -1,6 +1,6 @@ { "name": "entitlements", - "version": "1.2.0", + "version": "1.2.1", "api_version": "1.0.0", "description": "Feature gating, subscription plan management, usage quota tracking, and metered billing", "author": "nself", diff --git a/free/event-bus/plugin.json b/free/event-bus/plugin.json index e1be9a6e..bedfa0ae 100644 --- a/free/event-bus/plugin.json +++ b/free/event-bus/plugin.json @@ -1,6 +1,6 @@ { "name": "event-bus", - "version": "1.0.0", + "version": "1.2.1", "api_version": "1.0.0", "description": "Internal event bus with pub/sub, fan-out delivery, dead-letter queue, and replay for inter-plugin messaging.", "author": "nself", diff --git a/free/family-ancestry/plugin.json b/free/family-ancestry/plugin.json index 56232ab1..0b79b672 100644 --- a/free/family-ancestry/plugin.json +++ b/free/family-ancestry/plugin.json @@ -1,8 +1,8 @@ { "name": "family-ancestry", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", - "description": "Ancestry.com \u2192 nFamily migration helper (PLANNED). Imports profiles, photos, documents, sources into the family plugin. Pattern mirrors family-geni.", + "description": "Ancestry.com → nFamily migration helper (PLANNED). Imports profiles, photos, documents, sources into the family plugin. Pattern mirrors family-geni.", "author": "nself", "license": "MIT", "isCommercial": false, diff --git a/free/family-familysearch/plugin.json b/free/family-familysearch/plugin.json index cb45960c..e3b29c22 100644 --- a/free/family-familysearch/plugin.json +++ b/free/family-familysearch/plugin.json @@ -1,8 +1,8 @@ { "name": "family-familysearch", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", - "description": "FamilySearch \u2192 nFamily migration helper (PLANNED). Free public API from FamilySearch (LDS). Lowest-friction next-step importer after family-geni.", + "description": "FamilySearch → nFamily migration helper (PLANNED). Free public API from FamilySearch (LDS). Lowest-friction next-step importer after family-geni.", "author": "nself", "license": "MIT", "isCommercial": false, diff --git a/free/family-gedcom/plugin.json b/free/family-gedcom/plugin.json index 5c61d29b..39690e3b 100644 --- a/free/family-gedcom/plugin.json +++ b/free/family-gedcom/plugin.json @@ -1,18 +1,26 @@ { "name": "family-gedcom", - "version": "0.0.1", + "version": "1.2.1", "description": "Generic GEDCOM file importer for the family plugin. Accepts any GEDCOM 5.5.1 / 7.0 file from any provider with optional photo-folder upload. PLANNED: requires the 'family' plugin (ɳFamily bundle, planned v1.1.0) and 'object-storage' + 'photos' plugins. Not installable until the family plugin ships.", "author": "nself", "license": "MIT", "isCommercial": false, "minNselfVersion": "1.0.0", "category": "social", - "tags": ["family", "genealogy", "gedcom", "migration", "importer"], + "tags": [ + "family", + "genealogy", + "gedcom", + "migration", + "importer" + ], "tables": [], "webhooks": {}, "actions": {}, "envVars": { - "required": ["DATABASE_URL"], + "required": [ + "DATABASE_URL" + ], "optional": [] }, "config": {}, @@ -23,12 +31,25 @@ "defaultValue": "primary" }, "permissions": { - "database": ["create", "read", "update", "delete"], + "database": [ + "create", + "read", + "update", + "delete" + ], "network": [], - "filesystem": ["storage", "temp", "logs"] + "filesystem": [ + "storage", + "temp", + "logs" + ] }, "dependencies": { - "plugins": ["family", "object-storage", "photos"] + "plugins": [ + "family", + "object-storage", + "photos" + ] }, "homepage": "https://nself.org/plugins", "repository": "https://github.com/nself-org/plugins", diff --git a/free/family-myheritage/plugin.json b/free/family-myheritage/plugin.json index 203fd675..b325e5b8 100644 --- a/free/family-myheritage/plugin.json +++ b/free/family-myheritage/plugin.json @@ -1,8 +1,8 @@ { "name": "family-myheritage", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", - "description": "MyHeritage \u2192 nFamily migration helper (PLANNED). MyHeritage is Geni.com's parent company \u2014 lowest legal risk, potential partnership path.", + "description": "MyHeritage → nFamily migration helper (PLANNED). MyHeritage is Geni.com's parent company — lowest legal risk, potential partnership path.", "author": "nself", "license": "MIT", "isCommercial": false, diff --git a/free/family-wikitree/plugin.json b/free/family-wikitree/plugin.json index 96ec850d..b1a3d3ad 100644 --- a/free/family-wikitree/plugin.json +++ b/free/family-wikitree/plugin.json @@ -1,8 +1,8 @@ { "name": "family-wikitree", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", - "description": "WikiTree \u2192 nFamily migration helper (PLANNED). WikiTree is a free public genealogy wiki with a REST API (Apps API).", + "description": "WikiTree → nFamily migration helper (PLANNED). WikiTree is a free public genealogy wiki with a REST API (Apps API).", "author": "nself", "license": "MIT", "isCommercial": false, diff --git a/free/feature-flags/plugin.json b/free/feature-flags/plugin.json index fde4eb75..eba54065 100644 --- a/free/feature-flags/plugin.json +++ b/free/feature-flags/plugin.json @@ -1,6 +1,6 @@ { "name": "feature-flags", - "version": "1.0.0", + "version": "1.2.1", "description": "Feature flags service with targeting rules, segments, and evaluation engine", "author": "nself", "license": "MIT", diff --git a/free/federation/plugin.json b/free/federation/plugin.json index d42b0f85..53c9f7b2 100644 --- a/free/federation/plugin.json +++ b/free/federation/plugin.json @@ -1,6 +1,6 @@ { "name": "federation", - "version": "1.0.0", + "version": "1.2.1", "description": "Manage GraphQL Federation: compose an Apollo Router supergraph from installed plugin subgraphs, check subgraph health, and introspect the composed schema.", "author": "nself", "license": "MIT", diff --git a/free/file-processing/plugin.json b/free/file-processing/plugin.json index 1a5aada7..a151a3dc 100644 --- a/free/file-processing/plugin.json +++ b/free/file-processing/plugin.json @@ -1,6 +1,6 @@ { "name": "file-processing", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "File processing with thumbnails and optimization for MinIO/S3/GCS/R2/B2/Azure. Planned: Inbound webhook support for storage provider notifications", "author": "nself", diff --git a/free/flags/plugin.json b/free/flags/plugin.json index 103f148c..787140b5 100644 --- a/free/flags/plugin.json +++ b/free/flags/plugin.json @@ -1,6 +1,6 @@ { "name": "flags", - "version": "1.0.0", + "version": "1.2.1", "description": "Manage feature flags served by the feature-flags plugin: list, get, set, history, canary rollouts and kill switches.", "author": "nself", "license": "MIT", diff --git a/free/forgejo/plugin.json b/free/forgejo/plugin.json index d2a94709..56f473ac 100644 --- a/free/forgejo/plugin.json +++ b/free/forgejo/plugin.json @@ -1,6 +1,6 @@ { "name": "forgejo", - "version": "1.0.0", + "version": "1.2.1", "description": "Self-hosted Forgejo git forge + Forgejo Actions runner. Provides offline CI that executes .github/workflows/*.yml YAML on self-hosted compute — zero GitHub Actions quota consumed. Designed for the ops profile (ops server on staging/prod).", "author": "nself", "license": "MIT", diff --git a/free/functions-v8/plugin.json b/free/functions-v8/plugin.json index 3df32d5b..38bb063b 100644 --- a/free/functions-v8/plugin.json +++ b/free/functions-v8/plugin.json @@ -1,6 +1,6 @@ { "name": "functions-edge", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Edge Functions V8 Runtime. Deploy short-lived TypeScript functions with a Deno V8 isolate pool. HTTP-trigger, <50ms cold-start, allowlist-only env injection, Prometheus metrics, SSE log streaming.", "author": "nself", diff --git a/free/game-metadata/plugin.json b/free/game-metadata/plugin.json index 44bfd74e..3f69744c 100644 --- a/free/game-metadata/plugin.json +++ b/free/game-metadata/plugin.json @@ -1,6 +1,6 @@ { "name": "game-metadata", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Game metadata service with IGDB integration, ROM hash matching, tier requirements, and artwork management", "author": "nself", diff --git a/free/gateway/plugin.json b/free/gateway/plugin.json index 50da5647..d8b8a3f7 100644 --- a/free/gateway/plugin.json +++ b/free/gateway/plugin.json @@ -1,6 +1,6 @@ { "name": "gateway", - "version": "1.0.0", + "version": "1.2.1", "description": "Manage the nSelf AI gateway (nself-ai-gateway, port 3761): service health, provider key vault, quota usage, and routing rules.", "author": "nself", "license": "MIT", diff --git a/free/gauth/plugin.json b/free/gauth/plugin.json index c194ff6d..ad53869d 100644 --- a/free/gauth/plugin.json +++ b/free/gauth/plugin.json @@ -1,6 +1,6 @@ { "name": "gauth", - "version": "1.0.0", + "version": "1.2.1", "description": "Manage Google OAuth tokens for nSelf AI services: status, refresh, and revoke against plugin-gauth.", "author": "nself", "license": "MIT", diff --git a/free/gdpr/plugin.json b/free/gdpr/plugin.json index 1196b4c5..6800f82a 100644 --- a/free/gdpr/plugin.json +++ b/free/gdpr/plugin.json @@ -1,6 +1,6 @@ { "name": "gdpr", - "version": "1.0.0", + "version": "1.2.1", "description": "GDPR data portability (Art. 20) and right-to-erasure (Art. 17) tools for self-hosted nSelf instances.", "author": "nself", "license": "MIT", diff --git a/free/geocoding/plugin.json b/free/geocoding/plugin.json index dc7a1899..bb4d36b1 100644 --- a/free/geocoding/plugin.json +++ b/free/geocoding/plugin.json @@ -1,6 +1,6 @@ { "name": "geocoding", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Geocoding plugin with geofence storage. Planned: Google Maps API integration for forward/reverse geocoding and place search", "author": "nself", diff --git a/free/github-runner/plugin.json b/free/github-runner/plugin.json index a77e6475..49128337 100644 --- a/free/github-runner/plugin.json +++ b/free/github-runner/plugin.json @@ -1,6 +1,6 @@ { "name": "github-runner", - "version": "1.0.0", + "version": "1.2.1", "description": "GitHub Actions self-hosted runner. Registers with your GitHub org and picks up CI jobs tagged `runs-on: ubuntu-latest` — enabling private repos to run CI without GitHub-hosted runners.", "author": "nself", "license": "MIT", diff --git a/free/github/plugin.json b/free/github/plugin.json index 063aabf5..81132f77 100644 --- a/free/github/plugin.json +++ b/free/github/plugin.json @@ -1,6 +1,6 @@ { "name": "github", - "version": "1.0.0", + "version": "1.2.1", "description": "GitHub repository, issue, and workflow integration", "author": "nself", "license": "MIT", diff --git a/free/hipaa/plugin.json b/free/hipaa/plugin.json index 0d850bda..8f0fe9f1 100644 --- a/free/hipaa/plugin.json +++ b/free/hipaa/plugin.json @@ -1,6 +1,6 @@ { "name": "hipaa", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "HIPAA compliance add-on: PHI column registry, PHI access logging with 6-year retention, de-identification helpers (masking + tokenization), encryption-at-rest audit, and BAA workflow.", "author": "nself", @@ -29,7 +29,7 @@ "np_baa_records" ], "webhooks": { - "phi.accessed": "PHI column accessed \u2014 row written to np_phi_audit_log", + "phi.accessed": "PHI column accessed — row written to np_phi_audit_log", "phi.column.registered": "PHI column registered in registry", "phi.column.unregistered": "PHI column unregistered", "baa.requested": "BAA signing workflow initiated", diff --git a/free/home/plugin.json b/free/home/plugin.json index eaf3cf0a..173d15fb 100644 --- a/free/home/plugin.json +++ b/free/home/plugin.json @@ -1,6 +1,6 @@ { "name": "home", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Home automation bridge. Connects Home Assistant and MQTT to ɳSelf, enabling smart device control, state monitoring, scene activation, and command logging.", "author": "nself", diff --git a/free/idme/plugin.json b/free/idme/plugin.json index ed806ae8..99eb2fca 100644 --- a/free/idme/plugin.json +++ b/free/idme/plugin.json @@ -1,6 +1,6 @@ { "name": "idme", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "ID.me OAuth authentication with government-grade identity verification for 7 groups", "author": "nself", diff --git a/free/infra/plugin.json b/free/infra/plugin.json index 9226b19a..5bdb915d 100644 --- a/free/infra/plugin.json +++ b/free/infra/plugin.json @@ -1,6 +1,6 @@ { "name": "infra", - "version": "1.0.0", + "version": "1.2.1", "description": "Provision nSelf infrastructure with Terraform: plan, apply and destroy modules for aws, gcp, azure, hetzner, do and linode.", "author": "nself", "license": "MIT", diff --git a/free/invitations/plugin.json b/free/invitations/plugin.json index 30d6232b..578500ff 100644 --- a/free/invitations/plugin.json +++ b/free/invitations/plugin.json @@ -1,6 +1,6 @@ { "name": "invitations", - "version": "1.0.0", + "version": "1.2.1", "description": "Invitation management system with email/SMS delivery and tracking", "author": "nself", "license": "MIT", diff --git a/free/job-queue/plugin.json b/free/job-queue/plugin.json index 004109a8..7ba09e15 100644 --- a/free/job-queue/plugin.json +++ b/free/job-queue/plugin.json @@ -1,6 +1,6 @@ { "name": "job-queue", - "version": "1.0.0", + "version": "1.2.1", "api_version": "1.0.0", "description": "Durable background job queue with priorities, retries, scheduled execution, and per-job progress tracking.", "author": "nself", diff --git a/free/jobs/plugin.json b/free/jobs/plugin.json index 8eaebd3f..591a3d8c 100644 --- a/free/jobs/plugin.json +++ b/free/jobs/plugin.json @@ -1,6 +1,6 @@ { "name": "jobs", - "version": "1.0.0", + "version": "1.2.1", "description": "PostgreSQL-backed background job queue with priorities, scheduling, retries, and REST API. Simplified Go implementation using database polling instead of Redis/BullMQ.", "author": "nself", "license": "MIT", diff --git a/free/k8s/plugin.json b/free/k8s/plugin.json index 84938d0e..411b5051 100644 --- a/free/k8s/plugin.json +++ b/free/k8s/plugin.json @@ -1,6 +1,6 @@ { "name": "k8s", - "version": "1.0.0", + "version": "1.2.1", "description": "Deploy and manage nSelf on any Kubernetes cluster via the official Helm chart: install, upgrade, and status commands wrapping helm.", "author": "nself", "license": "MIT", @@ -48,5 +48,5 @@ "required": [], "optional": [] }, - "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install k8s` must place the built nself-k8s binary at ~/.nself/plugins/bin/nself-k8s, where internal/plugin/router.go's ProxyCommand execs it for `nself k8s ` with stdio inherited. Extracted from cli/cmd/commands/k8s.go, cli/internal/k8s/, and cli/charts/nself/ under CLI-R11. Status is 'planned' (not 'stable') because the source command itself was PLANNED \u2014 deferred pending UD-12 minor release approval. The chart has a Postgres StatefulSet+Service, a Hasura Deployment+Service, an Auth Deployment, and an nginx Ingress (+ optional cert-manager Certificate) \u2014 it has not been helm-lint/template validated against a real cluster since extraction." + "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install k8s` must place the built nself-k8s binary at ~/.nself/plugins/bin/nself-k8s, where internal/plugin/router.go's ProxyCommand execs it for `nself k8s ` with stdio inherited. Extracted from cli/cmd/commands/k8s.go, cli/internal/k8s/, and cli/charts/nself/ under CLI-R11. Status is 'planned' (not 'stable') because the source command itself was PLANNED — deferred pending UD-12 minor release approval. The chart has a Postgres StatefulSet+Service, a Hasura Deployment+Service, an Auth Deployment, and an nginx Ingress (+ optional cert-manager Certificate) — it has not been helm-lint/template validated against a real cluster since extraction." } diff --git a/free/link-preview/plugin.json b/free/link-preview/plugin.json index aec7415f..a14eac85 100644 --- a/free/link-preview/plugin.json +++ b/free/link-preview/plugin.json @@ -1,6 +1,6 @@ { "name": "link-preview", - "version": "1.0.0", + "version": "1.2.1", "description": "URL metadata extraction with Open Graph, Twitter Cards, and caching", "author": "nself", "license": "MIT", diff --git a/free/linkedin/plugin.json b/free/linkedin/plugin.json index 91a881b1..5413da30 100644 --- a/free/linkedin/plugin.json +++ b/free/linkedin/plugin.json @@ -1,6 +1,6 @@ { "name": "linkedin", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "LinkedIn publishing integration. OAuth 2.0 connection, post to LinkedIn feed with optional image attachments, post history, and Claw tool descriptor.", "author": "nself", diff --git a/free/mail/plugin.json b/free/mail/plugin.json index 3d19ceba..59188f1d 100644 --- a/free/mail/plugin.json +++ b/free/mail/plugin.json @@ -1,6 +1,6 @@ { "name": "mail", - "version": "1.0.0", + "version": "1.2.1", "description": "Send transactional and broadcast email through the nSelf stack: mux + Postmark pipeline via ping_api, template management, and DKIM verification.", "author": "nself", "license": "MIT", @@ -51,5 +51,5 @@ "required": [], "optional": [] }, - "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables of its own \u2014 it calls ping_api (default https://ping.nself.org), which proxies to the mux + transactional-email (Postmark) pro plugins. `nself plugin install mail` must place the built nself-mail binary at ~/.nself/plugins/bin/nself-mail, where internal/plugin/router.go's ProxyCommand execs it for `nself mail ` with stdio inherited. Extracted from cli/cmd/commands/mail.go, mail_transactional.go, and mail_admin.go under CLI-R11. Requires an nSelf+ or nClaw bundle license (matching the underlying transactional-email plugin's requires_license: true); exits 2 with a clear message when no license key is configured, exactly as the in-core command did." + "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables of its own — it calls ping_api (default https://ping.nself.org), which proxies to the mux + transactional-email (Postmark) pro plugins. `nself plugin install mail` must place the built nself-mail binary at ~/.nself/plugins/bin/nself-mail, where internal/plugin/router.go's ProxyCommand execs it for `nself mail ` with stdio inherited. Extracted from cli/cmd/commands/mail.go, mail_transactional.go, and mail_admin.go under CLI-R11. Requires an nSelf+ or nClaw bundle license (matching the underlying transactional-email plugin's requires_license: true); exits 2 with a clear message when no license key is configured, exactly as the in-core command did." } diff --git a/free/maintenance/plugin.json b/free/maintenance/plugin.json index 5b58b947..511b166c 100644 --- a/free/maintenance/plugin.json +++ b/free/maintenance/plugin.json @@ -1,6 +1,6 @@ { "name": "maintenance", - "version": "1.0.0", + "version": "1.2.1", "description": "Maintenance utilities: disk cleanup, log rotation and the maintenance scheduler.", "author": "nself", "license": "MIT", diff --git a/free/mdns/plugin.json b/free/mdns/plugin.json index 8425e3bc..b8b23518 100644 --- a/free/mdns/plugin.json +++ b/free/mdns/plugin.json @@ -1,6 +1,6 @@ { "name": "mdns", - "version": "1.0.0", + "version": "1.2.1", "description": "mDNS/Bonjour service discovery for zero-config LAN advertising", "author": "nself", "language": "go", diff --git a/free/media-processing/plugin.json b/free/media-processing/plugin.json index f98a4546..10a0bf58 100644 --- a/free/media-processing/plugin.json +++ b/free/media-processing/plugin.json @@ -1,6 +1,6 @@ { "name": "media-processing", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "FFmpeg-based media encoding and processing with HLS streaming support", "author": "nself", diff --git a/free/meetings/plugin.json b/free/meetings/plugin.json index 7dad0fb5..0801b4c0 100644 --- a/free/meetings/plugin.json +++ b/free/meetings/plugin.json @@ -1,6 +1,6 @@ { "name": "meetings", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Calendar integration and meeting management with room booking, recurring meetings, and availability tracking. External calendar sync (Google/Outlook) planned for future release.", "author": "nself", diff --git a/free/mlflow/plugin.json b/free/mlflow/plugin.json index a358618f..a7ea75a5 100644 --- a/free/mlflow/plugin.json +++ b/free/mlflow/plugin.json @@ -1,6 +1,6 @@ { "name": "mlflow", - "version": "1.0.0", + "version": "1.2.1", "description": "MLflow experiment tracking and model registry", "author": "nself", "license": "MIT", diff --git a/free/model/plugin.json b/free/model/plugin.json index 9550a1cd..fac7ad44 100644 --- a/free/model/plugin.json +++ b/free/model/plugin.json @@ -1,6 +1,6 @@ { "name": "model", - "version": "1.0.0", + "version": "1.2.1", "description": "Manage local AI models via Ollama: list, pull, remove, update, benchmark, plus the legacy `ollama` command tree.", "author": "nself", "license": "MIT", diff --git a/free/monitor/plugin.json b/free/monitor/plugin.json index 69f6e12b..6120ac4d 100644 --- a/free/monitor/plugin.json +++ b/free/monitor/plugin.json @@ -1,6 +1,6 @@ { "name": "monitor", - "version": "1.0.0", + "version": "1.2.1", "description": "Monitoring stack management: upgrade the bundled Grafana dashboards.", "author": "nself", "license": "MIT", @@ -43,5 +43,5 @@ "required": [], "optional": [] }, - "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install monitor` must place the built nself-monitor binary at ~/.nself/plugins/bin/nself-monitor, where internal/plugin/router.go's ProxyCommand execs it for `nself monitor ` with stdio inherited. Extracted from cli/cmd/commands/monitor.go under CLI-R11 (the command had no internal/* package of its own \u2014 the dashboard list was inline)." + "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install monitor` must place the built nself-monitor binary at ~/.nself/plugins/bin/nself-monitor, where internal/plugin/router.go's ProxyCommand execs it for `nself monitor ` with stdio inherited. Extracted from cli/cmd/commands/monitor.go under CLI-R11 (the command had no internal/* package of its own — the dashboard list was inline)." } diff --git a/free/monitoring/plugin.json b/free/monitoring/plugin.json index bc14756c..19bdc460 100644 --- a/free/monitoring/plugin.json +++ b/free/monitoring/plugin.json @@ -1,6 +1,6 @@ { "name": "monitoring", - "version": "1.0.0", + "version": "1.2.1", "description": "Full monitoring stack: Prometheus, Grafana, Loki, Promtail, Tempo, Alertmanager, and exporters", "author": "nself", "license": "MIT", diff --git a/free/notifications/plugin.json b/free/notifications/plugin.json index 80c6cf8f..b7bd85e0 100644 --- a/free/notifications/plugin.json +++ b/free/notifications/plugin.json @@ -1,6 +1,6 @@ { "name": "notifications", - "version": "1.0.0", + "version": "1.2.1", "description": "Email notification service (SMTP). Push and SMS channels are always-error placeholders — they accept requests but return 501 Not Implemented. Use the 'notify' plugin for real push notifications. Deprecated since v1.1.0; replacement: notify.", "author": "nself", "license": "MIT", @@ -80,7 +80,9 @@ "replacedBy": "notify", "removal_target": "v2.0.0", "status": "deprecated", - "capabilities": ["email"], + "capabilities": [ + "email" + ], "binary_name": "notifications", "health_endpoint": "/health", "arch_support": [ diff --git a/free/notify/plugin.json b/free/notify/plugin.json index c6472ac4..04bddbf7 100644 --- a/free/notify/plugin.json +++ b/free/notify/plugin.json @@ -1,6 +1,6 @@ { "name": "notify", - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-channel notification service. Channels: Email (SMTP), Webhook (HMAC-signed). HTTP endpoints for sending notifications, managing templates, and viewing delivery history.", "author": "nself", "license": "MIT", diff --git a/free/nself-cloud/plugin.json b/free/nself-cloud/plugin.json index a8933cb9..79858e48 100644 --- a/free/nself-cloud/plugin.json +++ b/free/nself-cloud/plugin.json @@ -1,6 +1,6 @@ { "name": "nself-cloud", - "version": "0.1.0", + "version": "1.2.1", "api_version": "1.0.0", "description": "ɳCloud managed hosting infrastructure: tenant lifecycle, server provisioning saga, Stripe metered billing, custom domain management, and team memberships for cloud.nself.org.", "author": "nSelf Team", @@ -108,7 +108,7 @@ "method": "POST", "path": "/api/cloud/login", "auth": "none", - "description": "Email+password or magic link \u2014 returns JWT." + "description": "Email+password or magic link — returns JWT." }, { "method": "GET", @@ -181,7 +181,7 @@ "path": "/webhooks/stripe", "auth": "none", "hmac": "STRIPE_PLATFORM_WEBHOOK_SECRET", - "description": "Stripe platform webhook \u2014 HMAC verified, raw body required." + "description": "Stripe platform webhook — HMAC verified, raw body required." }, { "method": "POST", diff --git a/free/nself-eval-gate/plugin.json b/free/nself-eval-gate/plugin.json index 992f7e07..b55c2941 100644 --- a/free/nself-eval-gate/plugin.json +++ b/free/nself-eval-gate/plugin.json @@ -1,6 +1,6 @@ { "name": "nself-eval-gate", - "version": "1.0.0", + "version": "1.2.1", "api_version": "1.0.0", "description": "Eval harness and autonomy-tier gate for nSelf. Three-mode scoring (exact, semantic via BGE-M3, rubric via LLM-as-judge), recall-quality precision/recall/fact_f1 metrics, CI integration via nself ci eval, and autonomy-tier threshold enforcement.", "author": "nself", diff --git a/free/nself-geo/plugin.json b/free/nself-geo/plugin.json index 2ebee4cb..4a544956 100644 --- a/free/nself-geo/plugin.json +++ b/free/nself-geo/plugin.json @@ -1,6 +1,6 @@ { "name": "nself-geo", - "version": "1.1.0", + "version": "1.2.1", "api_version": "1.0.0", "description": "Forward and reverse geocoding with provider-agnostic caching layer. Nominatim (free, OSM) is the default; Google Places and Mapbox are premium fallbacks. Exposes geocodeAddress, reverseGeocode, geocodeBatch, clearGeoCache via Hasura Remote Schema.", "author": "nself", diff --git a/free/nself-image/plugin.json b/free/nself-image/plugin.json index 28cdc048..db894dec 100644 --- a/free/nself-image/plugin.json +++ b/free/nself-image/plugin.json @@ -1,6 +1,6 @@ { "name": "nself-image", - "version": "0.1.0", + "version": "1.2.1", "api_version": "1.1.0", "description": "Server-side image processing plugin for nSelf: resize, crop, format conversion (WebP/AVIF/JPEG/PNG), EXIF strip, and MinIO-integrated upload pipeline. Replaces per-app Sharp/Node.js usage across nFamily, nChat, and any consumer app needing image normalization.", "author": "nSelf Team", diff --git a/free/nself-pdf/plugin.json b/free/nself-pdf/plugin.json index 5f51b28b..532b88a6 100644 --- a/free/nself-pdf/plugin.json +++ b/free/nself-pdf/plugin.json @@ -3,7 +3,7 @@ "author": "nSelf Team", "minNselfVersion": "1.0.0", "display_name": "PDF Generation", - "version": "0.1.0", + "version": "1.2.1", "language": "go", "bundle": "shared", "visibility": "public", diff --git a/free/nself-scan/plugin.json b/free/nself-scan/plugin.json index 2f017480..140ca0ba 100644 --- a/free/nself-scan/plugin.json +++ b/free/nself-scan/plugin.json @@ -3,7 +3,7 @@ "author": "nSelf Team", "minNselfVersion": "1.0.0", "display_name": "File Virus & Content Scanning", - "version": "0.1.0", + "version": "1.2.1", "language": "go", "bundle": [ "nFamily", @@ -14,7 +14,7 @@ "tier": "free", "port": 3829, "service_type": "custom_service", - "description": "Server-side file scanning for MinIO uploads: magic-byte MIME validation, ClamAV virus/malware scanning (always free, Security-Always-Free Doctrine), and optional CSAM hash detection (deferred \u2014 requires partner agreement)", + "description": "Server-side file scanning for MinIO uploads: magic-byte MIME validation, ClamAV virus/malware scanning (always free, Security-Always-Free Doctrine), and optional CSAM hash detection (deferred — requires partner agreement)", "category": "security", "license": "MIT", "min_nself_version": "1.1.0", @@ -78,7 +78,7 @@ "SCAN-CSAM-02", "SCAN-PERF-01" ], - "csam_note": "CSAM hash detection disabled by default. Requires operator partner agreement (Microsoft PhotoDNA or NCMEC). Not a bundle add-on. See SPEC.md \u00a714.", + "csam_note": "CSAM hash detection disabled by default. Requires operator partner agreement (Microsoft PhotoDNA or NCMEC). Not a bundle add-on. See SPEC.md §14.", "checksum": "2a8943610ddd543293f398437a371290485e6d27c3d8feb034d5f813f0670018", "bundles": [ "nsentry" diff --git a/free/nself-sync/plugin.json b/free/nself-sync/plugin.json index 6aff4174..cc4b43ad 100644 --- a/free/nself-sync/plugin.json +++ b/free/nself-sync/plugin.json @@ -2,7 +2,7 @@ "name": "nself-sync", "author": "nSelf Team", "displayName": "Event-Log Sync Engine for ɳClaw", - "version": "1.1.2", + "version": "1.2.1", "tier": "free", "category": "infrastructure", "minNselfVersion": "1.1.1", diff --git a/free/nself-vault/plugin.json b/free/nself-vault/plugin.json index 12fe360b..3e94a476 100644 --- a/free/nself-vault/plugin.json +++ b/free/nself-vault/plugin.json @@ -2,7 +2,7 @@ "name": "nself-vault", "author": "nSelf Team", "displayName": "Per-Row Encryption (Vault)", - "version": "1.0.0", + "version": "1.2.1", "tier": "free", "category": "security", "minNselfVersion": "1.0.0", diff --git a/free/object-storage/plugin.json b/free/object-storage/plugin.json index 1f7725ef..6febd665 100644 --- a/free/object-storage/plugin.json +++ b/free/object-storage/plugin.json @@ -1,6 +1,6 @@ { "name": "object-storage", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Multi-provider object storage with S3-compatible API, local storage, presigned URLs, and multipart uploads", "author": "nself", diff --git a/free/observability/plugin.json b/free/observability/plugin.json index 55589212..7ce33705 100644 --- a/free/observability/plugin.json +++ b/free/observability/plugin.json @@ -1,6 +1,6 @@ { "name": "observability", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Unified observability service with health probes, watchdog timers, service auto-discovery, and systemd integration", "author": "nself", diff --git a/free/ollama/plugin.json b/free/ollama/plugin.json index 552ca3b3..db31ac31 100644 --- a/free/ollama/plugin.json +++ b/free/ollama/plugin.json @@ -1,6 +1,6 @@ { "name": "ollama", - "version": "1.1.1", + "version": "1.2.1", "api_version": "1.0.0", "description": "One-click offline LLM stack. Stands up an Ollama Docker container, auto-pulls gemma-3-4b on first start, and registers as a provider in plugin-ai. All nSelf AI features route through Ollama when NSELF_AI_PROVIDER=ollama. Zero cloud dependency, zero API key, zero usage cost after install. GPU passthrough is optional and localhost-only (port 11434 binds to 127.0.0.1 — never exposed externally).", "author": "nself", diff --git a/free/payments/plugin.json b/free/payments/plugin.json index 1837a69a..0eb534a3 100644 --- a/free/payments/plugin.json +++ b/free/payments/plugin.json @@ -1,6 +1,6 @@ { "name": "payments", - "version": "1.0.0", + "version": "1.2.1", "api_version": "1.0.0", "description": "Unified payments abstraction supporting Stripe, PayPal, and Apple/Google Pay with webhook normalization.", "author": "nself", diff --git a/free/paypal/plugin.json b/free/paypal/plugin.json index 7fa2b775..8acd9ff3 100644 --- a/free/paypal/plugin.json +++ b/free/paypal/plugin.json @@ -1,6 +1,6 @@ { "name": "paypal", - "version": "1.0.0", + "version": "1.2.1", "description": "PayPal payment data sync with webhook handling", "author": "nself", "license": "MIT", diff --git a/free/pentest-kit/plugin.json b/free/pentest-kit/plugin.json index 4ae76d58..6fc81327 100644 --- a/free/pentest-kit/plugin.json +++ b/free/pentest-kit/plugin.json @@ -1,6 +1,6 @@ { "name": "pentest-kit", - "version": "1.0.0", + "version": "1.2.1", "description": "CLI front end for the pentest plugin: generate scope documents, provision test credentials, import findings, and check remediation status. Business+ tier.", "author": "nself", "license": "MIT", diff --git a/free/pentest/plugin.json b/free/pentest/plugin.json index 0e529010..1aa2656e 100644 --- a/free/pentest/plugin.json +++ b/free/pentest/plugin.json @@ -1,7 +1,7 @@ { "name": "pentest", - "version": "1.1.2", - "description": "Penetration-test readiness kit. Generates structured scope documents, provisions pentest credentials, tracks findings, and manages remediation. FREE \u2014 Security-Always-Free Doctrine.", + "version": "1.2.1", + "description": "Penetration-test readiness kit. Generates structured scope documents, provisions pentest credentials, tracks findings, and manages remediation. FREE — Security-Always-Free Doctrine.", "author": "nself", "license": "MIT", "isCommercial": false, diff --git a/free/plugin-clawde/plugin.json b/free/plugin-clawde/plugin.json index c443963d..305da4a5 100644 --- a/free/plugin-clawde/plugin.json +++ b/free/plugin-clawde/plugin.json @@ -1,6 +1,6 @@ { "name": "plugin-clawde", - "version": "0.1.0", + "version": "1.2.1", "description": "ClawDE daemon integration backend. Manages session lifecycle, tracks daemon health, and streams events via SSE for the ClawDE AI development environment.", "author": "nSelf", "license": "MIT", diff --git a/free/plugin-gauth/plugin.json b/free/plugin-gauth/plugin.json index 4bb46674..870ba2b2 100644 --- a/free/plugin-gauth/plugin.json +++ b/free/plugin-gauth/plugin.json @@ -1,6 +1,6 @@ { "name": "plugin-gauth", - "version": "0.1.0", + "version": "1.2.1", "description": "Headless server-side Google OAuth token refresh for nSelf AI services", "author": "nSelf", "license": "MIT", diff --git a/free/plugin-llm-gateway/plugin.json b/free/plugin-llm-gateway/plugin.json index 927d8358..a4247cde 100644 --- a/free/plugin-llm-gateway/plugin.json +++ b/free/plugin-llm-gateway/plugin.json @@ -1,6 +1,6 @@ { "name": "plugin-llm-gateway", - "version": "0.1.0", + "version": "1.2.1", "description": "ClawDE-facing LLM gateway: per-tenant token quota, Redis response caching, session context injection, and SSRF guard over nself-ai-gateway (port 3761). Simplifies ClawDE client LLM calls.", "author": "nSelf", "license": "MIT", diff --git a/free/plugin-pty/plugin.json b/free/plugin-pty/plugin.json index 8dbf8a52..93a45987 100644 --- a/free/plugin-pty/plugin.json +++ b/free/plugin-pty/plugin.json @@ -1,7 +1,7 @@ { "name": "plugin-pty", "display_name": "ɳSelf PTY Bridge", - "version": "1.0.0", + "version": "1.2.1", "description": "Pseudo-terminal bridge for ClawDE AI sessions. Spawns, manages, and relays PTY processes with per-tenant resource limits and WebSocket I/O.", "author": "nself-org", "license": "MIT", diff --git a/free/plugin-retrieval/plugin.json b/free/plugin-retrieval/plugin.json index 925cf9b8..251b8d5b 100644 --- a/free/plugin-retrieval/plugin.json +++ b/free/plugin-retrieval/plugin.json @@ -1,6 +1,6 @@ { "name": "plugin-retrieval", - "version": "0.1.0", + "version": "1.2.1", "description": "Hybrid retrieval plugin: pgvector ANN + tsvector BM25 merged with Reciprocal Rank Fusion (RRF). Provides the search backend for ɳClaw memory and nself-ai-mcp search/recall tools.", "author": "nSelf", "license": "MIT", diff --git a/free/podcast/plugin.json b/free/podcast/plugin.json index 04e7457b..58f6b1a3 100644 --- a/free/podcast/plugin.json +++ b/free/podcast/plugin.json @@ -1,6 +1,6 @@ { "name": "podcast", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Podcast service with RSS feed parsing, episode management, playback position sync, and subscription management", "author": "nself", diff --git a/free/post/plugin.json b/free/post/plugin.json index 28c997b0..ef97dd7c 100644 --- a/free/post/plugin.json +++ b/free/post/plugin.json @@ -1,6 +1,6 @@ { "name": "post", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Multi-platform content publishing. Publish to WordPress, Ghost, Twitter/X, LinkedIn, Telegram channels, Dev.to, and Hashnode with optional scheduling.", "author": "nself", diff --git a/free/push/plugin.json b/free/push/plugin.json index a4dae523..5723ec70 100644 --- a/free/push/plugin.json +++ b/free/push/plugin.json @@ -1,6 +1,6 @@ { "name": "push", - "version": "1.0.0", + "version": "1.2.1", "description": "APNs + FCM push notification relay. Hasura event-trigger fan-out, delivery state tracking, exponential backoff retry. Handles iOS (Apple Push Notification service) and Android (Firebase Cloud Messaging v1 API).", "author": "nself", "license": "MIT", @@ -26,7 +26,9 @@ "np_push_outbox", "np_push_devices" ], - "dependencies": {"redis": ">=1.0.0"}, + "dependencies": { + "redis": ">=1.0.0" + }, "optionalDependencies": [], "envVars": { "required": [ diff --git a/free/queue/plugin.json b/free/queue/plugin.json index 0a422e7e..e15dea61 100644 --- a/free/queue/plugin.json +++ b/free/queue/plugin.json @@ -1,6 +1,6 @@ { "name": "queue", - "version": "1.0.0", + "version": "1.2.1", "description": "Inspect and manage nSelf background job queues: depth, stuck jobs, retries and purges.", "author": "nself", "license": "MIT", diff --git a/free/region/plugin.json b/free/region/plugin.json index 11a94db8..b5e3ef6e 100644 --- a/free/region/plugin.json +++ b/free/region/plugin.json @@ -1,6 +1,6 @@ { "name": "region", - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-region management: add replica regions, list and inspect their status, and promote a region to primary.", "author": "nself", "license": "MIT", diff --git a/free/release/plugin.json b/free/release/plugin.json index 381e6c0e..dac08a1a 100644 --- a/free/release/plugin.json +++ b/free/release/plugin.json @@ -1,6 +1,6 @@ { "name": "release", - "version": "1.0.0", + "version": "1.2.1", "description": "Orchestrate the nSelf project's own 12-step release cascade: tag and release cli and plugins-pro, build and push the admin image, and open the Homebrew formula PR.", "author": "nself", "license": "MIT", diff --git a/free/retro-gaming/plugin.json b/free/retro-gaming/plugin.json index f47026cc..1c86e10a 100644 --- a/free/retro-gaming/plugin.json +++ b/free/retro-gaming/plugin.json @@ -1,6 +1,6 @@ { "name": "retro-gaming", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Retro gaming ROM library management, emulator core serving, save state synchronization, play sessions, and controller configuration for nself-tv", "author": "nself", diff --git a/free/rom-discovery/plugin.json b/free/rom-discovery/plugin.json index b11b00bd..1e5af264 100644 --- a/free/rom-discovery/plugin.json +++ b/free/rom-discovery/plugin.json @@ -1,6 +1,6 @@ { "name": "rom-discovery", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "ROM metadata database, search, discovery, automated download orchestration, and multi-source scraping for nself-tv", "author": "nself", diff --git a/free/search/plugin.json b/free/search/plugin.json index 2ae0f3c7..c25ecff0 100644 --- a/free/search/plugin.json +++ b/free/search/plugin.json @@ -1,6 +1,6 @@ { "name": "search", - "version": "1.0.0", + "version": "1.2.1", "description": "Full-text search engine with PostgreSQL FTS and MeiliSearch support", "author": "nself", "license": "MIT", @@ -109,4 +109,4 @@ "min_memory_mb": 64, "systemd_after": "network.target", "tier": "free" -} \ No newline at end of file +} diff --git a/free/sentry-cli/plugin.json b/free/sentry-cli/plugin.json index d8d13053..ed7765f0 100644 --- a/free/sentry-cli/plugin.json +++ b/free/sentry-cli/plugin.json @@ -1,6 +1,6 @@ { "name": "sentry-cli", - "version": "1.0.0", + "version": "1.2.1", "description": "ɳSentry operations: monitors, incidents, status pages, alerts, cloud login, and provisioning a self-hosted sentry server.", "author": "nself", "license": "MIT", diff --git a/free/shared-utils/plugin.json b/free/shared-utils/plugin.json index 5fc2d0b6..b5edc296 100644 --- a/free/shared-utils/plugin.json +++ b/free/shared-utils/plugin.json @@ -1,6 +1,6 @@ { "name": "shared-utils", - "version": "1.0.0", + "version": "1.2.1", "description": "Shared Go utilities (request-ID tracing middleware, HTTP client propagation, server lifecycle helpers) used internally by multiple free nself plugins. Not installable directly.", "author": "nself", "license": "MIT", @@ -10,9 +10,21 @@ "requires_license": false, "installable": false, "port": 0, - "tags": ["shared", "internal", "library"], - "multiApp": { "supported": false }, + "tags": [ + "shared", + "internal", + "library" + ], + "multiApp": { + "supported": false + }, "tables": [], - "dependencies": { "required": [], "optional": [] }, - "envVars": { "required": [], "optional": [] } + "dependencies": { + "required": [], + "optional": [] + }, + "envVars": { + "required": [], + "optional": [] + } } diff --git a/free/shopify/plugin.json b/free/shopify/plugin.json index d62ba1f9..db7f8052 100644 --- a/free/shopify/plugin.json +++ b/free/shopify/plugin.json @@ -1,6 +1,6 @@ { "name": "shopify", - "version": "1.0.0", + "version": "1.2.1", "description": "Shopify store, orders, and product synchronization", "author": "nself", "language": "go", diff --git a/free/siem/plugin.json b/free/siem/plugin.json index 5cae8ed8..3521517f 100644 --- a/free/siem/plugin.json +++ b/free/siem/plugin.json @@ -1,6 +1,6 @@ { "name": "siem", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.3.0", "description": "Forward nSelf audit logs and security events to external SIEM platforms: Datadog, Splunk HEC, Elastic, Loki, and custom webhooks. OCSF/ECS schema normalization.", "author": "nself", diff --git a/free/sms/plugin.json b/free/sms/plugin.json index a838efe2..5f799b35 100644 --- a/free/sms/plugin.json +++ b/free/sms/plugin.json @@ -1,6 +1,6 @@ { "name": "sms", - "version": "1.0.0", + "version": "1.2.1", "displayName": "plugin-sms", "description": "SMS messaging via Twilio. Send, track, and manage opt-outs.", "port": 9009, diff --git a/free/soak/plugin.json b/free/soak/plugin.json index a06b22e5..50a34928 100644 --- a/free/soak/plugin.json +++ b/free/soak/plugin.json @@ -1,6 +1,6 @@ { "name": "soak", - "version": "1.0.0", + "version": "1.2.1", "description": "Manage soak testing lifecycle: abort an active soak and roll back to a prior version.", "author": "nself", "license": "MIT", diff --git a/free/sports/plugin.json b/free/sports/plugin.json index 54ebccde..a8f50748 100644 --- a/free/sports/plugin.json +++ b/free/sports/plugin.json @@ -1,6 +1,6 @@ { "name": "sports", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Sports data plugin with storage for scores, schedules, and standings. Planned: Live data provider integration (ESPN, The Sports DB) for real-time scores and stats", "author": "nself", diff --git a/free/storage-transform/plugin.json b/free/storage-transform/plugin.json index ab63df20..26fd0bc9 100644 --- a/free/storage-transform/plugin.json +++ b/free/storage-transform/plugin.json @@ -1,6 +1,6 @@ { "name": "storage-transform", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "On-the-fly image transformation CDN: resize, crop, format convert (WebP/AVIF/JPEG/PNG), quality, and device-pixel-ratio support. URL-param driven, Redis LRU cache, Nginx cache headers, rate limiting.", "author": "nself", diff --git a/free/storage/plugin.json b/free/storage/plugin.json index 3332bfe5..cd838b58 100644 --- a/free/storage/plugin.json +++ b/free/storage/plugin.json @@ -1,6 +1,6 @@ { "name": "storage", - "version": "1.0.0", + "version": "1.2.1", "api_version": "1.0", "description": "S3-compatible file storage: bucket management, object PUT/GET/DELETE/LIST, presigned URLs, per-tenant isolation.", "author": "nself", diff --git a/free/stripe/plugin.json b/free/stripe/plugin.json index 5937ef86..101a3837 100644 --- a/free/stripe/plugin.json +++ b/free/stripe/plugin.json @@ -1,6 +1,6 @@ { "name": "stripe", - "version": "1.0.0", + "version": "1.2.1", "description": "Stripe billing data sync with webhook handling", "author": "nself", "license": "MIT", diff --git a/free/subtitle-manager/plugin.json b/free/subtitle-manager/plugin.json index bf50a845..44a4f7f2 100644 --- a/free/subtitle-manager/plugin.json +++ b/free/subtitle-manager/plugin.json @@ -1,6 +1,6 @@ { "name": "subtitle-manager", - "version": "1.0.0", + "version": "1.2.1", "description": "Subtitle search, download, and sync verification via OpenSubtitles", "author": "nself", "license": "MIT", diff --git a/free/tenant-controller/plugin.json b/free/tenant-controller/plugin.json index 24c355b5..5b46d0aa 100644 --- a/free/tenant-controller/plugin.json +++ b/free/tenant-controller/plugin.json @@ -1,6 +1,6 @@ { "name": "tenant-controller", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.3.0", "description": "Multi-tenant master controller for nCloud. Manages N isolated nSelf project instances behind a single deploy: per-project Postgres schema, Hasura metadata namespace, Nginx vhost, JWT secret, Redis key prefix, and MinIO bucket. Enables 50 projects on one Hetzner CX21.", "author": "nself", diff --git a/free/tenant/plugin.json b/free/tenant/plugin.json index 6e6da5c8..5b1f16f1 100644 --- a/free/tenant/plugin.json +++ b/free/tenant/plugin.json @@ -1,6 +1,6 @@ { "name": "tenant", - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-tenant operations: create, suspend, upgrade and destroy tenants, plus per-tenant usage metering and billing reports.", "author": "nself", "license": "MIT", diff --git a/free/tmdb/plugin.json b/free/tmdb/plugin.json index b16d4e09..008d0b25 100644 --- a/free/tmdb/plugin.json +++ b/free/tmdb/plugin.json @@ -1,6 +1,6 @@ { "name": "tmdb", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Comprehensive media metadata enrichment from TMDB/IMDb/TVDB/MusicBrainz with auto-matching, manual review queue, and multi-provider support", "author": "nself", diff --git a/free/tokens/plugin.json b/free/tokens/plugin.json index bb541410..d0016366 100644 --- a/free/tokens/plugin.json +++ b/free/tokens/plugin.json @@ -1,6 +1,6 @@ { "name": "tokens", - "version": "1.0.0", + "version": "1.2.1", "description": "Secure content delivery tokens, HLS encryption key management, and entitlement checks", "author": "nself", "license": "MIT", diff --git a/free/torrent-manager/plugin.json b/free/torrent-manager/plugin.json index 53d7d34b..ccaf8ec1 100644 --- a/free/torrent-manager/plugin.json +++ b/free/torrent-manager/plugin.json @@ -1,6 +1,6 @@ { "name": "torrent-manager", - "version": "1.0.0", + "version": "1.2.1", "description": "Torrent downloading with Transmission/qBittorrent integration, multi-source search, seeding policies, and VPN enforcement", "author": "nself", "license": "MIT", diff --git a/free/transactional-email/plugin.json b/free/transactional-email/plugin.json index 77dfa967..a36660f6 100644 --- a/free/transactional-email/plugin.json +++ b/free/transactional-email/plugin.json @@ -1,6 +1,6 @@ { "name": "transactional-email", - "version": "1.1.0", + "version": "1.2.1", "api_version": "1.0", "description": "Provider-agnostic transactional email: template rendering, per-tenant domain management, SPF/DKIM reporting, delivery webhook relay.", "author": "nself", diff --git a/free/vpn/plugin.json b/free/vpn/plugin.json index d04f1f34..cd25fe9c 100644 --- a/free/vpn/plugin.json +++ b/free/vpn/plugin.json @@ -1,6 +1,6 @@ { "name": "vpn", - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-provider VPN management (NordVPN, PIA, Mullvad) with P2P optimization, server carousel, kill switch, and leak protection. Torrent download forwarding requires the torrent-manager plugin.", "author": "nself", "license": "MIT", diff --git a/free/waf/plugin.json b/free/waf/plugin.json index 0548840a..56b436fd 100644 --- a/free/waf/plugin.json +++ b/free/waf/plugin.json @@ -1,6 +1,6 @@ { "name": "waf", - "version": "1.0.0", + "version": "1.2.1", "description": "Web Application Firewall management: enable Coraza with the OWASP Core Rule Set, switch between detection and blocking mode, and review recent WAF events.", "author": "nself", "license": "MIT", diff --git a/free/warehouse/plugin.json b/free/warehouse/plugin.json index 979a1c1c..0c354540 100644 --- a/free/warehouse/plugin.json +++ b/free/warehouse/plugin.json @@ -1,8 +1,8 @@ { "name": "warehouse", - "version": "1.0.0", + "version": "1.2.1", "api_version": "1.0.0", - "description": "Data warehouse sync \u2014 exports nself table data to BigQuery, Snowflake, or Redshift on a configurable schedule.", + "description": "Data warehouse sync — exports nself table data to BigQuery, Snowflake, or Redshift on a configurable schedule.", "author": "nself", "license": "MIT", "isCommercial": false, diff --git a/free/watchdog/plugin.json b/free/watchdog/plugin.json index fd90a47f..9ae1b362 100644 --- a/free/watchdog/plugin.json +++ b/free/watchdog/plugin.json @@ -1,6 +1,6 @@ { "name": "watchdog", - "version": "1.0.0", + "version": "1.2.1", "description": "Self-healing container watchdog with circuit breaker: status, resets, event history, and TG/email escalation alerts.", "author": "nself", "license": "MIT", @@ -58,5 +58,5 @@ "required": [], "optional": [] }, - "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install watchdog` must place the built nself-watchdog binary at ~/.nself/plugins/bin/nself-watchdog, where internal/plugin/router.go's ProxyCommand execs it for `nself watchdog ` with stdio inherited. Extracted from cli/cmd/commands/watchdog.go and cli/internal/watchdog/ under CLI-R11. internal/watchdog depended on internal/health.DockerClient (a Docker-CLI shell-exec adapter), which lives in a file cli/cmd/commands/start.go also uses and therefore could not move \u2014 so this plugin reimplements that narrow adapter (docker ps/inspect/restart) locally in internal/watchdog/docker.go rather than forking internal/health's health-check engine. internal/watchdog's escalation.go also used internal/httptimeout, replaced with an inline *http.Client at the same 30s default." + "notes": "This is a CLI-proxy plugin, not a service plugin: it has no port, no HTTP server, and no database tables. `nself plugin install watchdog` must place the built nself-watchdog binary at ~/.nself/plugins/bin/nself-watchdog, where internal/plugin/router.go's ProxyCommand execs it for `nself watchdog ` with stdio inherited. Extracted from cli/cmd/commands/watchdog.go and cli/internal/watchdog/ under CLI-R11. internal/watchdog depended on internal/health.DockerClient (a Docker-CLI shell-exec adapter), which lives in a file cli/cmd/commands/start.go also uses and therefore could not move — so this plugin reimplements that narrow adapter (docker ps/inspect/restart) locally in internal/watchdog/docker.go rather than forking internal/health's health-check engine. internal/watchdog's escalation.go also used internal/httptimeout, replaced with an inline *http.Client at the same 30s default." } diff --git a/free/web3/plugin.json b/free/web3/plugin.json index fe0f74b5..35afe062 100644 --- a/free/web3/plugin.json +++ b/free/web3/plugin.json @@ -1,6 +1,6 @@ { "name": "web3", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Blockchain integration, NFT support, token-gated access, DAO governance, and decentralized identity", "author": "nself", diff --git a/free/webhooks/plugin.json b/free/webhooks/plugin.json index 79f94d8f..835d2710 100644 --- a/free/webhooks/plugin.json +++ b/free/webhooks/plugin.json @@ -1,6 +1,6 @@ { "name": "webhooks", - "version": "1.0.0", + "version": "1.2.1", "description": "Outbound webhook delivery service with retry logic, HMAC signing, and dead-letter queue", "author": "nself", "license": "MIT", diff --git a/free/workflows/plugin.json b/free/workflows/plugin.json index 8d27e604..b3fdf466 100644 --- a/free/workflows/plugin.json +++ b/free/workflows/plugin.json @@ -1,6 +1,6 @@ { "name": "workflows", - "version": "1.1.2", + "version": "1.2.1", "api_version": "1.0.0", "description": "Automation engine providing trigger-action workflow chains, conditional logic, scheduled tasks, webhook integrations, and cross-plugin orchestration", "author": "nself", diff --git a/registry-schema.json b/registry-schema.json index 867452d3..268d1f3c 100644 --- a/registry-schema.json +++ b/registry-schema.json @@ -270,7 +270,22 @@ "type": "object", "description": "Legacy/nested checksum record. NOT read by any known CLI code path (verified against nself-org/cli internal/, 2026-09) — kept for tooling that may still reference it and must stay equal to the flat `checksum` field above.", "properties": { - "sha256": { "type": "string" } + "sha256": { + "type": "string", + "description": "SHA-256 of the source tarball -.tar.gz. Duplicates the top-level `checksum` field." + }, + "platforms": { + "type": "object", + "description": "SHA-256 checksums of the five per-platform binary tarballs (--.tar.gz), one per key. Present only for plugins with a binaryName (implementation.binaryName or the flat binaryName field) — internal/plugin/download.go tries this asset before the source tarball whenever binaryName is set, and internal/plugin/security.go refuses the install if the matching entry here is absent, so an entry is required for every platform that plugin actually ships. Keys MUST be exactly the platform strings internal/plugin/arch.go's PlatformArch() returns; values are plain lowercase hex sha256, no 'sha256:' prefix (unlike the sibling `sha256` field above, which some writers prefix — the CLI compares platform checksums with a raw hex equality check).", + "properties": { + "darwin-arm64": { "type": "string", "pattern": "^[0-9a-f]{64}$" }, + "darwin-amd64": { "type": "string", "pattern": "^[0-9a-f]{64}$" }, + "linux-amd64": { "type": "string", "pattern": "^[0-9a-f]{64}$" }, + "linux-arm64": { "type": "string", "pattern": "^[0-9a-f]{64}$" }, + "windows-amd64": { "type": "string", "pattern": "^[0-9a-f]{64}$" } + }, + "additionalProperties": false + } } }, "tarballUrl": { diff --git a/registry.json b/registry.json index d5e472bc..32b4d6d3 100644 --- a/registry.json +++ b/registry.json @@ -8,13 +8,13 @@ "note": "nSelf Free Plugin Registry — 60 MIT-licensed plugins.", "plugins": { "ai-cli": { - "version": "1.0.0", + "version": "1.2.1", "description": "AI operations for nSelf: chat, local Ollama model management, and Gemini API key pool provisioning and rotation.", "category": "automation", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/ai-cli-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/ai-cli-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/ai-cli/tarball", "requires_license": false, "language": "go", @@ -37,16 +37,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-ai" + }, + "releaseTag": "v1.2.1", + "checksum": "5d8bce9d80fac57c2912ce2f61dcb461b79659708ce3080f72f59ee0419e5e8b", + "checksums": { + "sha256": "5d8bce9d80fac57c2912ce2f61dcb461b79659708ce3080f72f59ee0419e5e8b", + "platforms": { + "darwin-arm64": "3c5687010cecb95fac74cc099dfa40e861bec9bc6db296df2136dd286102405c", + "darwin-amd64": "f09699e679ec95a1dd4b0e43ca7300d2ef380cdc3146e41f3251d574a38b73df", + "linux-amd64": "ad2c47cb0763c493959ea42094d3a74152bbec5f1800d3b11e47dd406a3da9ff", + "linux-arm64": "eacdabe4bb7d6c5c098f39256037fc9cfba7e64d49ae719daadd6f12b973ce54", + "windows-amd64": "eebc395738b5b2c99014b0e59c2fc56963e5a70373cc030f67a6fa27ce492a84" + } } }, "ai-studio": { - "version": "1.0.0", + "version": "1.2.1", "description": "Google AI Studio integration for local nSelf instances via a secure Cloudflare Tunnel.", "category": "integrations", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/ai-studio-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/ai-studio-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/ai-studio/tarball", "requires_license": false, "language": "go", @@ -67,16 +79,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-ai-studio" + }, + "releaseTag": "v1.2.1", + "checksum": "322bbccd08a298202f4032102654e6d8511df87a69d97d6af2be75ce2ee0b198", + "checksums": { + "sha256": "322bbccd08a298202f4032102654e6d8511df87a69d97d6af2be75ce2ee0b198", + "platforms": { + "darwin-arm64": "2c9bfaba7462d5bed7eb962160b9955dc940ba4364e15d04d0fec7f809a388c0", + "darwin-amd64": "4cad8160bad0b21ff2ebaf2f6cfac66aec6ce32d125494cfc444673e7fd094c9", + "linux-amd64": "994666d6f80aa52fa94d9a5bab9a92cd2ffe2aa092abecaf89a8772a20a58b30", + "linux-arm64": "d3ec888c5043c6623f52fd76c5ec315a8b21e2034d616bcebf68c51b1c9355a4", + "windows-amd64": "c1daf80e5a1c2e2bbbb8d03a65bff9d9174a8a90c3b7822ceb473a2e18ee339b" + } } }, "alerts": { - "version": "1.0.0", + "version": "1.2.1", "description": "Manage Prometheus alert rules and Alertmanager silences: list, silence, and send synthetic test alerts.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/alerts-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/alerts-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/alerts/tarball", "requires_license": false, "language": "go", @@ -98,16 +122,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-alerts" + }, + "releaseTag": "v1.2.1", + "checksum": "9ec0a307eda1b50f741bf748fa8dce695f0dda302271710f621ae010faea7184", + "checksums": { + "sha256": "9ec0a307eda1b50f741bf748fa8dce695f0dda302271710f621ae010faea7184", + "platforms": { + "darwin-arm64": "6c99a15e613dcb34e6168c7db78851142985bccc58cbf42c365efac58a4eff23", + "darwin-amd64": "3b06082098cebb4fce74e2ed50e75ab0749bf04ecd942bf0ada9793943c6a7d2", + "linux-amd64": "39aa3f7b186839b0c2d615dc1b25bac2ce37c1a312180d40da18b8f65aebddeb", + "linux-arm64": "485a6a4241cc551bd4f18ccbec199453c42afbe8a0b2a8805cd62ed62f706e08", + "windows-amd64": "28e8522de5fb8637e89697b6228a96c3826fe98b41c9d7884584fd5e5890e645" + } } }, "api": { - "version": "1.0.0", + "version": "1.2.1", "description": "Inspect the nSelf plugin API surface: endpoint probes, deprecation calendar, and the API changelog.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/api-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/api-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/api/tarball", "requires_license": false, "language": "go", @@ -128,16 +164,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-api" + }, + "releaseTag": "v1.2.1", + "checksum": "2ac834a3264a1c877b525f07eea4c9777c566be9915745432207c02cf7090cff", + "checksums": { + "sha256": "2ac834a3264a1c877b525f07eea4c9777c566be9915745432207c02cf7090cff", + "platforms": { + "darwin-arm64": "43c25e1bbcbc159da14c4c7f4fd0b4e4ef1e2aaf6a1055035b9af42ec147c546", + "darwin-amd64": "2e6aa55310ac8996ac48420cdaaeab7322e068001f8b98fee6133dbe3787c5a4", + "linux-amd64": "08ca39730a98b4978f55bc0edba367350a9ced6f9242269f875f72b30f927175", + "linux-arm64": "bb56793bc586f82a7aae885273a7841c0f43990ecb4f1a9ddc1537aa09758f02", + "windows-amd64": "d760a3596320705c80651e829de6a360ad201bf21c662b50da1a5ad8e5a6066c" + } } }, "audit": { - "version": "1.0.0", + "version": "1.2.1", "description": "Ecosystem documentation audit: banned words, dead links, and missing anchors across READMEs, wiki, docs, SPORT, PPI, and PRI.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/audit-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/audit-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/audit/tarball", "requires_license": false, "language": "go", @@ -158,16 +206,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-audit" + }, + "releaseTag": "v1.2.1", + "checksum": "450fc7fb249560e46d3b83873ce97dd2046f521515e323e881b7a82a081c4f9a", + "checksums": { + "sha256": "450fc7fb249560e46d3b83873ce97dd2046f521515e323e881b7a82a081c4f9a", + "platforms": { + "darwin-arm64": "12f5056cd57d0d0c0761dc3386aa9cd3bad098a312ff7717af00e95d55ab349d", + "darwin-amd64": "11aec83f998a2992eb36c0db0a28eef243015721e7a8dfad8c32dbdf226b148c", + "linux-amd64": "ab7156d092d9c36099f7dce658be489976e7301cb44156227d48f3612b6bf748", + "linux-arm64": "7556aa206ff903a226111ccc66f6e5f09fa71eb5295c012e9c3b11c70cf1d531", + "windows-amd64": "024757e38a7e6c600ccb0c23c56177ed29f8ca5edcb4a56ca4508cc91fd5a86a" + } } }, "audit-log": { - "version": "1.0.0", + "version": "1.2.1", "description": "Append-only audit log for security-relevant events: auth, privilege change, secret access, plugin install/uninstall. Queryable from Admin with filters by event type, actor, severity, and time range.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/audit-log-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/audit-log-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/audit-log/tarball", "requires_license": false, "language": "go", @@ -189,16 +249,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "29c963c02da01691c8fab7793289df9f3587e3bef4a580ae1eac52fef9cdf5b2", + "checksums": { + "sha256": "29c963c02da01691c8fab7793289df9f3587e3bef4a580ae1eac52fef9cdf5b2" } }, "backup": { - "version": "1.0.0", + "version": "1.2.1", "description": "PostgreSQL backup and restore automation with scheduling", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/backup-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/backup-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/backup/tarball", "requires_license": false, "language": "go", @@ -221,16 +286,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main" + }, + "releaseTag": "v1.2.1", + "checksum": "4f63a2c5a203c6024ee1fd4b742b78e158f60af9d67a17a65cab1b1bc2ea00d7", + "checksums": { + "sha256": "4f63a2c5a203c6024ee1fd4b742b78e158f60af9d67a17a65cab1b1bc2ea00d7" } }, "ci": { - "version": "1.0.1", + "version": "1.2.1", "description": "Local CI gate runner: detects repo stack (Go/Node/Flutter/Dart), runs lint+test+build, scans secrets with gitleaks, then posts a GitHub commit status (nself-ci) via gh OAuth. Replaces billing-blocked GitHub Actions as the merge gate.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/ci-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/ci-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/ci/tarball", "requires_license": false, "language": "go", @@ -253,16 +323,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "14e42744db3afa80b0693371f46ce02c3dea91683eaf735839bcae7760f23aa2", + "checksums": { + "sha256": "14e42744db3afa80b0693371f46ce02c3dea91683eaf735839bcae7760f23aa2" } }, "claw-cli": { - "version": "1.0.0", + "version": "1.2.1", "description": "CLI client for the nClaw AI assistant: prompt, chat, pairing, keys, memories, topics, sessions, MCP server, OpenAI-compatible proxy, and schema migrations.", "category": "integrations", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/claw-cli-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/claw-cli-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/claw-cli/tarball", "requires_license": false, "language": "go", @@ -284,16 +359,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-claw" + }, + "releaseTag": "v1.2.1", + "checksum": "fda0dbe768b3317d5692d007f7f1e2853668ab1a7f25bb7e33fa7c7c9f8a418d", + "checksums": { + "sha256": "fda0dbe768b3317d5692d007f7f1e2853668ab1a7f25bb7e33fa7c7c9f8a418d", + "platforms": { + "darwin-arm64": "d96e1ab5928c45d5594ffc60ee690951c22bd37fcf76ab92d539c6455f60d5c0", + "darwin-amd64": "6ff90642a3d18c8165bf92856584d014def34fe16b6baabb76604bf888163b82", + "linux-amd64": "589742d390eb81ca04b803db46b8342e85f7dc6de0389b018b7a5c2766bd302f", + "linux-arm64": "603d8859579ba5b6227a409313d5295d2e5455bf87916766f830e2a2c468f34f", + "windows-amd64": "abffbca7caa3499110289601d5ff1f5180a6147b8dddd2566e1e9792008c9616" + } } }, "content-acquisition": { - "version": "1.0.0", + "version": "1.2.1", "description": "Content acquisition with download rules engine. Planned: RSS feed monitoring, release calendar integration, automated download orchestration", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/content-acquisition-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/content-acquisition-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/content-acquisition/tarball", "requires_license": false, "language": "go", @@ -340,16 +427,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "2cf3425a4788534364067fc00465d1e35f932088d0ecf8d81c81b0b1da82ca31", + "checksums": { + "sha256": "2cf3425a4788534364067fc00465d1e35f932088d0ecf8d81c81b0b1da82ca31" } }, "content-progress": { - "version": "1.0.0", + "version": "1.2.1", "description": "Track video, audio, and content playback progress with continue watching, watchlists, and favorites", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/content-progress-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/content-progress-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/content-progress/tarball", "requires_license": false, "language": "go", @@ -376,16 +468,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" - } + }, + "checksum": "d74f9d89b48ceaed53f73ec5e201041a239482ac69d29cc02ec7c5a5e6127501", + "checksums": { + "sha256": "d74f9d89b48ceaed53f73ec5e201041a239482ac69d29cc02ec7c5a5e6127501" + }, + "releaseTag": "v1.2.1" }, "costs": { - "version": "1.0.0", + "version": "1.2.1", "description": "Show estimated per-install operational costs: Hetzner VPS, Cloudflare, Vercel, Stripe fees, and installed paid plugin licenses.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/costs-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/costs-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/costs/tarball", "requires_license": false, "language": "go", @@ -405,16 +502,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-costs" + }, + "releaseTag": "v1.2.1", + "checksum": "7a763a4205afd8315061fb8b8a723c34f38f90fe66cacd4e2065b4fd3c233b89", + "checksums": { + "sha256": "7a763a4205afd8315061fb8b8a723c34f38f90fe66cacd4e2065b4fd3c233b89", + "platforms": { + "darwin-arm64": "e1c557b28fbf8d64113b19f675dc73be1d27689bf2427b003dd206e2046aa75b", + "darwin-amd64": "427334120d315034e79a98ec14ba37aa0842bc14fb435a712bd95b748f03a0da", + "linux-amd64": "21e108234ba639dbb395c7a8226a3c166079441cea1097a5fb2b3285645d57f4", + "linux-arm64": "32530453e23a84759a416c96155fe759af10dbc814be2a4de39b838823cff0db", + "windows-amd64": "350510e8461ce3e6f7deece14163ac55e329c40ccd6176df407b7eca940b54c3" + } } }, "cron": { - "version": "1.0.0", + "version": "1.2.1", "description": "Cron job scheduler. Register jobs with standard cron syntax, execute via HTTP callbacks, track run history.", "category": "automation", "tier": "free", "license": "MIT", "min_nself_version": "0.9.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/cron-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/cron-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/cron/tarball", "requires_license": false, "tier_pair": true, @@ -438,16 +547,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" - } + }, + "checksum": "fd1d114767aedede617ece8ae72b8237177dad38d6121384b94b7bc881cf8420", + "checksums": { + "sha256": "fd1d114767aedede617ece8ae72b8237177dad38d6121384b94b7bc881cf8420" + }, + "releaseTag": "v1.2.1" }, "dlq": { - "version": "1.0.0", + "version": "1.2.1", "description": "Manage dead-letter queues for nSelf plugins: re-enqueue rows that failed processing back to the work queue, with safe row limits and dry-run preview.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/dlq-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/dlq-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/dlq/tarball", "requires_license": false, "language": "go", @@ -469,16 +583,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-dlq" + }, + "releaseTag": "v1.2.1", + "checksum": "ec1310beb970106b0902134441b6910c2217e3816e801584eb6aca11bfe7cb5c", + "checksums": { + "sha256": "ec1310beb970106b0902134441b6910c2217e3816e801584eb6aca11bfe7cb5c", + "platforms": { + "darwin-arm64": "baa953b92c4d14220d01241920dc3d8388b30dbcd7341538e9c5afd68b76515c", + "darwin-amd64": "2f2a90f8a01934fbd8ce743ab46f1525dfe1006b8907225a33fa1e20e2a01d8c", + "linux-amd64": "0b8eb5377d99e55383ce485ba1c46b8de5263620b871f10da3e1f916749fee6f", + "linux-arm64": "bf32e542335329949174d45e3e5a2a2d667ad79dcde390ea3b0efba38f1b3075", + "windows-amd64": "d4525b9a91ded889078b0a8db7072210133fc42a10218f18cf5737cad7e60497" + } } }, "dogfood": { - "version": "1.0.0", + "version": "1.2.1", "description": "Production dogfood audit and reporting: 21 read-only checks covering backups, DR, tenancy, licensing, secrets, migrations, monitoring, security, watchdog, and queue health.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/dogfood-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/dogfood-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/dogfood/tarball", "requires_license": false, "language": "go", @@ -500,16 +626,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-dogfood" + }, + "releaseTag": "v1.2.1", + "checksum": "2db55540508ec2e372f3637746b592992949474a2b4c3ebec9a38c6a5fd7c4fc", + "checksums": { + "sha256": "2db55540508ec2e372f3637746b592992949474a2b4c3ebec9a38c6a5fd7c4fc", + "platforms": { + "darwin-arm64": "8e5185c456697874f825130e68db8f11654c5d5dd1df819a5075318a2cc25b2f", + "darwin-amd64": "2da0bd5c4e9fb614866d228aadeeeaebfeedf1c69fd6a66296fda0bd7126b09a", + "linux-amd64": "5e02fc20aca6966d4914950753e7d70a59af03069d4001695738e547e534c9ff", + "linux-arm64": "afb00da5c318b8acc9c88fa7aba99a680b2e60706f0b15285bde80fb32c40ee4", + "windows-amd64": "8f3e7d0ac00c3abce4f0c93114e03d75bdd62f8420ae3124b8df5a07882ba991" + } } }, "donorbox": { - "version": "1.0.0", + "version": "1.2.1", "description": "Donorbox donation data sync with webhook handling", "category": "commerce", "tier": "free", "license": "MIT", "min_nself_version": "0.9.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/donorbox-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/donorbox-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/donorbox/tarball", "requires_license": false, "language": "go", @@ -537,16 +675,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" - } + }, + "checksum": "7b6b2a862085cfe34591d19f1fc8bfd8b8c586fb554c328e8e9d03032efa7a5d", + "checksums": { + "sha256": "7b6b2a862085cfe34591d19f1fc8bfd8b8c586fb554c328e8e9d03032efa7a5d" + }, + "releaseTag": "v1.2.1" }, "dr": { - "version": "1.0.0", + "version": "1.2.1", "description": "Disaster recovery: promote a standby, fence the old primary, run drills, and install the systemd units DR needs.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/dr-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/dr-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/dr/tarball", "requires_license": false, "language": "go", @@ -568,16 +711,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-dr" + }, + "releaseTag": "v1.2.1", + "checksum": "50fc6cc42d137615071ef00ceaf8c8a4ccc5bf5ec7be09aa531575815a800c02", + "checksums": { + "sha256": "50fc6cc42d137615071ef00ceaf8c8a4ccc5bf5ec7be09aa531575815a800c02", + "platforms": { + "darwin-arm64": "66c247eb4aeb9c3ca52166c37241bb2ca340039c3416040e106af48a51e37104", + "darwin-amd64": "fbeac561ad222ce0ece064eef5bd40bc74f81074d755b5d3b41b3a9018f658b1", + "linux-amd64": "a501f350a087da762e89e7f2034270693f07257deb3d8f59c641c86dcbdb5348", + "linux-arm64": "fd99b15917f3c53882f044b3474154368c2b607c6943c20e1b1e0633e766be54", + "windows-amd64": "d279e2d418b045a866ef664e9968f124d31db8b32ab33b897a91b173de98a397" + } } }, "e2ee": { - "version": "1.0.0", + "version": "1.2.1", "description": "End-to-end encryption key directory: X3DH prekey distribution + Kyber-1024 (ML-KEM-1024) post-quantum prekeys for nchat. Server stores PUBLIC keys only; private keys never leave the client.", "category": "authentication", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/e2ee-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/e2ee-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/e2ee/tarball", "requires_license": false, "language": "go", @@ -611,16 +766,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "7bd6f7db7718cd769f2e185c1ee59326f3f70229d4e7c75a144effc80870302d", + "checksums": { + "sha256": "7bd6f7db7718cd769f2e185c1ee59326f3f70229d4e7c75a144effc80870302d" } }, "family-gedcom": { - "version": "0.0.1", + "version": "1.2.1", "description": "Generic GEDCOM file importer for the family plugin (PLANNED). Accepts any GEDCOM 5.5.1 / 7.0 file from any provider, with optional photo-folder upload. Free MIT plugin — showcases the core + helper-importer pattern.", "category": "content", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.0.1/family-gedcom-0.0.1.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/family-gedcom-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/family-gedcom/tarball", "requires_license": false, "language": "go", @@ -644,16 +804,21 @@ "language": "go", "runtime": "go", "entryPoint": "binary" + }, + "releaseTag": "v1.2.1", + "checksum": "00fd7d24c6459bcfb757cc9d51d5f07b0a190ddd74823d29292d1766ddcf3297", + "checksums": { + "sha256": "00fd7d24c6459bcfb757cc9d51d5f07b0a190ddd74823d29292d1766ddcf3297" } }, "feature-flags": { - "version": "1.0.0", + "version": "1.2.1", "description": "Feature flags service with targeting rules, segments, and evaluation engine", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/feature-flags-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/feature-flags-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/feature-flags/tarball", "requires_license": false, "language": "go", @@ -676,16 +841,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "a0e76608fd08d1b3b1a12c4e990ad6b8dee61c26bfc34a40a5b622eee4ee23b9", + "checksums": { + "sha256": "a0e76608fd08d1b3b1a12c4e990ad6b8dee61c26bfc34a40a5b622eee4ee23b9" } }, "federation": { - "version": "1.0.0", + "version": "1.2.1", "description": "Manage GraphQL Federation: compose an Apollo Router supergraph from installed plugin subgraphs, check subgraph health, and introspect the composed schema.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/federation-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/federation-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/federation/tarball", "requires_license": false, "language": "go", @@ -707,16 +877,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-federation" + }, + "releaseTag": "v1.2.1", + "checksum": "49b20ce3e8b1610177037c3203a13e67ce74937a9cb93c8215c6ca5df3cf6e37", + "checksums": { + "sha256": "49b20ce3e8b1610177037c3203a13e67ce74937a9cb93c8215c6ca5df3cf6e37", + "platforms": { + "darwin-arm64": "40bf742f304f4771c5d574ed257549d3035de1e9a8d9ad35f6f936b6378e23ee", + "darwin-amd64": "281a6fa9f3006b0e84e1d3db6f69f3053b9d0c22e5de10e222991422a36813e4", + "linux-amd64": "d1696402ffebc834635c398a72ec301e5a1561b78e0dea2ff583660b299f24df", + "linux-arm64": "e28a7075fe83433d12bf3b14cc9c060e9f0367f11ef86abd13431e5a463c7662", + "windows-amd64": "c409afc20f7f3f0aa09d9f21190c80db24bafc3c28aa352dcaed60402221da8a" + } } }, "flags": { - "version": "1.0.0", + "version": "1.2.1", "description": "Manage feature flags served by the feature-flags plugin: list, get, set, history, canary rollouts and kill switches.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/flags-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/flags-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/flags/tarball", "requires_license": false, "language": "go", @@ -737,16 +919,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-flags" + }, + "releaseTag": "v1.2.1", + "checksum": "cc83fd76d0bcf9ba2ef981b5f86d7e61e32a4c2014e82080267bc13433b4dd56", + "checksums": { + "sha256": "cc83fd76d0bcf9ba2ef981b5f86d7e61e32a4c2014e82080267bc13433b4dd56", + "platforms": { + "darwin-arm64": "e42c33ac1d7161a2a5e2b5134a6492018808a8e1074e39fb117adb2652ffacb2", + "darwin-amd64": "2b01840568d763d95be95003a96e8a68a6e55058b381a79a7c4fdcd5e5959ef1", + "linux-amd64": "f82ef4460e9d96fc8883785325a4c48873de18bf866e439c0fa5a0acf3b19059", + "linux-arm64": "fdfe2c9b4792bb1c3e18811ae0ddf8d48d8a8425033264d8245e72a675aa29ad", + "windows-amd64": "5c67c99342c8e03b18b8ae6b6a9815faaff24d92446defce17e7ea304c3060bb" + } } }, "forgejo": { - "version": "1.0.0", + "version": "1.2.1", "description": "Self-hosted Forgejo git forge + Forgejo Actions runner. Provides offline CI that executes .github/workflows/*.yml YAML on self-hosted compute — zero GitHub Actions quota consumed. Designed for the ops profile (ops server on staging/prod).", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.1.1", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/forgejo-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/forgejo-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/forgejo/tarball", "requires_license": false, "language": "config", @@ -770,16 +964,21 @@ "language": "shell", "runtime": "docker", "entryPoint": "docker-compose.plugin.yml" + }, + "releaseTag": "v1.2.1", + "checksum": "0eb602a748df90687a9b949db12cbe5a6b39c84d4598274779c1b8a5b827b21f", + "checksums": { + "sha256": "0eb602a748df90687a9b949db12cbe5a6b39c84d4598274779c1b8a5b827b21f" } }, "gateway": { - "version": "1.0.0", + "version": "1.2.1", "description": "Manage the nSelf AI gateway (nself-ai-gateway, port 3761): service health, provider key vault, quota usage, and routing rules.", "category": "integrations", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/gateway-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/gateway-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/gateway/tarball", "requires_license": false, "language": "go", @@ -800,16 +999,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-gateway" + }, + "releaseTag": "v1.2.1", + "checksum": "84716057a7122967772f48889ed722974efe51715999e325e38a12766175556c", + "checksums": { + "sha256": "84716057a7122967772f48889ed722974efe51715999e325e38a12766175556c", + "platforms": { + "darwin-arm64": "589f52cb8894481679934dcacb740e556887628d9b948d4ca08558dedc410448", + "darwin-amd64": "9d8e079ec1f31a61ae27fdcde724e561bb2c69f27dbaf3657e08e04ce13cecec", + "linux-amd64": "2726129207cbee5cc4d8499774e9d76b98d6d494d8185f054dd9a6e95d148521", + "linux-arm64": "0a3fe72f0271b161943f929cfaf37d4c8ecd6af1154653b4227ab36d906fcb5f", + "windows-amd64": "8792f9393c8718936c9fe65e64fe03e383aee8ac34be553f70864970dceee1cd" + } } }, "gauth": { - "version": "1.0.0", + "version": "1.2.1", "description": "Manage Google OAuth tokens for nSelf AI services: status, refresh, and revoke against plugin-gauth.", "category": "integrations", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/gauth-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/gauth-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/gauth/tarball", "requires_license": false, "language": "go", @@ -830,16 +1041,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-gauth" + }, + "releaseTag": "v1.2.1", + "checksum": "aab9055409bb391fd76704a251d33665caab9f2a0623581604278b9c492a161e", + "checksums": { + "sha256": "aab9055409bb391fd76704a251d33665caab9f2a0623581604278b9c492a161e", + "platforms": { + "darwin-arm64": "b33aa4b68e9f838223f69fddd9e44ed317c4ebd08a7a2fc9e7b32385b49b6adc", + "darwin-amd64": "d2f1c6bee6dd25c6e355a7d5c16b55e685e5bbb073a9f5497fa17772f39668af", + "linux-amd64": "dd8205a2ff9fc4ad90a8d3d30d329def5216413ed54915b7cafff13db25903ec", + "linux-arm64": "dcc6357ba23e59ef089be7f6686b3d867d660c458e0f42f276a1e97fc4cde64c", + "windows-amd64": "eec873e83b810497d5a30233d0746da04c6744b7fe8d8c2139167fbe30bf8aa2" + } } }, "gdpr": { - "version": "1.0.0", + "version": "1.2.1", "description": "GDPR data portability (Art. 20) and right-to-erasure (Art. 17) tools for self-hosted nSelf instances.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/gdpr-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/gdpr-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/gdpr/tarball", "requires_license": false, "language": "go", @@ -862,16 +1085,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-gdpr" + }, + "releaseTag": "v1.2.1", + "checksum": "84e43aee22db62992a983059cedf531e5ab10b07bfd71af55ac62c6a14f470c4", + "checksums": { + "sha256": "84e43aee22db62992a983059cedf531e5ab10b07bfd71af55ac62c6a14f470c4", + "platforms": { + "darwin-arm64": "f087fb4de45a531593d9f0152d9724c2cbae8025f343ec9c543b2acc884a4de3", + "darwin-amd64": "f4daa6e7f575672dc8fa506d2f547b3739c4cf34f09b03583d2b745cfe9ac0b4", + "linux-amd64": "1f3bba453d5667a46acdaa738a9b017296f3f35ddc96763dfdcaec0615af0afd", + "linux-arm64": "a39cf8f9163709cbb321f371cb283d2f4f7fa431b3002c51f2de2124dc84d68a", + "windows-amd64": "249498c5b282148c344ca19613a1e47db864616b6d42b1b49217a7ce1868ee07" + } } }, "github": { - "version": "1.0.0", + "version": "1.2.1", "description": "GitHub repository, issue, and workflow integration", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/github-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/github-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/github/tarball", "requires_license": false, "language": "go", @@ -916,16 +1151,21 @@ "language": "go", "runtime": "go", "entryPoint": "nself-github" + }, + "releaseTag": "v1.2.1", + "checksum": "a16375697c2971fbb72f7619696f8682348c0eead09fe33827e816d1831e0ca9", + "checksums": { + "sha256": "a16375697c2971fbb72f7619696f8682348c0eead09fe33827e816d1831e0ca9" } }, "github-runner": { - "version": "1.0.0", + "version": "1.2.1", "description": "GitHub Actions self-hosted runner. Registers with your GitHub org and picks up CI jobs tagged `runs-on: ubuntu-latest` — enabling private repos to run CI without GitHub-hosted runners.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/github-runner-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/github-runner-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/github-runner/tarball", "requires_license": false, "language": "go", @@ -947,16 +1187,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "db307e5fd0857c2d16af9002b7f740a2f8348f55fed3e6893d9fce68fd908bd4", + "checksums": { + "sha256": "db307e5fd0857c2d16af9002b7f740a2f8348f55fed3e6893d9fce68fd908bd4" } }, "infra": { - "version": "1.0.0", + "version": "1.2.1", "description": "Provision nSelf infrastructure with Terraform: plan, apply and destroy modules for aws, gcp, azure, hetzner, do and linode.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/infra-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/infra-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/infra/tarball", "requires_license": false, "language": "go", @@ -981,16 +1226,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-infra" + }, + "releaseTag": "v1.2.1", + "checksum": "4994b5799c9ae9e6cd89d59f9921cd552cd5270d8fd52102a8cab26672db6879", + "checksums": { + "sha256": "4994b5799c9ae9e6cd89d59f9921cd552cd5270d8fd52102a8cab26672db6879", + "platforms": { + "darwin-arm64": "67c8cf445938b18a9362d48418b15a315d6f2414aa33c7751bae0c504a3ebee5", + "darwin-amd64": "0b351ce379f7a7bfcaed52c24349105d8e9b0d0202e73684304ccb32680a5e74", + "linux-amd64": "aad7a6410ed19bf406369750de5289c0ffb179170a2731a1cdb510c89585b732", + "linux-arm64": "09350027570bc7a896dd0eae27da5bb27901f7303eae48bc16f72cb9c66dac21", + "windows-amd64": "5984954c1c61121e5041434ca3d0283381c3a9599437600b7e7a39f8fde1f965" + } } }, "invitations": { - "version": "1.0.0", + "version": "1.2.1", "description": "Invitation management system with email/SMS delivery and tracking", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/invitations-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/invitations-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/invitations/tarball", "requires_license": false, "language": "go", @@ -1013,16 +1270,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "0007c353120e003b5a10c564be065f3e3ede58c211cf80be4bb7f0cb0f23f0a9", + "checksums": { + "sha256": "0007c353120e003b5a10c564be065f3e3ede58c211cf80be4bb7f0cb0f23f0a9" } }, "jobs": { - "version": "1.0.0", + "version": "1.2.1", "description": "PostgreSQL-backed background job queue with priorities, scheduling, retries, and REST API. Simplified Go implementation using database polling instead of Redis/BullMQ.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "0.9.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/jobs-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/jobs-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/jobs/tarball", "requires_license": false, "language": "go", @@ -1046,16 +1308,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "5149e099cb9746235176853ebb08952b3cdee6394f5b434b21612b1c7752c75b", + "checksums": { + "sha256": "5149e099cb9746235176853ebb08952b3cdee6394f5b434b21612b1c7752c75b" } }, "k8s": { - "version": "1.0.0", + "version": "1.2.1", "description": "Deploy and manage nSelf on any Kubernetes cluster via the official Helm chart: install, upgrade, and status commands wrapping helm.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/k8s-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/k8s-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/k8s/tarball", "requires_license": false, "language": "go", @@ -1077,16 +1344,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-k8s" + }, + "releaseTag": "v1.2.1", + "checksum": "3458454eb5d6f3f918fea51b4f0676994d860dd79da8769fae99f73be78492b2", + "checksums": { + "sha256": "3458454eb5d6f3f918fea51b4f0676994d860dd79da8769fae99f73be78492b2", + "platforms": { + "darwin-arm64": "ba86cf228c9cc43520d3e890ac33c4c76309f98386400a4859d5773f9d780932", + "darwin-amd64": "961c0d941f748745969e57d1ac67e0ae4a6b968fe7c58207c569e3e3c7892359", + "linux-amd64": "1faa10fcd6b2f99d3100e6adcc39fd6e62d9b0eb77bf35538b0ad97c187964d9", + "linux-arm64": "734b340b1fc43e0bb3b69a18ebb3e1808cbd61d20f39b42785fb9efc70aa5a5f", + "windows-amd64": "784aeb198d2b2ade2515f40704ed41d43bee269027e5055ab37f09182ca1c8c1" + } } }, "link-preview": { - "version": "1.0.0", + "version": "1.2.1", "description": "URL metadata extraction with Open Graph, Twitter Cards, and caching", "category": "content", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/link-preview-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/link-preview-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/link-preview/tarball", "requires_license": false, "language": "go", @@ -1109,16 +1388,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "8939955cafdfef1743985078a3a193854f93da47b203ce38e041bbb83a50c92d", + "checksums": { + "sha256": "8939955cafdfef1743985078a3a193854f93da47b203ce38e041bbb83a50c92d" } }, "maintenance": { - "version": "1.0.0", + "version": "1.2.1", "description": "Maintenance utilities: disk cleanup, log rotation and the maintenance scheduler.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/maintenance-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/maintenance-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/maintenance/tarball", "requires_license": false, "language": "go", @@ -1139,16 +1423,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-maintenance" - } + }, + "checksum": "d468014ea12b88bc1e2065d0d4879d1fe7cdd356e8f0bf74e9ab8b115c91ae87", + "checksums": { + "sha256": "d468014ea12b88bc1e2065d0d4879d1fe7cdd356e8f0bf74e9ab8b115c91ae87", + "platforms": { + "darwin-arm64": "1fef1d6fe8328134bda4e93a9dfef43f04b8c72b3910f84525d3e322940b0035", + "darwin-amd64": "40a8ce73eb38d942ec9b65198f07dd3044fc37d25ef2f6f8dfd6b88105bba2b5", + "linux-amd64": "e943796452602fc9f1d4ac07403e0a7e7018160bf0648bfa5d311dc32fda9b66", + "linux-arm64": "67089460c37789c9aa661711e90f5f6fcb93c9943a72339e2d39afc956a4973c", + "windows-amd64": "2c73233b6acbc6b0185965a0288917b496994671a0c25d590e6bb1ee1283a64e" + } + }, + "releaseTag": "v1.2.1" }, "mdns": { - "version": "1.0.0", + "version": "1.2.1", "description": "mDNS/Bonjour service discovery for zero-config LAN advertising", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/mdns-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/mdns-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/mdns/tarball", "requires_license": false, "language": "go", @@ -1171,16 +1467,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "69809c4431c073ba9e9227dea71d1f87fe29cdcf6368774fe6b993dc74fea106", + "checksums": { + "sha256": "69809c4431c073ba9e9227dea71d1f87fe29cdcf6368774fe6b993dc74fea106" } }, "mlflow": { - "version": "1.0.0", + "version": "1.2.1", "description": "MLflow experiment tracking and model registry", "category": "data", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/mlflow-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/mlflow-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/mlflow/tarball", "requires_license": false, "language": "go", @@ -1201,16 +1502,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "29ec27322ac8e24b3761422b2f3970e3ae50fdfe248157a41b68e34a2036c209", + "checksums": { + "sha256": "29ec27322ac8e24b3761422b2f3970e3ae50fdfe248157a41b68e34a2036c209" } }, "model": { - "version": "1.0.0", + "version": "1.2.1", "description": "Manage local AI models via Ollama: list, pull, remove, update, benchmark, plus the legacy ollama command tree.", "category": "integrations", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/model-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/model-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/model/tarball", "requires_license": false, "language": "go", @@ -1231,16 +1537,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-model" + }, + "releaseTag": "v1.2.1", + "checksum": "a618f1dd152cb7b81ed7b76b1036eb3f4837970e1e8d1b0dace62fffb3671a77", + "checksums": { + "sha256": "a618f1dd152cb7b81ed7b76b1036eb3f4837970e1e8d1b0dace62fffb3671a77", + "platforms": { + "darwin-arm64": "5bdd26917abbcae43bdd995710657dff8d388e3100b928a450a073400e600c6e", + "darwin-amd64": "ba6d765de85249661af777625b62789fdd8635e68f0596e0266db2eb99b220aa", + "linux-amd64": "60b563de03f2dbe8b39457c27f26dbc42ebe4ccaeefc7077d48280d77830a561", + "linux-arm64": "2e8ba35aac8d2efc17bce7a7f386a139c53c247d037bb29a7938fe4ad2813dc1", + "windows-amd64": "19d7a1e745958bf1e47a58d595a6ec2ea9bbf2d32e16451da067dd6a514ecf4a" + } } }, "monitor": { - "version": "1.0.0", + "version": "1.2.1", "description": "Monitoring stack management: upgrade the bundled Grafana dashboards.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/monitor-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/monitor-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/monitor/tarball", "requires_license": false, "language": "go", @@ -1262,16 +1580,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-monitor" + }, + "releaseTag": "v1.2.1", + "checksum": "9478bdb762a48af0edf4812833f38cfd83e18c688d22ca2e5f84a1e0ddfcd0e0", + "checksums": { + "sha256": "9478bdb762a48af0edf4812833f38cfd83e18c688d22ca2e5f84a1e0ddfcd0e0", + "platforms": { + "darwin-arm64": "60a5e68325ee243d087908fcf2719b77671780e552f8e3c6e61ae416537f5ea4", + "darwin-amd64": "3be57ed1a6641fa1478587dce95a2aa18c57062d3473c206dc70f15d1bf5fa3e", + "linux-amd64": "fc38bc30aba2516b4800bb93cbcdefa49b23b0ecc0af0717f52f66cadc4fdea2", + "linux-arm64": "7daa0c2ba22ea065fc4913e852242e0e10726d2c99b3b05b6c4bf24f53cfd0e3", + "windows-amd64": "4728958bdfaa9e569dfac6baf1e03ac632f5265437fbf3d260682ecc25c154c4" + } } }, "monitoring": { - "version": "1.0.0", + "version": "1.2.1", "description": "Full monitoring stack: Prometheus, Grafana, Loki, Promtail, Tempo, Alertmanager, and exporters", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/monitoring-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/monitoring-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/monitoring/tarball", "requires_license": false, "language": "config", @@ -1297,16 +1627,21 @@ "language": "config", "runtime": "compose", "entryPoint": "docker-compose.plugin.yml" + }, + "releaseTag": "v1.2.1", + "checksum": "7b5b0f49a758515f1da7ac11ea9250d58ad8f4f0f780279d5e20ca0fcc21bb1e", + "checksums": { + "sha256": "7b5b0f49a758515f1da7ac11ea9250d58ad8f4f0f780279d5e20ca0fcc21bb1e" } }, "notifications": { - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-channel notification service. Channels: Email (SMTP), Push (placeholder), SMS (placeholder). HTTP endpoints for sending notifications, managing templates, and user notification preferences.", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "0.9.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/notifications-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/notifications-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/notifications/tarball", "requires_license": false, "language": "go", @@ -1331,16 +1666,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" - } + }, + "checksum": "3bd65950cfc0e4a03362d3d4aa8b0c04086ed0650181462092a14921c387a399", + "checksums": { + "sha256": "3bd65950cfc0e4a03362d3d4aa8b0c04086ed0650181462092a14921c387a399" + }, + "releaseTag": "v1.2.1" }, "notify": { - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-channel notification service. Channels: Email (SMTP), Webhook (HMAC-signed). HTTP endpoints for sending notifications, managing templates, and viewing delivery history.", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "0.9.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/notify-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/notify-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/notify/tarball", "requires_license": false, "tier_pair": true, @@ -1363,16 +1703,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" - } + }, + "checksum": "ce8fefb861ef43622fd8833417de29feeeaa536e9d8dd0de7a02e2829fa0d94f", + "checksums": { + "sha256": "ce8fefb861ef43622fd8833417de29feeeaa536e9d8dd0de7a02e2829fa0d94f" + }, + "releaseTag": "v1.2.1" }, "ollama": { - "version": "1.1.1", + "version": "1.2.1", "description": "One-click offline LLM stack. Stands up an Ollama container, auto-pulls gemma-3-4b on first start, and registers as a provider in plugin-ai. All nSelf AI features route through Ollama when NSELF_AI_PROVIDER=ollama. Zero cloud dependency, zero API key, zero usage cost after install.", "category": "integrations", "tier": "free", "license": "Source-Available", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.1/ollama-1.1.1.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/ollama-1.2.1.tar.gz", "download_url": "https://ping.nself.org/plugins/ollama/download", "requires_license": false, "language": "go", @@ -1387,16 +1732,20 @@ ], "dependencies": [], "name": "ollama", - "checksum": "" + "checksum": "3369853a2b55ea87782d1144986ebabbbfbbf5b9757758d54eb9a9ef5591f08b", + "checksums": { + "sha256": "3369853a2b55ea87782d1144986ebabbbfbbf5b9757758d54eb9a9ef5591f08b" + }, + "releaseTag": "v1.2.1" }, "paypal": { - "version": "1.0.0", + "version": "1.2.1", "description": "PayPal payment data sync with webhook handling", "category": "commerce", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/paypal-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/paypal-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/paypal/tarball", "requires_license": false, "language": "go", @@ -1431,16 +1780,21 @@ "language": "go", "runtime": "go", "entryPoint": "nself-paypal" + }, + "releaseTag": "v1.2.1", + "checksum": "110e8472893855c8f6c4d6ef77c82fc8cd5e849a9d58b79cf16f6d7fd5126863", + "checksums": { + "sha256": "110e8472893855c8f6c4d6ef77c82fc8cd5e849a9d58b79cf16f6d7fd5126863" } }, "push": { - "version": "1.0.0", + "version": "1.2.1", "description": "APNs + FCM push notification relay. Hasura event-trigger fan-out, delivery state tracking, exponential backoff retry. Handles iOS (Apple Push Notification service) and Android (Firebase Cloud Messaging v1 API).", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/push-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/push-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/push/tarball", "requires_license": false, "language": "go", @@ -1467,16 +1821,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "e4b23cef0fb3887d51938ab21aa6100456d812d2635d4c59af0b4363c926a401", + "checksums": { + "sha256": "e4b23cef0fb3887d51938ab21aa6100456d812d2635d4c59af0b4363c926a401" } }, "queue": { - "version": "1.0.0", + "version": "1.2.1", "description": "Inspect and manage nSelf background job queues: depth, stuck jobs, retries and purges.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/queue-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/queue-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/queue/tarball", "requires_license": false, "language": "go", @@ -1497,16 +1856,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-queue" + }, + "releaseTag": "v1.2.1", + "checksum": "6bf30d6e0f8a7debe96d3c0d8f8b6ee7375d52ac4572b6f32780b91e0273326c", + "checksums": { + "sha256": "6bf30d6e0f8a7debe96d3c0d8f8b6ee7375d52ac4572b6f32780b91e0273326c", + "platforms": { + "darwin-arm64": "fb6de207e92af115151cb984f57b4ad660843dd61caa02b3071fc42d715a2d46", + "darwin-amd64": "18a1c5561c5d85ac6ba5459386c608164e173141f037292a8446e65657a8e98f", + "linux-amd64": "85eb88559ef1e8223672b295b35db7414575d693f1116d51556f3bc5d1f1cde9", + "linux-arm64": "66f248bec20afca52b9556c3139600ffb5258b15c60daa096de394b39b1af572", + "windows-amd64": "7bac24e8ca57ebb1d5d6808417607483e9609a5fd06e86c1c500215042d4374d" + } } }, "region": { - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-region management: add replica regions, list and inspect their status, and promote a region to primary.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/region-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/region-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/region/tarball", "requires_license": false, "language": "go", @@ -1528,16 +1899,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-region" + }, + "releaseTag": "v1.2.1", + "checksum": "b199110ab9cb94c74a9f6e62c0722f7e58ad12844e1baad30bde213fbdc2dae3", + "checksums": { + "sha256": "b199110ab9cb94c74a9f6e62c0722f7e58ad12844e1baad30bde213fbdc2dae3", + "platforms": { + "darwin-arm64": "dfbc4b2a54b37f543024c660838977ee719c7084240d473baf11783eb9639c3b", + "darwin-amd64": "461dc5e1b85fe836734fe5fd59c048a67fd8b68d18dc3a7fe0dc41597086021b", + "linux-amd64": "580f5f8e458225251f206d64c3e18a5815470d032fbd1f69bfad95f327f12c1f", + "linux-arm64": "2cce93e171cddccd1ac9c61572f2a35ab7ba6efabcd7e2b33540797bbbe19a71", + "windows-amd64": "dc9eaf76a086a14691ee120161def9c9eadbc9bf77b16322817f6edc70f6e03c" + } } }, "release": { - "version": "1.0.0", + "version": "1.2.1", "description": "Orchestrate the nSelf project's own 12-step release cascade: tag and release cli and plugins-pro, build and push the admin image, and open the Homebrew formula PR.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/release-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/release-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/release/tarball", "requires_license": false, "language": "go", @@ -1559,16 +1942,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-release" + }, + "releaseTag": "v1.2.1", + "checksum": "1bf4027c65d095a726570b335cbd84a40a4f4dd4938e4897bb23f76b52f57d26", + "checksums": { + "sha256": "1bf4027c65d095a726570b335cbd84a40a4f4dd4938e4897bb23f76b52f57d26", + "platforms": { + "darwin-arm64": "3b9e11ca0d0d57f91987830d0babdbff8ff5240d5f10b82dd33dc26bc8eca556", + "darwin-amd64": "c05388622e679ac98b489b41c502e0cbfe623206931a9ee1cbfbc6888653c1d2", + "linux-amd64": "b1411f544578e9dc87612778bc45941cd4a00828465f37aee4a6f0fa61dc79b9", + "linux-arm64": "c05132030073003b8af79ebcd79773b99ecbafbbbc10c8567857fce699a6f5bd", + "windows-amd64": "b834de5cf8fb0cbb0f706ebd39f0c9c1ab4db53c9d021c77c685b92c5a941212" + } } }, "search": { - "version": "1.0.0", + "version": "1.2.1", "description": "Full-text search engine with PostgreSQL FTS and MeiliSearch support", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "0.9.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/search-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/search-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/search/tarball", "requires_license": false, "language": "go", @@ -1598,16 +1993,21 @@ }, "bundles": [ "task" - ] + ], + "checksum": "022db9d01e5d3965b8621395748fa576f320cd09198f5f3f62f31258cf89bc41", + "checksums": { + "sha256": "022db9d01e5d3965b8621395748fa576f320cd09198f5f3f62f31258cf89bc41" + }, + "releaseTag": "v1.2.1" }, "sentry-cli": { - "version": "1.0.0", + "version": "1.2.1", "description": "ɳSentry operations: monitors, incidents, status pages, alerts, cloud login, and provisioning a self-hosted sentry server.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/sentry-cli-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/sentry-cli-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/sentry-cli/tarball", "requires_license": false, "language": "go", @@ -1640,16 +2040,28 @@ "name": "sentry-server", "description": "Provision and manage a self-hosted ɳSentry server" } - ] + ], + "releaseTag": "v1.2.1", + "checksum": "c40c0bc559a13df25b46ce6396c555a7f2edef7ed8943d5390ff3f85357e64df", + "checksums": { + "sha256": "c40c0bc559a13df25b46ce6396c555a7f2edef7ed8943d5390ff3f85357e64df", + "platforms": { + "darwin-arm64": "af9bb63fd89f349e4e00f9cbb1d18cb51f696460d6364d1159da5e65220981a6", + "darwin-amd64": "72e31bf43529c73c6c69c175ac0b8b2b00a135dc9a58015e5eade100a9963ae0", + "linux-amd64": "62e328002dd7402971df080636b0ec0b2d06df0691e53beb900b9314e5b7761b", + "linux-arm64": "a3e63cca12f2a6b45cb70a37216f5b31964c970c656a34987dec0c5a34e1881e", + "windows-amd64": "f59f1267d043219a354e7e7edd573cbb8a594b71d4f9a56ac40f7148b57e8ed0" + } + } }, "shopify": { - "version": "1.0.0", + "version": "1.2.1", "description": "Shopify store, orders, and product synchronization", "category": "commerce", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/shopify-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/shopify-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/shopify/tarball", "requires_license": false, "language": "go", @@ -1679,16 +2091,21 @@ "language": "go", "runtime": "go", "entryPoint": "nself-shopify" + }, + "releaseTag": "v1.2.1", + "checksum": "c5da83c169e8672330b9377fd654b41ab7e60e802b6f1fc4ce98c4f299a3de07", + "checksums": { + "sha256": "c5da83c169e8672330b9377fd654b41ab7e60e802b6f1fc4ce98c4f299a3de07" } }, "soak": { - "version": "1.0.0", + "version": "1.2.1", "description": "Manage soak testing lifecycle: abort an active soak and roll back to a prior version.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/soak-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/soak-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/soak/tarball", "requires_license": false, "language": "go", @@ -1709,16 +2126,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-soak" + }, + "releaseTag": "v1.2.1", + "checksum": "3958da4da9b2929e1c3e2f5fe0aaa0f705cc2b0c1dad15f79b5adc7bd866e96b", + "checksums": { + "sha256": "3958da4da9b2929e1c3e2f5fe0aaa0f705cc2b0c1dad15f79b5adc7bd866e96b", + "platforms": { + "darwin-arm64": "63eba62b2a2af02173f639662034b4d35a49fba00bc4d852e16cce71e0093257", + "darwin-amd64": "ce8b798caa20e3dc3c35a0d60faa10c12a03ec8255115d8740b9dfc66b5f145c", + "linux-amd64": "1fd80d6c57447413070be7ff1455d9e3717e1d986dbe5aea8891f8002429abf3", + "linux-arm64": "427c2e4825c5849c66a89cc2f6b2c3de91afcc3748cd7794ef06a75f593d7838", + "windows-amd64": "22a13cdc300111d5d6646106940a6caf8606cf38caa5d742f3962c45b55087dc" + } } }, "stripe": { - "version": "1.0.0", + "version": "1.2.1", "description": "Stripe billing data sync with webhook handling", "category": "commerce", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/stripe-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/stripe-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/stripe/tarball", "requires_license": false, "language": "go", @@ -1763,16 +2192,21 @@ "language": "go", "runtime": "go", "entryPoint": "nself-stripe" + }, + "releaseTag": "v1.2.1", + "checksum": "f766461fef712b04878d2019d3a6eebd2eb9be8c8d1c6541c3d3c6bd213a8ce1", + "checksums": { + "sha256": "f766461fef712b04878d2019d3a6eebd2eb9be8c8d1c6541c3d3c6bd213a8ce1" } }, "subtitle-manager": { - "version": "1.0.0", + "version": "1.2.1", "description": "Subtitle search, download, and sync verification via OpenSubtitles", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/subtitle-manager-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/subtitle-manager-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/subtitle-manager/tarball", "requires_license": false, "language": "go", @@ -1809,16 +2243,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "9bcddc4a5ad34e6caaa468d82b337b62d8b46dcb9d74f9ee226c2595e887b37a", + "checksums": { + "sha256": "9bcddc4a5ad34e6caaa468d82b337b62d8b46dcb9d74f9ee226c2595e887b37a" } }, "tenant": { - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-tenant operations: create, suspend, upgrade and destroy tenants, plus per-tenant usage metering and billing reports.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/tenant-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/tenant-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/tenant/tarball", "requires_license": false, "language": "go", @@ -1850,16 +2289,28 @@ "name": "billing", "description": "Per-tenant usage metering, invoices and billing reports" } - ] + ], + "releaseTag": "v1.2.1", + "checksum": "81a3019c764c19947aa20b1810062d9694acafe5579fd107e88f9a37194c84da", + "checksums": { + "sha256": "81a3019c764c19947aa20b1810062d9694acafe5579fd107e88f9a37194c84da", + "platforms": { + "darwin-arm64": "bc645193a521877379b36f45cee855b5999617e9914e72d5715d090ec4f314a4", + "darwin-amd64": "01c95f78ac85ac02c1c5e7cd8ccaa1aebc50aaff25285374a9044928736f446a", + "linux-amd64": "6a577b9dd4ba54768541eee0d50f4359879d6ee31cd1bf346143c7986a5a1594", + "linux-arm64": "84db957ee06a6b793f4d6de8d6812382bcab9444a28b3e443ca642dfb73de4b3", + "windows-amd64": "26f79656eada5b5334bb922667b1aebac0f73988fa511d93904351aa0505d6f4" + } + } }, "tokens": { - "version": "1.0.0", + "version": "1.2.1", "description": "Secure content delivery tokens, HLS encryption key management, and entitlement checks", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/tokens-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/tokens-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/tokens/tarball", "requires_license": false, "language": "go", @@ -1887,16 +2338,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "6e612a79e4decd181554b2b1d51873253c50b8232cbc916113fb8907d9c0133b", + "checksums": { + "sha256": "6e612a79e4decd181554b2b1d51873253c50b8232cbc916113fb8907d9c0133b" } }, "torrent-manager": { - "version": "1.0.0", + "version": "1.2.1", "description": "Torrent downloading with Transmission/qBittorrent integration, multi-source search, seeding policies, and VPN enforcement", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/torrent-manager-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/torrent-manager-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/torrent-manager/tarball", "requires_license": false, "language": "go", @@ -1945,16 +2401,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "f00d5213c05c2d4c35427437e1ee998107fb352b4c75386912e9e0fc9dc4cbd1", + "checksums": { + "sha256": "f00d5213c05c2d4c35427437e1ee998107fb352b4c75386912e9e0fc9dc4cbd1" } }, "vpn": { - "version": "1.0.0", + "version": "1.2.1", "description": "Multi-provider VPN management (NordVPN, PIA, Mullvad) with P2P optimization, server carousel, kill switch, and leak protection. Torrent download forwarding requires the torrent-manager plugin.", "category": "authentication", "tier": "free", "license": "MIT", "min_nself_version": "0.9.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/vpn-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/vpn-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/vpn/tarball", "requires_license": false, "language": "go", @@ -1983,16 +2444,21 @@ "language": "go", "runtime": "go", "entryPoint": "cmd/main.go" + }, + "releaseTag": "v1.2.1", + "checksum": "8eb838953889a7f3a3b5002b7f1ee2af22ea16a888a7e5171e1c1cc861b75346", + "checksums": { + "sha256": "8eb838953889a7f3a3b5002b7f1ee2af22ea16a888a7e5171e1c1cc861b75346" } }, "waf": { - "version": "1.0.0", + "version": "1.2.1", "description": "Web Application Firewall management: enable Coraza with the OWASP Core Rule Set, switch between detection and blocking mode, and review recent WAF events.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/waf-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/waf-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/waf/tarball", "requires_license": false, "language": "go", @@ -2014,16 +2480,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-waf" + }, + "releaseTag": "v1.2.1", + "checksum": "195ffabffc7529a0fb587fdd945907a398775a9e5befeb6eb9ff3b976234a764", + "checksums": { + "sha256": "195ffabffc7529a0fb587fdd945907a398775a9e5befeb6eb9ff3b976234a764", + "platforms": { + "darwin-arm64": "316bf389893ed8e06e55de71d456e3fa2b86696a67ea6cce9faf1843ed4b3c0d", + "darwin-amd64": "8048ecc9619d56cb41411a6d7e27b0c816f6fcf0c87b65c8bac9b6e1de449f7b", + "linux-amd64": "9fef314843ace6404425d13bf59d90066c7eb6057718a358354082d8e6417de6", + "linux-arm64": "1db9b97b6edd3329c03f8526a39ad064390e0bf14789c6d4e339b585562a9823", + "windows-amd64": "fc3da3b511acaf102a03488978519916200a1a08169aef9185ddae9151e1bf2a" + } } }, "watchdog": { - "version": "1.0.0", + "version": "1.2.1", "description": "Self-healing container watchdog with circuit breaker: status, resets, event history, and TG/email escalation alerts.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/watchdog-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/watchdog-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/watchdog/tarball", "requires_license": false, "language": "go", @@ -2045,16 +2523,28 @@ "entryPoint": "cmd/", "pluginType": "cli", "binaryName": "nself-watchdog" + }, + "releaseTag": "v1.2.1", + "checksum": "689f3a9dbb44c9092ca10b90a20e98e7964128daa5aaea57993842b79cc5b5c0", + "checksums": { + "sha256": "689f3a9dbb44c9092ca10b90a20e98e7964128daa5aaea57993842b79cc5b5c0", + "platforms": { + "darwin-arm64": "ba165c82d9651dc42044732d2adee06df0a96f0877cc235c4c4ccb04557e4dd7", + "darwin-amd64": "30a6a5e4b231c00f37343efea0e0e4b25885ec75945bdda7b20b06c1f12cb415", + "linux-amd64": "192c43e0a00841947a52bf794e2fdbce586b9ca24080d795c0210d5749c592e1", + "linux-arm64": "bfe9b24f669ac3b348ca62f165691c4d0ea635c7f00a10041529942f499b5441", + "windows-amd64": "1febc7701438fd6f875443b7b44969cd9751b2fed4f65693a2f95d409ced8005" + } } }, "webhooks": { - "version": "1.0.0", + "version": "1.2.1", "description": "Outbound webhook delivery service with retry logic, HMAC signing, and dead-letter queue", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "0.9.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/webhooks-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/webhooks-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/webhooks/tarball", "requires_license": false, "language": "go", @@ -2080,16 +2570,28 @@ }, "bundles": [ "task" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "cc1d3f53a5bc48c19403a5eba9ea8fd9be09a9445c112920cc37285d8ec43a79", + "checksums": { + "sha256": "cc1d3f53a5bc48c19403a5eba9ea8fd9be09a9445c112920cc37285d8ec43a79", + "platforms": { + "darwin-arm64": "952d8a79b643a26428a343453b939b1cf3ae85c01dd1e6d9ec9e06927333ca19", + "darwin-amd64": "b4a5379902b7abe25c12332de5032f55c66db1ed2dd35325dfe67a889022f62e", + "linux-amd64": "e5844b9b8f231c3a9892e98ae088e9da7a8184e731fc678157b2380a11fa92e0", + "linux-arm64": "122b0e89cfed1d2b60453100aad5c6a4d441494940a1f91d6edae64e5cd4d201", + "windows-amd64": "8602828883813a69c2c0d0e421af9620784996b3bc66ba81afcc25b9465d2d07" + } + } }, "access-controls": { - "version": "1.1.2", + "version": "1.2.1", "description": "Role-based and attribute-based access control (RBAC + ABAC) with policy engine", "category": "authentication", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/access-controls-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/access-controls-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/access-controls/tarball", "requires_license": false, "language": "go", @@ -2105,16 +2607,21 @@ "name": "access-controls", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "1b002b683499d312bc2819870252f18e8a82fd34f2792c408e04ab9798bcf865", + "checksums": { + "sha256": "1b002b683499d312bc2819870252f18e8a82fd34f2792c408e04ab9798bcf865" + } }, "admin-api": { - "version": "1.1.2", + "version": "1.2.1", "description": "Admin API service providing aggregated metrics, system health, session counts, storage breakdown, and real-time dashboard endpoints", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/admin-api-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/admin-api-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/admin-api/tarball", "requires_license": false, "language": "go", @@ -2129,16 +2636,21 @@ "name": "admin-api", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "b713febd954e8b1d4c42cb4d33ede85d29ce044e8d1449e49c7b2a425bbb14bb", + "checksums": { + "sha256": "b713febd954e8b1d4c42cb4d33ede85d29ce044e8d1449e49c7b2a425bbb14bb" + } }, "analytics": { - "version": "1.1.2", + "version": "1.2.1", "description": "Event tracking, counters, funnels, and quota management analytics engine", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/analytics-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/analytics-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/analytics/tarball", "requires_license": false, "language": "go", @@ -2153,16 +2665,21 @@ "name": "analytics", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "6155012ec0a9bdbfcc3461a8f33acd3482331d606829d7ac005eb8035f386c74", + "checksums": { + "sha256": "6155012ec0a9bdbfcc3461a8f33acd3482331d606829d7ac005eb8035f386c74" + } }, "audit-analytics": { - "version": "1.0.0", + "version": "1.2.1", "description": "Advanced audit analytics over np_audit_log: anomaly detection (z-score baseline), user behaviour heatmaps, privileged-action review queue, and webhook/email alerts.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/audit-analytics-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/audit-analytics-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/audit-analytics/tarball", "requires_license": false, "language": "go", @@ -2181,16 +2698,21 @@ "name": "audit-analytics", "author": "nself", "minNselfVersion": "1.0.9", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "e9d657cd268ac136d75b631cbf2d6342382e38d7afb7b11739410338a883c8ed", + "checksums": { + "sha256": "e9d657cd268ac136d75b631cbf2d6342382e38d7afb7b11739410338a883c8ed" + } }, "auth-enterprise": { - "version": "1.1.2", + "version": "1.2.1", "description": "MFA enforcement (TOTP + WebAuthn policy) and SSO via SAML 2.0 and OIDC for Google Workspace, Okta, and Microsoft Entra ID.", "category": "authentication", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/auth-enterprise-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/auth-enterprise-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/auth-enterprise/tarball", "requires_license": false, "language": "go", @@ -2199,16 +2721,21 @@ "name": "auth-enterprise", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "1a3b1c30aa0453d3b484fa13a9e7f41a47a8861c9e80b3a34f9030f267309394", + "checksums": { + "sha256": "1a3b1c30aa0453d3b484fa13a9e7f41a47a8861c9e80b3a34f9030f267309394" + } }, "byok": { - "version": "1.1.2", + "version": "1.2.1", "description": "Bring Your Own Key (BYOK) per-tenant encryption. Envelope encryption with customer-managed keys (CMK) via AWS KMS, GCP Cloud KMS, or HashiCorp Vault Transit. DEK wrapped by CMK. Satisfies HIPAA, FedRAMP High, FFIEC, and DORA key-control requirements. Enterprise-only.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/byok-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/byok-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/byok/tarball", "requires_license": false, "language": "go", @@ -2228,16 +2755,21 @@ "name": "byok", "author": "nself", "minNselfVersion": "1.0.9", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "60f45d3d2d6ea9bed83f41bec5048606eb6c7030f81710cb231e74d904cffe3c", + "checksums": { + "sha256": "60f45d3d2d6ea9bed83f41bec5048606eb6c7030f81710cb231e74d904cffe3c" + } }, "cdc": { - "version": "1.0.0", + "version": "1.2.1", "description": "Change Data Capture — streams Postgres WAL events to downstream consumers via webhooks or message queues.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/cdc-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/cdc-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/cdc/tarball", "requires_license": false, "language": "go", @@ -2252,16 +2784,21 @@ "name": "cdc", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "aff247dee48fffc154bd44599ffe066e8555f81f0227c94f0a1b255d374ffe09", + "checksums": { + "sha256": "aff247dee48fffc154bd44599ffe066e8555f81f0227c94f0a1b255d374ffe09" + } }, "cdn": { - "version": "1.1.2", + "version": "1.2.1", "description": "CDN management and integration plugin - cache purging, signed URLs. Planned: analytics sync from Cloudflare/BunnyCDN", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/cdn-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/cdn-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/cdn/tarball", "requires_license": false, "language": "go", @@ -2276,16 +2813,21 @@ "name": "cdn", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "be3187f70eea6b7633215c4d4ef554ac8b260896c9f3d334141d48eeab6d79d4", + "checksums": { + "sha256": "be3187f70eea6b7633215c4d4ef554ac8b260896c9f3d334141d48eeab6d79d4" + } }, "cloudflare": { - "version": "1.1.2", + "version": "1.2.1", "description": "Cloudflare zone, DNS, R2, cache, and analytics management", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/cloudflare-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/cloudflare-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/cloudflare/tarball", "requires_license": false, "language": "go", @@ -2301,16 +2843,21 @@ "name": "cloudflare", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "d1462d23b1b7091e216a130f84d7129a3851fdf1746e2e909b2c820c86a3aa48", + "checksums": { + "sha256": "d1462d23b1b7091e216a130f84d7129a3851fdf1746e2e909b2c820c86a3aa48" + } }, "compliance": { - "version": "1.1.2", + "version": "1.2.1", "description": "Comprehensive compliance and audit platform with GDPR/CCPA/HIPAA/SOC2/PCI management, DSARs, consent tracking, data retention, breach notification, immutable audit logging, SIEM integration, and compliance reporting", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/compliance-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/compliance-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/compliance/tarball", "requires_license": false, "language": "go", @@ -2335,16 +2882,21 @@ "name": "compliance", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "aacd8c24bcb48c4d704601ffaa4cda8959abf9f0677e67c0115d33816c7c5e66", + "checksums": { + "sha256": "aacd8c24bcb48c4d704601ffaa4cda8959abf9f0677e67c0115d33816c7c5e66" + } }, "content-safety": { - "version": "1.0.0", + "version": "1.2.1", "description": "Trust-safety evidence, legal holds, spam detection, raid protection, and abuse scoring", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/content-safety-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/content-safety-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/content-safety/tarball", "requires_license": false, "language": "go", @@ -2360,16 +2912,21 @@ "name": "content-safety", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "005a70b25d9830136ad8749461a4528cdfc72b538b60943a5558b8f4958e5d0c", + "checksums": { + "sha256": "005a70b25d9830136ad8749461a4528cdfc72b538b60943a5558b8f4958e5d0c" + } }, "crdt": { - "version": "1.1.2", + "version": "1.2.1", "description": "CRDT offline-first primitives. Self-hosted Yjs (y-websocket protocol) and automerge sync server with Postgres persistence. Drop-in replacement for Liveblocks/PartyKit with zero extra infra.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/crdt-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/crdt-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/crdt/tarball", "requires_license": false, "language": "go", @@ -2387,16 +2944,21 @@ "name": "crdt", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "e586d0f7ef211633dd8f39a634a909e9f5cc50f32c1a9b8cb09dff848f59c9b2", + "checksums": { + "sha256": "e586d0f7ef211633dd8f39a634a909e9f5cc50f32c1a9b8cb09dff848f59c9b2" + } }, "ddns": { - "version": "1.1.2", + "version": "1.2.1", "description": "Dynamic DNS plugin with external IP monitoring. Planned: DNS provider API integration (Cloudflare, Route53) for automated record updates", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/ddns-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/ddns-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/ddns/tarball", "requires_license": false, "language": "go", @@ -2412,16 +2974,21 @@ "name": "ddns", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "e9c005f824810e59a74e67eca02a19a5c4504a50a656ed14b9454276bfc0796e", + "checksums": { + "sha256": "e9c005f824810e59a74e67eca02a19a5c4504a50a656ed14b9454276bfc0796e" + } }, "devices": { - "version": "1.1.2", + "version": "1.2.1", "description": "IoT device enrollment, trust management, and command dispatch service.", "category": "streaming", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/devices-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/devices-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/devices/tarball", "requires_license": false, "language": "go", @@ -2437,16 +3004,21 @@ "name": "devices", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "58fdcd29b130f84d4fe276f85f01dce8f79ff19045be9d473b5f9527037c142c", + "checksums": { + "sha256": "58fdcd29b130f84d4fe276f85f01dce8f79ff19045be9d473b5f9527037c142c" + } }, "documents": { - "version": "1.1.2", + "version": "1.2.1", "description": "Document management and generation service with templates, versioning, and sharing", "category": "data", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/documents-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/documents-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/documents/tarball", "requires_license": false, "language": "go", @@ -2462,16 +3034,21 @@ "name": "documents", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "cd6925df104e0cd87aa26050aa1d1ad1fb8b22d81921e516ef231a858aecd926", + "checksums": { + "sha256": "cd6925df104e0cd87aa26050aa1d1ad1fb8b22d81921e516ef231a858aecd926" + } }, "email": { - "version": "1.0.0", + "version": "1.2.1", "description": "Transactional email via Elastic Email. Send, template, and track emails.", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/email-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/email-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/email/tarball", "requires_license": false, "language": "go", @@ -2480,16 +3057,21 @@ "name": "email", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "bdac751f0b65adfe53af60e3c20886d06cc9307878251abe78d54d3bc6cf19b3", + "checksums": { + "sha256": "bdac751f0b65adfe53af60e3c20886d06cc9307878251abe78d54d3bc6cf19b3" + } }, "encryption": { - "version": "1.0.0", + "version": "1.2.1", "description": "Bring Your Own Key (BYOK) per-tenant envelope encryption for nSelf Cloud: AWS KMS, GCP Cloud KMS, and HashiCorp Vault Transit, with key rotation and an audit trail.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/encryption-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/encryption-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/encryption/tarball", "requires_license": false, "language": "go", @@ -2504,16 +3086,28 @@ "name": "encryption", "author": "nself", "minNselfVersion": "1.2.8", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "afa7c72de503da649a481c9cd8b7d136e393061a6f058b295b8ad0cac4340dd7", + "checksums": { + "sha256": "afa7c72de503da649a481c9cd8b7d136e393061a6f058b295b8ad0cac4340dd7", + "platforms": { + "darwin-arm64": "68dfc43cef1b38ecbb1b03aabae1931746cd6e8ac51b747266a84165d10a18f3", + "darwin-amd64": "5798acdbc72bb963a027f457b63feecebd4ebe572fb5acda8f5b5560260d35f3", + "linux-amd64": "509608c14c987776033e0f098c7511a4a1151447e4aa9ea4ce1164224f409da4", + "linux-arm64": "a8f0a8a6637e37a1560b8089dd88ece7720d9ae75c544bc1c36e7ecb4165205e", + "windows-amd64": "ea735f9e7e58f4aa546005fe8454c029fe3a8d8affdeb70a925ccfde14fba28d" + } + } }, "entitlements": { - "version": "1.2.0", + "version": "1.2.1", "description": "Feature gating, subscription plan management, usage quota tracking, and metered billing", "category": "commerce", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.0/entitlements-1.2.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/entitlements-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/entitlements/tarball", "requires_license": false, "language": "go", @@ -2529,16 +3123,21 @@ "name": "entitlements", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "702d26062701654494ab2da0957b4e56337627da4e1b30debe1cfedd873e4976", + "checksums": { + "sha256": "702d26062701654494ab2da0957b4e56337627da4e1b30debe1cfedd873e4976" + } }, "event-bus": { - "version": "1.0.0", + "version": "1.2.1", "description": "Internal event bus with pub/sub, fan-out delivery, dead-letter queue, and replay for inter-plugin messaging.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/event-bus-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/event-bus-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/event-bus/tarball", "requires_license": false, "language": "go", @@ -2552,16 +3151,21 @@ "name": "event-bus", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "a62bd1756f48c3b4e98d202f8ca01bcc9867d90111129b89819d97511a025243", + "checksums": { + "sha256": "a62bd1756f48c3b4e98d202f8ca01bcc9867d90111129b89819d97511a025243" + } }, "family-ancestry": { - "version": "1.1.2", + "version": "1.2.1", "description": "Ancestry.com → nFamily migration helper (PLANNED). Imports profiles, photos, documents, sources into the family plugin. Pattern mirrors family-geni.", "category": "social", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/family-ancestry-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/family-ancestry-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/family-ancestry/tarball", "requires_license": false, "language": "go", @@ -2577,16 +3181,21 @@ "name": "family-ancestry", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "1b055a79f44307a9e9a6c151a4a45c7287c6715782fe61a8f379ec656671de5e", + "checksums": { + "sha256": "1b055a79f44307a9e9a6c151a4a45c7287c6715782fe61a8f379ec656671de5e" + } }, "family-familysearch": { - "version": "1.1.2", + "version": "1.2.1", "description": "FamilySearch → nFamily migration helper (PLANNED). Free public API from FamilySearch (LDS). Lowest-friction next-step importer after family-geni.", "category": "social", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/family-familysearch-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/family-familysearch-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/family-familysearch/tarball", "requires_license": false, "language": "go", @@ -2603,16 +3212,21 @@ "name": "family-familysearch", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "52dfd9e628a486ab229f17dfd25d2ddb295bbda479fa382137111832642883c3", + "checksums": { + "sha256": "52dfd9e628a486ab229f17dfd25d2ddb295bbda479fa382137111832642883c3" + } }, "family-myheritage": { - "version": "1.1.2", + "version": "1.2.1", "description": "MyHeritage → nFamily migration helper (PLANNED). MyHeritage is Geni.com's parent company — lowest legal risk, potential partnership path.", "category": "social", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/family-myheritage-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/family-myheritage-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/family-myheritage/tarball", "requires_license": false, "language": "go", @@ -2628,16 +3242,21 @@ "name": "family-myheritage", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "552f748893dcb6f24642b0d2d17082cce4a64cda640be5925844f2b3d19356bd", + "checksums": { + "sha256": "552f748893dcb6f24642b0d2d17082cce4a64cda640be5925844f2b3d19356bd" + } }, "family-wikitree": { - "version": "1.1.2", + "version": "1.2.1", "description": "WikiTree → nFamily migration helper (PLANNED). WikiTree is a free public genealogy wiki with a REST API (Apps API).", "category": "social", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/family-wikitree-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/family-wikitree-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/family-wikitree/tarball", "requires_license": false, "language": "go", @@ -2653,16 +3272,21 @@ "name": "family-wikitree", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "a277e7b207b35e4b3add5ded5e29a665e3753138b17de4ea002dfb3e08572cf9", + "checksums": { + "sha256": "a277e7b207b35e4b3add5ded5e29a665e3753138b17de4ea002dfb3e08572cf9" + } }, "functions-v8": { - "version": "1.1.2", + "version": "1.2.1", "description": "Edge Functions V8 Runtime. Deploy short-lived TypeScript functions with a Deno V8 isolate pool. HTTP-trigger, <50ms cold-start, allowlist-only env injection, Prometheus metrics, SSE log streaming.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/functions-v8-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/functions-v8-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/functions-v8/tarball", "requires_license": false, "language": "go", @@ -2679,16 +3303,21 @@ "name": "functions-v8", "author": "nself", "minNselfVersion": "1.0.9", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "d84410738f366aa99c0ebf87969aee21cd8d42346720d7a00a4ccaead9d5afd6", + "checksums": { + "sha256": "d84410738f366aa99c0ebf87969aee21cd8d42346720d7a00a4ccaead9d5afd6" + } }, "hipaa": { - "version": "1.1.2", + "version": "1.2.1", "description": "HIPAA compliance add-on: PHI column registry, PHI access logging with 6-year retention, de-identification helpers (masking + tokenization), encryption-at-rest audit, and BAA workflow.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/hipaa-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/hipaa-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/hipaa/tarball", "requires_license": false, "language": "go", @@ -2706,16 +3335,21 @@ "name": "hipaa", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "36eff51c37ed25fbda80e6392f6f58bb6a10d9771a3eb8b403693190e834df25", + "checksums": { + "sha256": "36eff51c37ed25fbda80e6392f6f58bb6a10d9771a3eb8b403693190e834df25" + } }, "home": { - "version": "1.1.2", + "version": "1.2.1", "description": "Home automation bridge. Connects Home Assistant and MQTT to ɳSelf, enabling smart device control, state monitoring, scene activation, and command logging.", "category": "integrations", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/home-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/home-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/home/tarball", "requires_license": false, "language": "go", @@ -2730,16 +3364,21 @@ "name": "home", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "a004bd9d330d13e9dc82c7fc40eaf6f5b3515ce184f05f9991215db079b9fb06", + "checksums": { + "sha256": "a004bd9d330d13e9dc82c7fc40eaf6f5b3515ce184f05f9991215db079b9fb06" + } }, "idme": { - "version": "1.1.2", + "version": "1.2.1", "description": "ID.me OAuth authentication with government-grade identity verification for 7 groups", "category": "authentication", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/idme-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/idme-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/idme/tarball", "requires_license": false, "language": "go", @@ -2756,16 +3395,21 @@ "name": "idme", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "c89719026ab07ff02c33ab7695145db850cf0a7308448c4c66c4dc98f7fb115d", + "checksums": { + "sha256": "c89719026ab07ff02c33ab7695145db850cf0a7308448c4c66c4dc98f7fb115d" + } }, "job-queue": { - "version": "1.0.0", + "version": "1.2.1", "description": "Durable background job queue with priorities, retries, scheduled execution, and per-job progress tracking.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/job-queue-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/job-queue-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/job-queue/tarball", "requires_license": false, "language": "go", @@ -2779,16 +3423,21 @@ "name": "job-queue", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "b64d5b3ccc3bb80f03f95cdf042e21c0725fba821bf3a2d09ce1a466c74b24b5", + "checksums": { + "sha256": "b64d5b3ccc3bb80f03f95cdf042e21c0725fba821bf3a2d09ce1a466c74b24b5" + } }, "linkedin": { - "version": "1.1.2", + "version": "1.2.1", "description": "LinkedIn publishing integration. OAuth 2.0 connection, post to LinkedIn feed with optional image attachments, post history, and Claw tool descriptor.", "category": "content", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/linkedin-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/linkedin-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/linkedin/tarball", "requires_license": false, "language": "go", @@ -2803,16 +3452,21 @@ "name": "linkedin", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "4c62bc22c5a93891fea1ab21e9a8a3ec478b99feee4e5b20d4877116ca13a849", + "checksums": { + "sha256": "4c62bc22c5a93891fea1ab21e9a8a3ec478b99feee4e5b20d4877116ca13a849" + } }, "mail": { - "version": "1.0.0", + "version": "1.2.1", "description": "Send transactional and broadcast email through the nSelf stack: mux + Postmark pipeline via ping_api, template management, and DKIM verification.", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/mail-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/mail-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/mail/tarball", "requires_license": false, "language": "go", @@ -2827,16 +3481,28 @@ "name": "mail", "author": "nself", "minNselfVersion": "1.2.8", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "2eb0dc05fbd51961882b344568c0eacff0da8fcfdcf31ad37f2d0a0de0c0c873", + "checksums": { + "sha256": "2eb0dc05fbd51961882b344568c0eacff0da8fcfdcf31ad37f2d0a0de0c0c873", + "platforms": { + "darwin-arm64": "86bc44042674e4363e96b36ebf2c2f253816de207c9cbaea708838b2956541bc", + "darwin-amd64": "0ac4d707fe0a34fd00d01aa3447d680e9cb9971da04ff25283b2f082d3a9bbe4", + "linux-amd64": "46a67d46f9ab14cb4e25556120158aa6e8c9fd90604a34352f7893f2b3241384", + "linux-arm64": "2e1273530459282a9855c4e9c4ff53b0509ec1dbdf88c7d0906f6a90b0f03d72", + "windows-amd64": "2d4f26b9b8dfdc4f4a0920f923e70a3a725106617ee11b030e7f8f03d151e26d" + } + } }, "meetings": { - "version": "1.1.2", + "version": "1.2.1", "description": "Calendar integration and meeting management with room booking, recurring meetings, and availability tracking. External calendar sync (Google/Outlook) planned for future release.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/meetings-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/meetings-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/meetings/tarball", "requires_license": false, "language": "go", @@ -2853,16 +3519,21 @@ "name": "meetings", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "fa4333958f1a9b487bccdecf446b2f5a31131706d6bffa0ecd4ec05f93f00a2a", + "checksums": { + "sha256": "fa4333958f1a9b487bccdecf446b2f5a31131706d6bffa0ecd4ec05f93f00a2a" + } }, "nself-cloud": { - "version": "0.1.0", + "version": "1.2.1", "description": "Internal ɳCloud managed hosting infrastructure plugin — provisions isolated nSelf instances for Cloud customers", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.1.0/nself-cloud-0.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/nself-cloud-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/nself-cloud/tarball", "requires_license": false, "language": "go", @@ -2876,16 +3547,21 @@ "name": "nself-cloud", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "7c541caf3443a5bf5e5dba278cbb7648230026ca4da4b514e8d3689c91e051f7", + "checksums": { + "sha256": "7c541caf3443a5bf5e5dba278cbb7648230026ca4da4b514e8d3689c91e051f7" + } }, "nself-eval-gate": { - "version": "1.0.0", + "version": "1.2.1", "description": "Eval harness and autonomy-tier gate for nSelf. Three-mode scoring (exact, semantic via BGE-M3, rubric via LLM-as-judge), recall-quality precision/recall/fact_f1 metrics, CI integration via nself ci eval, and autonomy-tier threshold enforcement.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.1.1", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/nself-eval-gate-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/nself-eval-gate-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/nself-eval-gate/tarball", "requires_license": false, "language": "go", @@ -2900,16 +3576,21 @@ "name": "nself-eval-gate", "author": "nself", "minNselfVersion": "1.1.1", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "346a3d6db2316b598f755bb4b1314953cb95f1dd46a8997d25ae07ac59dc484d", + "checksums": { + "sha256": "346a3d6db2316b598f755bb4b1314953cb95f1dd46a8997d25ae07ac59dc484d" + } }, "nself-geo": { - "version": "1.1.0", + "version": "1.2.1", "description": "Forward and reverse geocoding with provider-agnostic caching layer. Nominatim (free, OSM) is the default; Google Places and Mapbox are premium fallbacks. Exposes geocodeAddress, reverseGeocode, geocodeBatch, clearGeoCache via Hasura Remote Schema.", "category": "integrations", "tier": "free", "license": "MIT", "min_nself_version": "1.1.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.0/nself-geo-1.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/nself-geo-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/nself-geo/tarball", "requires_license": false, "language": "go", @@ -2925,16 +3606,21 @@ "name": "nself-geo", "author": "nself", "minNselfVersion": "1.1.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "98351e8a37ce7f34367e22df6536081ee2a66cda981570b2912c4d5c892a268a", + "checksums": { + "sha256": "98351e8a37ce7f34367e22df6536081ee2a66cda981570b2912c4d5c892a268a" + } }, "nself-image": { - "version": "0.1.0", + "version": "1.2.1", "description": "Server-side image processing plugin for nSelf: resize, crop, format conversion (WebP/AVIF/JPEG/PNG), EXIF strip, and MinIO-integrated upload pipeline. Replaces per-app Sharp/Node.js usage across nFamily, nChat, and any consumer app needing image normalization.", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.2.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.1.0/nself-image-0.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/nself-image-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/nself-image/tarball", "requires_license": false, "language": "rust", @@ -2955,16 +3641,21 @@ "name": "nself-image", "author": "nself", "minNselfVersion": "1.2.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "07363f7181a5d1d3b8702bb72939b02479046a2360aa5b8de6afc9ff651f5f06", + "checksums": { + "sha256": "07363f7181a5d1d3b8702bb72939b02479046a2360aa5b8de6afc9ff651f5f06" + } }, "nself-pdf": { - "version": "0.1.0", + "version": "1.2.1", "description": "Server-side PDF generation from HTML templates (Handlebars/Nunjucks) with MinIO output and Hasura Action trigger", "category": "content", "tier": "free", "license": "MIT", "min_nself_version": "1.1.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.1.0/nself-pdf-0.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/nself-pdf-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/nself-pdf/tarball", "requires_license": false, "language": "go", @@ -2982,16 +3673,21 @@ "name": "nself-pdf", "author": "nself", "minNselfVersion": "1.1.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "3f2a19ac47dfc5a32a8d496b3945ad41230d18866e0619ef456fc4b220e77bf3", + "checksums": { + "sha256": "3f2a19ac47dfc5a32a8d496b3945ad41230d18866e0619ef456fc4b220e77bf3" + } }, "nself-scan": { - "version": "0.1.0", + "version": "1.2.1", "description": "Server-side file scanning for MinIO uploads: magic-byte MIME validation, ClamAV virus/malware scanning (always free, Security-Always-Free Doctrine), and optional CSAM hash detection (deferred — requires partner agreement)", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.1.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.1.0/nself-scan-0.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/nself-scan-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/nself-scan/tarball", "requires_license": false, "language": "go", @@ -3011,16 +3707,21 @@ "name": "nself-scan", "author": "nself", "minNselfVersion": "1.1.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "7cb80dd9f78f1572d7ce23adf1d84c7eb9a6ef90441b8d08e803d7b40b0d6743", + "checksums": { + "sha256": "7cb80dd9f78f1572d7ce23adf1d84c7eb9a6ef90441b8d08e803d7b40b0d6743" + } }, "nself-sync": { - "version": "1.1.2", + "version": "1.2.1", "description": "Event-log sync engine for nClaw. Multi-device state synchronization via hybrid logical clocks (HLC) and last-write-wins (LWW) conflict resolution. JWT-authenticated push/pull/snapshot/subscribe with Ed25519-signed events.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.1.1", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/nself-sync-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/nself-sync-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/nself-sync/tarball", "requires_license": false, "language": "go", @@ -3043,16 +3744,21 @@ "np_sync_events", "np_devices", "np_sync_cursors" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "65cb9d210f62a25130624bbcb0340add8c7a1e970fbfc7137d6470834421870d", + "checksums": { + "sha256": "65cb9d210f62a25130624bbcb0340add8c7a1e970fbfc7137d6470834421870d" + } }, "nself-vault": { - "version": "1.0.0", + "version": "1.2.1", "description": "nSelf-managed envelope encryption KMS. Provides per-row/column selective encryption with key rotation, audit logging, and Hasura Action surface. Eliminates ad-hoc per-team AES wrappers.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.1.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/nself-vault-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/nself-vault-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/nself-vault/tarball", "requires_license": false, "language": "go", @@ -3070,16 +3776,21 @@ "name": "nself-vault", "author": "nself", "minNselfVersion": "1.1.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "3b6d18a67a8e8abbedddecab93e5a95051f6d1cc7ad08440f1cca6fa410baadd", + "checksums": { + "sha256": "3b6d18a67a8e8abbedddecab93e5a95051f6d1cc7ad08440f1cca6fa410baadd" + } }, "object-storage": { - "version": "1.1.2", + "version": "1.2.1", "description": "Multi-provider object storage with S3-compatible API, local storage, presigned URLs, and multipart uploads", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/object-storage-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/object-storage-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/object-storage/tarball", "requires_license": false, "language": "go", @@ -3098,16 +3809,21 @@ "name": "object-storage", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "e00366c466ec95d3049053a94e81ea65e3d351b8a16f528e41bdf3c662ae4b5b", + "checksums": { + "sha256": "e00366c466ec95d3049053a94e81ea65e3d351b8a16f528e41bdf3c662ae4b5b" + } }, "observability": { - "version": "1.1.2", + "version": "1.2.1", "description": "Unified observability service with health probes, watchdog timers, service auto-discovery, and systemd integration", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/observability-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/observability-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/observability/tarball", "requires_license": false, "language": "go", @@ -3122,16 +3838,21 @@ "name": "observability", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "67de59538cc3cb9cce8b724c044105e2fd616c5d336056394150010c18b99d04", + "checksums": { + "sha256": "67de59538cc3cb9cce8b724c044105e2fd616c5d336056394150010c18b99d04" + } }, "payments": { - "version": "1.0.0", + "version": "1.2.1", "description": "Unified payments abstraction supporting Stripe, PayPal, and Apple/Google Pay with webhook normalization.", "category": "commerce", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/payments-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/payments-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/payments/tarball", "requires_license": false, "language": "go", @@ -3146,16 +3867,21 @@ "name": "payments", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "992a6466f6674e2d18abd19056bdc9169df95abb4999213c3480280bdf0a2cd8", + "checksums": { + "sha256": "992a6466f6674e2d18abd19056bdc9169df95abb4999213c3480280bdf0a2cd8" + } }, "pentest": { - "version": "1.1.2", + "version": "1.2.1", "description": "Penetration-test readiness kit. Generates structured scope documents, provisions pentest credentials, tracks findings, and manages remediation. ɳSelf+ tier.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/pentest-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/pentest-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/pentest/tarball", "requires_license": false, "language": "go", @@ -3170,16 +3896,21 @@ "name": "pentest", "author": "nself", "minNselfVersion": "1.0.9", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "544e8279821b3f9ce8329829246fdb3c38bd8980bb620e6a0c0fccbc098a43a0", + "checksums": { + "sha256": "544e8279821b3f9ce8329829246fdb3c38bd8980bb620e6a0c0fccbc098a43a0" + } }, "pentest-kit": { - "version": "1.0.0", + "version": "1.2.1", "description": "CLI front end for the pentest plugin: generate scope documents, provision test credentials, import findings, and check remediation status from `nself pentest-kit`. Business+ tier.", "category": "compliance", "tier": "free", "license": "MIT", "min_nself_version": "1.2.8", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/pentest-kit-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/pentest-kit-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/pentest-kit/tarball", "requires_license": false, "language": "go", @@ -3193,16 +3924,28 @@ "name": "pentest-kit", "author": "nself", "minNselfVersion": "1.2.8", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "2f65723883754824a551e3b223cc607c3622fec937e9bb593620b35fdf4bc3b8", + "checksums": { + "sha256": "2f65723883754824a551e3b223cc607c3622fec937e9bb593620b35fdf4bc3b8", + "platforms": { + "darwin-arm64": "986af84284f9162f3a02063b2c4d5bc30d8582ae20146db9fa257036da4b78a3", + "darwin-amd64": "aac14ea870734570a85d0c6d08e6cce63e96472250814363ca294d3643853ec3", + "linux-amd64": "1f7d485729b5b5eaa428b4b16653dfb0924df229e946f08dc3c5a69b43cf9c68", + "linux-arm64": "3fb1dc48b8ba9a235808da659bb1f2218d1febbbdd405475b54b225818d64b0c", + "windows-amd64": "7e0326d8190ca97d8a5a0fdf88495095bf8bb9d00e97cf8f029c500b7f5a2b69" + } + } }, "plugin-clawde": { - "version": "0.1.0", + "version": "1.2.1", "description": "ClawDE daemon integration backend. Manages session lifecycle, tracks daemon health, and streams events via SSE for the ClawDE AI development environment.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.1.1", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.1.0/plugin-clawde-0.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/plugin-clawde-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/plugin-clawde/tarball", "requires_license": false, "language": "go", @@ -3211,16 +3954,21 @@ "name": "plugin-clawde", "author": "nself", "minNselfVersion": "1.1.1", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "dfec158c22aefbdd972f8857f6ef0646c3f5410ce9509a4c3c4b631e6a3ae925", + "checksums": { + "sha256": "dfec158c22aefbdd972f8857f6ef0646c3f5410ce9509a4c3c4b631e6a3ae925" + } }, "plugin-gauth": { - "version": "0.1.0", + "version": "1.2.1", "description": "Headless server-side Google OAuth token refresh for nSelf AI services", "category": "authentication", "tier": "free", "license": "MIT", "min_nself_version": "1.1.1", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.1.0/plugin-gauth-0.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/plugin-gauth-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/plugin-gauth/tarball", "requires_license": false, "language": "rust", @@ -3229,16 +3977,21 @@ "name": "plugin-gauth", "author": "nself", "minNselfVersion": "1.1.1", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "0c1cf7be503faa53076ac022fa9e9cf2b08ee46d5e4b49e0ca3ddced580c2265", + "checksums": { + "sha256": "0c1cf7be503faa53076ac022fa9e9cf2b08ee46d5e4b49e0ca3ddced580c2265" + } }, "plugin-llm-gateway": { - "version": "0.1.0", + "version": "1.2.1", "description": "ClawDE-facing LLM gateway: per-tenant token quota, Redis response caching, session context injection, and SSRF guard over nself-ai-gateway (port 3761). Simplifies ClawDE client LLM calls.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.1.1", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.1.0/plugin-llm-gateway-0.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/plugin-llm-gateway-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/plugin-llm-gateway/tarball", "requires_license": false, "language": "go", @@ -3247,16 +4000,21 @@ "name": "plugin-llm-gateway", "author": "nself", "minNselfVersion": "1.1.1", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "a2e52a8ea3592797ede141a7ed3efeaf87471b4787b5c31934b37db6ce9db2c0", + "checksums": { + "sha256": "a2e52a8ea3592797ede141a7ed3efeaf87471b4787b5c31934b37db6ce9db2c0" + } }, "plugin-pty": { - "version": "1.0.0", + "version": "1.2.1", "description": "Pseudo-terminal bridge for ClawDE AI sessions. Spawns, manages, and relays PTY processes with per-tenant resource limits and WebSocket I/O.", "category": "development", "tier": "free", "license": "MIT", "min_nself_version": "1.1.1", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/plugin-pty-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/plugin-pty-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/plugin-pty/tarball", "requires_license": false, "language": "go", @@ -3265,16 +4023,21 @@ "name": "plugin-pty", "author": "nself", "minNselfVersion": "1.1.1", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "cd4ec1a8fd29553a11f76891ed1ca06f0ce04ad489fa66616e900ca4c488ccdf", + "checksums": { + "sha256": "cd4ec1a8fd29553a11f76891ed1ca06f0ce04ad489fa66616e900ca4c488ccdf" + } }, "plugin-retrieval": { - "version": "0.1.0", + "version": "1.2.1", "description": "Hybrid retrieval plugin: pgvector ANN + tsvector BM25 merged with Reciprocal Rank Fusion (RRF). Provides the search backend for ɳClaw memory and nself-ai-mcp search/recall tools.", "category": "data", "tier": "free", "license": "MIT", "min_nself_version": "1.1.1", - "tarball": "https://github.com/nself-org/plugins/releases/download/v0.1.0/plugin-retrieval-0.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/plugin-retrieval-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/plugin-retrieval/tarball", "requires_license": false, "language": "go", @@ -3283,16 +4046,21 @@ "name": "plugin-retrieval", "author": "nself", "minNselfVersion": "1.1.1", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "83861eb3d036276680c7c58bd14df6a1bdfa1528572564f9750f35f86f3bcae4", + "checksums": { + "sha256": "83861eb3d036276680c7c58bd14df6a1bdfa1528572564f9750f35f86f3bcae4" + } }, "post": { - "version": "1.1.2", + "version": "1.2.1", "description": "Multi-platform content publishing. Publish to WordPress, Ghost, Twitter/X, LinkedIn, Telegram channels, Dev.to, and Hashnode with optional scheduling.", "category": "content", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/post-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/post-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/post/tarball", "requires_license": false, "language": "go", @@ -3311,16 +4079,21 @@ "name": "post", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "4730166dfacc1de7f7763c6f9fa2b6c12a5d6bc691544a41a82fd70e2df3c172", + "checksums": { + "sha256": "4730166dfacc1de7f7763c6f9fa2b6c12a5d6bc691544a41a82fd70e2df3c172" + } }, "retro-gaming": { - "version": "1.1.2", + "version": "1.2.1", "description": "Retro gaming ROM library management, emulator core serving, save state synchronization, play sessions, and controller configuration for nself-tv", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/retro-gaming-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/retro-gaming-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/retro-gaming/tarball", "requires_license": false, "language": "go", @@ -3338,16 +4111,21 @@ "name": "retro-gaming", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "978b18176f279ec352c0a55c969eda39311545b00f4065c2ec19c1472ccd8d4c", + "checksums": { + "sha256": "978b18176f279ec352c0a55c969eda39311545b00f4065c2ec19c1472ccd8d4c" + } }, "rom-discovery": { - "version": "1.1.2", + "version": "1.2.1", "description": "ROM metadata database, search, discovery, automated download orchestration, and multi-source scraping for nself-tv", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/rom-discovery-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/rom-discovery-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/rom-discovery/tarball", "requires_license": false, "language": "go", @@ -3365,16 +4143,21 @@ "name": "rom-discovery", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "9e11ad43026ea1ec79c2914894b3ec9db1321f07c58972df0eb3f8355d349f0f", + "checksums": { + "sha256": "9e11ad43026ea1ec79c2914894b3ec9db1321f07c58972df0eb3f8355d349f0f" + } }, "siem": { - "version": "1.1.2", + "version": "1.2.1", "description": "Forward nSelf audit logs and security events to external SIEM platforms: Datadog, Splunk HEC, Elastic, Loki, and custom webhooks. OCSF/ECS schema normalization.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/siem-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/siem-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/siem/tarball", "requires_license": false, "language": "go", @@ -3393,16 +4176,21 @@ "name": "siem", "author": "nself", "minNselfVersion": "1.0.9", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "b447d05872c51fbbe35169ee850b60751e2909ec0926a578e5b02167672d98d5", + "checksums": { + "sha256": "b447d05872c51fbbe35169ee850b60751e2909ec0926a578e5b02167672d98d5" + } }, "sms": { - "version": "1.0.0", + "version": "1.2.1", "description": "SMS messaging via Twilio. Send, track, and manage opt-outs.", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/sms-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/sms-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/sms/tarball", "requires_license": false, "language": "go", @@ -3411,16 +4199,21 @@ "name": "sms", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "bad33c5141cb77acbadcc75746e9080154d04979c6c67f66bf420876d9bf1e3e", + "checksums": { + "sha256": "bad33c5141cb77acbadcc75746e9080154d04979c6c67f66bf420876d9bf1e3e" + } }, "storage": { - "version": "1.0.0", + "version": "1.2.1", "description": "S3-compatible file storage: bucket management, object PUT/GET/DELETE/LIST, presigned URLs, per-tenant isolation.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.1.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/storage-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/storage-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/storage/tarball", "requires_license": false, "language": "go", @@ -3435,16 +4228,21 @@ "name": "storage", "author": "nself", "minNselfVersion": "1.1.0", - "tables": [] + "tables": [], + "checksum": "4ffc35d775a0c99771faf3b9b10075d66c5ba32344e72a7e839a07eb4b5bb632", + "checksums": { + "sha256": "4ffc35d775a0c99771faf3b9b10075d66c5ba32344e72a7e839a07eb4b5bb632" + }, + "releaseTag": "v1.2.1" }, "storage-transform": { - "version": "1.1.2", + "version": "1.2.1", "description": "On-the-fly image transformation CDN: resize, crop, format convert (WebP/AVIF/JPEG/PNG), quality, and device-pixel-ratio support. URL-param driven, Redis LRU cache, Nginx cache headers, rate limiting.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/storage-transform-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/storage-transform-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/storage-transform/tarball", "requires_license": false, "language": "go", @@ -3461,16 +4259,21 @@ "name": "storage-transform", "author": "nself", "minNselfVersion": "1.0.9", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "8b9031d5a7b41fd0f270270e1d743f905c983e8a58f659b2358c38a2f874bbe8", + "checksums": { + "sha256": "8b9031d5a7b41fd0f270270e1d743f905c983e8a58f659b2358c38a2f874bbe8" + } }, "tenant-controller": { - "version": "1.1.2", + "version": "1.2.1", "description": "Multi-tenant master controller for nCloud. Manages N isolated nSelf project instances behind a single deploy: per-project Postgres schema, Hasura metadata namespace, Nginx vhost, JWT secret, Redis key prefix, and MinIO bucket. Enables 50 projects on one Hetzner CX21.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.9", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/tenant-controller-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/tenant-controller-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/tenant-controller/tarball", "requires_license": false, "language": "go", @@ -3486,16 +4289,21 @@ "name": "tenant-controller", "author": "nself", "minNselfVersion": "1.0.9", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "09b0b44869209ab6637995fc095365530c1fc44e9367a03f9ec58a95cb6c5a61", + "checksums": { + "sha256": "09b0b44869209ab6637995fc095365530c1fc44e9367a03f9ec58a95cb6c5a61" + } }, "transactional-email": { - "version": "1.1.0", + "version": "1.2.1", "description": "Provider-agnostic transactional email: template rendering, per-tenant domain management, SPF/DKIM reporting, delivery webhook relay.", "category": "communication", "tier": "free", "license": "MIT", "min_nself_version": "1.1.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.0/transactional-email-1.1.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/transactional-email-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/transactional-email/tarball", "requires_license": false, "language": "go", @@ -3512,16 +4320,21 @@ "name": "transactional-email", "author": "nself", "minNselfVersion": "1.1.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "fd08f54f6f79a3ffc2fc4e6c22ed3ce64a5131ff318e6441f7fcf8aa3bc7b0fd", + "checksums": { + "sha256": "fd08f54f6f79a3ffc2fc4e6c22ed3ce64a5131ff318e6441f7fcf8aa3bc7b0fd" + } }, "warehouse": { - "version": "1.0.0", + "version": "1.2.1", "description": "Data warehouse sync — exports nself table data to BigQuery, Snowflake, or Redshift on a configurable schedule.", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.0.0/warehouse-1.0.0.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/warehouse-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/warehouse/tarball", "requires_license": false, "language": "go", @@ -3536,16 +4349,21 @@ "name": "warehouse", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "91384c9f196fb368a27eb825cb2ce5d6a14fdf29b0837d9e92b6da47b7b68d13", + "checksums": { + "sha256": "91384c9f196fb368a27eb825cb2ce5d6a14fdf29b0837d9e92b6da47b7b68d13" + } }, "web3": { - "version": "1.1.2", + "version": "1.2.1", "description": "Blockchain integration, NFT support, token-gated access, DAO governance, and decentralized identity", "category": "integrations", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/web3-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/web3-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/web3/tarball", "requires_license": false, "language": "go", @@ -3563,16 +4381,21 @@ "name": "web3", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "9426659414d8b164940b03f9023ddf4a0866e8b84cabb247d93b7ab93bf9e33f", + "checksums": { + "sha256": "9426659414d8b164940b03f9023ddf4a0866e8b84cabb247d93b7ab93bf9e33f" + } }, "workflows": { - "version": "1.1.2", + "version": "1.2.1", "description": "Automation engine providing trigger-action workflow chains, conditional logic, scheduled tasks, webhook integrations, and cross-plugin orchestration", "category": "automation", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/workflows-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/workflows-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/workflows/tarball", "requires_license": false, "language": "go", @@ -3589,10 +4412,15 @@ "name": "workflows", "author": "nself", "minNselfVersion": "1.0.0", - "tables": [] + "tables": [], + "releaseTag": "v1.2.1", + "checksum": "6f457b9c1b7a03236bcef82a81fcb72220181c01d7c6579330a0b64bfc4dbef8", + "checksums": { + "sha256": "6f457b9c1b7a03236bcef82a81fcb72220181c01d7c6579330a0b64bfc4dbef8" + } }, "shared-utils": { - "version": "1.0.0", + "version": "1.2.1", "description": "Shared Go utilities (request-ID tracing middleware, HTTP client propagation, server lifecycle helpers) used internally by multiple free nself plugins. Not installable directly.", "category": "infrastructure", "tier": "free", @@ -3613,13 +4441,13 @@ "installable": false }, "tmdb": { - "version": "1.1.2", + "version": "1.2.1", "description": "Comprehensive media metadata enrichment from TMDB/IMDb/TVDB/MusicBrainz with auto-matching, manual review queue, and multi-provider support", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/tmdb-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/tmdb-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/tmdb/tarball", "requires_license": false, "language": "go", @@ -3647,16 +4475,21 @@ "np_tmdb_genres", "np_tmdb_match_queue", "np_tmdb_webhook_events" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "771d00e5a7d63ecd0dd311fdc10ca9a212ba74473e5a842a13de7e9c3c3784e4", + "checksums": { + "sha256": "771d00e5a7d63ecd0dd311fdc10ca9a212ba74473e5a842a13de7e9c3c3784e4" + } }, "game-metadata": { - "version": "1.1.2", + "version": "1.2.1", "description": "Game metadata service with IGDB integration, ROM hash matching, tier requirements, and artwork management", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/game-metadata-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/game-metadata-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/game-metadata/tarball", "requires_license": false, "language": "go", @@ -3678,16 +4511,21 @@ "np_game_artwork", "np_game_platforms", "np_game_genres" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "482125be2dce22ac5eb5ac5bcbba6c0471dc420f0ae44dfcfa2eb3cb179882a0", + "checksums": { + "sha256": "482125be2dce22ac5eb5ac5bcbba6c0471dc420f0ae44dfcfa2eb3cb179882a0" + } }, "sports": { - "version": "1.1.2", + "version": "1.2.1", "description": "Sports data plugin with storage for scores, schedules, and standings. Planned: Live data provider integration (ESPN, The Sports DB) for real-time scores and stats", "category": "sports", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/sports-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/sports-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/sports/tarball", "requires_license": false, "language": "go", @@ -3720,16 +4558,21 @@ "np_sports_schedule_cache", "np_sports_sync_state", "np_sports_webhook_events" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "7365f5081d1543a7fb03c73b0ba71ded8cd9cf8004b7f7f339f65ed553ab859d", + "checksums": { + "sha256": "7365f5081d1543a7fb03c73b0ba71ded8cd9cf8004b7f7f339f65ed553ab859d" + } }, "podcast": { - "version": "1.1.2", + "version": "1.2.1", "description": "Podcast service with RSS feed parsing, episode management, playback position sync, and subscription management", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/podcast-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/podcast-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/podcast/tarball", "requires_license": false, "language": "go", @@ -3751,16 +4594,21 @@ "np_podcast_subscriptions", "np_podcast_playback_positions", "np_podcast_categories" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "5e421670608d252f56bd64eba16b1a4917dd20ff631cadb5686eeaf7f8ce588a", + "checksums": { + "sha256": "5e421670608d252f56bd64eba16b1a4917dd20ff631cadb5686eeaf7f8ce588a" + } }, "file-processing": { - "version": "1.1.2", + "version": "1.2.1", "description": "File processing with thumbnails and optimization for MinIO/S3/GCS/R2/B2/Azure. Planned: Inbound webhook support for storage provider notifications", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/file-processing-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/file-processing-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/file-processing/tarball", "requires_license": false, "language": "rust", @@ -3779,16 +4627,21 @@ "np_fileproc_jobs", "np_fileproc_thumbnails", "np_fileproc_metadata" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "6695dc38cd01823e944373e8ebfb893003ec804afae312970ea1babc592cd362", + "checksums": { + "sha256": "6695dc38cd01823e944373e8ebfb893003ec804afae312970ea1babc592cd362" + } }, "media-processing": { - "version": "1.1.2", + "version": "1.2.1", "description": "FFmpeg-based media encoding and processing with HLS streaming support", "category": "media", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/media-processing-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/media-processing-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/media-processing/tarball", "requires_license": false, "language": "rust", @@ -3817,16 +4670,21 @@ "np_mediap_webhook_events", "np_mediap_watcher_events", "np_mediap_uploads" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "fb908d7bab56eddeb75649f2fd4e32d568ea2bc4c47eca49df89ec0c2ae81d93", + "checksums": { + "sha256": "fb908d7bab56eddeb75649f2fd4e32d568ea2bc4c47eca49df89ec0c2ae81d93" + } }, "geocoding": { - "version": "1.1.2", + "version": "1.2.1", "description": "Geocoding plugin with geofence storage. Planned: Google Maps API integration for forward/reverse geocoding and place search", "category": "infrastructure", "tier": "free", "license": "MIT", "min_nself_version": "1.0.0", - "tarball": "https://github.com/nself-org/plugins/releases/download/v1.1.2/geocoding-1.1.2.tar.gz", + "tarball": "https://github.com/nself-org/plugins/releases/download/v1.2.1/geocoding-1.2.1.tar.gz", "download_url": "https://plugins.nself.org/plugins/geocoding/tarball", "requires_license": false, "language": "go", @@ -3846,7 +4704,12 @@ "np_geoc_geofences", "np_geoc_geofence_events", "np_geoc_places" - ] + ], + "releaseTag": "v1.2.1", + "checksum": "fd243377a98045b3df88eed92d9bf414eca5bb8e75cbbc7a6906a82b084d9d9d", + "checksums": { + "sha256": "fd243377a98045b3df88eed92d9bf414eca5bb8e75cbbc7a6906a82b084d9d9d" + } } } } diff --git a/scripts/build-tarballs.sh b/scripts/build-tarballs.sh index cebf8746..657ebf5d 100755 --- a/scripts/build-tarballs.sh +++ b/scripts/build-tarballs.sh @@ -1,39 +1,50 @@ #!/usr/bin/env bash # build-tarballs.sh -# Build tarballs for all 27 free plugins without uploading. -# Outputs to dist/ directory. Run build-and-upload-tarballs.sh to also upload. +# Build tarballs for all free plugins without uploading. Outputs to dist/. +# Run build-and-upload-tarballs.sh to also upload. # # Usage: ./scripts/build-tarballs.sh [VERSION] -# VERSION defaults to the registry.json version field (e.g. 1.0.0) +# VERSION defaults to the registry.json top-level version field (e.g. 1.0.0) # -# Requirements: jq, sha256sum (or shasum on macOS) -# Output: dist/-.tar.gz + dist/-.tar.gz.sha256 +# Every plugin gets its source tarball. A plugin that also declares a +# binaryName (it provides an `nself `) additionally gets five +# per-platform tarballs, built with the SAME Go cross-compile + tar recipe +# .github/workflows/release-tarballs.yml uses to build the real release +# assets — see build_platform_tarballs() below. Set +# NSELF_SKIP_PLATFORM_TARBALLS=1 to build source tarballs only (faster local +# iteration when you don't need the platform checksums); CI's +# tarball-checksum-gate.yml never sets it, since a platform tarball's +# checksum is exactly what it exists to verify. +# +# This file is also sourceable: tarball-checksum-gate.yml sources it and +# calls build_platform_tarballs() directly per plugin, so the Go-build +# orchestration (which command maps to which cmd/ subdirectory, which +# platforms exist) is defined in exactly one place, not copy-pasted into the +# workflow YAML a second time. +# +# Requirements: jq, sha256sum (or shasum on macOS), scripts/deterministic-tar.sh +# (GNU tar). Platform tarballs additionally require a Go toolchain matching +# go.mod's directive for each plugin (CGO_ENABLED=0 cross-compile). +# Output: dist/-.tar.gz(.sha256) +# dist/--.tar.gz(.sha256) [binaryName plugins] + +# NOTE: no `set -euo pipefail` at sourcing time — see the execution guard at +# the bottom of this file. Functions below assume it (via `main`'s own +# `set -euo pipefail`), consistent with how this script always ran standalone. -set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DETERMINISTIC_TAR="${SCRIPT_DIR}/deterministic-tar.sh" -PLUGINS_DIR="${PLUGINS_DIR:-free}" -DIST_DIR="${DIST_DIR:-dist}" -ERRORS=0 +# The five platform strings nself plugin install requests, exactly as +# internal/plugin/arch.go's PlatformArch() returns them. binaryPluginDownloadURL() +# builds the asset filename from the same strings — a mismatch here is an +# install failure there. +PLATFORMS="darwin-arm64 darwin-amd64 linux-amd64 linux-arm64 windows-amd64" log() { printf "[build-tarballs] %s\n" "$*"; } -err() { printf "[build-tarballs] ERROR: %s\n" "$*" >&2; ERRORS=$((ERRORS + 1)); } +err() { printf "[build-tarballs] ERROR: %s\n" "$*" >&2; } warn() { printf "[build-tarballs] WARN: %s\n" "$*" >&2; } -# Detect version from registry.json or first arg -if [ -n "${1:-}" ]; then - VERSION="$1" -else - if ! command -v jq >/dev/null 2>&1; then - err "jq not found; pass VERSION as first argument" - exit 1 - fi - VERSION="$(jq -r '.version' registry.json 2>/dev/null || printf '')" - if [ -z "$VERSION" ]; then - err "Cannot read version from registry.json; pass VERSION as first argument" - exit 1 - fi -fi - # sha256 helper — macOS uses shasum -a 256, Linux uses sha256sum sha256_file() { if command -v sha256sum >/dev/null 2>&1; then @@ -43,42 +54,174 @@ sha256_file() { fi } -mkdir -p "$DIST_DIR" - -# Walk free/ plugin directories -BUILT=0 -for plugin_dir in "${PLUGINS_DIR}"/*/; do - [ -d "$plugin_dir" ] || continue - plugin_name="$(basename "$plugin_dir")" - tarball_name="${plugin_name}-${VERSION}.tar.gz" - checksum_name="${tarball_name}.sha256" - tarball_path="${DIST_DIR}/${tarball_name}" - checksum_path="${DIST_DIR}/${checksum_name}" - - # Verify plugin.json exists (skip non-plugin dirs) - if [ ! -f "${plugin_dir}/plugin.json" ]; then - warn "Skipping $plugin_name (no plugin.json)" - continue +# build_platform_tarballs builds the five per-platform tarballs for one +# plugin, when it declares a binaryName, into dist_dir. No-op (returns 0) for +# a plugin with no binaryName — its package is source and works everywhere. +# +# Ported from .github/workflows/release-tarballs.yml's build_plugin() step, +# which is the proven, already-running-in-CI version of this logic; kept +# byte-for-byte equivalent in command/package resolution so a local build and +# a CI build can never disagree about which commands get compiled or from +# which cmd/ subdirectory. +# +# Args: plugin_dir plugin_name version dist_dir +build_platform_tarballs() { + local plugin_dir="$1" plugin_name="$2" version="$3" dist_dir="$4" + + local bin_name + bin_name="$(jq -r '.binaryName // .implementation.binaryName // ""' "${plugin_dir}/plugin.json")" + if [ -z "$bin_name" ]; then + return 0 fi - log "Building ${tarball_name} ..." - if ! tar -czf "$tarball_path" "$plugin_dir" 2>/dev/null; then - err "Failed to build tarball for $plugin_name" - continue + # A plugin may provide more than one command; cliCommands lists them and + # the CLI publishes one binary per entry, so every one has to be built or + # the command it names is dead on arrival. + local commands + commands="$(jq -r 'if (.cliCommands // []) | length > 0 then (.cliCommands[].name) else "" end' "${plugin_dir}/plugin.json")" + if [ -z "$commands" ]; then + commands="${bin_name#nself-}" fi - sha256="$(sha256_file "$tarball_path")" - printf "%s %s\n" "$sha256" "$tarball_name" > "$checksum_path" + local dist_dir_abs + dist_dir_abs="$(cd "$dist_dir" && pwd)" - log " sha256: ${sha256}" - BUILT=$((BUILT + 1)) -done + local platform + for platform in $PLATFORMS; do + local goos="${platform%%-*}" + local goarch="${platform##*-}" + local stage="${dist_dir}/stage-${plugin_name}-${platform}" + local exe="" + [ "$goos" = "windows" ] && exe=".exe" -log "Built ${BUILT} tarballs in ${DIST_DIR}/" + rm -rf "$stage" + mkdir -p "${stage}/${plugin_name}" + cp -R "${plugin_dir}/." "${stage}/${plugin_name}/" -if [ "$ERRORS" -gt 0 ]; then - log "Completed with $ERRORS error(s)." - exit 1 -fi + local failed=0 + local command + for command in $commands; do + # A plugin providing several commands keeps each under cmd//; + # one providing a single command may put it at cmd/ directly. + local pkg="./cmd/${command}/" + [ -d "${plugin_dir}/cmd/${command}" ] || pkg="./cmd/" + + if ! (cd "${plugin_dir}" && CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" \ + go build -trimpath -ldflags="-s -w" \ + -o "${dist_dir_abs}/$(basename "$stage")/${plugin_name}/nself-${command}${exe}" "$pkg"); then + err "$plugin_name failed to build nself-${command} for $platform" + failed=1 + break + fi + done + + if [ "$failed" -ne 0 ]; then + rm -rf "$stage" + return 1 + fi + + local ptar="${dist_dir}/${plugin_name}-${version}-${platform}.tar.gz" + # Same shared recipe as the source tarball — the per-platform binary + # archives had the identical mtime/ordering non-determinism (compiled + # binary mtimes, per-run staging-dir enumeration order) that the source + # tarball did before deterministic-tar.sh. + "$DETERMINISTIC_TAR" "$ptar" -C "$stage" "${plugin_name}" + local psha + psha="$(sha256_file "$ptar")" + printf "%s %s\n" "$psha" "$(basename "$ptar")" > "${ptar}.sha256" + rm -rf "$stage" + log " ${platform} sha256: ${psha}" + done +} + +# main runs the full build: every plugin's source tarball, plus (unless +# NSELF_SKIP_PLATFORM_TARBALLS=1) every binaryName plugin's five platform +# tarballs. Only invoked when this file is executed directly — see the guard +# below — so tarball-checksum-gate.yml can source it for build_platform_tarballs +# alone without also running this whole pass. +main() { + set -euo pipefail -log "Done." + local plugins_dir="${PLUGINS_DIR:-free}" + local dist_dir="${DIST_DIR:-dist}" + local errors=0 + + local version + if [ -n "${1:-}" ]; then + version="$1" + else + if ! command -v jq >/dev/null 2>&1; then + err "jq not found; pass VERSION as first argument" + exit 1 + fi + version="$(jq -r '.version' registry.json 2>/dev/null || printf '')" + if [ -z "$version" ]; then + err "Cannot read version from registry.json; pass VERSION as first argument" + exit 1 + fi + fi + + mkdir -p "$dist_dir" + + local built=0 + # Walk free/ plugin directories in a fixed, filesystem-order-independent + # sequence (matches the traversal .github/workflows/release-tarballs.yml + # uses) — member order inside each individual tarball is already pinned by + # deterministic-tar.sh's --sort=name, this just makes the build log/exit + # order predictable too. + while IFS= read -r plugin_dir; do + local plugin_name tarball_name checksum_name tarball_path checksum_path + plugin_name="$(basename "$plugin_dir")" + tarball_name="${plugin_name}-${version}.tar.gz" + checksum_name="${tarball_name}.sha256" + tarball_path="${dist_dir}/${tarball_name}" + checksum_path="${dist_dir}/${checksum_name}" + + # Verify plugin.json exists (skip non-plugin dirs) + if [ ! -f "${plugin_dir}/plugin.json" ]; then + warn "Skipping $plugin_name (no plugin.json)" + continue + fi + + log "Building ${tarball_name} ..." + # No trailing slash on plugin_dir: deterministic-tar.sh's --sort=name + # already makes member order stable regardless, but a consistent + # no-trailing-slash argument keeps this script and the workflow's + # `find -type d` output (which never has one) textually identical inputs. + if ! "$DETERMINISTIC_TAR" "$tarball_path" "${plugin_dir%/}"; then + err "Failed to build tarball for $plugin_name" + errors=$((errors + 1)) + continue + fi + + local sha256 + sha256="$(sha256_file "$tarball_path")" + printf "%s %s\n" "$sha256" "$tarball_name" > "$checksum_path" + log " sha256: ${sha256}" + built=$((built + 1)) + + if [ "${NSELF_SKIP_PLATFORM_TARBALLS:-}" != "1" ]; then + if ! build_platform_tarballs "$plugin_dir" "$plugin_name" "$version" "$dist_dir"; then + err "Failed to build one or more platform tarballs for $plugin_name" + errors=$((errors + 1)) + fi + fi + done < <(find "$plugins_dir" -maxdepth 1 -mindepth 1 -type d | sort) + + log "Built ${built} plugin(s) in ${dist_dir}/" + + if [ "$errors" -gt 0 ]; then + log "Completed with $errors error(s)." + exit 1 + fi + + log "Done." +} + +# Only run main when executed directly (./build-tarballs.sh or bash +# build-tarballs.sh), not when sourced — tarball-checksum-gate.yml sources +# this file to reuse build_platform_tarballs()/sha256_file() without +# triggering a full build of every plugin. +if [ "${BASH_SOURCE[0]}" = "${0}" ]; then + main "$@" +fi diff --git a/scripts/deterministic-tar.sh b/scripts/deterministic-tar.sh new file mode 100755 index 00000000..6349591f --- /dev/null +++ b/scripts/deterministic-tar.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# deterministic-tar.sh +# The ONE tarball recipe for this repo. Both scripts/build-tarballs.sh and +# .github/workflows/release-tarballs.yml call this instead of invoking `tar` +# directly, so a source tarball or a per-platform binary tarball built here, +# built on a laptop, or built by CI always produces byte-identical output for +# byte-identical input. That is a hard requirement: registry.json stores a +# single sha256 per plugin and `nself plugin install` refuses the install on +# any mismatch (internal/plugin/security.go verifyChecksum) — so if two build +# sites can disagree on the bytes, the checksum is worthless. +# +# What made plain `tar -czf` non-reproducible, both fixed here: +# 1. mtime — tar preserves each member's on-disk mtime, and gzip stamps the +# wall-clock build time into its header. Two builds of the identical +# source tree, seconds apart, produced different bytes. +# 2. member order — scripts/build-tarballs.sh (bash glob "*/ ") and the old +# inline workflow step (`find | sort`) could walk directories in +# different orders, changing tar's member sequence and therefore the +# output bytes even when every member's content was identical. +# +# Usage: +# deterministic-tar.sh +# +# are passed through to `tar -cf -` after the fixed +# determinism flags, so both plain forms work: +# deterministic-tar.sh dist/foo-1.0.1.tar.gz free/foo +# deterministic-tar.sh dist/foo-1.0.1-darwin-arm64.tar.gz -C "$stage" foo +# +# Requires GNU tar. macOS ships bsdtar as `/usr/bin/tar`, which does not +# support --sort/--owner/--group/--numeric-owner/--pax-option the same way +# (some are silently ignored, some error) — there is no equivalent bsdtar +# invocation that reliably reproduces GNU tar's byte layout, and CI runs GNU +# tar (ubuntu-latest), so a "works on my Mac" bsdtar path would silently +# diverge from what CI actually publishes. Policy: require GNU tar +# everywhere. On macOS: `brew install gnu-tar` (provides the `gtar` binary) +# and this script picks it up automatically. On Linux, `tar` already is GNU +# tar. + +set -euo pipefail + +if [ "$#" -lt 2 ]; then + printf "usage: %s \n" "$0" >&2 + exit 1 +fi + +OUT="$1" +shift + +# Locate a GNU tar binary: prefer `tar` if it identifies as GNU tar (true on +# every Linux CI runner), else fall back to `gtar` (Homebrew's GNU tar on +# macOS). Fail loudly and tell the operator exactly how to fix it rather than +# silently building non-reproducible archives with bsdtar. +TAR_BIN="" +if tar --version 2>/dev/null | grep -q "GNU tar"; then + TAR_BIN="tar" +elif command -v gtar >/dev/null 2>&1 && gtar --version 2>/dev/null | grep -q "GNU tar"; then + TAR_BIN="gtar" +else + printf "[deterministic-tar] ERROR: GNU tar is required to build reproducible tarballs.\n" >&2 + printf "[deterministic-tar] macOS: brew install gnu-tar (installs GNU tar as 'gtar')\n" >&2 + printf "[deterministic-tar] Linux: GNU tar ships as 'tar' by default — check your PATH.\n" >&2 + printf "[deterministic-tar] Refusing to fall back to bsdtar: it cannot reproduce GNU tar's\n" >&2 + printf "[deterministic-tar] byte layout, and CI (ubuntu-latest) always uses GNU tar — a\n" >&2 + printf "[deterministic-tar] bsdtar-built tarball would not match the checksum CI records.\n" >&2 + exit 1 +fi + +mkdir -p "$(dirname "$OUT")" + +# Fixed epoch chosen to match the same normalization already shipped for paid +# plugins (nself-org/web@51518c38, ping_api's streamScopedPluginTarball): +# every entry's mtime pinned to the Unix epoch. --owner/--group/--numeric-owner +# zero out uid/gid so the building machine's user account never leaks into +# the archive or its bytes. --pax-option strips the PAX extended-header +# atime/ctime fields GNU tar otherwise emits for some filesystems, which are +# themselves wall-clock noise. --sort=name makes the member order a pure +# function of the file tree, independent of the underlying filesystem's +# directory-entry order or which shell mechanism (glob vs find) enumerated it. +# +# --mode='go-w,a+rX' normalizes file MODE bits too — measured directly (P6 +# re-cut, 2026-09-11): with everything else above already pinned, identical +# git content checked out on two different machines still produced tar +# streams that hashed differently (b8f9afaf vs db4dc18d) because one +# checkout had files at 644 and the other at 664. tar records each member's +# mode byte-for-byte, so the building machine's umask was leaking into the +# archive exactly like mtime/uid/gid did before those were pinned above. +# go-w clears group/other write regardless of umask; a+rX makes files +# world-readable and directories/already-executable files world-executable, +# without flipping a non-executable file executable. Adding this flag made +# both machines produce the byte-identical tar stream for the same content. +"$TAR_BIN" --sort=name \ + --mtime='UTC 1970-01-01' \ + --owner=0 --group=0 --numeric-owner \ + --mode='go-w,a+rX' \ + --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \ + -cf - "$@" | gzip -n -9 > "$OUT" diff --git a/scripts/verify-published-checksums.sh b/scripts/verify-published-checksums.sh index b81b9627..4d71d592 100755 --- a/scripts/verify-published-checksums.sh +++ b/scripts/verify-published-checksums.sh @@ -1,58 +1,86 @@ #!/usr/bin/env bash # verify-published-checksums.sh # -# Purpose: spot-check that the checksum registry.json WOULD carry for a -# release tag matches the SHA-256 of the tarball actually served for that -# tag on the GitHub release. This never writes registry.json — it downloads -# each plugin's real tarball asset for TAG and diffs the computed SHA-256 -# against the registry's checksum/checksums.sha256 (if either is already -# populated for that tag) and prints the computed value regardless, so it -# can seed a future registry update by hand or via build-and-upload-tarballs.sh. +# Purpose: the release model this repo ships under (see .github/RELEASE- +# v1.2.1.md and tarball-checksum-gate.yml) treats the PUBLISHED release +# asset as the artifact of record — registry.json's checksums are supposed +# to be written FROM those published bytes, not from an independent local +# rebuild that merely hopes to match (gzip's DEFLATE output is +# implementation/version-dependent; two byte-identical tar streams can +# still produce different .tar.gz bytes on different machines — see +# tarball-checksum-gate.yml's header comment for the measured proof). This +# script is the one place that reads real published bytes and either +# reports how registry.json disagrees with them, or writes them in. # -# Why this exists (P6, registry-flat-checksum-field fix): most of this -# registry's 129 plugins have never had ANY checksum field computed against -# their real published v1.0.0 asset — recomputing all of them from the repo -# source tree would NOT verify what a user's `nself plugin install` actually -# downloads, since the published tarball's bytes depend on the exact `tar` -# invocation/timestamps used at release time, not just file contents. This -# script downloads the real released asset and hashes THAT. +# Inputs: TAG (e.g. v1.2.1) — a release that must already exist (the owner +# creates it as a draft first; `gh release download` works against a draft +# with repo access). registry.json in the current directory is read (and, +# with --write, rewritten). # -# Inputs: TAG (e.g. v1.0.0), PLUGIN_NAMES (space-separated plugin slugs). -# Outputs: a table of plugin / computed sha256 / registry checksum / -# registry checksums.sha256 / match — to stdout. Exit 0 always -# (informational spot-check, not a CI gate); pass --strict to -# exit 1 on any mismatch against a NON-EMPTY registry value. -# Constraints: read-only against registry.json and GitHub; requires gh CLI -# authenticated + jq + sha256sum/shasum. Never edits registry.json. +# For every registry.json entry whose releaseTag equals TAG and which +# carries a checksum-eligible tarball (i.e. NOT shared-utils-style +# installable:false entries with no tarball/checksum fields at all), this +# downloads: +# - the source tarball -.tar.gz +# - if the plugin's free//plugin.json declares a binaryName (or the +# registry entry already has checksums.platforms), the five per-platform +# binary tarballs --.tar.gz +# and computes sha256 for each. +# +# Outputs: +# Default (report mode): prints ONLY the mismatches found (registry value +# vs. the freshly computed published-asset hash) and a final summary +# line; registry.json is NOT modified. Exit 0 if no mismatches, exit 1 +# if any (whether a value disagreed or an expected asset was simply +# missing from the release). +# --write: writes the computed hashes into registry.json — the flat +# `checksum` field, the nested `checksums.sha256` field (both from the +# source tarball), and `checksums.platforms.` for each +# downloaded platform asset — then reports what changed. Exit 0 on +# success, exit 1 if any expected asset could not be downloaded (in +# which case registry.json is left with whatever it already had for +# that specific field; nothing partial is written for a missing asset). +# +# Constraints: requires `gh` (authenticated, repo access — including to a +# draft release), `jq`, and `sha256sum`/`shasum`. Never touches anything +# but registry.json. Never creates or publishes a release, never tags. # # Usage: -# ./scripts/verify-published-checksums.sh v1.0.0 storage cron notify search maintenance -# ./scripts/verify-published-checksums.sh --strict v1.0.0 ollama +# ./scripts/verify-published-checksums.sh v1.2.1 +# ./scripts/verify-published-checksums.sh --write v1.2.1 set -euo pipefail REPO="nself-org/plugins" -STRICT=false +WRITE=false -if [ "${1:-}" = "--strict" ]; then - STRICT=true +if [ "${1:-}" = "--write" ]; then + WRITE=true shift fi TAG="${1:-}" -shift || true -PLUGIN_NAMES=("$@") -if [ -z "$TAG" ] || [ "${#PLUGIN_NAMES[@]}" -eq 0 ]; then - printf "Usage: %s [--strict] TAG PLUGIN_NAME [PLUGIN_NAME ...]\n" "$0" >&2 +if [ -z "$TAG" ]; then + printf "Usage: %s [--write] TAG\n" "$0" >&2 + printf " e.g. %s v1.2.1\n" "$0" >&2 + printf " %s --write v1.2.1\n" "$0" >&2 exit 1 fi +VERSION="${TAG#v}" + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REGISTRY_FILE="$(cd "${SCRIPT_DIR}/.." && pwd)/registry.json" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +REGISTRY_FILE="${REPO_ROOT}/registry.json" +PLUGINS_DIR="${REPO_ROOT}/free" WORK_DIR="$(mktemp -d)" trap 'rm -rf "$WORK_DIR"' EXIT +# Matches internal/plugin/arch.go's PlatformArch() — the same list +# scripts/build-tarballs.sh cross-compiles for a binaryName plugin. +PLATFORMS="darwin-arm64 darwin-amd64 linux-amd64 linux-arm64 windows-amd64" + log() { printf "[verify-published-checksums] %s\n" "$*"; } err() { printf "[verify-published-checksums] ERROR: %s\n" "$*" >&2; } @@ -73,55 +101,178 @@ sha256_file() { fi } +if [ ! -f "$REGISTRY_FILE" ]; then + err "registry.json not found at ${REGISTRY_FILE}" + exit 1 +fi + if ! gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1; then - err "Release $TAG not found in $REPO." + err "Release $TAG not found in $REPO (draft releases work fine with repo access — create it first)." exit 1 fi +REGISTRY_JSON="$(cat "$REGISTRY_FILE")" MISMATCHES=0 +MISSING_ASSETS=0 +DOWNLOAD_ERRORS=0 +CHECKED=0 +WRITTEN=0 + +# Fetch the release's asset list ONCE, and fetch the bytes ONCE. +# +# This used to run `gh release download --pattern ` per asset: 578 API +# calls for v1.2.1. That is slow, it trips GitHub's secondary rate limit (the +# same limit that broke the upload job at 525 assets), and — because the call +# was `>/dev/null 2>&1` — a throttled or transient download was indistinguishable +# from a genuinely absent asset and got reported as "MISSING". On the first +# v1.2.1 run that produced a false MISSING for flags/linux-arm64, an asset which +# was in fact present on the release. A checksum gate that cries missing under +# load is worse than no gate: the failure mode is to dismiss it as noise. +# +# So: list once, download everything once, then work from local files. An asset +# absent from the manifest is MISSING (a real release defect). An asset that is +# in the manifest but has no local file is a DOWNLOAD ERROR (transient/infra). +# They are counted separately and mean different things. +ASSET_MANIFEST="${WORK_DIR}/.asset-manifest" +if ! gh release view "$TAG" --repo "$REPO" --json assets --jq '.assets[].name' > "$ASSET_MANIFEST" 2>/dev/null; then + err "could not list assets on release $TAG" + exit 1 +fi +log "Release $TAG lists $(wc -l < "$ASSET_MANIFEST" | tr -d ' ') asset(s); downloading them once." + +asset_is_published() { grep -Fxq "$1" "$ASSET_MANIFEST"; } + +dl_err="${WORK_DIR}/.download-stderr" +if ! gh release download "$TAG" --repo "$REPO" --dir "$WORK_DIR" --clobber >/dev/null 2>"$dl_err"; then + err "bulk download of $TAG's assets failed; cannot verify against published bytes." + err "gh said: $(tr '\n' ' ' < "$dl_err" | cut -c1-400)" + exit 1 +fi +rm -f "$dl_err" + +# Iterate plugin names in a stable, deterministic order rather than +# registry.json's own (already-alphabetical) key order directly, so this +# script's log output is predictable even if that ever changes. +while IFS= read -r name; do + entry="$(printf '%s' "$REGISTRY_JSON" | jq -c --arg n "$name" '.plugins[$n]')" + + entry_tag="$(printf '%s' "$entry" | jq -r '.releaseTag // empty')" + if [ "$entry_tag" != "$TAG" ]; then + # Not on this release — nothing published under TAG to check it against. + continue + fi -printf "%-20s %-10s %-64s %-10s %-10s\n" "plugin" "version" "computed_sha256" "reg.flat" "reg.nested" -printf "%-20s %-10s %-64s %-10s %-10s\n" "------" "-------" "---------------" "--------" "----------" + has_checksum_field="$(printf '%s' "$entry" | jq -r 'has("checksum") or (has("checksums") and (.checksums | has("sha256")))')" + if [ "$has_checksum_field" != "true" ]; then + # e.g. shared-utils: installable:false, no tarball, nothing to verify. + continue + fi -for plugin_name in "${PLUGIN_NAMES[@]}"; do - version="${TAG#v}" - tarball_name="${plugin_name}-${version}.tar.gz" + tarball_name="${name}-${VERSION}.tar.gz" asset_path="${WORK_DIR}/${tarball_name}" - if ! gh release download "$TAG" --repo "$REPO" --pattern "$tarball_name" --dir "$WORK_DIR" --clobber >/dev/null 2>&1; then - printf "%-20s %-10s %-64s %-10s %-10s\n" "$plugin_name" "$version" "(asset not found on $TAG)" "-" "-" + if ! asset_is_published "$tarball_name"; then + printf "MISSING %s: no asset named %s on release %s\n" "$name" "$tarball_name" "$TAG" + MISSING_ASSETS=$((MISSING_ASSETS + 1)) + continue + fi + if [ ! -f "$asset_path" ]; then + printf "DOWNLOAD-ERROR %s: %s is published but was not downloaded\n" "$name" "$tarball_name" + DOWNLOAD_ERRORS=$((DOWNLOAD_ERRORS + 1)) continue fi computed_sha="$(sha256_file "$asset_path")" + CHECKED=$((CHECKED + 1)) - reg_flat="$(jq -r --arg n "$plugin_name" '.plugins[$n].checksum // ""' "$REGISTRY_FILE")" - reg_nested="$(jq -r --arg n "$plugin_name" '.plugins[$n].checksums.sha256 // ""' "$REGISTRY_FILE")" - reg_nested_norm="${reg_nested#sha256:}" + reg_flat="$(printf '%s' "$entry" | jq -r '.checksum // ""')" + reg_nested="$(printf '%s' "$entry" | jq -r '.checksums.sha256 // ""' )" + reg_nested_hex="${reg_nested#sha256:}" - match_flag="" - if [ -n "$reg_flat" ] && [ "$reg_flat" != "$computed_sha" ]; then - match_flag="${match_flag} FLAT-MISMATCH" - MISMATCHES=$((MISMATCHES + 1)) + if [ "$WRITE" = "true" ]; then + REGISTRY_JSON="$(printf '%s' "$REGISTRY_JSON" | jq \ + --arg name "$name" --arg sha "$computed_sha" \ + '(.plugins[$name].checksum) = $sha | (.plugins[$name].checksums.sha256) = $sha')" + WRITTEN=$((WRITTEN + 1)) + else + if [ -n "$reg_flat" ] && [ "$reg_flat" != "$computed_sha" ]; then + printf "MISMATCH %s: .checksum=%s published=%s\n" "$name" "$reg_flat" "$computed_sha" + MISMATCHES=$((MISMATCHES + 1)) + fi + if [ -n "$reg_nested_hex" ] && [ "$reg_nested_hex" != "$computed_sha" ]; then + printf "MISMATCH %s: .checksums.sha256=%s published=%s\n" "$name" "$reg_nested" "$computed_sha" + MISMATCHES=$((MISMATCHES + 1)) + fi fi - if [ -n "$reg_nested_norm" ] && [ "$reg_nested_norm" != "$computed_sha" ]; then - match_flag="${match_flag} NESTED-MISMATCH" - MISMATCHES=$((MISMATCHES + 1)) + + # Per-platform assets: only for plugins that actually ship a binary — + # either the registry entry already carries checksums.platforms, or the + # plugin's own manifest declares a binaryName (covers the "not yet + # populated" case, e.g. a brand-new binaryName plugin with nothing under + # checksums.platforms yet — --write should still be able to seed it). + plugin_json="${PLUGINS_DIR}/${name}/plugin.json" + bin_name="" + if [ -f "$plugin_json" ]; then + bin_name="$(jq -r '.binaryName // .implementation.binaryName // ""' "$plugin_json" 2>/dev/null || printf '')" fi - [ -z "$match_flag" ] && match_flag="ok-or-unset" + has_platforms_field="$(printf '%s' "$entry" | jq -r '(.checksums.platforms // {}) | length > 0')" + + if [ -n "$bin_name" ] || [ "$has_platforms_field" = "true" ]; then + for platform in $PLATFORMS; do + ptar_name="${name}-${VERSION}-${platform}.tar.gz" + ptar_path="${WORK_DIR}/${ptar_name}" - printf "%-20s %-10s %-64s %-10s %-10s\n" \ - "$plugin_name" "$version" "$computed_sha" "${reg_flat:--}" "${reg_nested:--}" - log " ${plugin_name}: ${match_flag}" -done + if ! asset_is_published "$ptar_name"; then + printf "MISSING %s/%s: no asset named %s on release %s\n" "$name" "$platform" "$ptar_name" "$TAG" + MISSING_ASSETS=$((MISSING_ASSETS + 1)) + continue + fi + if [ ! -f "$ptar_path" ]; then + printf "DOWNLOAD-ERROR %s/%s: %s is published but was not downloaded\n" "$name" "$platform" "$ptar_name" + DOWNLOAD_ERRORS=$((DOWNLOAD_ERRORS + 1)) + continue + fi -if [ "$MISMATCHES" -gt 0 ]; then - err "$MISMATCHES mismatch(es) between a computed checksum and a NON-EMPTY registry value." - if [ "$STRICT" = "true" ]; then - exit 1 + p_computed="$(sha256_file "$ptar_path")" + CHECKED=$((CHECKED + 1)) + + if [ "$WRITE" = "true" ]; then + REGISTRY_JSON="$(printf '%s' "$REGISTRY_JSON" | jq \ + --arg name "$name" --arg p "$platform" --arg sha "$p_computed" \ + '(.plugins[$name].checksums.platforms[$p]) = $sha')" + WRITTEN=$((WRITTEN + 1)) + else + reg_platform="$(printf '%s' "$entry" | jq -r --arg p "$platform" '.checksums.platforms[$p] // ""')" + if [ -n "$reg_platform" ] && [ "$reg_platform" != "$p_computed" ]; then + printf "MISMATCH %s/%s: .checksums.platforms.%s=%s published=%s\n" \ + "$name" "$platform" "$platform" "$reg_platform" "$p_computed" + MISMATCHES=$((MISMATCHES + 1)) + fi + fi + done fi +done < <(printf '%s' "$REGISTRY_JSON" | jq -r '.plugins | keys[]') + +if [ "$WRITE" = "true" ]; then + printf '%s\n' "$REGISTRY_JSON" > "$REGISTRY_FILE" + log "Wrote ${WRITTEN} checksum field(s) into registry.json from ${TAG}'s published assets (checked ${CHECKED} asset(s))." else - log "No mismatches against any non-empty registry checksum field." + log "Checked ${CHECKED} published asset(s) against registry.json for ${TAG}. Mismatches: ${MISMATCHES}." +fi + +if [ "$MISSING_ASSETS" -gt 0 ]; then + err "${MISSING_ASSETS} expected asset(s) are genuinely absent from release ${TAG}." + err "That is a release defect: rebuild and upload the missing artifact(s)." +fi + +if [ "$DOWNLOAD_ERRORS" -gt 0 ]; then + err "${DOWNLOAD_ERRORS} asset(s) are published but could not be downloaded." + err "That is transient (network or GitHub rate limiting), NOT a missing artifact." + err "Re-run this script; do not rebuild or re-upload anything on account of it." +fi + +if [ "$MISMATCHES" -gt 0 ] || [ "$MISSING_ASSETS" -gt 0 ] || [ "$DOWNLOAD_ERRORS" -gt 0 ]; then + exit 1 fi -log "Done. Registry.json was NOT modified by this script." +log "Done."