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

@travetto/cli

v8.0.2

Published

CLI infrastructure for Travetto framework

Readme

Command Line Interface

CLI infrastructure for Travetto framework

Install: @travetto/cli

npm install @travetto/cli

# or

yarn add @travetto/cli

The cli module represents the primary entry point for execution within the framework. One of the main goals for this module is extensibility, as adding new entry points is meant to be trivial. The framework leverages this module for exposing all executable tools and entry points. To see a high level listing of all supported commands, invoke trv --help

Terminal: General Usage

$ trv --help

Usage:  [options] [command]

Commands:
  doc                   Generate documentation outputs from a module `DOC.tsx` entry file.
  doc:angular           Generate documentation into the angular webapp under related/travetto.github.io
  doc:mapping           Generate module mapping for
  email:compile         Compile all email templates into generated runtime artifacts.
  email:editor          Start the email template editor service for interactive preview and testing.
  email:test            Render and send a template file to a target recipient for quick validation.
  firestore:indexes     Generate the Firestore composite indexes JSON for all registered models.
  lint:check            Run oxlint linter for the workspace or changed files.
  lint:format           Run oxfmt formatter for the workspace or changed files.
  lint:register         Generate the workspace oxlint, oxfmt, and cspell configuration entry files.
  lint:spell            Run cspell spell checker for the workspace or changed files.
  llm:support:execute   Execute llm-support operations with dry-run by default.
  llm:support:inline    Inline and compile reference snippets for llm-support packaging.
  llm:support:mcp       Minimal MCP stdio server for llm-support tools.
  llm:support:plan      Build plan-first execution details for llm-support operations.
  llm:support:recommend Recommend llm-support bundles, workflows, and operations.
  llm:support:status    Show llm-support execution coverage status.
  model:export          Export model definitions for a selected provider and model set.
  model:install         Install or update model definitions for a selected provider.
  openapi:client        Generate API clients from an OpenAPI specification using the generator image.
  openapi:spec          Generate the OpenAPI specification for the selected module.
  pack                  Build a standard module package artifact.
  pack:docker           Build container-ready artifacts and optionally publish Docker images.
  pack:lambda           Build an AWS Lambda-ready zip package using the pack pipeline.
  pack:zip              Build a deployable zip artifact using the standard pack pipeline.
  repo:exec             Execute a shell command across workspace modules.
  repo:list             List workspace modules and their relationships.
  repo:publish          Publish unpublished workspace modules to the package registry.
  repo:version          Bump workspace module versions and optionally commit/tag release metadata.
  repo:version-sync     Synchronize package versions and dependency ranges across the monorepo.
  run:double            Doubles a number
  service               Manage development services (start/stop/restart/status) across the workspace.
  test                  Execute the test framework for targeted files, suites, or methods.
  test:watch            Start the test watcher for continuous test execution.
  web:http              Start the configured web HTTP server for a module.
  web:rpc-client        Generate web-rpc client artifacts from a specified provider or leveraging local config.

This listing is from the Travetto monorepo, and represents the majority of tools that can be invoked from the command line.

This module also has a tight integration with the VSCode plugin, allowing the editing experience to benefit from the commands defined. The most commonly used commands will be the ones packaged with the framework, but its also very easy to create new commands. With the correct configuration, these commands will also be exposed within VSCode.

At it's heart, a cli command is the contract defined by what flags, and what arguments the command supports. Within the framework this requires three criteria to be met:

  • The file must be located in the support/ folder, and have a name that matches cli.*.ts
  • The file must be a class that has a main method
  • The class must use the @CliCommand decorator

Code: Basic Command

import { CliCommand } from '@travetto/cli';

@CliCommand()
export class BasicCommand {
  main() {
    console.log('Hello');
  }
}

Terminal: Basic Command Help

$ trv basic --help

Usage: basic [options]

Options:
  --help  display help for command

Command Naming

The file name support/cli.<name>.ts has a direct mapping to the cli command name. This hard mapping allows for the framework to be able to know which file to invoke without needing to load all command-related files.

Examples of mappings:

  • cli.test.ts maps to test
  • cli.pack_docker.ts maps to pack:docker
  • cli.email_template.ts maps to email:template

The pattern is that underscores(_) translate to colons (:), and the cli. prefix, and .ts suffix are dropped.

Binding Flags

@CliCommand is a wrapper for @Schema, and so every class that uses the @CliCommand decorator is now a full @Schema class. The fields of the class represent the flags that are available to the command.

