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

@dmfaster/sdk

v1.4.0

Published

Typed client for the DM Faster Agent API.

Readme

@dmfaster/sdk

Typed Node.js client for DM Faster Agent 1.0. It exposes bounded workspace inspection, stateless campaign planning, exact audience previews, idempotent private-draft preparation, and authorized campaign controls through a scoped, workspace-bound dmf_pat_… token.

Distribution note: the registry command below works only after this exact release is published. Before then, maintainers use the built package from an authorized source checkout.

npm install @dmfaster/[email protected]

Non-loopback endpoints must use HTTPS. The client also refuses HTTP redirects so the bearer token cannot be forwarded to a different origin.

import { createDmfasterClient } from "@dmfaster/sdk";

const client = createDmfasterClient({
  baseUrl: process.env.DMFASTER_API_URL!,
  token: process.env.DMFASTER_TOKEN!,
});

const result = await client.invoke("campaigns.list", {
  status: "Running",
  limit: 10,
});

Campaign planning calls take the complete latest campaign state. This keeps the public API stateless while allowing any client to resume, validate, or hand the plan to another agent. Launch and pause are two-step operations: request a preflight, let the owner approve the exact campaign version in DM Faster, then invoke the action with the returned authorization ID and the same idempotency key. Repeating the exact preflight reads the existing authorization status. A client-supplied approved boolean is never accepted as authorization.

Launch preflight is a discriminated result. status: "setup_required" supplies a human-owned browser setup URL and the exact preflight input to resume while the campaign remains disabled. status: "approval_required" supplies the version-bound authorization and approval URL. Browser setup never substitutes for launch approval.

The caller must provide an absolute API base URL and a scoped bearer token. The SDK sends tool inputs directly to POST /api/v1/agent/tools/{toolName}, applies a bounded timeout, and validates the shared result envelope before returning it.

Import Instagram usernames

Save a reviewed username collection as a private list:

dmfaster list import --name "Finland Coaches" --file instagram-usernames.csv --json

Use a one-column CSV with an optional username or instagram_username header, or one username per line. UTF-8 BOM, quoted cells, and CRLF are supported. Up to 1,000 rows and 64 KiB are accepted. Invalid rows reject the whole import. Case and leading @ are normalized; duplicates are reported and removed. The command derives a stable retry key from the name and unique usernames; supply a new --idempotency-key to intentionally create another copy.

The SDK equivalent is client.invoke("list.import", { name, usernames, idempotencyKey }). It requires campaigns:write and owner access, and is available on all plans including Basic. A successful result contains listId, name, importedCount, inputCount, duplicateCount, created, and replayed. A changed payload or an edited saved list returns idempotency_conflict. The list is selectable in the campaign builder; no campaign is created and nothing is sent. Import validates syntax, not live Instagram account existence.

Existing Instagram lists (1.1.0)

Find a saved list, check the whole audience for an exact username, remove a requested target, and prepare an unstarted campaign through the same contract:

dmfaster lists list --query "Coaches" --json
dmfaster list inspect LIST_ID --username pt.j.jylha --json
dmfaster list target remove LIST_ID --username pt.j.jylha --expected-version INSPECTED_UPDATED_AT --json
dmfaster campaign draft prepare --input draft.json --json

Draft JSON contains listId, expectedListUpdatedAt, expectedTargetCount, name, messageVariants (1–4 strings), dailyCap, pacingSeconds, onlyNewChats, skipPreviouslyMessaged, and idempotencyKey. Use the version and exact total from the latest inspection/removal. Preparation verifies the saved copy and settings and always returns a disabled Draft. It does not start or arm sending. Reusing a key with different settings or an edited audience fails without changing the original campaign.

SDK operation names are lists.list, list.inspect, list.target.remove, campaign.draft.prepare, and campaign.draft.update; MCP names replace dots with underscores. List reads require campaigns:read; removal requires owner campaigns:write; draft preparation requires both scopes. No company-search entitlement is needed for these Instagram lists. Existing campaign launch/pause approval is unchanged.

Instagram campaigns always exclude known contacts: onlyNewChats and skipPreviouslyMessaged must both be true. Unsupported values are rejected before a draft is created.

To change an existing disabled Instagram draft, use dmfaster campaign draft update --input update.json --json. Supply campaignId, expectedCampaignUpdatedAt from campaign inspection, and a nonempty updates object containing any of name, messageVariants, dailyCap (1–60), or pacingSeconds (12–3,600). Omitted settings and the audience are preserved. Stale versions and started campaigns are rejected. After an uncertain response, inspect the campaign before retrying. No launch approval is needed to edit a disabled draft.

Automatic sending windows are also editable through campaign.draft.update: instagramSendingWindowEnabled is a boolean; instagramSendingWindowStartMinute is 0–1380; instagramSendingWindowEndMinute is 60–1440; and instagramSendingWindowWeekdays is a bitmask from 1–127 (Monday=1, Tuesday=2, through Sunday=64; Monday–Friday=31). The interval must span at least 60 minutes in the same day. Times use the workspace timezone returned by campaign.inspect in settings, alongside the current window, copy, pacing, and enabled state. Send both endpoints when changing the interval. A saved window can be toggled on or off while the draft stays disabled; only the separate launch operation arms the schedule. Started campaigns cannot be edited with this draft tool.

Direct campaign control (1.4.0)

An owner can grant campaigns:control once when connecting an agent with the full profile. Explicit user instructions then suffice for launch or pause: preflight returns ready and a version-bound authorization ID for immediate execution. The normal action scope is still required. Existing credentials retain per-action approval until the owner reconnects and grants this permission. Planning or preparing a campaign never authorizes launch.