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

@focusedobjective/deliverytower-cli

v0.1.2

Published

DeliveryTower external assessment API command-line client.

Readme

@focusedobjective/deliverytower-cli

Command-line client for starting and reading DeliveryTower external assessment runs.

The CLI talks to the DeliveryTower Assessment API using a DeliveryTower API key. It sends source references only, such as a GitHub issue, GitHub pull request, Jira issue, or DeliveryTower work item id. DeliveryTower resolves connected source context server-side.

Requirements

  • Node.js 20 or newer
  • A DeliveryTower Convex site URL
  • A DeliveryTower API key with assessment:run and assessment:read
  • Optional: assessment:publish when using --publish-github-pr-comment

Set credentials in the environment:

export DELIVERYTOWER_API_URL="https://YOUR_CONVEX_SITE_URL"
export DELIVERYTOWER_API_KEY="dt_live_..."

PowerShell:

$env:DELIVERYTOWER_API_URL = "https://YOUR_CONVEX_SITE_URL"
$env:DELIVERYTOWER_API_KEY = "dt_live_..."

Verify that the CLI can see the required environment:

npx @focusedobjective/deliverytower-cli auth check

Usage

Run without installing:

npx @focusedobjective/deliverytower-cli assess \
  --source github-pr \
  --owner acme \
  --repo web \
  --pr 42 \
  --format both \
  --wait

Install globally:

npm install -g @focusedobjective/deliverytower-cli
deliverytower auth check

Local repository checkout:

npm run deliverytower -- assess \
  --source github-issue \
  --owner acme \
  --repo web \
  --issue 42

Commands

deliverytower auth check
deliverytower assess --source <github-issue|github-pr|jira-issue|work-item> [flags]
deliverytower batch --file <requests.json> [flags]
deliverytower get --run-id <runId>
deliverytower wait --run-id <runId> [flags]

Start An Assessment

GitHub pull request:

deliverytower assess \
  --source github-pr \
  --owner acme \
  --repo web \
  --pr 42 \
  --format markdown \
  --idempotency-key "ci-acme-web-pr-42" \
  --wait

GitHub issue:

deliverytower assess \
  --source github-issue \
  --owner acme \
  --repo web \
  --issue 123 \
  --format json

Jira issue by key:

deliverytower assess \
  --source jira-issue \
  --issue PLAT-123 \
  --project PLAT \
  --format both \
  --wait

Jira issue by URL:

deliverytower assess \
  --source jira-issue \
  --issue-url "https://example.atlassian.net/browse/PLAT-123"

Existing DeliveryTower work item:

deliverytower assess \
  --source work-item \
  --work-item-id wi_123 \
  --format json

assess starts a run and prints the accepted run JSON. Add --wait to poll until the run reaches succeeded or failed.

Request Formats

Use --format to request output formats:

  • json: machine-readable response only. This is the default.
  • markdown: human-readable markdown summary.
  • both: request both JSON and markdown.

When a result includes markdown, --format markdown prints the markdown body. --format both prints markdown first, followed by the JSON response.

JSON Input

For advanced options, pass the API request body as JSON on stdin or with --file.

request.json:

{
  "source": {
    "type": "github_pull_request",
    "owner": "acme",
    "repo": "web",
    "pullRequestNumber": 42
  },
  "outputFormats": ["json", "markdown"]
}

Run it:

deliverytower assess --file request.json --idempotency-key "manual-acme-web-pr-42" --wait

The same request can be piped through stdin:

cat request.json | deliverytower assess --wait

Publish A GitHub PR Comment

For GitHub pull request assessments, DeliveryTower can publish or update one PR summary comment:

deliverytower assess \
  --source github-pr \
  --owner acme \
  --repo web \
  --pr 42 \
  --format markdown \
  --publish-github-pr-comment \
  --idempotency-key "ci-acme-web-pr-42" \
  --wait

The API key must include assessment:publish. DeliveryTower writes the comment through its connected GitHub App, not through the CLI process.

Retrieve Or Wait For A Run

Retrieve the latest known state:

deliverytower get --run-id arun_... --format json

Poll until the run is terminal:

deliverytower wait \
  --run-id arun_... \
  --timeout-seconds 600 \
  --poll-interval-seconds 10 \
  --format markdown

Terminal statuses are succeeded and failed.

Batch Runs

batch reads a non-empty array, or an object with a requests array. Each entry can be a source reference or a full request body.

requests.json:

[
  {
    "type": "github_issue",
    "owner": "acme",
    "repo": "web",
    "issueNumber": 1
  },
  {
    "source": {
      "type": "jira_issue",
      "issueKey": "PLAT-123"
    },
    "outputFormats": ["json", "markdown"],
    "idempotencyKey": "manual-plat-123"
  }
]

Run the batch:

deliverytower batch \
  --file requests.json \
  --format markdown \
  --idempotency-key-prefix "nightly-2026-06-17" \
  --wait

When --idempotency-key-prefix is provided, entries without their own idempotencyKey use <prefix>-1, <prefix>-2, and so on.

GitHub Actions Example

name: DeliveryTower Assessment

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: read

jobs:
  assess:
    runs-on: ubuntu-latest
    steps:
      - name: Run DeliveryTower assessment
        env:
          DELIVERYTOWER_API_URL: ${{ secrets.DELIVERYTOWER_API_URL }}
          DELIVERYTOWER_API_KEY: ${{ secrets.DELIVERYTOWER_API_KEY }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
        run: |
          npx @focusedobjective/deliverytower-cli assess \
            --source github-pr \
            --owner "${{ github.repository_owner }}" \
            --repo "${{ github.event.repository.name }}" \
            --pr "$PR_NUMBER" \
            --format both \
            --idempotency-key "${{ github.run_id }}-${{ github.repository }}-pr-$PR_NUMBER" \
            --wait

Store DELIVERYTOWER_API_URL and DELIVERYTOWER_API_KEY as repository or organization secrets.

Exit Codes

  • 0: command succeeded, or the assessment reached succeeded
  • 1: invalid input, missing environment, HTTP/API error, or unknown command
  • 2: assessment completed with status failed
  • 3: wait or assess --wait timed out

Notes

  • Use an idempotency key for CI and agent workflows so retries reuse the same run.
  • The API accepts one source reference per request. Use batch when you need to create multiple runs from one file.
  • Assessment output is advisory context. It does not grant permission to merge code, edit files, create tickets, or publish comments unless your surrounding workflow explicitly allows that action.