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

@skyporch/daykeeper-cli

v0.5.0

Published

Machine-readable command line for the Daykeeper management API

Readme

Daykeeper CLI

For more about Daykeeper, visit mydaykeeper.com.

A command line for people, agents, and CI jobs managing Daykeeper. It calls the @skyporch/[email protected] SDK and returns one versioned JSON envelope per invocation. The code is Apache-2.0; see LICENSE and RELEASING.md.

Get a support inbox with one command

npx @skyporch/daykeeper-cli init --name "Acme Support"

That's it. No sign-up, card, website, or DNS. init enrolls a machine owner, creates a Free workspace with one API inbox, waits for it to be ready, turns it on, and stores the credential under ~/.config/daykeeper (directory mode 0700, file mode 0600). It prints the workspace and inbox IDs, the next steps, and ready-to-paste SDK and MCP configuration. Run it again and it picks up where it stopped; it never creates a second workspace, credential, or inbox.

Run in a terminal, init prints readable text. Add --json, or capture stdout from an agent or script, for the JSON envelope.

Every other command then uses the stored credential, with nothing to export:

npx @skyporch/daykeeper-cli tenants list

Every init ends with a way for a person to own the inbox. Until somebody claims it, customer messages reach only the agent and nobody is emailed about them, so the output leads with a handoff message to relay as is:

  • By default, an open claim link: whoever opens it first and signs in at https://app.mydaykeeper.com owns the workspace.
  • With --owner-email, a claim only that address can accept (and that the person also finds waiting when they sign in with it). Prefer it whenever you know the address.
  • With --connect, init prints the link (on stderr), opens it in the browser when a person is at the terminal, and waits up to 3 minutes for them to accept it, then reports who owns the inbox.
  • With --no-claim, no claim is issued (for CI, or a workspace a person already owns).
npx @skyporch/daykeeper-cli init --name "Acme Support" --owner-email [email protected]
npx @skyporch/daykeeper-cli init --name "Acme Support" --connect
npx @skyporch/daykeeper-cli claim                      # the open link again, or a new one
npx @skyporch/daykeeper-cli claim --email [email protected]

The link carries its token in the URL fragment and is printed unredacted, because it is the handoff: treat it like a password reset link, and use --no-claim for runs whose output is shared (CI logs, public transcripts). It works once and expires in 72 hours. The state file keeps a pending claim's link beside the machine credential (which can mint a new claim anyway), so rerunning init prints the same link, or who claimed it, or a fresh link once the old one expired. claim --reissue revokes the pending link and issues a new one, and claim status lists what the server holds.

Install it globally to type daykeeper instead of npx @skyporch/daykeeper-cli:

npm install --global @skyporch/daykeeper-cli
daykeeper tenants list

The credential is redacted from output unless you pass --reveal-key, but <home>/mcp.json always carries the literal credential so an MCP client can read it. Full flags, state layout, resume behavior, and error codes are in COMMANDS.md.

Authenticate

Each command uses the first credential it finds:

  1. --token-stdin, with the token piped from a trusted credential provider.
  2. DAYKEEPER_API_KEY, injected by your secret manager or CI environment. DAYKEEPER_ACCESS_TOKEN still works as a deprecated alias.
  3. The credential init stored in <home>/credentials.json.

Set at most one of the first two. A supplied credential goes to --base-url, then DAYKEEPER_API_URL. Without either, the key init stored goes to the origin that issued it; any other key goes to https://api.mydaykeeper.com unless this machine's state is for a different origin, in which case set the URL explicitly. Include any reverse-proxy prefix in the URL. Remote origins must use HTTPS; http://127.0.0.1 and http://localhost are supported for local development. URLs with credentials, query strings, or fragments are rejected, and requests never follow redirects.

The stored credential is only ever sent to the origin that issued it. If you ran init with --origin or DAYKEEPER_ORIGIN, set the same origin for later commands; a different one fails with STATE_ORIGIN_MISMATCH before any request. Use --home or DAYKEEPER_HOME to point at a state file outside the default location. A stored credential near expiry is rotated before it is used.

