← Back to list

cli-tool-development
by autohandai
A collection of curated useful skills for autohand cli agent
⭐ 0🍴 0📅 Jan 23, 2026
SKILL.md
name: cli-tool-development description: Build professional CLI tools with Node.js, commander, and Ink license: MIT compatibility: nodejs 18+, typescript 5+ allowed-tools: read_file write_file apply_patch run_command search_with_context
CLI Tool Development
Project Structure
src/
index.ts # Entry point with shebang
cli.ts # Commander setup
commands/ # Command handlers
ui/ # Ink components (if interactive)
utils/ # Helpers
types.ts # Type definitions
Commander.js Setup
#!/usr/bin/env node
import { Command } from 'commander';
import packageJson from '../package.json' with { type: 'json' };
const program = new Command();
program
.name('mytool')
.description('My awesome CLI tool')
.version(packageJson.version);
program
.command('init')
.description('Initialize a new project')
.option('-t, --template <name>', 'Template to use', 'default')
.option('-f, --force', 'Overwrite existing files', false)
.action(async (options) => {
await initCommand(options);
});
program.parseAsync();
User Feedback with Chalk & Ora
import chalk from 'chalk';
import ora from 'ora';
// Status messages
console.log(chalk.green('✓') + ' Operation complete');
console.log(chalk.red('✗') + ' Operation failed');
console.log(chalk.yellow('⚠') + ' Warning message');
// Progress spinner
const spinner = ora('Loading...').start();
try {
await longOperation();
spinner.succeed('Done!');
} catch (error) {
spinner.fail('Failed');
}
Interactive Prompts with Enquirer
import enquirer from 'enquirer';
const { name } = await enquirer.prompt<{ name: string }>({
type: 'input',
name: 'name',
message: 'Project name:',
validate: (v) => v.length > 0 || 'Name required',
});
const { confirm } = await enquirer.prompt<{ confirm: boolean }>({
type: 'confirm',
name: 'confirm',
message: 'Continue?',
initial: true,
});
Ink for Rich TUI
import React, { useState } from 'react';
import { render, Box, Text, useInput } from 'ink';
function App() {
const [selected, setSelected] = useState(0);
const items = ['Option 1', 'Option 2', 'Option 3'];
useInput((input, key) => {
if (key.downArrow) setSelected(s => Math.min(s + 1, items.length - 1));
if (key.upArrow) setSelected(s => Math.max(s - 1, 0));
if (key.return) process.exit(0);
});
return (
<Box flexDirection="column">
{items.map((item, i) => (
<Text key={i} color={i === selected ? 'cyan' : undefined}>
{i === selected ? '>' : ' '} {item}
</Text>
))}
</Box>
);
}
render(<App />);
Configuration Management
import fs from 'fs-extra';
import path from 'node:path';
import os from 'node:os';
const CONFIG_DIR = path.join(os.homedir(), '.mytool');
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
async function loadConfig(): Promise<Config> {
await fs.ensureDir(CONFIG_DIR);
if (await fs.pathExists(CONFIG_FILE)) {
return fs.readJson(CONFIG_FILE);
}
return getDefaultConfig();
}
async function saveConfig(config: Config): Promise<void> {
await fs.writeJson(CONFIG_FILE, config, { spaces: 2 });
}
Error Handling
// Graceful exit handling
process.on('SIGINT', () => {
console.log('\nCancelled');
process.exit(0);
});
// Top-level error handler
try {
await program.parseAsync();
} catch (error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
Package.json Setup
{
"bin": {
"mytool": "./dist/index.js"
},
"files": ["dist"],
"type": "module",
"scripts": {
"build": "tsup src/index.ts --format esm --dts",
"dev": "tsx src/index.ts"
}
}
Best Practices
- Add
#!/usr/bin/env nodeshebang to entry file - Support both flags (
-f) and options (--force) - Provide helpful error messages with suggestions
- Support
--helpand--versionflags - Use exit codes: 0 for success, 1 for error
- Support piping and stdin when appropriate
- Respect
NO_COLORenvironment variable
Score
Total Score
60/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
○言語
プログラミング言語が設定されている
0/5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon
