Skip to Content
ScriptingScript Resolution

Script Resolution

Understanding how Miso resolves commands is important for organizing your scripts and avoiding conflicts. This page explains the resolution order and priority.

Core Built-In Commands

Before anything else, Miso checks its own built-in commands. These always win over a same-named script:

  • init — initialize a new project
  • version — display the Miso version
  • env — validate environment variables from .env files
  • scripts — list available scripts and actions
  • skills — add miso skills

The package-management verbs (install, add, remove, run, dev) and upgrade work the other way around: a folder script sharing one of those names runs instead of the built-in, so you can shadow them when you need to.

The Resolution Ladder

After built-in commands, miso <name> resolves in this order — identical in every repo mode:

  1. Task entryrepo.tasks.<name> in miso.json. Miso orchestrates: the task contributes concurrent and dependsOn, and the command body itself still resolves through the steps below. In turbo/nx repos this is the opt-out — declare a task and miso owns that name instead of the delegated runner.
  2. Delegated pipeline task — turbo/nx mode only. If the name appears in turbo.json, turbo runs it (graph, cache, and all) inside Miso’s wrapper.
  3. Workspace member fan-out — every member defining the name runs in the shared TUI. The root is the orchestrator, not a fan-out member: root scripts never join fan-out and never preempt it, so a root "dev": "miso dev" entry point is safe.
  4. Root script — root package.json script or scripts-folder file, run in a single Miso pane.
  5. Passthrough — forwarded to the package manager.

In simple mode ("packageManager": false), the ladder doesn’t apply — there’s no package manager to delegate to or fan out through. Miso resolves core commands and scripts-folder files only, and ignores tasks, turbo/nx, and package.json entirely.

Scripts Folder

Miso searches your configured scripts folder recursively and runs the match:

scripts/ build.sh → miso build test.py → miso test deploy/ staging.sh → miso deploy/staging

A file is discovered if it has executable permissions or a recognized extension (.sh, .ts, .py, and the rest — see Script Execution); files starting with . or _ are skipped. The extension is optional when you invoke it, and an index file is a directory’s default — scripts/publish/index.sh runs as miso publish.

package.json Scripts

Miso also checks for an entry in package.json:

{ "scripts": { "dev": "vite start", "build": "tsc && vite build", "lint": "eslint ." } }

If a match is found, it runs via your configured package manager:

miso dev # Executes: npm run dev (or bun dev, pnpm dev, etc)

Package-Management Commands

Alongside the ladder above, Miso checks its package-management commands:

  • install or i — install dependencies
  • add — add new dependencies
  • remove — remove dependencies

Passthrough

If the command isn’t found anywhere in the ladder, Miso forwards it to your package manager:

miso outdated # → forwarding "outdated" to pnpm # Executes: pnpm outdated

This lets you use Miso as a unified interface for all package-manager commands without needing to remember which package manager you’re using.

Collisions Are Errors

Miso never silently picks a winner:

  • Two scripts-folder files resolving to the same command name (e.g. build.sh and build.ts) — error, rename one.

  • A name in both root package.json and the scripts folder — error, rename one.

  • A name in both turbo.json and a scripts-folder file, with no task entry to break the tie — error:

    "<name>" is both a turbo task and a folder script — declare repo.tasks.<name> to have miso own it, or rename the script so turbo owns it

    A root package.json script sharing a turbo task’s name is not a conflict — "build": "turbo run build" is the standard entry point, so turbo keeps the name.

  • A concurrent entry that resolves nowhere — the launch fails, naming the entry and where Miso looked:

    concurrent "<entry>": no script found at <scope>
  • A task entry with no body and no concurrent/dependsOn — config error:

    repo.tasks.<name> declares nothing: no script named "<name>" found and no concurrent entries

Targeting specific workspaces with an @scope (e.g. miso build @api) is covered in Monorepos.

Last updated on