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

@ossy/cli

v1.40.3

Published

Command line tool that makes it easier to interact with our APIs

Downloads

1,724

Readme

@ossy/cli

Unified CLI for the Ossy platform.

Install

npm install -g @ossy/cli

After install, the ossy command is on your PATH:

ossy --version
ossy --help
ossy <command> --help

For one-off use without installing, you can still run npx @ossy/cli <command>.

How the CLI is organized

The contract for everything the platform can do is the SDK action POJO in @ossy/sdk ({ id, endpoint, method, payload }). The CLI is one channel onto that catalog, organized in three layers:

  1. Local utilities — no API call, or per-machine state. auth, workspace, app init, app build, app validate.
  2. Action dispatcherinvoke <action.id> invokes any action in the SDK catalog. New endpoints added to the SDK are callable from the terminal with no extra CLI wiring.
  3. High-level workflows — verbs that wrap one or more actions and add value the dispatcher doesn't (reading src/config.js, formatting output for CI, multi-step pipelines). Each workflow's docs name the underlying action(s) so you can drop down to ossy invoke if you outgrow the verb.

| Layer | Command | Description | |-------|---------|-------------| | Local | auth login \| logout \| status | Save / delete / inspect the Ossy API token under ~/.config/ossy/credentials.json | | Local | workspace use <id> \| list \| current | Manage the active workspace (saved to ~/.config/ossy/config.json) | | Local | app init [dir] | Scaffold a new Ossy app (default: current directory) | | Local | app build | Production build of the app in the current directory | | Local | app validate | Validate src/config.js (workspaceId) without calling the API | | Dispatcher | invoke <action.id> | Invoke any Ossy SDK action by id (ossy invoke --help for the full catalog) | | Workflow | app upload | Informational — schemas live in *.schema.js and are discovered at app build | | Workflow | app publish | Upload build/ to the CMS and register the app domain | | Workflow | upload-dir <dir> <location> | Recursively mirror a local directory into the CMS (mkdir + upload per file) |

If you need an endpoint that no verb wraps, reach for ossy invoke — it's the universal channel.

Auth and active workspace

Once installed, the recommended flow is to log in once and pick an active workspace; subsequent commands inherit those:

ossy auth login                      # paste your Ossy API token
ossy workspace list                  # see workspaces you can access
ossy workspace use <workspace-id>    # set the active one
ossy auth status                     # confirm

Credentials live in ~/.config/ossy/credentials.json (chmod 600); the active workspace lives in ~/.config/ossy/config.json. Both honor XDG_CONFIG_HOME.

Resolution order for every command that needs auth:

  1. --authentication / -a flag
  2. OSSY_API_KEY env var
  3. Saved credentials

