npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qadar-ai/disclose-stamp

v0.1.0

Published

Disclose Stamp — publisher-side CLI that embeds C2PA + IPTC AI-content marking into assets (EU AI Act Art. 50). Transparency tool, not a compliance guarantee.

Readme

Disclose Stamp — @qadar-ai/disclose-stamp

A publisher-side CLI that embeds machine-readable AI-content marking into your image files at publish time, so the marking travels with the asset even after it's downloaded — a C2PA manifest carrying the IPTC DigitalSourceType (trainedAlgorithmicMedia / compositedWithTrainedAlgorithmicMedia). It complements the on-page Disclose widget (the visible EU AI Act Art. 50(4) disclosure).

Transparency tool, not a compliance guarantee. Stamp adds a machine-readable contribution alongside provider-side marking; it does not by itself discharge the provider's Art. 50(2) duty.

Local-only / privacy. Stamp runs entirely on your machine. Your assets never leave it — nothing is uploaded to Qadar, and signing is local.

Install & use

Requires Node ≥ 22.

# stamp every JPEG/PNG/WebP/AVIF under content/ as AI-generated
npx @qadar-ai/disclose-stamp "content/**/*.{jpg,png,webp,avif}" --level ai-generated

# one file, a specific level, write to a dist dir
npx @qadar-ai/disclose-stamp hero.png --level ai-modified --out dist/

# sign with your own (trusted) certificate instead of the self-signed default
npx @qadar-ai/disclose-stamp img/*.jpg --level ai-generated --cert chain.pem --key key.pem

# also bake a visible EU label badge into the pixels
npx @qadar-ai/disclose-stamp hero.png --level ai-modified --badge \
  --badge-position top-right --badge-size lg --badge-tone black

Levels (consistent with the widget taxonomy): ai-assisted, ai-generated, ai-reviewed, ai-modified. A per-file sidecar hero.jpg.disclose.json ({ "level": "ai-generated" }) overrides --level.

| Level | IPTC DigitalSourceType | | --- | --- | | ai-generated, ai-reviewed | trainedAlgorithmicMedia | | ai-assisted, ai-modified | compositedWithTrainedAlgorithmicMedia |

Formats: JPEG, PNG, WebP, AVIF. Options: --level, --cert/--key, --out, --overwrite, --badge (+ --badge-position/--badge-size/--badge-tone), --dry-run, --help.

Visible baked-in badge (--badge)

Composites the official EU label icon (matching the widget's badge — same size ladder and positions) into the image pixels, so a human-visible mark travels with the file:

  • --badge-position top-left (default) · top-right · bottom-left · bottom-right · center
  • --badge-size sm (27px) · md (38) · lg (53) · xl (74) · 2xl (104) · 3xl (146)
  • --badge-tone black (default, dark pill) · white (light pill)

The badge family follows the level (AI · AI GENERATED · AI MODIFIED). The badge is composited before the C2PA manifest, so the manifest hashes the final pixels.

Known limit: a pixel badge survives re-encode but is destroyed by cropping and permanently alters the asset — so it is opt-in. The machine-readable C2PA/IPTC marking (always on) is the durable part.

Signing: self-signed vs trusted

By default Stamp generates a local self-signed certificate chain. The resulting C2PA marking is structurally valid and fully machine-readable — but provenance viewers will show the signer as "unverified" because the certificate isn't on the C2PA trust list.

Untrusted signer ≠ invalid AI assertion. The "unverified signer" note is about who signed (identity), not about the AI-disclosure content. The DigitalSourceType marking is present and readable regardless. To remove the note, sign with a trusted certificate via --cert/--key.

(DE) Nicht vertrauenswürdiger Signierer ≠ ungültige AI-Kennzeichnung. Der Hinweis „Signierer nicht verifiziert" betrifft nur die Identität des Signierers, nicht den Inhalt der AI-Kennzeichnung. Die DigitalSourceType-Markierung ist vorhanden und maschinenlesbar. Mit einem vertrauenswürdigen Zertifikat (--cert/--key) entfällt der Hinweis.

What survives

The embedded C2PA + IPTC marking is present after a download and local open, and major platforms (TikTok/YouTube/Meta/LinkedIn/Pinterest) read C2PA at upload and can re-label. Most social platforms re-encode and strip embedded metadata, so surviving a social re-upload needs durable watermarking — that is a planned v2 (not in this release).

API

import { generateSelfSignedSigner, stampBuffer, readStamp } from '@qadar-ai/disclose-stamp';

const signer = await generateSelfSignedSigner();
const stamped = stampBuffer(pngBuffer, 'image/png', 'ai-generated', signer, '0.1.0');
const info = await readStamp(stamped, 'image/png'); // { hasManifest, title, digitalSourceType }

Publishing (maintainers)

Publishing is gated and manual — the Publish disclose-stamp to npm workflow only runs via workflow_dispatch and defaults to a dry run. It uses npm OIDC Trusted Publishing (no long-lived token). npm requires a package to exist before a trusted publisher can be configured, so the first publish is manual:

  1. First publish (creates the package). From stamp/ with dist built, sign in with 2FA and npm publish — this creates @qadar-ai/disclose-stamp on npm. (OIDC/CI cannot create a brand-new package.)
  2. Add the Trusted Publisher. At npmjs.com/package/@qadar-ai/disclose-stamp/accessTrusted Publisher: Organization/user qadar-ai · Repository disclose · Workflow filename publish-stamp.yml · Environment name npm-publish · Allowed action npm publish (must be explicitly selected for configs created after 2026-05-20).
  3. Every later publish is CI-only. Push a stamp-vX.Y.Z tag, then dispatch the workflow with dry_run=false. No token; npm authenticates via OIDC. Provenance attaches automatically once the repository is public.

License

MIT © Qadar AI. Built on the Content Authenticity Initiative's C2PA tools (@contentauth/c2pa-node, Apache-2.0/MIT), @peculiar/x509, and sharp.