init and claim always run under the stored credential. They refuse --token-stdin, and a supplied DAYKEEPER_API_KEY that is not the stored one.

# DAYKEEPER_API_KEY is supplied by your environment.
daykeeper capabilities

# A credential provider can pipe the token instead.
credential-provider print-daykeeper-api-key | daykeeper capabilities --token-stdin

The credential provider above represents your existing secret-management command, not a bundled Daykeeper command. Tenant IDs select resources; they do not grant access or change the token's organization. The API remains responsible for verifying credentials, scopes, and tenant membership. Tokens must be 20–16,384 bearer characters. The CLI accepts no token argument and never opens an interactive sign-in prompt.

Run from this repository

Use Node.js 20 or newer and pnpm 10.8.0:

pnpm install --frozen-lockfile
pnpm build
node dist/cli.js --help

pnpm daykeeper --help runs the same CLI from source.

Plan, inspect, then apply

daykeeper tenants plan --input tenant.json > tenant-plan.json

# Inspect the returned changes, warnings, requiredScopes, version, and expiry.
jq '.data' tenant-plan.json

# Apply only when approved, using the exact plan and a durable key for this action.
daykeeper tenants apply \
  --plan-id 33333333-3333-4333-8333-333333333333 \
  --plan-version 1 \
  --idempotency-key daykeeper-acme-tenant-create-0001

tenants plan and email-channels plan create expiring server-side plans but do not create provider resources. Apply is a separate explicit command. The CLI does not generate plan IDs, fetch replacement plans, change versions, generate idempotency keys, or automatically repeat mutations.

Use --input - to read a JSON body from stdin. JSON must match the command's strict schema and stay within 512 KiB. Unknown fields—including organization, role, or policy overrides—are rejected. When using --token-stdin, JSON must come from a regular file; one stdin stream cannot carry both token and body.

The command names, exact flags, scope requirements, flow examples, and output schema are documented in COMMANDS.md. --help provides the command catalog as JSON without making a request.

Errors, cancellation, and safe retries

Every result is one JSON line on stdout. The one exception is init run in a terminal without --json, which prints readable text. There are no prompts or progress messages. Exit status is 0 for success and 1 for a command error. The executable uses 130 for SIGINT and 143 for SIGTERM after emitting a cancellation error.

Use --timeout-ms or DAYKEEPER_TIMEOUT_MS to set one 1–60 second budget for input reading and the API request (default: 30 seconds). Cancellation aborts the local request, not work already accepted by the server. An interrupted mutation reports mutationOutcome: "unknown"; inspect the relevant resource or operation before retrying. For plan/apply and flow mutations, reuse the original idempotency key for the exact same logical action. Operation retries have no idempotency key in SDK 0.2.0; they are never replayed automatically.

API failures retain their bounded error code, status, retryability, safe field names, next actions, and correlation ID. Raw remote messages, request bodies, stack traces, file paths, and credential-provider errors are not emitted as diagnostics. Auth and tenant denials do not trigger broader lookups. Normal successful resource output can contain authorized customer information; handle stdout as application data, not a public log. Supplied access tokens are redacted if reflected in output.

What is not implemented

  • Hosted OAuth login, human signup, account ownership verification, or token refresh. init performs machine enrollment only, and claim only issues the invitation: accepting it, and every sign-in it needs, stays in the console.
  • Membership or API-key administration, billing, usage, or entitlement changes.
  • Automatic DNS changes, operation polling, background workers, or flow execution.
  • Customer-session token issuance from the CLI; credentials are never minted to stdout.

Flow create/version/publish commands manage stored definitions only. Inspect capabilities for the server's actual execution status. A successful publish does not mean that a flow is executing against conversations.

Validate

pnpm check

Checks cover all 16 single-call command mappings through the real SDK, the whole init step machine and both claim forms against loopback onboarding and management fixtures with state in a temporary home, input and credential boundaries, denial/redaction behavior, deadlines and cancellation, the compiled executable against a synthetic loopback API, and an unpacked npm tarball with its pinned production dependencies installed offline using a verification-only copy of this repository's frozen lockfile. That lockfile is not shipped in the tarball. These checks do not certify a deployed server's tenant isolation or production availability.