Code: Basic Command with Flag

import { CliCommand } from '@travetto/cli';

@CliCommand()
export class BasicCommand {
  loud?: boolean;

  main() {
    console.log(this.loud ? 'HELLO' : 'Hello');
  }
}

Terminal: Basic Command with Flag Help

$ trv basic:flag --help

Usage: basic:flag [options]

Options:
  -l, --loud
  --help      display help for command

As you can see the command now has the support of a basic boolean flag to determine if the response should be loud or not. The default value here is undefined/false, and so is an opt-in experience.

Terminal: Basic Command with Loud Flag

$ trv basic:flag --loud

HELLO

The @CliCommand supports the following data types for flags:

  • Boolean values
  • Number values. The @Integer, @Float, @Precision, @Min and @Max decorators help provide additional validation.
  • String values. @MinLength, @MaxLength, @Match and @Enum provide additional constraints
  • Date values. The @Min and @Max decorators help provide additional validation.
  • String lists. Same as String, but allowing multiple values.
  • Numeric lists. Same as Number, but allowing multiple values.

Binding Arguments

The main() method is the entrypoint for the command, represents a series of parameters. Some will be required, some may be optional. The arguments support all types supported by the flags, and decorators can be provided using the decorators inline on parameters. Optional arguments in the method, will be optional at run time, and filled with the provided default values.

Code: Basic Command with Arg

import { CliCommand } from '@travetto/cli';
import { Max, Min } from '@travetto/schema';

@CliCommand()
export class BasicCommand {
  main(@Min(1) @Max(10) volume: number = 1) {
    console.log(volume > 7 ? 'HELLO' : 'Hello');
  }
}

Terminal: Basic Command

$ trv basic:arg --help

Usage: basic:arg [options] [volume:number]

Options:
  --help  display help for command

Terminal: Basic Command with Invalid Loud Arg

$ trv basic:arg 20

Execution failed:
 * Argument volume is greater than (10)

Usage: basic:arg [options] [volume:number]

Options:
  --help  display help for command

Terminal: Basic Command with Loud Arg > 7

$ trv basic:arg 8

HELLO

Terminal: Basic Command without Arg

$ trv basic:arg

Hello

Additionally, if you provide a field as an array, it will collect all valid values (excludes flags, and any arguments past a --).

Code: Basic Command with Arg List

import { CliCommand } from '@travetto/cli';
import { Max, Min } from '@travetto/schema';

@CliCommand()
export class BasicCommand {
  reverse?: boolean;

  main(@Min(1) @Max(10) volumes: number[]) {
    console.log(volumes.toSorted((a, b) => (a - b) * (this.reverse ? -1 : 1)).join(' '));
  }
}

Terminal: Basic Command

$ trv basic:arg-list --help

Usage: basic:arg-list [options] <volumes...:number>

Options:
  -r, --reverse
  --help         display help for command

Terminal: Basic Arg List

$ trv basic:arg-list 10 5 3 9 8 1

1 3 5 8 9 10

Terminal: Basic Arg List with Invalid Number

$ trv basic:arg-list 10 5 3 9 20 1

Execution failed:
 * Argument volumes[4] is greater than (10)

Usage: basic:arg-list [options] <volumes...:number>

Options:
  -r, --reverse
  --help         display help for command

Terminal: Basic Arg List with Reverse

$ trv basic:arg-list -r 10 5 3 9 8 1

10 9 8 5 3 1

Customization

By default, all fields are treated as flags and all parameters of main() are treated as arguments within the validation process. Like the standard @Schema behavior, we can leverage the metadata of the fields/parameters to help provide additional customization/context for the users of the commands.

Code: Custom Command with Metadata

import { CliCommand } from '@travetto/cli';
import { Max, Min } from '@travetto/schema';

/**
 * Example command with a custom argument
 */
@CliCommand()
export class CustomCommand {
  /**
   * The message to send back to the user
   * @alias -m
   * @alias --message
   */
  text: string = 'hello';

  main(@Min(1) @Max(10) volume: number = 1) {
    console.log(volume > 7 ? this.text.toUpperCase() : this.text);
  }
}

Terminal: Custom Command Help

$ trv custom:arg --help

Usage: custom:arg [options] [volume:number]

Description:
  Example command with a custom argument

Options:
  -m, --message <string>  The message to send back to the user (default: "hello")
  --help                  display help for command

Terminal: Custom Command Help with overridden Text

