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

@clink-ai/clink-cli

v0.2.0

Published

TypeScript CLI for Clink customer wallet APIs

Readme

clink-cli

clink-cli is a command-line client for Clink customer wallet APIs.

中文说明

Install

Install globally:

npm install -g @clink-ai/clink-cli

Run without installing globally:

npx @clink-ai/clink-cli --help

Published package name:

@clink-ai/clink-cli

Installed commands:

clink-cli
clink

clink is a shorter alias that invokes the same CLI as clink-cli.

Requirements:

  • Node.js >=20
  • Access to the target Clink API environment

Default base URL:

https://api.clinkbill.com

Quick Start

Every command starts with:

clink-cli <command> [subcommand] [options]

1. Initialize your wallet

Run this once to authorize the CLI and save OAuth credentials locally:

clink-cli wallet init --email [email protected] --name "Alice"

For sandbox, run wallet init with --sandbox. The CLI prints the browser URL and attempts to open it automatically. If the browser cannot be opened, the CLI prints a warning and continues polling; open the displayed URL manually on any device. Complete email verification and confirmation in the browser while the CLI polls for tokens. Existing customers keep their server-side name; --name is only used when creating a new customer and is always saved to local config.

The browser URL keeps only user_code in the query string. The supplied email and name are carried in the URL fragment, which the Portal reads and immediately removes from the address bar.

clink-cli wallet init --sandbox --email [email protected] --name "Alice"

After authorization succeeds, wallet init also refreshes local cached payment methods from the card setup-link endpoint. If that refresh fails, initialization still succeeds and the output marks paymentMethodsCached: false.

Access and Refresh Tokens are stored in the root authorization object in ~/.clink-cli/config.json. The CLI refreshes shortly before Access Token expiry, and atomically replaces both tokens because the server rotates the Refresh Token on every refresh. The saved authorization also records its issuer origin; the CLI never sends either token to another origin. If an OAuth-authenticated Agent API request returns 401, the CLI refreshes and retries that request once. A second 401 and all 403 responses are returned without another refresh.

Check the saved local config:

clink-cli wallet status --format pretty

Log out and remove local credentials:

clink-cli wallet logout

The local config file is stored at:

~/.clink-cli/config.json

2. Open card pages

Get the raw binding link:

clink-cli card binding-link

Open the add-card page:

clink-cli card setup-link --open

Open the manage-card page:

clink-cli card modify-link --open

3. Check saved payment methods

List cached payment methods:

clink-cli card list --format pretty

Get one cached payment method:

clink-cli card get --payment-instrument-id pi_xxx

Notes:

  • card add/update/delete happens on the web page, not in the CLI
  • card list and card get read local cached data
  • card binding-link, card setup-link, and card modify-link refresh the local payment method cache

4. Make a payment

Pay with merchant mode:

clink-cli pay \
  --merchant-id merchant_xxx \
  --amount 10.00 \
  --currency USD \
  --payment-instrument-id pi_xxx

Pay with session mode:

clink-cli pay --session-id sess_xxx --payment-instrument-id pi_xxx

VIC-routed charge with instruction/mandate context:

clink-cli pay \
  --session-id sess_xxx \
  --payment-instrument-id pi_xxx \
  --instruction-id ins_xxx \
  --mandate-id mndt_xxx \
  --shipping-address '{"street_address":"1 Market St","address_locality":"San Francisco","address_region":"CA","address_country":"US","postal_code":"94105","first_name":"Ada","last_name":"Lovelace","phone_number":"+14155550100"}' \
  --products '[{"productId":"sku_1","productName":"Demo","quantity":1,"unitPrice":12.99,"currencyCode":"USD"}]'

If --payment-instrument-id is omitted, pay uses the default cached payment method. --purchase-instruction-id remains as a backward-compatible alias for --instruction-id. --shipping-address maps to aiAgentInstructionBo.shippingAddressJson and should use the UCP Postal Address shape (street_address, address_locality, address_region, address_country, postal_code, first_name, last_name, phone_number). --products maps to aiAgentInstructionBo.products in the Clink order charge request; unitPrice is a major-unit decimal.

List all public skills

clink-cli skills list --all --format pretty
clink-cli skills list --all --tippable --format pretty

