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

@medianaura/automaton

v0.2.0

Published

**Automaton** is a powerful Node.js CLI tool that enables developers to create automated job workflows using TypeScript configuration files. Define complex sequences of actions, interact with users through prompts, and automate your development workflow w

Readme

Automaton

Automaton is a powerful Node.js CLI tool that enables developers to create automated job workflows using TypeScript configuration files. Define complex sequences of actions, interact with users through prompts, and automate your development workflow with type safety.

Version Downloads/week

Installation

Install Automaton globally or locally in your project using your preferred package manager:

npm

# Global installation
npm install -g @medianaura/automaton

# Local installation
npm install --save-dev @medianaura/automaton

pnpm

# Global installation
pnpm install -g @medianaura/automaton

# Local installation
pnpm install --save-dev @medianaura/automaton

yarn

# Global installation
yarn global add @medianaura/automaton

# Local installation
yarn add --dev @medianaura/automaton

Requirements:

  • Node.js >= 22.0.0

How it Works

Automaton operates on three core concepts:

  1. Jobs: Collections of actions with unique IDs and descriptive names
  2. Actions: Individual steps that can be shell commands (cmd) or custom JavaScript functions (run)
  3. Prompts: Interactive questions that collect user input before job execution

When you run a job, Automaton:

  1. Loads your configuration file
  2. Executes all prompts to collect user input
  3. Runs actions sequentially, substituting variables from user answers
  4. Provides real-time feedback during execution

Quick Start

  1. Create a configuration file at your project root:
// automaton.config.mts
import { defineConfig, createPrompt } from '@medianaura/automaton';

// `createPrompt` is a helper for defining reusable prompts. The `enquirer` object provides access to the Enquirer.js API.
const namePrompt = createPrompt(async (enquirer) => {
  const result = await enquirer.prompt({
    type: 'input',
    name: 'name',
    message: 'What is your name?',
  });
  return result;
});

export default () => {
  return defineConfig({
    jobs: [
      {
        id: 'hello',
        name: 'Say Hello',
        actions: [{ type: 'cmd', cmd: 'echo "Hello, %(name)s!"' }],
        prompts: [namePrompt],
      },
    ],
  });
};
  1. Run your job:
automaton hello
  1. Answer the prompt and watch Automaton execute your workflow!

Configuration

Basic Structure

Create an automaton.config.mts (or .js, .ts, .mjs, .cjs, .cts) file at your project root to define your jobs. This file is essential for Automaton to function.

import { defineConfig } from '@medianaura/automaton';

export default () => {
  return defineConfig({
    jobs: [
      // Your jobs go here
    ],
  });
};

Job Definition

Each job requires:

  • id: Unique identifier for the job
  • name: Human-readable description
  • actions: Array of actions to execute
  • prompts (optional): Array of prompt functions
{
  id: 'deploy',
  name: 'Deploy to production',
  actions: [
    // Actions here
  ],
  prompts: [
    // Prompts here
  ]
}

Actions

Command Actions (cmd)

Execute shell commands with variable substitution:

{
  type: 'cmd',
  cmd: 'npm run build',
  when: (answers) => answers.build === true  // Optional condition
}

Variable Substitution: Use %(variable)s syntax to substitute user answers:

{
  type: 'cmd',
  cmd: 'git commit -m "%(commit_message)s"'
}

Function Actions (run)

Execute custom JavaScript functions:

{
  type: 'run',
  run: async (answers) => {
    console.log('Processing answers:', answers);
    // Custom logic here
    if (!answers.confirm) {
      process.exit(1);
    }
  },
  when: (answers) => answers.process === true  // Optional condition
}

Conditional Actions with when

The when property allows you to conditionally execute actions based on user answers or other logic. This is useful for:

  • Skipping unnecessary steps based on user choices
  • Creating branching workflows that adapt to different scenarios
  • Validating prerequisites before running critical actions
  • Implementing dry-run modes that skip destructive operations

Examples:

// Skip git operations if repository is clean
{
  type: 'cmd',
  cmd: 'git add . && git commit -m "chore: release"',
  when: async (answers) => {
    // Note: `execa` must be installed as a dependency in your project for `execaCommand` to work.
    const { stdout } = await execaCommand('git status --porcelain');
    return stdout.trim().length > 0; // Only if there are changes
  }
}

