dart-build-cli-app
Skill4 starsChanged 4 months agoMITView on GitHub
Entrypoint structure, exit codes, cross-platform scripts. Use when building command line utilities, scripts, or applications.
4 other projects use a version of this.
Adopted by
Most recently taken up by
- dart-lang/skillstheir own version, first seen Oct 16, 2026
- zhouycheng/skillsword for word, first seen Oct 13, 2026
- flutter/skillstheir own version, first seen Oct 8, 2026
- RodotDev/arb_aiword for word, first seen May 30, 2026
Other versions4 projects use a version of this.
Word for word · 2
- RodotDev/arb_ai★ 1100% same
- zhouycheng/skills★ 1100% same
Edited · 0
None found.
Wrote their own version · 2
- flutter/skills★ 3.2ksame name
- dart-lang/skills★ 548same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository70 other files it gives its agents.
- AGENTS.mdAGENTS.md
- engine/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- engine/CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- brandkitSkill
- code-reviewSkill
- dart-add-unit-testSkill
- dart-collect-coverageSkill
- dart-fix-runtime-errorsSkill
- dart-generate-test-mocksSkill
- dart-migrate-to-checks-packageSkill
- dart-resolve-package-conflictsSkill
- dart-run-static-analysisSkill
- dart-setup-ffi-assetsSkill
- dart-use-ffigenSkill
- dart-use-pattern-matchingSkill
- dart-use-primary-constructorsSkill
- design-taste-frontendSkill
- flutter-add-integration-testSkill
- flutter-add-widget-previewSkill
- flutter-add-widget-testSkill
- flutter-apply-architecture-best-practicesSkill
- flutter-build-responsive-layoutSkill
- flutter-fix-layout-issuesSkill
- flutter-implement-json-serializationSkill
- flutter-setup-declarative-routingSkill
- flutter-setup-localizationSkill
- flutter-use-http-packageSkill
- frontend-code-reviewSkill
- full-output-enforcementSkill
- github-releaseSkill
- grill-with-docsSkill
- high-end-visual-designSkill
- imagegen-frontend-webSkill
- image-to-codeSkill
- improve-codebase-architectureSkill
- industrial-brutalist-uiSkill
- minimalist-uiSkill
- redesign-existing-projectsSkill
- source-command-frontend-code-review-skillSkill
- source-command-impeccable-skillSkill
- stitch-design-tasteSkill
- tddSkill
- to-prdSkill
- frontend-code-reviewSkill
- impeccableSkill
- dart-add-unit-testSkill
- dart-build-cli-appSkill
- dart-collect-coverageSkill
- dart-fix-runtime-errorsSkill
- dart-generate-test-mocksSkill
- dart-migrate-to-checks-packageSkill
- dart-resolve-package-conflictsSkill
- dart-run-static-analysisSkill
- dart-setup-ffi-assetsSkill
- dart-use-ffigenSkill
- dart-use-pattern-matchingSkill
- dart-use-primary-constructorsSkill
- flutter-add-integration-testSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. About 0 are common, 0 are distinctive, and 16 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
16
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 23
Run dart create -t cli <project_name> to scaffold a console application with basic argument parsing.
- Very specific: line 24
Place executable entry points (files containing main()) exclusively in the bin/ directory.
- Very specific: line 25
Place internal implementation logic in lib/src/ and expose public APIs via lib/<project_name>.dart.
- Very specific: line 30
Import the args package to manage command-line arguments, flags, and subcommands.
- Very specific: line 32
If building a simple script: Use ArgParser directly to define flags (addFlag) and options (addOption).
- Very specific: line 33
If building a complex, multi-command CLI (like git): Implement CommandRunner and extend Command for each subcommand.
- Very specific: line 42
Use the io package's ExitCode enum to return standard POSIX exit codes (e.g., ExitCode.success.code, ExitCode.usage.code).
- Very specific: line 43
Use sharedStdIn from the io package if multiple asynchronous listeners need sequential access to standard input.
- Very specific: line 47
Fail fast and with non-zero exit codes: Ensure operation failures result in descriptive error messages to stderr and appropriate non-zero …
- Very specific: line 54
Use test_process and test_descriptor to write high-fidelity integration tests for your CLI.
- Very specific: line 57
Create the mock filesystem before execution using await d.Descriptor.create().
- Very specific: line 67
If testing locally during development: Use dart run bin/cli.dart.
- Very specific: line 68
If bundling code assets and dynamic libraries: Use dart build cli. This runs build hooks and outputs to build/cli/_/bundle/.
- Very specific: line 69
If distributing a standalone native executable: Use dart compile exe bin/cli.dart -o <output_path>.
- Very specific: line 70
If distributing multiple apps with strict disk space limits: Use dart compile aot-snapshot bin/cli.dart.
- Very specific: line 76
Use the --target-os and --target-arch flags with dart compile exe or dart compile aot-snapshot.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Building Dart CLI Applications
Contents
- Project Setup & Architecture
- Argument Parsing & Command Routing
- Execution & Error Handling
- Testing CLI Applications
- Compilation & Distribution
- Workflows
- Examples
Project Setup & Architecture
Initialize new CLI projects using the official Dart template to ensure standard directory structures.
- Run
dart create -t cli <project_name>to scaffold a console application with basic argument parsing. - Place executable entry points (files containing
main()) exclusively in thebin/directory. - Place internal implementation logic in
lib/src/and expose public APIs vialib/<project_name>.dart. - Enforce formatting in CI environments by running
dart format . --set-exit-if-changed. This returns exit code 1 if formatting violations exist.
Argument Parsing & Command Routing
Import the args package to manage command-line arguments, flags, and subcommands.
- If building a simple script: Use
ArgParserdirectly to define flags (addFlag) and options (addOption). - If building a complex, multi-command CLI (like
git): ImplementCommandRunnerand extendCommandfor each subcommand. - Define global arguments on the
CommandRunner.argParserand command-specific arguments on the individualCommand.argParser. - Catch
UsageExceptionto gracefully handle invalid arguments and display the automatically generated help text. - Validate Help Text Accuracy: Ensure the help text provides all necessary information to run the tool. If the help text references a compiled executable name, and the user needs to add it to their PATH to run it that way, provide clear instructions on how to do so in the help text or description.
Execution & Error Handling
Leverage the io and stack_trace packages to build robust, production-ready CLI tools.
- Use the
iopackage'sExitCodeenum to return standard POSIX exit codes (e.g.,ExitCode.success.code,ExitCode.usage.code). - Use
sharedStdInfrom theiopackage if multiple asynchronous listeners need sequential access to standard input. - Wrap the application execution in
Chain.capture()from thestack_tracepackage to track asynchronous stack chains. - Format output stack traces using
Trace.terseorChain.terseto strip noisy core library frames and present readable errors to the user. - Do not swallow exceptions in lower-level logic or storage classes unless recovery is possible. Let them bubble up or rethrow them so higher-level commands know operations failed.
- Fail fast and with non-zero exit codes: Ensure operation failures result in descriptive error messages to
stderrand appropriate non-zero exit codes (e.g., usingexit(1)or triggering a 64 exit code after a caughtUsageException).
Testing CLI Applications
[!IMPORTANT] All new commands and significant features must be covered by automated tests. Manual verification is not sufficient for testing logic. However, manual verification of help text and user experience (UX) is still required to ensure the interface is intuitive and correct.
Use test_process and test_descriptor to write high-fidelity integration tests for your CLI.
- Define expected filesystem states using
test_descriptor(d.dir,d.file). - Create the mock filesystem before execution using
await d.Descriptor.create(). - Spawn the CLI process using
TestProcess.start('dart', ['run', 'bin/cli.dart', ...args]). - Validate standard output and error streams using
StreamQueuematchers (e.g.,emitsThrough,emits). - Assert the final exit code using
await process.shouldExit(0). - Validate resulting filesystem mutations using
await d.Descriptor.validate().
Compilation & Distribution
Select the appropriate compilation target based on your distribution requirements.
- If testing locally during development: Use
dart run bin/cli.dart. This uses the JIT compiler for rapid iteration. - If bundling code assets and dynamic libraries: Use
dart build cli. This runs build hooks and outputs tobuild/cli/_/bundle/. - If distributing a standalone native executable: Use
dart compile exe bin/cli.dart -o <output_path>. This bundles the Dart runtime and machine code into a single file. - If distributing multiple apps with strict disk space limits: Use
dart compile aot-snapshot bin/cli.dart. Run the resulting.aotfile usingdartaotruntime.
<details>
<summary>Cross-Compilation Targets (Linux Only)</summary>Dart supports cross-compiling to Linux from macOS, Windows, or Linux hosts.
Use the --target-os and --target-arch flags with dart compile exe or dart compile aot-snapshot.
--target-os=linux(Only Linux is currently supported as a cross-compilation target)--target-arch=arm64(64-bit ARM)--target-arch=x64(x86-64)--target-arch=arm(32-bit ARM)--target-arch=riscv64(64-bit RISC-V)
Example: dart compile exe --target-os=linux --target-arch=arm64 bin/cli.dart
</details>Workflows
Task Progress: Implement a New CLI Command
- Create a new class extending
Commandinlib/src/commands/. - Define the
nameanddescriptionproperties. - Register command-specific flags in the constructor using
argParser.addFlag()orargParser.addOption(). - Implement the
run()method with the core logic. - Register the new command in the
CommandRunnerinstance inbin/cli.dartusingaddCommand(). - Create tests for the new command in the
test/directory usingtest_processor standard tests. - Run validator -> Execute
dart run bin/cli.dart help <command_name>to verify help text generation. - Verify final UX: Compile the application using
dart compile exeand run the resulting executable to verify the target user experience (e.g.,./bin/cli <command>).
Task Progress: Compile and Release Native Executable
- Run validator -> Execute
dart format . --set-exit-if-changedto ensure code formatting. - Run validator -> Execute
dart analyzeto ensure no static analysis errors. - Run validator -> Execute
dart testto pass all integration tests. - Compile for host OS:
dart compile exe bin/cli.dart -o build/cli-host - Compile for Linux (if host is macOS/Windows):
dart compile exe --target-os=linux --target-arch=x64 bin/cli.dart -o build/cli-linux-x64
Examples
Example: CommandRunner Implementation
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:stack_trace/stack_trace.dart';
class CommitCommand extends Command {
@override
final String name = 'commit';
@override
final String description = 'Record changes to the repository.';
CommitCommand() {
argParser.addFlag('all', abbr: 'a', help: 'Commit all changed files.');
}
@override
Future<void> run() async {
final commitAll = argResults?['all'] as bool? ?? false;
print('Committing... (All: $commitAll)');
}
}
void main(List<String> args) {
Chain.capture(() async {
final runner = CommandRunner('dgit', 'Distributed version control.')
..addCommand(CommitCommand());
await runner.run(args);
}, onError: (error, chain) {
if (error is UsageException) {
stderr.writeln(error.message);
stderr.writeln(error.usage);
exit(64); // ExitCode.usage.code
} else {
stderr.writeln('Fatal error: $error');
stderr.writeln(chain.terse);
exit(1);
}
});
}Example: Integration Testing with Subprocesses
import 'package:test/test.dart';
import 'package:test_process/test_process.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
void main() {
test('CLI formats output correctly and modifies filesystem', () async {
// 1. Setup mock filesystem
await d.dir('project', [
d.file('config.json', '{"key": "value"}')
]).create();
// 2. Spawn the CLI process
final process = await TestProcess.start(
'dart',
['run', 'bin/cli.dart', 'process', '--path', '${d.sandbox}/project']
);
// 3. Validate stdout stream
await expectLater(process.stdout, emitsThrough('Processing complete.'));
// 4. Validate exit code
await process.shouldExit(0);
// 5. Validate filesystem mutations
await d.dir('project', [
d.file('config.json', '{"key": "value"}'),
d.file('output.log', 'Success')
]).validate();
});
}Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

