TypeScript functions, ready for the CLI

Point uptask at a glob. Every function exported from a matching file becomes a CLI command.

Everything a task runner needs

Sensible defaults, no setup to start, fully customizable when you need it.

Zero boilerplate

Plain exported functions become commands. JSDoc descriptions surface in --help.

Type-driven CLI

Argument types come straight from TypeScript. Defaults, optionality, and nested objects map themselves.

Runtime validation

Inputs are validated against zod schemas built from your function's signature. Bad input gets a clean one-line error.

Subcommand groups

Opt into nesting via config.groups[]. Carve the top level into named areas without compound function names.

Honors .gitignore

Discovery walks .gitignore up to the repo root, not above. Predictable across machines.

Powered by Commander

Generated commands are real Commander.js commands. Customize with the setupProgram hook when you need to.

Write a function. Get a command.

Your .ts files stay as they are — uptask does the rest.

@build.ts
// @build.ts
/**
 * Build the project.
 *
 * @param target Build target name
 * @param watch Enable watch mode
 */
export function build(
  target: string,
  watch: boolean = false,
) {
  console.log({ target, watch })
}
uptask --help
$ uptask build --help
USAGE uptask build [options] <target>

Build the project.

ARGUMENTS
  target          Build target name

OPTIONS
  --watch         Enable watch mode
  -h, --help      display help for command

Stop writing CLI glue. Just export a function.

Install, write a function, run it. That's the whole setup.