The command requests the dashboard marketplace with pageSize=999&sort=NEW. Every list first removes rows without nonempty publisher, name, or versionNo. --tippable additionally requires nonempty skillId and merchantId, parses the tipsConfigJson string, and keeps only records whose parsed configuration has the boolean value enabled: true. Missing, malformed, disabled, or string-typed enabled configurations are filtered without failing the command. The CLI then reverses the selected rows, injects contiguous one-based Number values, and returns the JSON array in the normal { "ok": true, "data": [...] } success envelope.

Tip a skill publisher

clink-cli skills tip --publisher clinkpay --name PollyReach --amount 2
clink-cli skills tip --publisher jinsx商户四 --name PollyReach --amount 2
clink-cli skills tip --publisher '草诀歌AI Labs' --name 'SEO Deep Audit' --amount 2

Skill tips always use USD and accept any positive finite amount. The CLI resolves a case-insensitive exact --publisher/--name match. Publisher and skill names accept Unicode letters, numbers, including Chinese, and internal ASCII spaces. Quote values containing spaces. CLI tips always use sort=NEW to select the latest Marketplace version. Successful output includes the resolved versionNo when the Marketplace supplies it.

The CLI uses only the selected marketplace record's merchantId and ignores tipsConfigJson. It refreshes the payment-method list and selects only a record with explicit isDefault=true. If no explicit default exists, the command returns HTTP-style code 422 with No default payment method before creating an order. A default CARD is sent to the charge API without checking Credit balance. A default BALANCE is sent only when its finite numeric availableBalance covers the full tip amount; a missing, invalid, non-finite, or insufficient balance returns 402 with Credit 余额不足,请先绑定银行卡. An unsupported explicit default type returns 422 with Unsupported default payment method. The backend calculates any Credit allocation.

After the synchronous payment response confirms success (channelPaymentResponse.status=1), and when the marketplace record includes skillId, the CLI best-effort reports the tip metric to the resolved dashboard base: POST /prod-api/skill-marketplace/internal/skills/{skillId}/metrics/tip. The metric uses only the response-verified latest Marketplace versionNo selected by the pre-payment sort=NEW lookup. The request body contains the payment orderId, locked versionNo, major-unit amount, currency, and the fixed source: "CLINK_PAYMENT". A metrics failure does not change the successful payment result. Failed and 3DS-pending payments are not reported.

Explicit terminal agent-pay failures return payment_failed with exit code 5. Missing or unknown agent-pay statuses return payment_unknown with exit code 6 and must be verified before retry. Tip results also expose the channel's original rawPaymentStatus, rawPaymentMessage, and complete payment payload so callers can diagnose the response without losing the compatibility status.

5. Manage UCP checkout for shadow merchants

Create a UCP checkout session for a CLI-discovered merchant:

clink-cli ucp-checkout create \
  --merchant-url https://shop.example/checkout/abc \
  --merchant-category-code 5311 \
  --currency USD \
  --line-items '[{"id":"li_1","item":{"id":"sku_1","title":"Demo","price":"10.00"},"quantity":1}]'

For ucp-checkout create, line_items monetary price / amount fields are decimal major-unit values; the CLI converts them by --currency before calling the external checkout API. The API body sends customer_id and buyer.email from the local clink-cli config get --format json data, and sends --currency as context.currency.

Then query, update, complete, or cancel it:

clink-cli ucp-checkout get --checkout-id chk_xxx
clink-cli ucp-checkout update \
  --checkout-id chk_xxx \
  --line-items '[{"id":"li_1","item":{"id":"sku_1","title":"Demo","price":1200},"quantity":1}]'
clink-cli ucp-checkout complete --checkout-id chk_xxx
clink-cli ucp-checkout cancel --checkout-id chk_xxx

By default these commands call {baseUrl}/agent/ucp/external/checkout-sessions. To point at a custom UCP endpoint prefix, pass --endpoint https://host/path; the CLI appends /checkout-sessions, /checkout-sessions/{checkoutId}, or the corresponding action path.