// Only run database migrations in production
{
  type: 'cmd',
  cmd: 'npm run migrate:prod',
  when: (answers) => answers.environment === 'production'
}

// Skip git operations if repository is clean
{
  type: 'cmd',
  cmd: 'git add . && git commit -m "chore: release"',
  when: async (answers) => {
    const { stdout } = await execaCommand('git status --porcelain');
    return stdout.trim().length > 0; // Only if there are changes
  }
}

// Dry-run mode that skips destructive operations
{
  type: 'cmd',
  cmd: 'rm -rf dist/',
  when: (answers) => !answers.dryRun
}

The when function receives the same answers object as the action and should return true to execute the action or false to skip it. This makes your workflows more flexible and intelligent.

Prompts

Create interactive prompts using the Enquirer API. The createPrompt function provides a convenient wrapper for creating prompt functions, standardizing prompt creation and providing a consistent API for future extensibility. The enquirer object passed to the createPrompt callback provides access to the full Enquirer.js API.

import { createPrompt } from '@medianaura/automaton';

const myPrompt = createPrompt(async (enquirer) => {
  const result = await enquirer.prompt({
    type: 'select',
    name: 'environment',
    message: 'Choose deployment environment:',
    choices: ['development', 'staging', 'production']
  });
  return result;
});

const myUsernamePrompt = createPrompt(async (enquirer) => {
  const result = await enquirer.prompt({
    type: 'input',
    name: 'username',
    message: 'Enter your username:',
  });
  return result;
});

// Use in job
{
  id: 'deploy',
  name: 'Deploy application',
  actions: [
    { type: 'cmd', cmd: 'npm run deploy:%(environment)s' }
  ],
  prompts: [myPrompt, myUsernamePrompt]
}

#### Version Tools

Automaton includes built-in version management with `getVersionPrompt`, which prompts the user to select a new version (e.g., patch, minor, major) and provides the chosen version as `answers.version`.

