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

@sigmapark/op-deploy-cli

v1.1.0

Published

The command-line interface for op-deploy. Materializes files from 1Password, runs deploy commands, and manages secrets.

Readme

@sigmapark/op-deploy-cli

The command-line interface for op-deploy. Materializes files from 1Password, runs deploy commands, and manages secrets.

Installation

npm install -D @sigmapark/op-deploy-cli
# or
pnpm add -D @sigmapark/op-deploy-cli

Quick Start

  1. Initialize your config:
pnpm op-deploy setup

This creates op-deploy.config.ts at your repo root.

  1. Set up an environment:
# Sign in to 1Password
eval $(op signin)

# Create 1Password items and scaffold attachments for your environment
pnpm op-deploy init --env production
  1. Edit and populate files:
pnpm op-deploy edit --env production my-config-file
  1. Run your first deploy:
pnpm op-deploy materialize --env production -- bash -c 'your-deploy-command'

Commands

op-deploy (interactive)

Run with no arguments for an interactive menu:

op-deploy

setup

Scaffold op-deploy.config.ts in the current directory. Run this once when setting up op-deploy in your repo.

op-deploy setup

init

Create missing 1Password items and initialize attachment files for an environment. Run this once per environment to set up the Secure Note items and example attachments in 1Password.

op-deploy init --env production

edit

Open a file in your $EDITOR for interactive round-trip editing in 1Password:

op-deploy edit --env production config-file-name

The file is fetched from 1Password, opened in your editor, and saved back when you close the editor.

materialize

Fetch files from 1Password into a secure temporary directory, optionally create symlinks, run your command, then securely clean up.

op-deploy materialize --env production --filter 'tag:deploy' -- your-command --with args

Files are exposed as environment variables: OP_DEPLOY_FILE_<FILENAME> (uppercase, underscores). Use these in your command.

upload

Run per-line commands for each line in matched files. Useful for uploading secrets line-by-line to a remote service.

op-deploy upload --env production --filter 'tag:secrets'

Each line in the matched files is passed to the configured upload command.

inject

Wrap op inject for inline secret substitution:

op-deploy inject input-file output-file

Configuration

Create op-deploy.config.ts at your repo root (or run op-deploy setup to scaffold it):

import { defineConfig } from "@sigmapark/op-deploy-cli";

export default defineConfig({
  environments: {
    staging: {
      files: {
        "app-wrangler": {
          // Where to fetch this file from in 1Password
          source: {
            vault: "Deploy",
            item: "staging",
            file: "app-wrangler.jsonc",
          },
          // Optional: symlink to this repo-relative path
          path: "wrangler.staging.jsonc",
          // Optional: tags for filtering with --filter
          tags: ["app", "kind:wrangler"],
          // Optional: example file used by `op-deploy init`
          example: "deploy/wrangler.staging.jsonc.example",
        },
        "app-secrets": {
          source: {
            vault: "Deploy",
            item: "staging",
            file: "app-secrets.env",
          },
          tags: ["app", "kind:secrets"],
          example: "deploy/app-secrets.env.example",
          // Optional: per-line upload command (e.g., for secret managers)
          upload: {
            // Spawned for each line: KEY=VALUE
            forEachLine: [
              "wrangler",
              "secret",
              "put",
              { var: "key" },
              "-c",
              "wrangler.staging.jsonc",
            ],
            // Pipe the value to stdin
            stdin: { var: "value" },
          },
        },
      },
    },
    production: {
      files: {
        // ... similar structure for production
      },
    },
  },
  // Enforce that symlinked files are gitignored (optional)
  materializedPathPatterns: ["wrangler.*.jsonc"],
});

Configuration Reference

Environments

Top-level environments (e.g., staging, production). Each environment contains a set of files to manage.

Files

Named files to materialize. Names must be alphanumeric with hyphens/underscores (1Password-compatible attachment names).

Each file entry has:

| Field | Required | Purpose | | -------------- | -------- | ----------------------------------------------------------------------------------------- | | source.vault | yes | 1Password vault name | | source.item | yes | 1Password Secure Note item name | | source.file | yes | Attachment file name within the item | | path | no | Repo-relative path for a symlink (must be gitignored if using materializedPathPatterns) | | tags | no | Free-form labels for filtering (e.g., app, kind:secrets, region:us) | | example | no | Repo-relative example file to seed new attachments during op-deploy init | | upload | no | Command template to run for each line (see "Upload Actions" below) |

Upload Actions

When upload is configured, op-deploy runs the command for each line in the file:

upload: {
  // Command to spawn, with placeholder objects for dynamic values
  forEachLine: [
    'wrangler', 'secret', 'put',
    { var: 'key' },      // Replaced with line's key
    '-c', 'wrangler.jsonc',
  ],
  // Optional: pipe one of the variables to stdin
  stdin: { var: 'value' },
  // Optional: working directory for the command
  cwd: 'apps/my-app',
}

