Usage
ACTIVEInstall
mkcmd-agent is not on npm yet. Clone it and run it from source with Bun 1.2 or later:
Any directory works; these docs use ~/mkcmd-agent, and the examples below call it as mkcmd-agent, which from source means bun ~/mkcmd-agent/src/index.ts.
Agents: run the full bun ~/mkcmd-agent/src/index.ts ... command each time. Most agent tools start a fresh shell per command, so an alias set in one call is gone in the next. People: add alias mkcmd-agent="bun ~/mkcmd-agent/src/index.ts" to your shell profile.
Quick start
Every command takes --json. Start an agent session with bun run src/index.ts describe: it prints every command, flag and example as JSON.
init
Create a new project. Writes into ./<name> unless you pass --dir, and refuses a non-empty directory unless you pass --force.
| Flag | Type | Description |
|---|---|---|
--name | string, required | Package name: lowercase letters, digits, - . _ and an optional @scope/ prefix. The command name is the part after the scope. |
--description | string | One line on what the CLI does. Default: "A command-line tool." |
--dir | string | Where to create it, relative or absolute. Default: ./<name without scope> |
--force | boolean | Write into a non-empty directory, overwriting files with the same names. |
--dry-run | boolean | List the files that would be written. Writes nothing. |
--install | boolean | Run bun install in the new project. |
Errors you can get: usage (exit 2) for a missing or invalid flag, and target_not_empty (exit 1) when the directory already has files.
add
Add a command to a project made by init: it writes src/commands/<name>.ts from a template and adds it to the list in src/commands/index.ts. The new command throws not_implemented until you write its run.
| Flag | Type | Description |
|---|---|---|
--name | string, required | Command name: lowercase letters, digits and dashes, starting with a letter. describe and help are reserved. |
--summary | string | One line shown in help and describe. |
--dir | string | Project root. Default: the current directory. |
--force | boolean | Overwrite the command file if it exists. |
--dry-run | boolean | Show what would change. Writes nothing. |
Dashed names become camelCase identifiers: sync-users is exported as syncUsers. Errors: not_a_project when there is no src/commands/index.ts, command_exists when the file is already there.
The generated project
my-cli/
├── AGENTS.md the contract and how to add commands
├── README.md
├── package.json bin: my-cli -> src/index.ts
├── tsconfig.json
├── src/
│ ├── index.ts entry point: runCLI({ name, about, commands })
│ ├── core/cli.ts the framework, one file, no dependencies
│ └── commands/
│ ├── index.ts export const commands = [hello]
│ └── hello.ts an example command
└── test/cli.test.ts subprocess tests of the contractScripts: bun run start, bun test, bun run typecheck, and bun run build for a single compiled binary in dist/; after bun install the project passes its own tests and tsc --noEmit.
Next: the output contract, then writing commands.