一键导入
dart-cli-creator
A skill for creating and improving robust, highly maintainable CLI tools using Dart. It covers comprehensive best practices.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
A skill for creating and improving robust, highly maintainable CLI tools using Dart. It covers comprehensive best practices.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
GitHub Actionsから各クラウド(Google Cloud, Firebase, AWS, Azure)へOIDC(OpenID Connect)およびWorkload Identity経由でセキュアにキーレス接続・デプロイするための設定を自動または半自動で完遂します。ユーザーから「GitHub ActionsでOIDCを設定して」「Firebase/GCPのOIDC連携を組んで」などの指示があった場合にこのスキルを使用し、設定コマンドの実行からGitHubワークフローYAMLの作成までを行います。
Dart/Flutterのモノレポ管理ツール「Melos」に関する操作支援(依存解決、スクリプト実行、バージョニング、CI設定)を行います。ユーザーが「Melos」について言及した場合や、複数パッケージの一括操作を求めた場合に有効化されます。
GitのコミットメッセージをConventional Commits仕様に従って日本語でフォーマットします。
Track Bambu Lab filament purchases from Gmail confirmations and payment notifications.
A specialized workflow for releasing Dart and Flutter packages to pub.dev. Use when the user asks to "release", "publish to pub.dev", or "create a release" for a Dart/Flutter project.
| name | dart-cli-creator |
| description | A skill for creating and improving robust, highly maintainable CLI tools using Dart. It covers comprehensive best practices. |
This skill provides guidelines and procedures for creating and improving top-quality Command-Line Interface (CLI) tools using Dart. As an agent, you must consistently follow these best practices when requested by the user to create or modify a Dart CLI.
bin/ directory: Place the entry point executable files for the CLI (e.g., bin/my_cli.dart). Keep this as a thin wrapper that only calls top-level functions or classes from lib/ or src/, avoiding complex logic here.lib/ directory: Place business logic, command implementations, and reusable utilities here (e.g., lib/src/commands/, lib/src/utils/).args package: Use CommandRunner and Command classes from the standard args package to build a Git-like CLI with subcommands.description and help for each command, flag, and option, ensuring that --help provides sufficient usage information.mason_logger: Avoid standard print statements; use the mason_logger package instead.
logger.info(), logger.success(), logger.err(), and logger.warn().logger.progress('Doing something...').logger.confirm() or logger.prompt() for user confirmations (y/n) or text input. If more advanced menu selections or spinners are needed, combine it with the interact package.final logger = Logger(); at the top level in lib/logger.dart and import it across the project. This reduces boilerplate and is highly convenient (ideal for small to medium-sized CLI tools where DI is not mandatory).cli_completion: Consider using the cli_completion package to provide shell completion features by extending CompletionCommandRunner.0 for success, 1 or sysexits-compliant error codes for errors).exit() calls: Calling exit() directly causes the Dart VM to terminate immediately, potentially bypassing resource cleanup (like finally blocks). Instead, return an int from CommandRunner.run(), propagate it to the main function, set it to the exitCode property, and allow the process to exit naturally (e.g., after waiting for Process.stdout.close()).AppException) and throw them from deep within the call stack.CommandRunner in a try-catch block to handle AppException, UsageException, and any uncaught exceptions. Rather than showing stack traces directly to the user, output errors gracefully using logger.err(e.message) and return an appropriate exit code.pedantic_mono: Configure pedantic_mono in analysis_options.yaml and adhere to strict static analysis rules.#!/usr/bin/env dart as the very first line of executable files directly under bin/.executables: section of pubspec.yaml to enable easy installation via dart pub global activate.pub_updater: Use pub_updater to check pub.dev or other registries for new version releases, either on every command execution or periodically.logger.warn('Update available!') or an interact-based prompt.pub_semver package (e.g., Version.parse, nextMajor, nextMinor) to prevent parsing failures related to edge cases like pre-release tags or build metadata.release-pub skill. If creating an advanced Dart CLI, recommend using this agentic skill to coordinate complex CI/CD and release pipelines safely rather than instructing users to perform these steps manually.When creating a CLI, use a structure and implementation similar to the following as a foundation.
pubspec.yamlenvironment:
sdk: ^3.11.0 # Always specify the latest stable version
dependencies:
args: ^2.5.0
cli_completion: ^0.4.0
mason_logger: ^0.2.16
pub_updater: ^0.4.0
dev_dependencies:
pedantic_mono: any
test: ^1.24.0
executables:
my_cli:
bin/my_cli.dart#!/usr/bin/env dart
import 'dart:io';
import 'package:my_cli/command_runner.dart';
Future<void> main(List<String> arguments) async {
final exitCode = await MyCliCommandRunner().run(arguments);
await flushThenExit(exitCode ?? 0);
}
/// Helper method to set the [status] to exitCode, and wait for the standard output/error to flush before exiting
Future<void> flushThenExit(int status) async {
exitCode = status;
await Future.wait<void>([
stdout.close(),
stderr.close(),
]);
}
lib/logger.dartimport 'package:mason_logger/mason_logger.dart';
/// The [Logger] shared across the application.
final logger = Logger();
lib/command_runner.dartimport 'package:args/args.dart';
import 'package:cli_completion/cli_completion.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:my_cli/logger.dart';
import 'package:pub_updater/pub_updater.dart';
class MyCliCommandRunner extends CompletionCommandRunner<int> {
MyCliCommandRunner({PubUpdater? pubUpdater})
: _pubUpdater = pubUpdater ?? PubUpdater(),
super('my_cli', 'A highly robust Dart CLI tool.') {
argParser
..addFlag(
'version',
abbr: 'v',
negatable: false,
help: 'Print the current version.',
)
..addFlag(
'verbose',
help: 'Enable verbose logging.',
);
// TODO: addCommand(MyCustomCommand());
}
final PubUpdater _pubUpdater;
Future<void> _checkForUpdates() async {
try {
final isUpToDate = await _pubUpdater.isUpToDate(
packageName: 'my_cli',
currentVersion: '1.0.0', // Optionally link to a packageVersion constant
);
if (!isUpToDate) {
final latestVersion = await _pubUpdater.getLatestVersion('my_cli');
logger.info('\nUpdate available: $latestVersion');
}
} catch (_) {}
}
@override
Future<int> run(Iterable<String> args) async {
try {
final argResults = parse(args);
if (argResults['verbose'] == true) {
logger.level = Level.verbose;
}
// Check for version updates (consider asynchronous background execution)
await _checkForUpdates();
return await runCommand(argResults) ?? 0;
} on FormatException catch (e) {
logger
..err(e.message)
..info('')
..info(usage);
return 64; // usage error
} on UsageException catch (e) {
logger
..err(e.message)
..info('')
..info(usage);
return 64;
} on AppException catch (e) {
// Gracefully output custom domain exceptions
logger.err(e.message);
return 1;
} catch (e, stackTrace) {
logger
..err('An unexpected error occurred: $e')
..err('$stackTrace');
return 1;
}
}
@override
Future<int?> runCommand(ArgResults topLevelResults) async {
if (topLevelResults['version'] == true) {
logger.info('my_cli version: 1.0.0');
return 0;
}
return super.runCommand(topLevelResults);
}
}
/// A custom exception specific to the domain.
class AppException implements Exception {
const AppException(this.message);
final String message;
@override
String toString() => message;
}
lib/src/commands/my_custom_command.dartimport 'package:args/command_runner.dart';
import 'package:my_cli/logger.dart';
class MyCustomCommand extends Command<int> {
MyCustomCommand() {
argParser.addOption(
'name',
abbr: 'n',
help: 'Your name.',
mandatory: true,
);
}
@override
String get description => 'A custom command example.';
@override
String get name => 'hello';
@override
Future<int> run() async {
final name = argResults?['name'] as String?;
final progress = logger.progress('Saying hello to $name...');
// Simulate a time-consuming task
await Future<void>.delayed(const Duration(seconds: 1));
progress.complete('Hello, $name!');
return 0; // Success
}
}
When requested by the user to "create a CLI tool for doing X", etc.:
args and mason_logger. Always specify the latest stable Dart SDK version (where the patch version is 0, e.g., ^3.11.0) in pubspec.yaml.pedantic_mono and generate high-quality code that adheres to strict static analysis.README.md and present the user with installation steps, such as using dart pub global activate --source path ..