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

@trayai/tray-sync-cli

v1.0.18

Published

CLI tool to clone Tray projects and related assets to a local directory, and promote them between Tray environments

Downloads

1,553

Readme

tray-sync-cli

Tray CLI tool allows users to

  • General-purpose, authenticated proxy to the Tray API
  • Clone, review and promote Tray projects and related assets on a local machine or a version controlled pipeline

Requirements

  • Node.js >= 22

Install

npm install -g @trayai/tray-sync-cli

CLI Commands

| Command | Description | |---------|-------------| | tray init -r <region> -w <workspace-id> | Scaffold a new tray-sync-cli repository | | tray pull | Export tracked projects from Tray and materialise them on disk | | tray promote <env> | Reconstruct local projects and import them into a target Tray environment | | tray status | Local checksum-based drift detection (zero API calls) | | tray project remove <project-id> | Untrack a project and delete its local directory (project scope only) | | tray project list | List managed projects with directory names and last-pulled timestamps | | tray env add <name> | Add a target environment | | tray env list | List source and target environments with connectivity status | | tray env remove <name> | Remove a target environment and its per-project mappings | | tray env discover [env] | List an env's projects (id + name, default) and/or matching authentications — env defaults to source | | tray env resolve <env-name> | Report unresolved auth requirements for a target env, with candidate matches | | tray auth set -w <workspace-id> -r <region> -t <token> | Set (or overwrite) a workspace's token | | tray auth remove -w <workspace-id> | Remove a workspace's stored token | | tray auth list | List workspaces with stored credentials | | tray --version | Print the installed CLI version | | tray --help | Show help for the CLI or a specific command |

Getting started: a first promotion, end to end

This is a concrete, step-by-step walkthrough of the most common workflow: pull a project from a source workspace, and promote it to a target workspace. It uses a two-org example (DEV_ORGPROD_ORG) since that's the realistic setup for most customer pipelines, but everything here works identically for two workspaces within the same org.

1. Pick a source and a target environment

Decide which workspace you're pulling from (the source) and which one you're promoting to (the target). For this guide:

  • Source: DEV_ORG
  • Target: PROD_ORG

You'll need each workspace's ID and region, and a Tray API token with access to it. 📚 Learn how to create tokens for your workspace (recommended) / account here.

2. Create a local directory for this project

mkdir -p ~/tcli-projects/my-first-tcli-project
cd ~/tcli-projects/my-first-tcli-project

Everything the CLI manages — tray.yaml, environments.json, and every pulled project — lives under this directory.

3. Initialize the repository against your source workspace

tray init -r <region> -w <your-SOURCE-workspace-id> -t <your-token> -p <project-id-to-pull>

Example:

tray init -r us1 -w 11111111-1111-1111-1111-111111111111 -t <token> -p <project_id>

Don't know the project ID yet? Run init without -p (an empty scaffold is fine), then:

tray env discover

lists every project in your source workspace — id + name — so you don't have to dig it out of Tray's UI.

A few notes on the flags:

  • -p <project-id> pulls that project immediately after scaffolding. Omit it and init just scaffolds an empty repository — you can pull specific projects later with tray pull -p <project_id>, which tracks and pulls it in one step.
  • -s workspace (i.e. tray init -s workspace -r <region> -w <id> -t <token>, omitting -p) switches to workspace scope: every project in the workspace is pulled automatically, and tray pull keeps that mirror in sync going forward (including removing projects deleted from Tray). -p is ignored in this scope.
  • -t <token> is optional at init time. If you skip it (or need to replace it later — tokens expire), set or refresh it any time with:
    tray auth set -w <workspace-id> -r <region> -t <token>
    tray auth set always overwrites whatever token was stored for that workspace — no separate "force" flag needed.

At this point you have a local mirror of your source project(s), configured against DEV_ORG.

4. Add your target environment

Now register where you want to promote to:

tray env add <env-name> -r <region> -w <target-workspace-id> -t <target-token>

Example:

tray env add PROD_ORG -r us1 -w 22222222-2222-2222-2222-222222222222 -t <prod-token>

You can add more than one target environment this way (e.g. STAGING_ORG, PROD_ORG) — each gets its own entry in environments.json.

Same as init, providing -t here stores the token in ~/.tray/credentials.json immediately. You can always set or refresh it independently with tray auth set -w <target-workspace-id> -r <region> -t <token>.

5. Promote

You're ready to import your local projects into the target environment. A few common invocations:

# Recommended first: see what would happen without changing anything.
tray promote --to PROD_ORG --dry-run

# Promote a single project.
tray promote --to PROD_ORG -p <project-id>

# Promote multiple specific projects.
tray promote --to PROD_ORG -p <project-id-1> <project-id-2>

# Promote every project tracked in this directory (see them with `tray project list`).
tray promote --to PROD_ORG

Important: every project needs a target_project_id per environment

The first time you promote a given project to a given environment — or whenever the target project changes — you need to tell the CLI which project in the target workspace this should import into.

Each pulled project has its own mappings.json, at:

projects/<project-id>--<project-name>/mappings.json

You don't have to create this file by hand — tray pull / tray init already scaffold it for you (with a placeholder entry showing the full shape) the first time a project is pulled. What you do need to do is edit the target environment's entry and fill in the real target_project_id:

{
  "version": 1,
  "environments": {
    "PROD_ORG": {
      "target_project_id": "<project-id>",
      "authentications": {},
      "config": {},
      "connectors": [],
      "services": []
    }
  }
}

target_project_id here is the ID of the project in PROD_ORG that this local project should be imported into.

Authentications

If any workflow in the project you're promoting uses an authentication, you'll also need to map it. Tray tracks this per authentication group — a logical "auth slot" a workflow step references — not the authentication ID itself. When tray promote finds one it doesn't recognize, it tells you and scaffolds a placeholder into mappings.json for you:

{
  "version": 1,
  "environments": {
    "PROD_ORG": {
      "target_project_id": "<project-id>",
      "authentications": {
        "<source_authentication_id>": "MISSING_TARGET_AUTHENTICATION"
      },
      "config": {},
      "connectors": [],
      "services": []
    }
  }
}

The key (<source_authentication_id>) is the source-side auth group ID — leave it as-is. Replace the placeholder value with the ID of the actual authentication in your target environment (PROD_ORG) that should serve that slot — you can find this in Tray's app, under that workspace's authentications. For example:

"authentications": {
  "<source_authentication_id>": "<resolved_target_authentication_id>"
}

If you get it wrong

If a required field is missing or still holds a placeholder value, tray promote refuses the attempt and tells you exactly what's outstanding and where to fix it — it won't silently promote a project into the wrong target, or with an unresolved authentication.