On this page

Commands in doc-kit are defined as modules that export a command object conforming to the Command interface:

interface Command {
  name: string;
  description: string;
  options: { [key: string]: Option };
  action: (options: any) => Promise<void>;
}

Each command consists of:

  • name: The command name used in the CLI (e.g., generate)
  • description: A short description shown in help text
  • options: An object mapping option names to their definitions
  • action: The async function that executes when the command is run

Create a new file in bin/commands/ with your command name:

// bin/commands/my-command.mjs
import logger from '../../src/logger/index.mjs';

/**
 * @type {import('./types').Command}
 */
export default {
  name: 'my-command',
  description: 'Does something useful',

  options: {
    // Define your options here (see next section)
  },

  async action(opts) {
    logger.info('Starting my-command', opts);

    // Your command logic here

    logger.info('Completed my-command');
  },
};

Add your command to the exports in bin/commands/index.mjs:

import generate from './generate.mjs';
import myCommand from './my-command.mjs'; // Add this

export default [
  generate,
  myCommand, // Add this
];

The CLI in bin/cli.mjs automatically loads commands from bin/commands/index.mjs, so no changes are needed there if you followed step 2.

Options define the flags and parameters your command accepts. Each option has:

interface Option {
  flags: string[]; // CLI flags (e.g., ['-i', '--input <value>'])
  desc: string; // Description for help text
}
options: {
  input: {
    flags: ['-i', '--input <patterns...>'],
    desc: 'Input file patterns (glob)',
    prompt: {
      type: 'text',
      message: 'Enter input glob patterns',
      variadic: true,
      required: true,
    },
  },

  force: {
    flags: ['-f', '--force'],
    desc: 'Force overwrite existing files',
    prompt: {
      type: 'confirm',
      message: 'Overwrite existing files?',
      initialValue: false,
    },
  },

  mode: {
    flags: ['-m', '--mode <mode>'],
    desc: 'Operation mode',
    prompt: {
      type: 'select',
      message: 'Choose operation mode',
      options: [
        { label: 'Fast', value: 'fast' },
        { label: 'Thorough', value: 'thorough' },
      ],
    },
  },
}
  • <value> - Required argument
  • [value] - Optional argument
  • <values...> - Variadic (multiple values)
  • [values...] - Optional variadic

Single-line text input.

prompt: {
  type: 'text',
  message: 'Enter a value',
  initialValue: 'default',
  required: true,
}

Yes/no confirmation.

prompt: {
  type: 'confirm',
  message: 'Are you sure?',
  initialValue: false,
}

Single choice from a list.

prompt: {
  type: 'select',
  message: 'Choose one',
  options: [
    { label: 'Option 1', value: 'opt1' },
    { label: 'Option 2', value: 'opt2' },
  ],
}

Multiple choices from a list.

prompt: {
  type: 'multiselect',
  message: 'Choose multiple',
  options: [
    { label: 'Choice A', value: 'a' },
    { label: 'Choice B', value: 'b' },
  ],
}