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

@flowwright/cli

v0.2.0

Published

FlowWright CLI — the `flow` command.

Readme

FlowWright CLI

@flowwright/cli provides the local-first flow command. It turns a typed pipeline.ts into a validated execution plan, runs the dependency graph on your machine or in declared containers, and formats the same typed event stream for developers, CI providers, test systems, and automation.

No account, server, or hosted runner is required. If the pipeline works through flow on a laptop, the same command can run inside any shell-capable CI system.

FlowWright · Documentation · @flowwright/core · @flowwright/runtime · GitHub

[!NOTE] FlowWright is pre-release. The CLI workflow works end to end, but commands and APIs may change before the first stable release.

Why use the CLI

  • Debug before pushing — validate, explain, and run the entire pipeline locally.
  • Keep pipelines in TypeScript — use functions, packages, types, editor support, code review, and unit tests instead of provider-specific YAML logic.
  • Inspect before execution — FlowWright records a serializable plan before any stage runs, so dependencies, commands, conditions, and containers are visible.
  • Run the DAG efficiently — independent stages can execute concurrently with a bounded -j value.
  • Use one event model everywhere — render readable terminal output, CI groups and annotations, JUnit XML, or NDJSON without changing the pipeline.
  • Keep history local — review previous runs and stage logs under the repository's .flowwright/ directory.
  • Adopt incrementally — start with one command in an existing repository; add CI wrappers or the optional team control plane later.

Try it from source

Requirements: Node.js 24+ and pnpm 9.

$ git clone https://github.com/Flow-Wright/FlowWright.git
$ cd flowwright
$ corepack enable
$ pnpm install
$ pnpm build
$ node apps/cli/dist/cli.js init
$ node apps/cli/dist/cli.js run

Once installed as a package, the normal repository workflow is shorter:

$ flow init
$ flow explain
$ flow run

flow init detects the package manager and available scripts, then creates a starter pipeline.ts. It will not overwrite an existing pipeline.

A pipeline is TypeScript

// pipeline.ts
import { pipeline, stage, sh, onBranch } from "@flowwright/core";

export default pipeline({
  name: "web-app",
  stages: [
    stage("Install", async () => {
      await sh`pnpm install --frozen-lockfile`;
    }),
    stage("Test", {
      needs: ["install"],
      run: async () => void (await sh`pnpm test`),
    }),
    stage("Build", {
      needs: ["install"],
      run: async () => void (await sh`pnpm build`),
    }),
    stage("Deploy", {
      needs: ["test", "build"],
      when: onBranch("main"),
      run: async () => void (await sh`pnpm deploy`),
    }),
  ],
});

Stage IDs are derived from their names, so the dependency references above use lowercase IDs. flow validate catches missing dependencies, cycles, duplicate IDs, and invalid execution-plan data before a command starts.

How a run works

FlowWright CLI architecture: pipeline.ts is loaded in a short-lived process, recorded as a serializable execution plan, validated and scheduled by the runtime, executed locally or in Docker, and emitted to terminal, CI, JUnit, NDJSON, and local history consumers.

  1. The CLI loads pipeline.ts in a short-lived node --import tsx child process.
  2. Pipeline code records a serializable execution-plan IR; closures and live objects do not cross back into the parent process.
  3. The parent validates the complete plan before execution.
  4. The runtime topologically schedules ready stages over the dependency graph.
  5. Steps execute on the host or through the Docker executor when a stage declares a container.
  6. Every lifecycle change becomes a typed event consumed by reporters and optional local history.

This plan boundary is what keeps authoring expressive while making execution inspectable, portable, and suitable for policy checks.

Command reference

| Command | Purpose | |---|---| | flow init | Detect the repository and create a starter pipeline.ts | | flow validate | Load and validate the plan without executing it | | flow explain | Print stages, dependencies, commands, conditions, containers, and outputs | | flow run | Validate and execute the pipeline | | flow list | List the 50 most recent local runs | | flow logs [id\|latest] | Read the recorded output for one run | | flow backup <path> | Create a consistent snapshot of local run history | | flow clean | Remove local history and logs while keeping the content cache | | flow clean --all | Remove the entire local .flowwright/ directory | | flow doctor | Check Node, pipeline loading, Docker, git context, and local-state access | | flow export <provider> | Print a thin GitHub Actions, GitLab CI, or Jenkins wrapper | | flow migrate jenkinsfile <path> | Scan a Jenkinsfile and suggest a typed pipeline plus migration report |

Run flow help or flow --help for the built-in reference.

Running pipelines

$ flow run
$ flow run -f ./ci/pipeline.ts
$ flow run -j 4
$ flow run --watch
$ flow run --no-docker
$ flow run --no-history

