New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@evoo/cli

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@evoo/cli

Welcome to the Evoo CLI, a powerful, job-based tool for automating project tasks. It can be used for both **one-off scaffolding** (like initializing a new project with `create-react-app.json`) and **stateful, incremental updates** (like adding a themed co

latest
npmnpm
Version
1.0.0-alpha.1
Version published
Maintainers
1
Created
Source

@evoo/cli 🏗️

Welcome to the Evoo CLI, a powerful, job-based tool for automating project tasks. It can be used for both one-off scaffolding (like initializing a new project with create-react-app.json) and stateful, incremental updates (like adding a themed component with add-material-ui-button.json).

Define a series of tasks in a single JSON file—creating files, asking questions, installing dependencies, and more. Evoo executes them sequentially with support for conditional logic, user prompts, and persistent state (evoo.store.json) to create highly adaptable and context-aware automations.

✨ Core Features

  • Job-Based System: Every action is a "job"—create a file, ask a question, install a package, or group other jobs.
  • Conditional Logic: Use powerful when clauses to run jobs only when specific conditions are met.
  • Interactive Prompts: Engage with the user through text inputs, confirmations (y/n), or a list of options.
  • State Management: Save user answers in-memory for the current session (#id) or persistently across runs (@id).
  • Dynamic Paths & Content: Use stored answers as variables in file paths, file content, and conditional checks.
  • Plugin-Driven: The CLI's functionality is extended through plugins, making it highly modular and adaptable.

💻 Installation

Install Evoo globally to use the evoo command anywhere:

npm install -g evoo

Or run it directly without a global installation using npx:

npx evoo@latest <jsonPath>

🚀 Usage

Basic Command

evoo <source> [options]
  • <source>: The path to a local .json file or a URL to a remote one.

CLI Options

OptionShortDescription
--dir-dSet the working directory for the scaffold.
--force-fOverwrite existing files without prompting.
--extend-path-eAdds a prefix to the name property of all file jobs.

📄 The evoo.json Structure

The power of Evoo comes from its JSON structure. At its core, it's a list of jobs to be executed in order.

Root Properties

PropertyTypeRequiredDescription
namestringThe internal name of the scaffold.
titlestringA user-friendly title for the scaffold.
versionstringThe semantic version of the scaffold.
descriptionstringA brief summary of what the scaffold does.
dependenciesstring[]A list of npm packages to install at the very beginning of the process.
jobsJob[]The primary array of jobs to be executed sequentially.
definitionsRecord<string, Job>A map of reusable job definitions that can be executed by a run job.
pluginsstring[]A list of plugins to load, which can provide custom job types.
sharedContextobjectA shared data object that is passed to all plugin job executors.

The Job Object

Every object in the jobs array is a Job. All jobs share these common properties:

PropertyTypeRequiredDescription
typestring✔️The type of job to run.
idstringA unique identifier, used to reference the job's result in when conditions. Required for question jobs.
whenstringA conditional expression. The job only runs if the expression evaluates to true.
confirmstringA yes/no question to ask before running the job.

⚙️ Built-in Job Types

file

Performs a file operation (write, append, or replace). This is the default job type if type is omitted.

PropertyTypeRequiredDescription
namestring✔️The path of the file, relative to the project or a base directory from a group job.
method"w", "a", or "replace"The file operation method. Defaults to "w".
contentstring or Record<string, string>✔️The content for the operation. If method is "replace", this must be an object of search/replace pairs.

Example:

{
  "jobs": [
    {
      "name": "src/components/<#componentName>.tsx",
      "content": "export const Button = () => <button>Click Me</button>;"
    }
  ]
}

question

Prompts the user for input and stores the answer.

PropertyTypeRequiredDescription
idstring✔️The key used to store the answer. Use #id for session storage and @id for persistent storage.
questionstring✔️The question text displayed to the user.
questionType"ask", "confirm", or "options"✔️The type of prompt to display.
defaultValuestringAn optional default value for the prompt.
optionsRecord<string, string>A map of options for the options questionType.

Example:

{
  "type": "question",
  "id": "@project.linter",
  "questionType": "confirm",
  "question": "Do you want to use ESLint?",
  "defaultValue": true
}

log

Displays a custom message in the terminal.

PropertyTypeRequiredDescription
messagestring✔️The message to display.
logLevel"error", "warn", "info", "success", "log"The style of the log message. Defaults to "log".

Example:

{
  "type": "log",
  "logLevel": "success",
  "message": "✅ Project has been successfully created!"
}

dependencies

Installs npm packages.

PropertyTypeRequiredDescription
dependenciesstring[] or string✔️The package(s) to install.
whenstring✔️This job must be conditional to prevent accidental installations.

Example:

{
  "type": "dependencies",
  "when": "@project.linter == true",
  "dependencies": ["eslint", "prettier"]
}

group

A container for a nested sequence of jobs.

PropertyTypeRequiredDescription
jobsJob[]✔️An array of Job objects to be executed sequentially.
basestringAn optional base path that prefixes all file paths within this group.

Example:

{
  "type": "group",
  "when": "#useTypescript == true",
  "base": "src/",
  "jobs": [
    { "name": "../tsconfig.json", "content": "{}" },
    { "name": "index.ts", "content": "// TS entry file" }
  ]
}

run

Executes a reusable job from the top-level definitions map.

PropertyTypeRequiredDescription
targetstring✔️The key of the job to execute from the definitions object.

Example:

{
  "definitions": {
    "createHook": {
      "type": "file",
      "name": "src/hooks/useMouse.ts",
      "content": "..."
    }
  },
  "jobs": [
    {
      "type": "run",
      "target": "createHook"
    }
  ]
}

🧠 Advanced Concepts

Conditional Logic (when)

A when expression determines if a job should run. It can access any stored variable, including nested values using dot notation (e.g., #project.linter).

  • Existence Check: Checks if a job has run (i.e., its result is defined), not whether the value is "truthy".

    • "#useAuth": Runs if the useAuth job was executed.
    • "!#useAuth": Runs if the useAuth job was skipped.
  • Value Comparison: Compares a job's result to a specific value.

    • Note: Use loose equality operators (==, !=) in the JSON. Evoo's engine will execute them as strict (===, !==) comparisons at runtime.
    • "#framework == 'react'": Runs if the framework result is strictly 'react'.
    • "@project.linter == true": Runs if the nested linter value is the boolean true.

Dynamic File Paths

The name property of a file job is highly dynamic. You can construct paths using a combination of:

  • Variables: Inject answers from questions.
    • "name": "src/components/<#componentName>/index.tsx"
  • Ask Placeholders: Prompt the user directly for a path segment.
    • <-ask->: Prompts the user (e.g., src/<-ask->/index.js).
    • <-ask|defaultName->: Prompts with a default value.
  • Directory Shortcuts: Use special keywords that resolve to common paths.
    • %SRC%, %COMPONENTS% (e.g., src, src/components).

💡 Examples

1. Conditional File Creation

Ask if they want TypeScript and only create tsconfig.json if they say yes.

{
  "jobs": [
    {
      "type": "question",
      "questionType": "confirm",
      "id": "@project.useTypescript",
      "question": "Use TypeScript?",
      "defaultValue": true
    },
    {
      "name": "tsconfig.json",
      "content": "{\n  \"compilerOptions\": {}\n}",
      "when": "@project.useTypescript == true"
    }
  ]
}

2. Dynamic Component Scaffolding

Ask for a component name and use it to generate a file with the correct name and content.

{
  "jobs": [
    {
      "type": "question",
      "questionType": "ask",
      "id": "#componentName",
      "question": "What is the name of your component?",
      "defaultValue": "Button"
    },
    {
      "name": "src/components/<#componentName>.tsx",
      "content": "export const %%COMPONENT_NAME%% = () => <></>;"
    },
    {
      "name": "src/components/<#componentName>.tsx",
      "method": "replace",
      "content": {
        "%%COMPONENT_NAME%%": "<#componentName>"
      }
    }
  ]
}

🔌 Plugin Development

The true power of the Evoo CLI lies in its plugin system. If you are interested in creating your own plugins, please refer to the Plugin Development Guide in the @evoo/core package for detailed documentation and best practices.

🔒 Configuration & Authentication

Evoo can store a GitHub personal access token to fetch configurations from private repositories.

Set a Value

# Set your GitHub token
evoo set githubToken ghp_abcdef123456

Get a Value

# View the currently stored token
evoo get githubToken

🤝 Contributing

Contributions are welcome! Please feel free to open an issue or submit a pull request on GitHub.

📄 License

This project is licensed under the MIT License.

FAQs

Package last updated on 30 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts