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

sdtk-marketing-kit

v0.10.0

Published

Standalone local-first governed-marketing CLI: measured KPI digest, a blocking truthfulness/claims linter (check), an eval-first campaign engine (campaign/attribution/eval), a channel registry (gate status, owned vs rented), an asset truthfulness gate (ca

Downloads

1,682

Readme

sdtk-marketing-kit

Governed, honest, measured marketing operations — local-first, free, MIT.

The SDTK governance kernel applied to marketing: this toolkit enforces truthfulness (you cannot ship an overclaim or a faked "demo"), measures before it targets, and treats human approval as a code gate, not a setting. It is designed to be operated by an agent (Hermes) and gated by a human. Phase 1 ships the two most-proven pieces: a measured KPI digest and a blocking truthfulness linter.

Install

npm i -g sdtk-marketing-kit
sdtk-marketing help

Requires Node ≥ 18.

Commands (Phase 1)

sdtk-marketing check <file|dir>…

Lint marketing post copy for truthfulness (BR-03 / honest-scorecard). Exits 1 on any error.

  • Blocking errors — claims that violate the "claims-NOT-made" discipline: trusted by, unverified adoption/user counts, revenue figures (MRR/ARR), productivity multipliers ("10x faster"), zero-touch / unattended / live-bot claims (negated honest usage like "nothing here is zero-touch" is allowed).
  • Warnings (review, non-blocking) — framings that are only truthful next to a real asset: unedited, real/raw demo, screen recording; and a stated-count-mismatch heuristic (catches "Six palettes (a · b · c · d · e · f · g)" = 6-vs-7).
  • Flags: --json (structured output for an agent), --strict (warnings also block), --stdin (lint copy piped in — the agent-gate path: pipe the exact publishable text so meta docs and asset notes don't cause false positives).
printf '%s' "$post_body" | sdtk-marketing check --stdin --json   # exit 1 blocks the post

Point it at post copy, not meta docs. Governance/analysis docs that discuss the banned terms (proposals, audits) will trip the rules by design — lint the actual posts you're about to publish.

sdtk-marketing check governance/marketing/SDTK_FB_POST5_*.md --json

sdtk-marketing digest

Measured weekly KPI digest: npm downloads · github stars/forks/issues · plausible visitors · lemonsqueezy orders · facebook followers.

  • npm + github need no keys. The rest read keys from env; unset keys print not configured — a valid state, not a failure (sections light up as you provision keys).
  • A configured section that fails prints FAILED: <reason> and the run exits 1 (fail-loud).
  • 0 is a real value (e.g. lemonsqueezy: orders 7d 0 is a PASS), never hidden.
  • Env: PLAUSIBLE_API_KEY/PLAUSIBLE_SITE_ID, LEMONSQUEEZY_API_KEY, FACEBOOK_PAGE_ACCESS_TOKEN/FB_PAGE_ID; overrides MKT_NPM_PACKAGES, MKT_GITHUB_REPO. Flag: --json.

campaign · attribution · eval — the eval-first engine (P2.1)

Pre-register a distribution campaign's success criteria, record each channel's measured funnel, and get KEEP / ITERATE / TRIM verdicts. Thresholds lock at campaign start so a result can't be rationalised after the numbers land. The funnel is visitor → pack download → order.

sdtk-marketing campaign start distribution-r2 --goal "find dev/maker channels" \
    --window-hours 72 --keep-visitors 30 --keep-downloads 3 --trim-visitors 10
sdtk-marketing attribution record distribution-r2 --channel devto --visitors 41 --downloads 5 --orders 0
sdtk-marketing eval distribution-r2 [--json]
#   [KEEP   ] devto: 41v → 5d → 0o  (v→d 12.2%)  ↳ ≥30v AND ≥3d — make it a repeatable slot
  • Decision: KEEP = visitors ≥ keep-visitors AND downloads ≥ keep-downloads; TRIM = visitors < trim-visitors; ITERATE = the middle band, or visitors-ok-but-downloads-short.
  • Ledger: .sdtk/marketing/campaigns/<id>/ (campaign.json + attribution.json) — file-backed, resumable, --json for an agent. Override the root with SDTK_MARKETING_HOME.
  • Attribution — auto or manual. attribution pull <campaign> auto-fills each channel's visitors/downloads from the Plausible Stats API per utm_source (needs PLAUSIBLE_API_KEY + PLAUSIBLE_SITE_ID; pulls for channels in the channel registry that have a utm). Or record by hand with attribution record. Per-channel orders stay manual — Lemon Squeezy checkout carries no UTM. The value is applying locked thresholds to measured numbers.

channel — the distribution registry (P2.2)

Tracks each channel's gate status and whether it's owned vs rented, so an agent proposes a postable channel instead of hitting a wall (the lesson from every quality channel gating posting — Reddit karma, IH earned privilege).

sdtk-marketing channel add devto --type rented --status open --gate none --utm devto --reach "dev/maker SEO, evergreen"
sdtk-marketing channel add indiehackers --type rented --status warming-up --gate "earned posting privilege"
sdtk-marketing channel status indiehackers ready     # flip when the gate clears
sdtk-marketing channel list                          # splits POSTABLE-NOW vs earn-in
  • status: open / ready = postable now; warming-up / blocked / trimmed / paused = not.
  • type: owned (email/site — no gate, no algorithm) vs rented (borrowed reach, plays by a gate).
  • Ledger: .sdtk/marketing/channels.json. --json for an agent.

capture · asset verify — the asset truthfulness gate (P2.3)

The visual counterpart to check: an evidence_capture must be a real recording of the real product — a generation tool (ComfyUI/LTX/WAN/Remotion) can never produce evidence; a generated_creative may only be cosmetic and must declare a truthfulness boundary.

# produce provenance-stamped evidence from a LIVE url (pixel grab delegated to your browser tool)
export SDTK_MARKETING_CAPTURE_CMD='node scripts/shot.js {url} {out}'   # operator-configured
sdtk-marketing capture https://sdtk.dev/pricing --out assets/pricing.png --id post5-pricing

# register an AI-generated cosmetic asset (must declare what it may/may not imply)
sdtk-marketing asset add hero-titlecard --role generated_creative --method remotion \
    --truthfulness "cinematic title card — cosmetic only, never implies it is the product"

sdtk-marketing asset verify --all       # exit 1 if any evidence asset is fake / any creative lacks a boundary
  • The gate: evidence_capture needs a real capture method (browser_capture/screen_record) + a source_url; an AI method in an evidence slot FAILS. generated_creative needs a truthfulness_boundary. Exit 1 on any error.
  • capture is honest: it stamps browser_capture provenance only after a real capture actually produced the file (via SDTK_MARKETING_CAPTURE_CMD); the kit stays dependency-free and never fabricates provenance.
  • Ledger: .sdtk/marketing/assets/<id>.json.

report — the campaign scorecard (P3)

Composes a campaign's locked thresholds + recorded funnel into a scorecard, and a measured-only draft post in the honest-scorecard voice — the loop feeding itself. The draft is measured by construction, so it passes check:

sdtk-marketing report distribution-r2                 # operator scorecard (verdicts + totals)
sdtk-marketing report distribution-r2 --post \
  | sdtk-marketing check --stdin                      # the draft post, self-verified truthful

video — reproducible video-build workflows (Phase 3a)

An agent builds channel videos by naming an exact, reproducible workflow — the kit holds the definition + honesty rules, the box does the render. The four installed backends (ComfyUI, LTX-2.3, WAN-2.1, Remotion) collapse to two delegate commands, mirroring capture so the kit stays dependency-free:

sdtk-marketing video list                              # the registry (id · purpose · backend · honesty)
sdtk-marketing video show tutorial-feature-walkthrough # the exact recipe + which delegate env it uses
sdtk-marketing video run tutorial-feature-walkthrough \
  --capture usage.cast --feature usage                 # render → record an honest asset → re-verify
sdtk-marketing video run intro-spectacle --dry-run     # print the exact backend command, render nothing
  • Delegated render: the box supplies SDTK_MARKETING_VIDEO_CMD_REMOTION / SDTK_MARKETING_VIDEO_CMD_COMFYUI (templates with {graph} {capture} {input} {out}). Unset → fail-closed, nothing stamped.

  • Output stays outside the kit: MP4 lands under SDTK_MARKETING_ASSET_HOME (the ledger keeps definitions + provenance, not bytes).

  • Honesty is enforced twice (D3): a tutorial/review is evidence_capture and requires a real --capture (a vhs/screen_record recording of the actual CLI) — the kit will not fabricate a tutorial from a generator; ComfyUI/LTX/WAN output is generated_creative, allowed for intro/b-roll only and must carry a truthfulness boundary. The produced asset is then re-checked by the same asset verify gate.

  • Quality gate: honesty isn't enough — a tiny/short stub render passes every honesty check and still wastes an upload. Each workflow declares minimum specs; the runner probes the real output via SDTK_MARKETING_VIDEO_PROBE_CMD (a {file} template) and a sub-spec render fails closed instead of being recorded. If no probe is configured, the gate is skipped with a warning.

    Size and duration alone were not enough, twice: a 1920×1080 / 300 s render passed and turned out to be a slideshow (frozen 97.7 % of its runtime), and the motion gate added to fix that then passed a moving empty screen (27 % near-blank frames). So the probe may also report motion and content, and a workflow may gate on them:

    | Probe field | Workflow threshold | Catches | |---|---|---| | median_mafd | min_median_mafd | a render that barely moves | | frozen_ratio | max_frozen_ratio | a slideshow | | edge_density | min_edge_density | an empty screen | | luma | luma_range | too dark to read, or blown out |

    The probe accepts either the original "<w> <h> <duration>" or key=value pairs:

    width=1920 height=1080 duration=75 median_mafd=0.544 frozen_ratio=0.485 edge_density=3.8 luma=182

    Existing probe commands keep working untouched — a threshold whose field the probe does not report is announced as NOT ENFORCED rather than silently passing.

  • video calibrate — derive your own thresholds. The shipped numbers were calibrated on light-mode product UI plus one dark-composite film, and each workflow carries a calibrated_against note saying so. They are not universal: a threshold picked by intuition once rejected a capture that measured better than the reference film's own signature frame. Point this at footage you consider good and paste the result into your workflow:

    sdtk-marketing video calibrate ref-a.mp4 ref-b.mp4          # measured spread + suggested fields
    sdtk-marketing video calibrate ref-a.mp4 --margin 0.2 --json

    None of these gates certify that a video is good. They rule out defects that were actually hit. Watch it before you publish it.

publish youtube / publish facebook — attended, sha-gated video publish (Phase 3b/3c)

A video reaches YouTube (or a Facebook Page) only after the owner approves this exact payload. The upload is impossible without a matching approval sha, so an agent cannot auto-post even if told to:

# 1) prepare — verifies the asset, guarantees the UTM, check-gates the copy, prints a payload sha
sdtk-marketing publish youtube tutorial-usage \
  --title "How I run sdtk usage in 60s" --description-file desc.md --tags "sdtk,cli,devtools"
#    → prints the drafted metadata + `payload sha256: <hex>` and uploads NOTHING

# 2) approve — re-run the identical command with the sha; only a MATCH uploads
sdtk-marketing publish youtube tutorial-usage \
  --title "How I run sdtk usage in 60s" --description-file desc.md --tags "sdtk,cli,devtools" \
  --approve <hex>
  • The asset gate first: publish refuses an asset that fails asset verify (no faked evidence ships) and refuses if the MP4 is missing on disk.
  • The copy gate: the title + description run through check — an overclaim blocks the publish.
  • Attribution built in: the description is guaranteed to carry sdtk.dev/heroes?utm_source=youtube&utm_medium=video&utm_campaign=<id>, and a successful publish upserts the youtube channel — so attribution pull measures it automatically.
  • Delegated upload, no secrets in the kit: the actual upload runs via the box's delegate (SDTK_MARKETING_PUBLISH_CMD_YOUTUBE / SDTK_MARKETING_PUBLISH_CMD_FACEBOOK_VIDEO, a {file} {title} {description-file} {tags} {privacy} template); the OAuth/Page token lives on the box. Unset → fail-closed, nothing uploaded.
  • Conservative by default: --privacy defaults to the safest state per platform (youtube unlisted, facebook unpublished) — the sha-gate approves the upload; going fully public stays a separate deliberate flip on the platform.
  • Drift = fail-closed: change any metadata after approval and the sha no longer matches — the upload is refused until the new payload is re-approved. The channel and payload are part of the hash, so a YouTube approval can never be replayed against Facebook.

What's coming (see the toolkit proposal)

An MCP / n8n surface exposing the whole governed spine (check · eval · video · publish) to an agent runtime. The attended schedule / gate approve / publish loop is provided by HerSocial today; this kit standardizes it.

Design principles

  • Never auto-publish; never fabricate a metric or a claim; AI only for cosmetic assets.
  • Not a spam / mass-posting tool — respects channel gates, eval-first.
  • File-backed and resumable; every command emits --json for an agent operator.

Develop

npm test   # node scripts/marketing-smoke.test.js — offline, no network

License: MIT.