Resolution order for the workspace id (when a command isn't reading it from src/config.js):

  1. --workspace-id / -w flag
  2. OSSY_WORKSPACE_ID env var
  3. Saved active workspace

So existing CI scripts that set OSSY_API_KEY keep working unchanged; you only need ossy auth login for interactive use.

Generic dispatcher: ossy invoke

ossy invoke invokes any Ossy API action by id. The action catalog comes from @ossy/sdk, so any new endpoint added to the SDK is callable from the terminal with no extra wiring.

# Discover what's available
ossy invoke --help                                  # full catalog, grouped by domain
ossy invoke resources.create --help                 # one action's method, endpoint, default payload

# Read calls
ossy invoke workspaces.get-current
ossy invoke resources.list --search 'location=/docs'

# Write calls — flag names map to payload keys (--first-name -> firstName)
ossy invoke resources.create-directory --location /docs --name images
ossy invoke workspaces.invite-user --email [email protected]

# Use --json for nested or non-string payloads
ossy invoke resources.update-content --id res_abc --json '{"content":{"title":"Hi"}}'

# Upload a file: --file fills name/type/size as defaults, then PUTs the bytes
# when the response carries content.uploadUrl (works for resources.upload,
# resources.upload-named-version, etc.)
ossy invoke resources.upload --location /docs --file ./hero.jpg
ossy invoke resources.upload-named-version --id res_abc --name medium --file ./hero.jpg

# Per-call overrides (otherwise resolved from `ossy auth login` / `ossy workspace use`)
ossy invoke workspaces.get-all -a <jwt> --api-url http://localhost:3001/api/v0

Output is JSON pretty-printed to stdout on success. Errors go to stderr with a non-zero exit. Add --raw to get the response body verbatim (useful for piping non-JSON responses).

--file <path> is a shortcut for upload-style actions: the CLI stats the file, fills name/type/size as defaults (any explicit --name / --type / --size flag wins), and after the dispatch it PUTs the bytes to result.content.uploadUrl with the right Content-Type/Content-Length. If the response doesn't include an upload URL, the bytes are skipped and a warning is printed.

App: build

ossy app build

Options: e.g. --config for src/config.js. See packages/app/README.md for app build behavior.

App: publish

Publishes a built app: mirrors the build/ folder into the CMS and registers the domain → workspace mapping. Run from the app package directory (where src/config.js lives) so config values are read automatically.

Schemas are not uploaded by app publish — they come from installed packages' *.schema.js files and are merged into the app manifest at app build time.

cd packages/my-website
npm run build                          # produce build/ first (discovers schemas)
ossy app publish                       # reads src/config.js, uploads build/

Workflow:

  1. Upload build/ to the CMS → @ossy/resources/actions/create-directory + @ossy/resources/actions/upload per file (same pattern as upload-dir), default destination /@ossy/apps/{domain}.
  2. Register domainworkspaceId via POST /apps/domains.

Config extraction

publish reads workspaceId, apiUrl, and domain from src/config.js without executing it (static regex + Babel AST parse), so imports like @ossy/themes that only resolve under Rollup are never run.

Authentication

Requires --authentication / -a or OSSY_API_KEY: an Ossy API JWT (workspace API token).

cd packages/my-website
export OSSY_API_KEY=<ossy-api-jwt>
npm run build
ossy app publish
# or with explicit options:
ossy app publish \
  --config src/config.js \
  --build-dir ./build \
  --build-dest /@ossy/apps/my-site.se

Options

| Flag | Description | |------|-------------| | -a, --authentication | Ossy API JWT (or OSSY_API_KEY, or ossy auth login) | | -c, --config | Path to src/config.js (default: ./src/config.js) | | --build-dir | Override build directory (default: <package>/build) | | --build-dest | Override remote CMS location (default: /@ossy/apps/{domain}) | | --api-url | API base URL (or OSSY_API_URL; relative apiUrl in config is ignored) |

CI example

- name: Publish
  run: |
    npm run build
    npx --yes @ossy/cli app publish \
      --authentication ${{ secrets.OSSY_API_KEY }}

App: upload

Deprecated as an upload workflow. ossy app upload now prints guidance that schemas are defined in package *.schema.js files and discovered automatically at app build time — it does not POST to the API.

To import schemas manually (e.g. one-off workspace bootstrap), use the dispatcher:

ossy invoke @ossy/workspaces/actions/import-schemas --json '{"schemas":[…]}'

The low-level HTTP helper postSchemas() in upload-schemas.js targets POST /schemas when you need a direct fetch from custom tooling.

Config consistency

  • App (build), app (app upload / app validate / app publish), and upload-dir all use --config (-c) for the app / workspace config file (src/config.js by default when present).

Workflow example

Prefer app publish after app build so the built site is deployed. Schemas ship with the build manifest — no separate upload step.

name: Deploy app

on:
  workflow_dispatch:

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm ci && npx ossy app build
      - run: npx ossy app publish --authentication ${{ secrets.OSSY_API_KEY }}

app validate

Validate an ossy config file before uploading:

ossy app validate --config src/config.js

When --config is omitted, ./src/config.js is used if it exists.

Arguments

| Argument | Description | Required | |----------|-------------|----------| | --authentication, -a | Ossy API JWT (primary; same role as OSSY_API_KEY) | Yes (upload only) | | --config, -c | App config (workspaceId, …) | Optional if ./src/config.js exists | | --api-url | API base URL for upload (…/api/v0) | No |

Upload a directory

Recursively mirrors a local directory tree into the Ossy CMS, preserving the folder structure.

ossy upload-dir ./public /my-folder

This:

  1. Walks the local tree and collects all subdirectories (breadth-first) and files.
  2. Creates each remote directory with resources.create-directory (parents before children; already-existing directories are skipped silently).
  3. Uploads each file with resources.upload + S3 presigned PUT, in the same order they were discovered.
  4. Logs per-item progress and prints a summary at the end.

Per-item errors are logged and skipped — the command continues to the next item and exits non-zero when any item failed.

Options:

| Flag | Description | |------|-------------| | --dry-run | Print what would happen without making any API calls | | -a, --authentication | Ossy API JWT (or OSSY_API_KEY, or ossy auth login) | | -w, --workspace-id | Workspace id (or OSSY_WORKSPACE_ID, or ossy workspace use) | | --api-url | Override the API base URL |

Examples:

# Preview before committing
ossy upload-dir ./public /my-folder --dry-run

# Upload into a nested location
ossy upload-dir ./assets /projects/2026/assets

# Point at a local API
ossy upload-dir ./public /my-folder --api-url http://localhost:3001/api/v0

App: init

Scaffold a new Ossy app:

ossy app init
ossy app init my-app

Creates src/home.page.jsx, src/config.js, and package.json (if missing).