Notes:

  • the CLI command is ucp-checkout; there is no external subcommand
  • CLI-discovered merchants use the shadow-merchant external checkout path internally
  • create sends merchant_url, customer_id, buyer.email, and context.currency; the backend resolves authorization and order_channel_id
  • complete sends a standard UCP payment.instruments object; the selected instrument id is local config customerId#paymentInstrumentId, credential.token is the payment instrument ID, and when --payment-instrument-id is omitted or empty it uses the cached default card
  • Idempotency-Key is generated by the CLI for create/update/complete; callers do not pass --idempotency-key
  • OAuth Bearer authorization is required after a wallet first uses OAuth; legacy CSK remains only for never-OAuth wallets

6. Refund an order

Create a full refund:

clink-cli refund create --order-id order_xxx

Check refund status:

clink-cli refund get --refund-id rfd_xxx

7. Check risk rules

Get current risk rule settings:

clink-cli risk get --format pretty

Open the risk rule page:

clink-cli risk link --open

Install agent skills

Install a specific release, let the server select the latest release, replace an unmanaged installation, or preview the operation:

clink-cli skills install clinkpay/[email protected]
clink-cli skills install clinkpay/PollyReach
clink-cli skills install clinkpay/PollyReach --force
clink-cli skills install clinkpay/PollyReach --dry-run --format pretty

The package format is <publisher>/<skillName>[@<version>]. When the version is omitted, the CLI omits versionNo from the request and lets the server select its latest release. It does not infer or report a resolved semantic version for that archive. Publisher and skill names may contain Unicode and internal ASCII spaces; quote the complete package identity when it contains spaces.

Download and install behavior

The CLI uses the existing base URL resolution and precedence described under Configuration, derives the matching dashboard base, then requests a short-lived download URL:

GET /prod-api/skill-marketplace/public/skills/download-url?publisher=...&skillName=...[&versionNo=...]

Clientid is sent only to this Clink dashboard endpoint, never to the signed download URL. The signed URL is treated as a secret and is never printed. --timeout applies to network operations; signed package downloads use at least 300000 milliseconds so slower transfers can finish. --dry-run performs no network requests and makes no filesystem changes; it only prints the planned result. Results support JSON and pretty output. Per-agent statuses are linked, shared, copied, unchanged, or unsupported.

The installer accepts raw single-Skill files and ZIP packages:

  • A single-Skill download may be a raw UTF-8 SKILL.md file or a ZIP with SKILL.md at the archive root. Otherwise, archive-root directories that directly contain SKILL.md are selected. One selected directory is installed as the requested single Skill; two or more selected directories form a multi-Skill package using their directory names. Ordinary files and other directories are ignored.
  • When no archive-root Skill directory exists and there is exactly one top-level directory, the same selection applies inside that common wrapper. All multi-Skill child releases and Agent updates are committed atomically and rolled back together on failure.

Multi-skill results include multiSkill: true and a skills array containing each child skill's action, install path, backup path, and Agent results. Single-skill output remains unchanged.

After a successful committed install, when the download-ticket response includes skillId, the CLI best-effort reports the public download metric to the resolved dashboard base: POST /prod-api/skill-marketplace/internal/skills/{skillId}/metrics/public-download with {"source":"AGENT_CLI"}. Metrics failures do not roll back or fail the completed installation.

Managed skills live under ~/.agents/skills; each skill uses immutable entries in releases/ and a current pointer. Reinstalling a managed skill updates that pointer automatically; an identical skill is left unchanged. If a destination is not managed by clink-cli, installation stops unless --force is supplied. A forced replacement retains the previous content as a backup. A failed single-skill update rolls back to the previously active release; a failed multi-skill update rolls back every child changed by that command.

Only agent roots that already exist are detected; installing a skill does not create new agent homes. Integration modes are:

| Agent | Mode | Notes | | --- | --- | --- | | Cursor, Claude Code, Codex, CodeBuddy | link | Links the agent's skill entry to the central installation. | | Trae | link | Creates the symlink only after its real target is verified as an immutable release. | | OpenClaw, OpenCode, GitHub Copilot | shared | Uses the shared central skill root. | | Gemini CLI (GEMINI_CLI_HOME unset or HOME-equivalent) | shared | Uses the shared central skill root. | | Gemini CLI (GEMINI_CLI_HOME resolves outside HOME) | link | Links the custom home to the central installation. | | Hermes | copy | Copies the installed skill into its existing root. | | CodeWork, ChatGPT | unsupported | Reports a warning and continues. |

