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

@connectx-sdk/cli

v0.4.0

Published

connectx scaffolding CLI — scaffold a starter project (init), generate a typed config (generate), and drive agent identity/login/sign.

Readme

@connectx-sdk/cli

Scaffold and drive @connectx-sdk/core (ANP-02) identity from the command line. This package ships the connectx binary — a separate package from the @connectx-sdk/core SDK library so the runtime library stays dependency-free for the browser.

Commands

# DID server — register, manage and update a DID. DID protocol only, no wallet.
connectx did create      generate a key for this (agent, profile) and store it — no DID yet
connectx did show        print the stored identity and where the key lives (no network);
                         before `did register` it prints the public key and says there is no DID
connectx did list        list the agents stored on this machine (no network)
connectx did register    claim a handle on the DID server — this is where the host and the DID come from
connectx did resolve     ask a DID's host what it publishes right now (--chain walks an update)
connectx did update      retire this identity's key and hand the hop to the DID server (--target)
connectx did update      --resume — settle an uncertain delivery by ASKING which DID is current
connectx did restore     recover this identity from a recovery key (in development)

# ANP server — sign in to an application, and sign requests. Takes a DID or a wallet.
connectx anp show        print the identity this agent signs as (DID, or a CAIP-10 wallet account)
connectx anp login       sign + POST, handle the 401 re-sign loop, print the token
connectx anp sign        produce RFC 9421 headers only (no network)

# which agent the commands above act as, when the invocation names none
connectx agent show      print the agent in force and which step decided it
connectx agent use <id>  make the later commands act as this agent
connectx agent list      list the agents stored here, the current one marked

connectx project init    scaffold a starter project (react-vite | nextjs | node-agent | vanilla)
connectx project generate  read connectx.config.ts, emit a typed connectx.generated.ts
connectx version         print the CLI version

A did:wba DID names the server that hosts it, so the host belongs to the DID server, not to this machine: did create mints a key and nothing else, and did register is the moment the host, the handle and the DID all land in identity.json. Until then the identity has no DID, and commands that need one say identity_not_registered rather than composing a DID under a host no server agreed to.

Scaffold

npx @connectx-sdk/cli project init my-app --template node-agent --host localhost --connectors cli --no-install

Interactive when run without --template; fully scriptable (CI / agent) when the flags are supplied.

Codegen

connectx project generate --init-config writes a connectx.config.ts (typed by defineConfig); connectx project generate loads it and emits connectx.generated.ts with a typed config and loginAs<Connector> / signRequestAs<Connector> / registerAs<Connector> wrappers keyed by connector id — so callers stop passing string connector ids.

Agent identity

The two groups answer different peers. did speaks to the DID server (DID protocol only, so no page there takes a wallet); anp speaks to the application, where a stored key and a web3 wallet are two sources of the same thing — a signature.

# local key (explicit --key, non-default path; the agent holds the key)
connectx anp login   --target https://host/api/login/anp/verify --key ./id.pem
connectx did register --target https://host/api/login/anp/register --handle alice --key ./id.pem
connectx anp sign    --target https://host/api --method POST --key ./id.pem

# the store route (recommended: no key material on the command line after this)
connectx did create
connectx did register --target https://host/api/login/anp/register --handle alice
connectx did show

# web3 wallet (EIP-1193 provider injected as --provider <module>; key stays in the wallet)
connectx anp show --wallet web3 --provider ./provider.mjs --address 0xabc --chain-id eip155:1

anp login / did register print the server's session token ({ did, token }). Pass it back as Authorization: Bearer <token> on subsequent requests. After a successful did register, the stored identity's identity.json gains registered: true, the host, the DID, the stable subject and the accepted handle (a key supplied via --key / $ANP_PRIVATE_KEY has no sidecar, so nothing is written); a handle the server rejects as taken is reported as such instead of as an opaque 409. did show / anp show read that sidecar and nothing else — bare key material has no identity to show, so they take no --key.

DID resolve

connectx did resolve did:wba:example.com:user:alice:e1_abc --allow-host example.com
connectx did resolve did:wba:example.com:user:alice:e1_abc --chain --allow-host example.com --json

A thin shell over the SDK's document / update-chain queries: --chain follows deactivated + successorDid links to the DID that is current now and reports each hop's assurance. Resolution always goes to the network — a copy on disk never answers for it; what it leaves behind is a copy of the served document when the DID is this identity's own, recorded beside it as did.json. The DID's own host is the only host ever contacted (an update chain cannot leave it). Two host flags cover the network policy, and naming a host is the whole confirmation:

| Flag | What it opens | |---|---| | --allow-host <h> | required, repeatable: may resolve via this host (hostname only, no port). localhost, 127.0.0.1 and ::1 are additionally allowed to be private and to answer over http, automatically | | --allow-private-host <h> | a host that is local without being spelled that way may be private and may answer over http |

Exit codes — this subcommand only; every other command is 0 or 1:

| Code | Meaning | |---|---| | 0 | the DID is current | | 2 | the DID is not current: the chain walked on, or the document is a retirement | | 3 | the update chain did not verify (did_chain_broken) | | 1 | anything else: network, policy, bad input |

DID update

connectx did update --target https://did.example.com/update

The write half: generate a new key for the same stable subject, have the SDK sign the retirement document (old key) and the successor's active document (new key), and POST the pair to --target. --target is required and never derived — ANP-03 §2.5.3 defines what a hop must contain and leaves the programmatic management interface out of scope, so the endpoint is the DID server's own contract.

The retirement document is built on the document the DID server has on file, not on one composed here: §2.5.3 says the old document gets deactivated + successorDid and the proof covers everything it carries, so a composed document would retire a different document than the one being superseded (no service endpoint, no keys added out of band). The base comes from the did.json copy, else one fetch from the identity's own host, else a composed document — and that last fallback is printed, never silent.

The order is the design: the successor key is staged to key.next before anything is sent, and the store only moves after the server accepts — so a crash in between can never lose the only key to the DID that was superseded to. On a failure the store never moves; a settled failure (not_supported and friends) drops the staged key, while an ambiguous one (a dropped connection) keeps it and prints its path, because the hop may well have been accepted. subject / registered / handle / createdAt are carried over: from the inside this is the same agent with a new key.

--target never settles an ambiguous delivery, so connectx did update --resume does it the only honest way: it asks. The staged key.next derives the successor DID, resolveDidChain asks the identity's own host which DID it serves, and only a match promotes the key. If the host still serves the old DID the hop never landed and the staged key is dropped; if it serves a third DID something else moved the identity on, so both files are left untouched — that key may be the only thing a later hop needs.

License

MIT