$ trv custom:arg 10 -m cUsToM

CUSTOM

Terminal: Custom Command Help with default Text

$ trv custom:arg 6

hello

Environment Variable Support

In addition to standard flag overriding (e.g. /** @alias -m */), the command execution also supports allowing environment variables to provide values (secondary to whatever is passed in on the command line).

Code: Custom Command with Env Var

import { CliCommand } from '@travetto/cli';
import { Max, Min } from '@travetto/schema';

/**
 * Example of a command with a custom environment variable argument
 */
@CliCommand()
export class CustomCommand {
  /**
   * The message to send back to the user
   * @alias env.MESSAGE
   */
  text: string = 'hello';

  main(@Min(1) @Max(10) volume: number = 1) {
    console.log(volume > 7 ? this.text.toUpperCase() : this.text);
  }
}

Terminal: Custom Command Help

$ trv custom:env-arg --help

Usage: custom:env-arg [options] [volume:number]

Description:
  Example of a command with a custom environment variable argument

Options:
  -t, --text <string>  The message to send back to the user (default: "hello")
  --help               display help for command

Terminal: Custom Command Help with default Text

$ trv custom:env-arg 6

hello

Terminal: Custom Command Help with overridden Text

$ MESSAGE=CuStOm trv custom:env-arg 10

CUSTOM

Terminal: Custom Command Help with overridden Text

$ MESSAGE=CuStOm trv custom:env-arg 7

CuStOm

Flag File Support

Sometimes its also convenient, especially with commands that support a variety of flags, to provide easy access to pre-defined sets of flags. Flag files represent a snapshot of command line arguments and flags, as defined in a file. When referenced, these inputs are essentially injected into the command line as if the user had typed them manually.

Code: Example Flag File

--host localhost
--port 3306
--username app

As you can see in this file, it provides easy access to predefine the host, port, and user flags.

Code: Using a Flag File

npx trv call:db +=base --password <custom>

The flag files can be included in one of a few ways:

  • +=<name> - This translates into <module>/support/<name>.flags, which is a convenient shorthand.
  • +=<module>/path/file.flags - This is a path-related file that will be resolved from the module's location.
  • +=/path/file.flags - This is an absolute path that will be read from the root of the file system.

Ultimately, after resolution, the content of these files will be injected inline within the location.

Code: Final arguments after Flag File resolution

npx trv call:db --host localhost --port 3306 --username app --password <custom>

VSCode Integration

By default, cli commands do not expose themselves to the VSCode extension, as the majority of them are not intended for that sort of operation. Web API does expose a cli target web:http that will show up, to help run/debug a web application. Any command can mark itself as being a run target, and will be eligible for running from within the VSCode plugin. This is achieved by setting the runTarget field on the @CliCommand decorator. This means the target will be visible within the editor tooling.

Code: Simple Run Target

import { CliCommand } from '@travetto/cli';

/**
 * Simple Run Target
 */
@CliCommand({ runTarget: true })
export class RunCommand {
  main(name: string) {
    console.log(name);
  }
}

Advanced Usage

Code: Anatomy of a Command

export interface CliCommandShape {
  /**
   * Action target of the command
   */
  main(...args: unknown[]): OrProm<undefined | void>;
  /**
   * Run before main runs
   */
  finalize?(help?: boolean): OrProm<void>;
  /**
   * Extra help
   */
  help?(): OrProm<string[]>;
}

Dependency Injection

If the goal is to run a more complex application, which may include depending on Dependency Injection, we can take a look at Web API's target:

Code: Simple Run Target

import { CliCommand, type CliCommandShape, CliDebugIpcFlag, CliModuleFlag, CliProfilesFlag, CliRestartOnChangeFlag } from '@travetto/cli';
import { DependencyRegistryIndex } from '@travetto/di';
import { Registry } from '@travetto/registry';
import { Runtime, toConcrete } from '@travetto/runtime';
import { NetUtil } from '@travetto/web';

import type { WebHttpServer } from '../src/types.ts';

/**
 * Start the configured web HTTP server for a module.
 *
 * Initializes registry and server bindings, supports restart-aware development
 * flags, and can attempt to clear conflicting port owners in local workflows.
 *
 * @example
 * Starting a web server on port 8000
 * > trv web:http -m <MODULE> -p 8000
 */
@CliCommand()
export class WebHttpCommand implements CliCommandShape {
  /** Port to run on */
  port?: number;

