home / skills / zenobi-us / dotfiles / mise

This skill helps you author robust mise file tasks with metadata, usage specs, and argument parsing for complex, monorepo workflows.

npx playbooks add skill zenobi-us/dotfiles --skill mise

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
8.9 KB
---
name: writing-mise-file-tasks
description: Use when creating complex mise tasks that require arguments, dependencies, or monorepo support. specialized guide for writing standalone task scripts (file tasks) with metadata and usage specs.
---

# Mise File Tasks

## Overview
Mise file tasks are standalone scripts (bash, node, python, etc.) located in `mise-tasks/` or `.mise/tasks/` that behave like full CLI commands. They support argument parsing, help generation, and dependency management via special comment directives.

## When to Use
- **Complex Logic**: When a task is too long for a single line in `mise.toml`.
- **Arguments**: When you need flags (`--force`), options (`--env prod`), or positional arguments.
- **Monorepo**: When organizing tasks across multiple projects (`//frontend:build`).
- **Polyglot**: When you want to write tasks in Node, Python, or Ruby instead of Bash.

## Core Pattern

### 1. File Location
Place scripts in:
- `./mise-tasks/` (Recommended)
- `./.mise/tasks/`
- Any directory configured in `mise.toml` under `[tasks]`

### 2. File Header (Directives)
Use comments to define metadata. The syntax adapts to the language (e.g., `#` for Bash/Python, `//` for JS).

```bash
#!/usr/bin/env bash
#MISE description="Deploy application to environment"
#MISE depends=["build", "lint"]
#MISE dir="{{cwd}}" 
#MISE env={NODE_ENV="production"}

#USAGE flag "-f --force" help="Skip safety checks"
#USAGE option "-e --env <env>" help="Target environment" default="dev"
#USAGE arg "<version>" help="Version tag to deploy"
```

## Argument Parsing (Usage Spec)
Mise uses [usage](https://usage.jdx.dev) to parse arguments. Variables are injected into the script environment prefixed with `usage_`.

| Directive | Example | Env Variable |
|-----------|---------|--------------|
| **Flag** | `#USAGE flag "--dry-run"` | `usage_dry_run` ("true"/"false") |
| **Option** | `#USAGE option "--port <port>"` | `usage_port` |
| **Arg** | `#USAGE arg "<target>"` | `usage_target` |

**Bash Example:**
```bash
if [ "${usage_force:-false}" = "true" ]; then ... fi
echo "Deploying to ${usage_env}"
```

**Node.js Example:**
```javascript
const { usage_force, usage_env } = process.env;
```

## Monorepo Tasks (Experimental)
Enable in root `mise.toml`:
```toml
experimental_monorepo_root = true
```

### Addressing Tasks
- **Absolute**: `mise run //packages/frontend:build`
- **Relative**: `mise run :build` (runs build in current config root)
- **Wildcards**: `mise run //packages/*:test` (run test in all packages)

### Inheritance
Sub-projects inherit tools and env vars from parent `mise.toml` files.

## Examples

### Bash Task with Arguments
File: `mise-tasks/deploy`
```bash
#!/usr/bin/env bash
#MISE description="Deploy artifact to S3"
#MISE depends=["build"]

#USAGE flag "-f --force" help="Overwrite existing"
#USAGE option "-r --region <region>" default="us-east-1" help="AWS Region"
#USAGE arg "<bucket>" help="Target S3 bucket"

set -euo pipefail

echo "Deploying to ${usage_bucket} in ${usage_region}..."

if [ "${usage_force:-false}" = "true" ]; then
  ARGS="--force"
else
  ARGS=""
fi

# aws s3 cp ... $ARGS
```

### Node.js Task
File: `mise-tasks/generate-report`
```javascript
#!/usr/bin/env node
//MISE description="Generate JSON report"

//USAGE option "-o --output <file>" default="report.json"
//USAGE arg "<input>"

const fs = require('fs');
const { usage_output, usage_input } = process.env;

console.log(`Reading ${usage_input}, writing to ${usage_output}`);
```

## Common Mistakes
- **Missing `usage`**: The `usage` CLI tool must be installed for autocompletion (`mise use -g usage`).
- **Variable Names**: `usage_` prefix is mandatory. Dashes in flags (`--dry-run`) become underscores (`usage_dry_run`).
- **Shebangs**: Always include `#!/usr/bin/env <shell>`.
- **Permissions**: Files don't strictly need `chmod +x` if run via `mise run`, but it's good practice.
- **Dependency Loops**: Watch out for circular dependencies in `#MISE depends`.

## Debugging
Use `mise tasks ls` to verify task discovery and parsing.
Run with `mise run taskname --help` to see the generated help message.

Overview

This skill provides a focused guide for writing standalone mise file tasks that support arguments, dependencies, and monorepo addressing. It explains where to place task scripts, how to declare metadata with comment directives, and how to expose parsed arguments into the script environment. The guidance is language-agnostic and includes common patterns for Bash and Node.js tasks.

How this skill works

The skill inspects task scripts placed in mise-tasks/ or .mise/tasks/ and parses special comment directives prefixed with MISE and USAGE to extract metadata, dependencies, and argument specifications. It maps usage directives into environment variables prefixed with usage_ and shows how to reference them in different runtimes. It also explains monorepo addressing, inheritance, and discovery rules from mise.toml.

When to use it

  • Task logic is too complex for a single line in mise.toml
  • You need flags, options, or positional arguments in a task
  • You want to author tasks in Node, Python, or other languages instead of plain shell
  • You need tasks organized across a monorepo with package-scoped addressing
  • You require declarative dependencies or environment injections for tasks

Best practices

  • Place tasks under ./mise-tasks/ (recommended) or ./ .mise/tasks/ and register additional paths in mise.toml
  • Include a proper shebang (#!/usr/bin/env ...) and set executable permissions when appropriate
  • Declare metadata with #MISE directives and usage with #USAGE so mise can generate help and inject variables
  • Use usage_ prefixed env vars inside scripts; convert dashes to underscores for flags (e.g., --dry-run -> usage_dry_run)
  • Avoid circular dependencies in #MISE depends and verify task ordering with mise tasks ls

Example use cases

  • Bash deploy script that accepts --force, --region, and a target bucket and depends on build
  • Node.js report generator that reads input and writes to an output file via usage_output and usage_input
  • Monorepo command addressed as //packages/frontend:build to run package-specific builds from the root
  • Polyglot tasks where some tasks are written in Python for complex logic and others in Node for tooling integration
  • A lint-and-fix workflow where tasks declare dependencies and expose flags for dry-run vs apply

FAQ

How are flags and options exposed inside my script?

Usage directives become environment variables with a usage_ prefix; flags are "true"/"false" and options/args map to their values (dashes become underscores).

What if my tasks live outside the recommended directories?

Add their paths under [tasks] in mise.toml so the discovery mechanism includes them.