~/.trae/skills is Trae's documented global skill directory, but Trae has not confirmed that it discovers per-skill symlinks there. Before release, validate discovery with a real Trae installation; if that check fails, use a copy adapter for Trae instead.

Verification and safety

After installation, verify discovery in the target agent:

  • OpenCode: start a fresh process and check its native skill inventory.
  • GitHub Copilot: run /skills reload, then /skills info <skillName>.
  • Gemini CLI: run /skills reload, then /skills list.

Downloads must use HTTPS. The installer enforces download and extracted-size limits, computes a local SHA-256 package identity, and rejects unsafe ZIP entries and archive layouts. The SHA-256 is used to identify local content; it is not a claim of publisher authenticity. Validation, authentication, API, and network failures keep exit codes 2, 4, 5, and 6. Archive validation and local filesystem, lock, link, copy, or rollback failures use error type install_error and exit code 8.

Common Usage

Use sandbox:

clink-cli wallet init --sandbox --email [email protected] --name "Alice"
clink-cli card list --sandbox --format pretty

--sandbox switches the API base and agent domain. OAuth credentials are environment-bound; run wallet init --sandbox before making sandbox calls. Legacy CSK is available only to wallets that have never used OAuth.

Override the base URL:

clink-cli wallet status --base-url https://api.clinkbill.com

Print requests without executing:

clink-cli pay \
  --merchant-id merchant_xxx \
  --amount 10.00 \
  --currency USD \
  --payment-instrument-id pi_xxx \
  --dry-run

Commands

Command groups:

  • clink-cli wallet init
  • clink-cli wallet logout
  • clink-cli wallet status
  • clink-cli card binding-link
  • clink-cli card setup-link
  • clink-cli card modify-link
  • clink-cli card list
  • clink-cli card get --payment-instrument-id <id>
  • clink-cli risk get
  • clink-cli risk link
  • clink-cli pay --merchant-id <id> --amount <amount> --currency <currency>
  • clink-cli pay --session-id <id>
  • clink-cli ucp-checkout create --merchant-url <url> --merchant-category-code <code> --currency <currency> --line-items <json> [--endpoint <url>]
  • clink-cli ucp-checkout get --checkout-id <id> [--endpoint <url>]
  • clink-cli ucp-checkout update --checkout-id <id> --line-items <json> [--endpoint <url>]
  • clink-cli ucp-checkout complete --checkout-id <id> [--payment-instrument-id <id>] [--endpoint <url>]
  • clink-cli ucp-checkout cancel --checkout-id <id> [--endpoint <url>]
  • clink-cli refund create --order-id <id>
  • clink-cli refund get --refund-id <id>
  • clink-cli instruction list --valid-only --payment-instrument-id <id> (VIC; ACTIVE only, and one-time mandates are filtered to reserveStatus=0)
  • clink-cli instruction create --payment-instrument-id <id> --title <t> --mandates <json> [--sandbox] (VIC; returns instructionId + passkeyUrl)
  • clink-cli instruction get --purchase-instruction-id <id> (VIC)
  • clink-cli instruction sign-url --payment-instrument-id <id> --purchase-instruction-id <id> [--sandbox] (VIC)
  • clink-cli instruction update|cancel [--sandbox] (VIC page URL only)
  • clink-cli pay --session-id <id> --instruction-id <id> --mandate-id <id> [--shipping-address <json>] [--products <json>] (VIC charge context; --products maps to aiAgentInstructionBo.products)
  • clink-cli skills install <publisher>/<skillName>[@<version>] [--force]
  • clink-cli tool item-id --url <url>
  • clink-cli tool parse-site --url <url>
  • clink-cli tool parse-item --url <url>
  • clink-cli tool checkout-total --url <url>
  • clink-cli tool get-ucp-profile --url <url>
  • clink-cli tool get-rest-endpoint --url <url>
  • clink-cli tool internal-ucp get-endpoint --product-url <url> [--sandbox]
  • clink-cli config set <key> <value>
  • clink-cli config get
  • clink-cli config unset <key>

tool internal-ucp get-endpoint performs an exact product-hostname lookup in the selected environment's bundled internal-merchant configuration and generates the corresponding Clink UCP REST endpoint without a network request. Production configuration is selected by default; --sandbox selects sandbox configuration. A domain outside the selected list returns {"error_code":"NOT_IN_INTERNAL_UCP_LIST"} with a successful process exit so callers can continue with standard UCP profile discovery.

