jido
Version:
A CLI tool to automate your development workflows using named flows. Simplifies task automation with readable config and plugin support.
280 lines (234 loc) ⢠6.8 kB
Markdown
# Jido
<img src="https://github.com/user-attachments/assets/038ca10c-9524-42de-b980-203ee0dc27b6" alt="jido-logo" height="80" />
**Automate your workflows in a flash**
---
## What is Jido?
[**Jido**](https://npmjs.com/package/jido) is a CLI tool for running named workflows, called *flows*, automating sequences of tasks and improving the developer experience without needing to memorize a bunch of commands or wiring up Makefiles.
Define your flows in a config file `jido.config.js` in the root directory of your project, and run a specific flow with:
```bash
jido flow <flowname>
```
**It's like `npm run` but cooler.**
## Installation
You can install `jido` globally or locally.
#### Global (Recommended)
```bash
npm install -g jido
```
#### (OR) Local (Per Project)
```bash
npm install --save-dev jido
```
Then, you're good to go!
## Getting Started
Run this to initialize a config:
```bash
npx jido init
```
It creates a basic `jido.config.js` in your project root.
<details>
<summary>Content of generated `jido.config.js`:</summary>
```js
import { jido } from "jido";
/*
* Define your workflows here.
* Each flow is a series of steps with commands to run and optional hooks (onStart, onSuccess, etc) to execute.
*/
const config = {
flows: [
{
name: "run",
description: "Run the project",
steps: [
{
run: "npm install",
onStart: () => console.log("Installing dependencies..."),
onSuccess: () => console.log("Dependencies installed!")
},
{
run: "npm run dev",
onStart: () => console.log("Starting dev server...")
}
]
}
]
}
export default jido(config);
```
</details>
## Commands
### `jido flow [flowname]`
Runs the named flow as defined in your config:
```bash
npx jido flow build
```
#### Options:
- `-d`, `--dry-run`: Preview what the flow would do without actually executing it.
```bash
npx jido flow build --dry-run
```
### `jido list`
Lists all available flows defined in `jido.config.js`:
```bash
npx jido list
```
### `jido init`
Scaffolds a basic `jido.config.js` in your project root:
```bash
npx jido init
```
#### Options:
- `-f`, `--force`: Overwrite existing `jido.config.js` files, if any.
```bash
npx jido init --force
```
## Config Format
The `jido()` function takes an object (the config) as argument, which should be defined as follows:
```js
export default jido({
flows: [
{
name: string, // Name of the flow
description?: string, // Description, what the flow does
steps: [
{
run: string, // Command to be run, eg. 'npm run dev'
// Optional hooks
onStart?: Hook,
onSuccess?: Hook,
onFailure?: Hook,
// Plugins
plugins: [
{
// Optional hooks received through plugins
onStart?: Hook,
onSuccess?: Hook,
onFailure?: Hook,
}
],
}
]
}
]
});
```
Commands are run **sequentially**. If any command fails, the flow stops immediately.
## Writing a Plugin
Jido supports lightweight plugins at the step level, allowing you to inject custom behavior during `onStart`, `onSuccess`, and/or `onFailure`.
A plugin should be a function that returns an object of the type Plugin:
```ts
type Plugin = {
onStart?: Hook;
onSuccess?: Hook;
onFailure?: Hook;
};
```
### Basic Plugin Example
Create a file (eg. `myPlugin.js`):
```js
export const myPlugin = () => ({
onStart: () => {
console.log("Plugin: Flow step is starting...");
},
onSuccess: () => {
console.log("Plugin: Step completed successfully!");
}
});
```
This plugin exports a function that returns an object containing hooks.
Use it in your `jido.config.js` as follows:
```js
import { myPlugin } from "./myPlugin.js";
export default jido({
flows: [
{
name: "example",
steps: [
{
run: "echo hello",
onStart: () => console.log("Echo step started..."),
plugins: [myPlugin()]
}
]
}
]
});
```
### Plugin as an Object (Not Recommended)
You can also pass a plugin directly as an object:
```js
// Plugin
const myPlugin = {
onStart: () => {
console.log("Plugin: Flow step started...");
},
onSuccess: () => {
console.log("Plugin: Step completed successfully!");
}
};
// jido.config.js
plugins: [myPlugin] // Directly passes the object, unlike previous example where a function was called to return the object
```
This works fine, but using **functions that return plugin objects** is recommended ā especially when your plugin logic needs configuration or arguments.
### Plugins with arguments
Plugins can be dynamic:
```js
// Plugin
const myPlugin = (name) => ({
onStart: () => {
console.log(`Hello, ${name}! Starting the flow step...`);
}
});
// jido.config.js
plugins: [myPlugin("Bob")] // Dynamic plugins, hooks dependent on arguments
```
This pattern keeps your plugins composable, configurable, and scalable.
### š§ Tip
You can enable better IntelliSense by adding this at the top of your plugin file:
```js
/** @type {import("jido-kit/types").Plugin} */
```
## Dry Run Mode
You can simulate a flow with:
```bash
npx jido flow build --dry-run
```
This prints the commands without executing them. Helpful for debugging.
## Example Use Cases
- `deploy`: Run build scripts and deploy using CLI tools.
- `validate`: Combine linting, testing, type checking tools into one command.
- `reset`: Clear caches, reinstall steps, reset DB, etc.
You are free to define **any set of shell commands** that makes sense for your workflow.
## FAQ
<details>
<summary>
- Can I use JS logic inside `jido.config.js`?
</summary>
Yes! It's a JS file, not JSON, so you can use variables, imports, etc.
</details>
<details>
<summary>
- Does it support `.ts` config?
</summary>
Not currently. However, you can use types from `jido-kit` to make custom plugins and build them into JS functions to be used as plugins in your jido config.
</details>
## Bonus: Type Support (`jido-kit`)
Install `jido-kit` for full IntelliSense in VS Code:
```bash
npm install --save-dev jido-kit
```
Then, in your config:
```js
/** @type {import("jido-kit/types").Config} */
export default jido({
...
});
```
## Why use Jido?
ā
Clean alternative to npm run clutter
ā
Centralizes all your workflows
ā
Dry-run support for safety
ā
Lightweight and dependency-free core
ā
Config in JS ā not YAML or JSON
## License
MIT