```typescript
import { getVersionPrompt } from '@medianaura/automaton';

export default () => {
  return defineConfig({
    jobs: [
      {
        id: 'release',
        name: 'Create new release',
        actions: [
          {
            type: 'run',
            run: (answers) => {
              if (!answers.confirm) {
                console.log('Release cancelled.');
                process.exit(0); // Exit gracefully if not confirmed
              }
            },
          },
          { type: 'cmd', cmd: 'npm version %(version)s' },
          { type: 'cmd', cmd: 'git push --tags' },
        ],
        prompts: [getVersionPrompt],
      },
    ],
  });
};

Commands

Basic Usage

automaton <job> [answer-files]
  • <job>: The ID of the job to run
  • [answer-files]: Optional JSON files containing pre-defined answers

Examples

# Run a job interactively
automaton deploy

# Run with pre-defined answers
automaton deploy answers.json

# Run the version job
automaton version

Answer Files

Create JSON files to provide answers without prompts:

// answers.json
{
  "environment": "production",
  "confirm": true,
  "version": "1.2.3"
}
automaton deploy answers.json

Examples

Example 1: Build and Deploy

// automaton.config.mts
import { defineConfig, createPrompt } from '@medianaura/automaton';

const deployPrompt = createPrompt(async (enquirer) => {
  const env = await enquirer.prompt({
    type: 'select',
    name: 'environment',
    message: 'Select environment:',
    choices: ['staging', 'production'],
  });

  const confirm = await enquirer.prompt({
    type: 'confirm',
    name: 'confirm',
    message: `Deploy to ${env.environment}?`,
    initial: false,
  });

  return { ...env, ...confirm };
});

export default () => {
  return defineConfig({
    jobs: [
      {
        id: 'deploy',
        name: 'Build and Deploy',
        actions: [
          { type: 'cmd', cmd: 'npm run test' },
          { type: 'cmd', cmd: 'npm run build' },
          {
            type: 'run',
            run: (answers) => {
              if (!answers.confirm) {
                console.log('Deployment cancelled');
                process.exit(0);
              }
            },
          },
          { type: 'cmd', cmd: 'npm run deploy:%(environment)s' },
        ],
        prompts: [deployPrompt],
      },
    ],
  });
};

Example 2: Release Workflow

// automaton.config.mts
import { defineConfig, getVersionPrompt, createPrompt } from '@medianaura/automaton';

const releaseNotesPrompt = createPrompt(async (enquirer) => {
  const result = await enquirer.prompt({
    type: 'input',
    name: 'notes',
    message: 'Enter release notes:',
    validate: (value) => value.length > 0 || 'Release notes are required',
  });
  return result;
});

export default () => {
  return defineConfig({
    jobs: [
      {
        id: 'release',
        name: 'Create new release',
        actions: [
          {
            type: 'run',
            run: (answers) => {
              if (!answers.confirm) {
                process.exit(4);
              }
            },
          },
          { type: 'cmd', cmd: 'npm run test' },
          { type: 'cmd', cmd: 'npm run build' },
          { type: 'cmd', cmd: 'npm version --force --no-git-tag-version %(version)s' }, // --force to bypass git checks, --no-git-tag-version to prevent npm from creating a git tag
          {
            type: 'cmd',
            cmd: 'git add . && git commit -m "chore: release v%(version)s\n\n%(notes)s"',
          },
          { type: 'cmd', cmd: 'git tag -a v%(version)s -m "Release v%(version)s"' },
          { type: 'cmd', cmd: 'git push && git push --tags' },
          { type: 'cmd', cmd: 'npm publish' },
        ],
        prompts: [getVersionPrompt, releaseNotesPrompt],
      },
    ],
  });
};

Example 3: Database Migration

// automaton.config.mts
import { defineConfig, createPrompt } from '@medianaura/automaton';

const migrationPrompt = createPrompt(async (enquirer) => {
  const name = await enquirer.prompt({
    type: 'input',
    name: 'migration_name',
    message: 'Migration name:',
    validate: (value) => value.length > 0 || 'Migration name is required',
  });

  const direction = await enquirer.prompt({
    type: 'select',
    name: 'direction',
    message: 'Migration direction:',
    choices: ['up', 'down'],
  });

  return { ...name, ...direction };
});

export default () => {
  return defineConfig({
    jobs: [
      {
        id: 'migrate',
        name: 'Run database migration',
        actions: [
          {
            type: 'cmd',
            cmd: 'npm run migration:create %(migration_name)s',
            when: (answers) => answers.direction === 'up',
          },
          { type: 'cmd', cmd: 'npm run migration:%(direction)s' },
          {
            type: 'run',
            run: (answers) => {
              console.log(`Migration ${answers.direction} completed successfully`);
            },
          },
        ],
        prompts: [migrationPrompt],
      },
    ],
  });
};

Troubleshooting

Common Issues

Configuration Not Found

Error: Configuration file not found

Solution: Ensure you have an automaton.config.js, automaton.config.ts, automaton.config.mjs, automaton.config.cjs, automaton.config.mts, or automaton.config.cts file at your project root.

TypeScript Compilation Errors

Error: TypeScript compilation fails

Solution:

  • Check your TypeScript syntax
  • Ensure all imports are correct
  • Verify your tsconfig.json configuration

Command Not Found

Error: automaton: command not found

Solution:

  • If installed locally, use npx automaton or add to your package.json scripts
  • If installed globally, ensure npm global bin directory is in your PATH

Permission Denied

Error: Permission errors when running commands

Solution:

  • For global installations: If you installed Automaton globally with npm install -g, you might need to run the installation command with sudo (e.g., sudo npm install -g @medianaura/automaton) on macOS/Linux, or ensure your user has appropriate permissions to write to the global npm directory.
  • For local scripts: Ensure the script you are trying to run has execute permissions (e.g., chmod +x your-script.sh).
  • For file operations: Check the permissions of the files or directories Automaton is trying to access or modify.

Getting Help

If you encounter issues:

  1. Check your configuration file syntax
  2. Verify all required dependencies are installed
  3. Ensure Node.js version >= 22.0.0
  4. Run with debug mode for detailed logs

For more help, visit the GitHub repository or file an issue.