Show help:

clink-cli --help
clink-cli wallet --help
clink-cli card --help
clink-cli ucp-checkout --help
clink-cli refund --help

Configuration

Useful config commands:

clink-cli config get
clink-cli config set base-url https://api.clinkbill.com
clink-cli config set customer-id cus_xxx
clink-cli config unset customer-api-key

config get and wallet status never print raw OAuth tokens or the raw customer API key. OAuth credentials take precedence over legacy CSK, and a request never sends both. wallet status makes no network request and reports the effective base URL and customer credentials after applying command flags, environment variables, and saved config in precedence order. It also reports authorizationEnvironmentMatches and the persistent oauthRequired state. After a wallet first uses OAuth, logout or token expiry requires wallet init; the CLI never falls back to stored, environment, or command-line CSK credentials.

Changing base-url to a different origin clears the saved OAuth and legacy CSK credentials before the new environment can be used.

The first OAuth release stores tokens as plaintext JSON under the current user's home directory. On Unix/macOS the CLI keeps ~/.clink-cli at mode 0700, config.json at mode 0600, and replaces the file atomically under a lock. OS Keychain integration is deferred.

Settable config keys:

  • base-url
  • customer-id
  • default-open-links
  • email
  • name

customer-api-key cannot be stored with config set. An existing saved legacy key can still be removed with config unset customer-api-key; never-OAuth legacy users may continue supplying it through CLINK_CUSTOMER_API_KEY or --customer-api-key. customer-id is directly settable only for never-OAuth legacy wallets; OAuth owns the customer identity and wallet init is the only way to switch it.

Resolution order:

  • command flags
  • environment variables
  • saved local config

Environment variables:

  • CLINK_BASE_URL
  • CLINK_CUSTOMER_ID
  • CLINK_CUSTOMER_API_KEY

Global Options

  • --format <json|pretty>
  • --dry-run
  • --open
  • --no-watch
  • --base-url <url>
  • --sandbox
  • --customer-id <id>
  • --customer-api-key <key>
  • --timeout <ms>
  • --help

Event Watching

Whenever a command prints a link for the user to act on in a browser (card binding-link, card setup-link, card modify-link, risk link, instruction create|sign-url|update|cancel, and pay when a 3-D Secure redirect is returned), the CLI starts consuming the webhook-event queue:

  • Polls POST /agent/event-hub/webhook-events/poll (pageSize: 20) every 5 seconds for up to 15 minutes, stopping at the first non-empty batch.
  • Processes the events it receives: logs a summary to stderr and updates wallet-derived local state where applicable. payment_method.* events refresh cached payment methods in ~/.clink-cli/config.json; other event payloads are returned in the command output but are not persisted in the config file.
  • Acknowledges the batch via POST /agent/event-hub/webhook-events/ack with { "eventIds": [...] }; acked events are removed server-side.
  • Prints the processed events as a second JSON envelope to stdout (stdout keeps carrying machine-readable output; progress messages go to stderr).

Pass --no-watch to print the link and exit immediately, without polling — use this for scripted or non-interactive runs, and whenever you call card binding-link only to refresh the cached card list. Polling is also skipped under --dry-run. Newly added event types that aren't recognized yet are still logged and acknowledged so they are never silently dropped.

Polling on demand: events poll

To consume state changes without printing a link, call clink-cli events poll. It polls the webhook-event queue within a bounded window (default --max-wait 60 seconds, --limit 20 page size), processes each event, updates wallet-derived state where applicable, and — unless --no-ack is passed — acknowledges it by eventId.

clink-cli events poll --type payment_method.added --format json

The result is { ready, timedOut, events, ackedEventIds }. On timeout it also returns resumeCommand: because acked events are removed server-side, resuming is just the same command again — there is no offset to pass. A single poll returns the whole batch it reads in events. payment_method.* events refresh cached payment methods; other event payloads are not stored in config.json. --type controls both when to stop waiting and which events are acked: only events matching type are acknowledged, so unrelated events stay on the queue for a later poll. Without --type, the whole batch is acked. Pass --no-ack to peek without acknowledging anything.

Local Development

Build from source:

npm install
npm run build
node dist/index.js --help

Run tests:

npm test
npm run test:e2e