  /** Kill conflicting port owner */
  killConflict?: boolean = Runtime.localDevelopment;

  @CliModuleFlag({ short: 'm' })
  module: string;

  @CliProfilesFlag()
  profile: string[];

  @CliRestartOnChangeFlag()
  restartOnChange: boolean = Runtime.localDevelopment;

  @CliDebugIpcFlag()
  debugIpc?: boolean;

  finalize(): void {
    if (this.port) {
      process.env.WEB_HTTP_PORT = `${this.port}`;
    }
  }

  async main(): Promise<void> {
    await Registry.init();
    const instance = await DependencyRegistryIndex.getInstance(toConcrete<WebHttpServer>());

    try {
      const handle = await instance.serve();
      return handle.complete;
    } catch (err) {
      const result = this.killConflict ? await NetUtil.freePortOnConflict(err) : undefined;
      if (result?.processId) {
        console.warn('Killed process owning port', result);
        process.exitCode = 1; // Indicate error, restart will use if in that mode
        return;
      }
      throw err;
    }
  }
}

As noted in the example above, fields is specified in this execution, with support for module, and env. These env flag is directly tied to the Runtime name defined in the Runtime module.

The module field is slightly more complex, but is geared towards supporting commands within a monorepo context. This flag ensures that a module is specified if running from the root of the monorepo, and that the module provided is real, and can run the desired command. When running from an explicit module folder in the monorepo, the module flag is ignored.

Custom Validation

In addition to dependency injection, the command contract also allows for a custom validation function, which will have access to bound command (flags, and args) as well as the unknown arguments. When a command implements this method, any ValidationError errors that are returned will be shared with the user, and fail to invoke the main method.

Code: ValidationError

export interface ValidationError {
  /**
   * The error message
   */
  message: string;
  /**
   * The object path of the error
   */
  path: string;
  /**
   * The kind of validation
   */
  kind: ValidationKind;
  /**
   * The value provided
   */
  value?: unknown;
  /**
   * Regular expression to match
   */
  regex?: string;
  /**
   * Number to compare against
   */
  limit?: NumericLikeIntrinsic;
  /**
   * The type of the field
   */
  type?: string;
  /**
   * Source of the error
   */
  source?: string;
}

A simple example of the validation can be found in the doc command:

Code: Simple Validation Example

@Validator(async cmd => {
  const docFile = path.resolve(cmd.input);
  if (!(await fs.stat(docFile, { throwIfNoEntry: false }))) {
    return { message: `input: ${cmd.input} does not exist`, path: 'input', source: 'flag', kind: 'invalid' };
  }
})

CLI - service

The module provides the ability to start/stop/restart services as docker containers. This is meant to be used for development purposes, to minimize the effort of getting an application up and running. Services can be targeted individually or handled as a group.

Terminal: Help for service

$ trv service --help

Usage: service [options] <action:restart|start|status|stop> [services...:string]

Description:
  Manage development services (start/stop/restart/status) across the workspace.

  Services are discovered from registered descriptors and executed with streamed
  terminal feedback, including optional quiet mode.

Options:
  -q, --quiet   (default: false)
  --help       display help for command

Available Services
--------------------
 * [email protected]
 * [email protected]
 * firestore@latest
 * [email protected]
 * [email protected]
 * [email protected]
 * [email protected]
 * [email protected]

A sample of all services available to the entire framework:

Terminal: All Services

$ trv service status

Service          Version    Status
-------------------------------------------------
dynamodb           3.3.0    Running 93af422e793a
elasticsearch      9.5.2    Running ed76ee063d13
firestore         latest    Running feec2e5e95b4
mongodb              8.3    Running 5513eba6734e
mysql                9.7    Running 307bc66d442a
postgresql          18.6    Running e78291e71040
redis               8.10    Running 77ba279b4e30
s3                4.12.4    Running fdacfc55b9e3

Defining new Services

The services are defined as plain typescript files within the framework and can easily be extended:

Code: Sample Service Definition

import type { ServiceDescriptor } from '@travetto/cli';

const version = process.env.MONGO_VERSION || '8.3';

/* cspell:words orbstack pthread rseq glibc TUNABLES */

export const service: ServiceDescriptor = {
  name: 'mongodb',
  version,
  port: 27017,
  image: `mongo:${version}`,
  env: {
    // Temp until mongo image fixes orbstack issue
    GLIBC_TUNABLES: 'glibc.pthread.rseq=1'
  }
};