| Option | Effect | |---|---| | -f, --file <path> | Use another pipeline file; defaults to pipeline.ts | | -j, --concurrency <N> | Execute up to N ready stages concurrently; defaults to 1 | | -w, --watch | Run once, then rerun after project files change | | --no-docker | Execute container-declared stages directly on the host | | --no-history | Do not persist the run or its logs | | --no-color | Disable ANSI color even in an interactive terminal |

Watch runs intentionally disable history and coalesce changes that arrive while a run is still active. Stop watch mode with Ctrl-C.

When a stage declares a container, the CLI uses Docker if it is available. If Docker is missing, it reports the fallback and executes that stage on the host; use flow doctor to detect the condition before CI starts.

Output and CI reporting

All reporters subscribe to the same typed execution events, so formatting never changes the behavior of the run.

$ flow run --reporter pretty
$ flow run --reporter github
$ flow run --reporter gitlab
$ flow run --json
$ flow run --junit .flowwright/junit.xml

| Reporter | Best for | |---|---| | pretty | Interactive terminal output with color and stage progress | | ci | Portable, non-colored CI logs | | github | GitHub Actions groups, annotations, and job summary | | gitlab | GitLab-compatible sections and collapsible output | | json | One JSON execution event per line for automation and ingestion |

The reporter is auto-detected from common CI environment variables. An explicit --reporter wins over detection; --json is shorthand for --reporter json. JUnit is additive, so it can be written alongside any console reporter.

Parallel runs use grouped output to prevent concurrent stage logs from becoming interleaved and unreadable.

Use it in existing CI

FlowWright does not replace the runner. The provider checks out the repository and calls the same local command:

$ flow export github-actions
$ flow export gitlab-ci
$ flow export jenkins

Each command prints a minimal wrapper to standard output, including its intended path. Review and redirect it into the repository when ready. The generated wrapper contains no pipeline logic; pipeline.ts remains the source of truth.

Local history and logs

Unless --no-history is set, each run records structured state and per-stage logs under:

.flowwright/
  state.db       local run and stage history
  runs/
    <run-id>/
      logs/      stage output
  cache/         content-addressed cache

Inspect that state without another service:

$ flow list
$ flow logs latest
$ flow logs <run-id> --stage test
$ flow backup ./backups/flowwright.db
$ flow clean

flow clean preserves the content cache because rebuilding it can be expensive. Use flow clean --all only when the cache should also be discarded.

Migrate from Jenkins

$ flow migrate jenkinsfile ./Jenkinsfile
$ flow migrate jenkinsfile ./Jenkinsfile --out pipeline.ts

The scanner extracts declarative stages, shell commands, container images, and common branch or tag conditions. It also reports constructs requiring manual attention—such as shared libraries, credentials, approvals, post blocks, or plugin-specific steps—and labels the migration easy, medium, or hard.

Migration is deliberately best-effort. The generated TypeScript is a reviewable starting point, not a promise of semantic equivalence with arbitrary Groovy.

CLI and app-suite boundary

The flow command is intentionally local-only:

  • It does not start or call flowwright-server.
  • It has no project, user, token, remote-run, server, or worker commands.
  • It depends only on @flowwright/core, @flowwright/runtime, and the TypeScript loader.
  • Pipeline execution and local history continue to work without the web application.

When a team needs shared projects, triggers, schedules, queues, RBAC, audit records, central history, or a worker fleet, add the optional flowwright-server, web app, and flowwright-worker. Existing pipeline.ts definitions keep the same execution-plan boundary.

Source layout

src/
  cli.ts          argument parsing, help, dispatch, and process exit handling
  commands.ts     run, validate, explain, history, cleanup, and doctor commands
  scaffold.ts     repository detection and starter pipeline generation
  watch.ts        recursive watch mode and rerun coordination
  migrate.ts      Jenkinsfile scanning and TypeScript generation
  export.ts       thin CI wrapper generation
  reporters/      terminal, GitHub, GitLab, JUnit, and NDJSON event consumers
  render.ts       sequential and grouped terminal rendering
  env.ts          CI provider detection
  git.ts          branch, tag, and commit context
  io.ts           injectable command I/O boundary

Command handlers return exit codes and accept injected I/O, keeping behavior testable without spawning the complete executable.

Development commands

Run these from the repository root:

$ pnpm --filter @flowwright/cli typecheck    # strict TypeScript validation
$ pnpm --filter @flowwright/cli test         # command, reporter, migration, and watch tests
$ pnpm --filter @flowwright/cli build        # compile the flow executable
$ node apps/cli/dist/cli.js --help           # exercise the built command

The test suite covers command behavior, scaffold detection, grouped rendering, reporter selection, NDJSON, JUnit, CI exports, Jenkins migration, formatting, and watch-mode coordination.