Lines are parsed as KEY=VALUE. Both key and value placeholders are available.

Filtering

Use --filter with a Lucene-lite query to match files:

# Match by tag
op-deploy materialize --env production --filter 'tag:kind:secrets' -- ...

# Match by file name
op-deploy materialize --env production --filter 'name:app-wrangler' -- ...

# Combine with AND/OR/NOT
op-deploy materialize --env production --filter 'tag:app AND -tag:internal' -- ...

Examples

Multi-app Deployment Setup

For a monorepo with multiple apps, configure each app with its own wrangler config and secrets:

files: {
  'dashboard-wrangler': {
    source: { vault: 'Deploy', item: 'production', file: 'dashboard-wrangler.jsonc' },
    path: 'wrangler.dashboard.jsonc',
    tags: ['app:dashboard', 'kind:wrangler'],
    example: 'deploy/dashboard-wrangler.example.jsonc',
  },
  'dashboard-secrets': {
    source: { vault: 'Deploy', item: 'production', file: 'dashboard-secrets.env' },
    tags: ['app:dashboard', 'kind:secrets'],
    upload: {
      forEachLine: ['wrangler', 'secret', 'put', { var: 'key' }, '-c', 'wrangler.dashboard.jsonc'],
      stdin: { var: 'value' },
    },
  },
  'api-wrangler': {
    source: { vault: 'Deploy', item: 'production', file: 'api-wrangler.jsonc' },
    path: 'wrangler.api.jsonc',
    tags: ['app:api', 'kind:wrangler'],
  },
  'api-secrets': {
    source: { vault: 'Deploy', item: 'production', file: 'api-secrets.env' },
    tags: ['app:api', 'kind:secrets'],
    upload: {
      forEachLine: ['wrangler', 'secret', 'put', { var: 'key' }, '-c', 'wrangler.api.jsonc'],
      stdin: { var: 'value' },
    },
  },
}

Then in your package.json:

{
  "scripts": {
    "deploy:dashboard": "op-deploy materialize --env production --filter 'app:dashboard AND kind:wrangler' -- bash -c 'pnpm build && wrangler deploy -c $OP_DEPLOY_FILE_DASHBOARD_WRANGLER'",
    "deploy:dashboard:secrets": "op-deploy upload --env production --filter 'app:dashboard AND kind:secrets'",
    "deploy:api": "op-deploy materialize --env production --filter 'app:api AND kind:wrangler' -- bash -c 'pnpm build && wrangler deploy -c $OP_DEPLOY_FILE_API_WRANGLER'",
    "deploy:api:secrets": "op-deploy upload --env production --filter 'app:api AND kind:secrets'",
    "deploy:migrations": "op-deploy materialize --env production --filter 'app:api AND kind:wrangler' -- bash -c 'wrangler d1 migrations apply my-database --remote -c $OP_DEPLOY_FILE_API_WRANGLER'"
  }
}

Per-Environment Configuration

Use separate 1Password items for each environment:

{
  staging: {
    files: {
      'config': {
        source: { vault: 'Deploy', item: 'staging-config', file: 'config.json' },
      },
    },
  },
  production: {
    files: {
      'config': {
        source: { vault: 'Deploy', item: 'production-config', file: 'config.json' },
      },
    },
  },
}

Symlinked Configuration Files

Optionally symlink materialized files into your repo for use by tools:

{
  'wrangler-config': {
    source: { vault: 'Deploy', item: 'production', file: 'wrangler.jsonc' },
    path: 'wrangler.production.jsonc',  // Creates a symlink here
    tags: ['wrangler'],
  },
}

The symlink persists only for the duration of your command. Add the path to .gitignore:

wrangler.*.jsonc

Secrets Upload with Custom Services

If you use a different secret service, customize the upload command:

{
  'api-secrets': {
    source: { vault: 'Deploy', item: 'production', file: 'api-secrets.env' },
    tags: ['secrets', 'api'],
    upload: {
      // Example: upload to a custom API
      forEachLine: ['curl', '-X', 'POST', 'https://secrets.company.internal/set', '-d', { string: ['key=', { var: 'key' }, '&value=', { var: 'value' }] }],
    },
  },
}

Workflow

Typical development + deployment workflow:

# One-time setup
eval $(op signin)
pnpm op-deploy init --env production
pnpm op-deploy edit --env production config-file-name  # fill in real values

# On each deploy
pnpm deploy:app          # materialize + run build + deploy
pnpm deploy:app:secrets  # upload secrets

# Edit files as needed
pnpm op-deploy edit --env production config-file-name

Help

op-deploy --help
op-deploy <command> --help