[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-flutter-dart-build-cli-app":3,"mdc--n4ix0q-key":29,"related-org-flutter-dart-build-cli-app":1765,"related-repo-flutter-dart-build-cli-app":1896},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":19,"repoUrl":20,"updatedAt":21,"license":22,"forks":23,"topics":24,"repo":25,"sourceUrl":27,"mdContent":28},"dart-build-cli-app","build Dart command line applications","Entrypoint structure, exit codes, cross-platform scripts. Use when building command line utilities, scripts, or applications.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"flutter","Flutter (Google)","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fflutter.png",[12,16],{"name":13,"slug":14,"type":15},"CLI","cli","tag",{"name":17,"slug":18,"type":15},"Dart","dart",2664,"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fagent-plugins","2026-07-15T05:22:18.863572",null,155,[],{"repoUrl":20,"stars":19,"forks":23,"topics":26,"description":22},[],"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fagent-plugins\u002Ftree\u002FHEAD\u002Fskills\u002Fdart-build-cli-app","---\nname: dart-build-cli-app\ndescription: Entrypoint structure, exit codes, cross-platform scripts. Use when building command line utilities, scripts, or applications.\nmetadata:\n  model: models\u002Fgemini-3.1-pro-preview\n  last_modified: Fri, 04 May 2026 17:41:00 GMT\n---\n# Building Dart CLI Applications\n\n## Contents\n- [Project Setup & Architecture](#project-setup--architecture)\n- [Argument Parsing & Command Routing](#argument-parsing--command-routing)\n- [Execution & Error Handling](#execution--error-handling)\n- [Testing CLI Applications](#testing-cli-applications)\n- [Compilation & Distribution](#compilation--distribution)\n- [Workflows](#workflows)\n- [Examples](#examples)\n\n## Project Setup & Architecture\n\nInitialize new CLI projects using the official Dart template to ensure standard directory structures.\n\n*   Run `dart create -t cli \u003Cproject_name>` to scaffold a console application with basic argument parsing.\n*   Place executable entry points (files containing `main()`) exclusively in the `bin\u002F` directory.\n*   Place internal implementation logic in `lib\u002Fsrc\u002F` and expose public APIs via `lib\u002F\u003Cproject_name>.dart`.\n*   Enforce formatting in CI environments by running `dart format . --set-exit-if-changed`. This returns exit code 1 if formatting violations exist.\n\n## Argument Parsing & Command Routing\n\nImport the `args` package to manage command-line arguments, flags, and subcommands.\n\n*   If building a simple script: Use `ArgParser` directly to define flags (`addFlag`) and options (`addOption`).\n*   If building a complex, multi-command CLI (like `git`): Implement `CommandRunner` and extend `Command` for each subcommand.\n*   Define global arguments on the `CommandRunner.argParser` and command-specific arguments on the individual `Command.argParser`.\n*   Catch `UsageException` to gracefully handle invalid arguments and display the automatically generated help text.\n*   **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.\n\n## Execution & Error Handling\n\nLeverage the `io` and `stack_trace` packages to build robust, production-ready CLI tools.\n\n*   Use the `io` package's `ExitCode` enum to return standard POSIX exit codes (e.g., `ExitCode.success.code`, `ExitCode.usage.code`).\n*   Use `sharedStdIn` from the `io` package if multiple asynchronous listeners need sequential access to standard input.\n*   Wrap the application execution in `Chain.capture()` from the `stack_trace` package to track asynchronous stack chains.\n*   Format output stack traces using `Trace.terse` or `Chain.terse` to strip noisy core library frames and present readable errors to the user.\n*   **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.\n*   **Fail fast and with non-zero exit codes**: Ensure operation failures result in descriptive error messages to `stderr` and appropriate non-zero exit codes (e.g., using `exit(1)` or triggering a 64 exit code after a caught `UsageException`).\n\n## Testing CLI Applications\n\n> [!IMPORTANT]\n> **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.\n\nUse `test_process` and `test_descriptor` to write high-fidelity integration tests for your CLI.\n\n*   Define expected filesystem states using `test_descriptor` (`d.dir`, `d.file`).\n*   Create the mock filesystem before execution using `await d.Descriptor.create()`.\n*   Spawn the CLI process using `TestProcess.start('dart', ['run', 'bin\u002Fcli.dart', ...args])`.\n*   Validate standard output and error streams using `StreamQueue` matchers (e.g., `emitsThrough`, `emits`).\n*   Assert the final exit code using `await process.shouldExit(0)`.\n*   Validate resulting filesystem mutations using `await d.Descriptor.validate()`.\n\n## Compilation & Distribution\n\nSelect the appropriate compilation target based on your distribution requirements.\n\n*   **If testing locally during development:** Use `dart run bin\u002Fcli.dart`. This uses the JIT compiler for rapid iteration.\n*   **If bundling code assets and dynamic libraries:** Use `dart build cli`. This runs build hooks and outputs to `build\u002Fcli\u002F_\u002Fbundle\u002F`.\n*   **If distributing a standalone native executable:** Use `dart compile exe bin\u002Fcli.dart -o \u003Coutput_path>`. This bundles the Dart runtime and machine code into a single file.\n*   **If distributing multiple apps with strict disk space limits:** Use `dart compile aot-snapshot bin\u002Fcli.dart`. Run the resulting `.aot` file using `dartaotruntime`.\n\n\u003Cdetails>\n\u003Csummary>Cross-Compilation Targets (Linux Only)\u003C\u002Fsummary>\n\nDart supports cross-compiling to Linux from macOS, Windows, or Linux hosts.\nUse the `--target-os` and `--target-arch` flags with `dart compile exe` or `dart compile aot-snapshot`.\n\n*   `--target-os=linux` (Only Linux is currently supported as a cross-compilation target)\n*   `--target-arch=arm64` (64-bit ARM)\n*   `--target-arch=x64` (x86-64)\n*   `--target-arch=arm` (32-bit ARM)\n*   `--target-arch=riscv64` (64-bit RISC-V)\n\nExample: `dart compile exe --target-os=linux --target-arch=arm64 bin\u002Fcli.dart`\n\u003C\u002Fdetails>\n\n## Workflows\n\n### Task Progress: Implement a New CLI Command\n- [ ] Create a new class extending `Command` in `lib\u002Fsrc\u002Fcommands\u002F`.\n- [ ] Define the `name` and `description` properties.\n- [ ] Register command-specific flags in the constructor using `argParser.addFlag()` or `argParser.addOption()`.\n- [ ] Implement the `run()` method with the core logic.\n- [ ] Register the new command in the `CommandRunner` instance in `bin\u002Fcli.dart` using `addCommand()`.\n- [ ] Create tests for the new command in the `test\u002F` directory using `test_process` or standard tests.\n- [ ] Run validator -> Execute `dart run bin\u002Fcli.dart help \u003Ccommand_name>` to verify help text generation.\n- [ ] Verify final UX: Compile the application using `dart compile exe` and run the resulting executable to verify the target user experience (e.g., `.\u002Fbin\u002Fcli \u003Ccommand>`).\n\n### Task Progress: Compile and Release Native Executable\n- [ ] Run validator -> Execute `dart format . --set-exit-if-changed` to ensure code formatting.\n- [ ] Run validator -> Execute `dart analyze` to ensure no static analysis errors.\n- [ ] Run validator -> Execute `dart test` to pass all integration tests.\n- [ ] Compile for host OS: `dart compile exe bin\u002Fcli.dart -o build\u002Fcli-host`\n- [ ] Compile for Linux (if host is macOS\u002FWindows): `dart compile exe --target-os=linux --target-arch=x64 bin\u002Fcli.dart -o build\u002Fcli-linux-x64`\n\n## Examples\n\n### Example: CommandRunner Implementation\n\n```dart\nimport 'dart:io';\nimport 'package:args\u002Fcommand_runner.dart';\nimport 'package:stack_trace\u002Fstack_trace.dart';\n\nclass CommitCommand extends Command {\n  @override\n  final String name = 'commit';\n  @override\n  final String description = 'Record changes to the repository.';\n\n  CommitCommand() {\n    argParser.addFlag('all', abbr: 'a', help: 'Commit all changed files.');\n  }\n\n  @override\n  Future\u003Cvoid> run() async {\n    final commitAll = argResults?['all'] as bool? ?? false;\n    print('Committing... (All: $commitAll)');\n  }\n}\n\nvoid main(List\u003CString> args) {\n  Chain.capture(() async {\n    final runner = CommandRunner('dgit', 'Distributed version control.')\n      ..addCommand(CommitCommand());\n\n    await runner.run(args);\n  }, onError: (error, chain) {\n    if (error is UsageException) {\n      stderr.writeln(error.message);\n      stderr.writeln(error.usage);\n      exit(64); \u002F\u002F ExitCode.usage.code\n    } else {\n      stderr.writeln('Fatal error: $error');\n      stderr.writeln(chain.terse);\n      exit(1);\n    }\n  });\n}\n```\n\n### Example: Integration Testing with Subprocesses\n\n```dart\nimport 'package:test\u002Ftest.dart';\nimport 'package:test_process\u002Ftest_process.dart';\nimport 'package:test_descriptor\u002Ftest_descriptor.dart' as d;\n\nvoid main() {\n  test('CLI formats output correctly and modifies filesystem', () async {\n    \u002F\u002F 1. Setup mock filesystem\n    await d.dir('project', [\n      d.file('config.json', '{\"key\": \"value\"}')\n    ]).create();\n\n    \u002F\u002F 2. Spawn the CLI process\n    final process = await TestProcess.start(\n      'dart',\n      ['run', 'bin\u002Fcli.dart', 'process', '--path', '${d.sandbox}\u002Fproject']\n    );\n\n    \u002F\u002F 3. Validate stdout stream\n    await expectLater(process.stdout, emitsThrough('Processing complete.'));\n\n    \u002F\u002F 4. Validate exit code\n    await process.shouldExit(0);\n\n    \u002F\u002F 5. Validate filesystem mutations\n    await d.dir('project', [\n      d.file('config.json', '{\"key\": \"value\"}'),\n      d.file('output.log', 'Success')\n    ]).validate();\n  });\n}\n```\n",{"data":30,"body":34},{"name":4,"description":6,"metadata":31},{"model":32,"last_modified":33},"models\u002Fgemini-3.1-pro-preview","Fri, 04 May 2026 17:41:00 GMT",{"type":35,"children":36},"root",[37,46,53,122,127,133,205,210,223,328,333,354,494,499,519,538,642,647,652,746,859,864,871,1062,1068,1149,1154,1160,1514,1520,1759],{"type":38,"tag":39,"props":40,"children":42},"element","h1",{"id":41},"building-dart-cli-applications",[43],{"type":44,"value":45},"text","Building Dart CLI Applications",{"type":38,"tag":47,"props":48,"children":50},"h2",{"id":49},"contents",[51],{"type":44,"value":52},"Contents",{"type":38,"tag":54,"props":55,"children":56},"ul",{},[57,68,77,86,95,104,113],{"type":38,"tag":58,"props":59,"children":60},"li",{},[61],{"type":38,"tag":62,"props":63,"children":65},"a",{"href":64},"#project-setup--architecture",[66],{"type":44,"value":67},"Project Setup & Architecture",{"type":38,"tag":58,"props":69,"children":70},{},[71],{"type":38,"tag":62,"props":72,"children":74},{"href":73},"#argument-parsing--command-routing",[75],{"type":44,"value":76},"Argument Parsing & Command Routing",{"type":38,"tag":58,"props":78,"children":79},{},[80],{"type":38,"tag":62,"props":81,"children":83},{"href":82},"#execution--error-handling",[84],{"type":44,"value":85},"Execution & Error Handling",{"type":38,"tag":58,"props":87,"children":88},{},[89],{"type":38,"tag":62,"props":90,"children":92},{"href":91},"#testing-cli-applications",[93],{"type":44,"value":94},"Testing CLI Applications",{"type":38,"tag":58,"props":96,"children":97},{},[98],{"type":38,"tag":62,"props":99,"children":101},{"href":100},"#compilation--distribution",[102],{"type":44,"value":103},"Compilation & Distribution",{"type":38,"tag":58,"props":105,"children":106},{},[107],{"type":38,"tag":62,"props":108,"children":110},{"href":109},"#workflows",[111],{"type":44,"value":112},"Workflows",{"type":38,"tag":58,"props":114,"children":115},{},[116],{"type":38,"tag":62,"props":117,"children":119},{"href":118},"#examples",[120],{"type":44,"value":121},"Examples",{"type":38,"tag":47,"props":123,"children":125},{"id":124},"project-setup-architecture",[126],{"type":44,"value":67},{"type":38,"tag":128,"props":129,"children":130},"p",{},[131],{"type":44,"value":132},"Initialize new CLI projects using the official Dart template to ensure standard directory structures.",{"type":38,"tag":54,"props":134,"children":135},{},[136,150,171,192],{"type":38,"tag":58,"props":137,"children":138},{},[139,141,148],{"type":44,"value":140},"Run ",{"type":38,"tag":142,"props":143,"children":145},"code",{"className":144},[],[146],{"type":44,"value":147},"dart create -t cli \u003Cproject_name>",{"type":44,"value":149}," to scaffold a console application with basic argument parsing.",{"type":38,"tag":58,"props":151,"children":152},{},[153,155,161,163,169],{"type":44,"value":154},"Place executable entry points (files containing ",{"type":38,"tag":142,"props":156,"children":158},{"className":157},[],[159],{"type":44,"value":160},"main()",{"type":44,"value":162},") exclusively in the ",{"type":38,"tag":142,"props":164,"children":166},{"className":165},[],[167],{"type":44,"value":168},"bin\u002F",{"type":44,"value":170}," directory.",{"type":38,"tag":58,"props":172,"children":173},{},[174,176,182,184,190],{"type":44,"value":175},"Place internal implementation logic in ",{"type":38,"tag":142,"props":177,"children":179},{"className":178},[],[180],{"type":44,"value":181},"lib\u002Fsrc\u002F",{"type":44,"value":183}," and expose public APIs via ",{"type":38,"tag":142,"props":185,"children":187},{"className":186},[],[188],{"type":44,"value":189},"lib\u002F\u003Cproject_name>.dart",{"type":44,"value":191},".",{"type":38,"tag":58,"props":193,"children":194},{},[195,197,203],{"type":44,"value":196},"Enforce formatting in CI environments by running ",{"type":38,"tag":142,"props":198,"children":200},{"className":199},[],[201],{"type":44,"value":202},"dart format . --set-exit-if-changed",{"type":44,"value":204},". This returns exit code 1 if formatting violations exist.",{"type":38,"tag":47,"props":206,"children":208},{"id":207},"argument-parsing-command-routing",[209],{"type":44,"value":76},{"type":38,"tag":128,"props":211,"children":212},{},[213,215,221],{"type":44,"value":214},"Import the ",{"type":38,"tag":142,"props":216,"children":218},{"className":217},[],[219],{"type":44,"value":220},"args",{"type":44,"value":222}," package to manage command-line arguments, flags, and subcommands.",{"type":38,"tag":54,"props":224,"children":225},{},[226,255,284,304,317],{"type":38,"tag":58,"props":227,"children":228},{},[229,231,237,239,245,247,253],{"type":44,"value":230},"If building a simple script: Use ",{"type":38,"tag":142,"props":232,"children":234},{"className":233},[],[235],{"type":44,"value":236},"ArgParser",{"type":44,"value":238}," directly to define flags (",{"type":38,"tag":142,"props":240,"children":242},{"className":241},[],[243],{"type":44,"value":244},"addFlag",{"type":44,"value":246},") and options (",{"type":38,"tag":142,"props":248,"children":250},{"className":249},[],[251],{"type":44,"value":252},"addOption",{"type":44,"value":254},").",{"type":38,"tag":58,"props":256,"children":257},{},[258,260,266,268,274,276,282],{"type":44,"value":259},"If building a complex, multi-command CLI (like ",{"type":38,"tag":142,"props":261,"children":263},{"className":262},[],[264],{"type":44,"value":265},"git",{"type":44,"value":267},"): Implement ",{"type":38,"tag":142,"props":269,"children":271},{"className":270},[],[272],{"type":44,"value":273},"CommandRunner",{"type":44,"value":275}," and extend ",{"type":38,"tag":142,"props":277,"children":279},{"className":278},[],[280],{"type":44,"value":281},"Command",{"type":44,"value":283}," for each subcommand.",{"type":38,"tag":58,"props":285,"children":286},{},[287,289,295,297,303],{"type":44,"value":288},"Define global arguments on the ",{"type":38,"tag":142,"props":290,"children":292},{"className":291},[],[293],{"type":44,"value":294},"CommandRunner.argParser",{"type":44,"value":296}," and command-specific arguments on the individual ",{"type":38,"tag":142,"props":298,"children":300},{"className":299},[],[301],{"type":44,"value":302},"Command.argParser",{"type":44,"value":191},{"type":38,"tag":58,"props":305,"children":306},{},[307,309,315],{"type":44,"value":308},"Catch ",{"type":38,"tag":142,"props":310,"children":312},{"className":311},[],[313],{"type":44,"value":314},"UsageException",{"type":44,"value":316}," to gracefully handle invalid arguments and display the automatically generated help text.",{"type":38,"tag":58,"props":318,"children":319},{},[320,326],{"type":38,"tag":321,"props":322,"children":323},"strong",{},[324],{"type":44,"value":325},"Validate Help Text Accuracy",{"type":44,"value":327},": 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.",{"type":38,"tag":47,"props":329,"children":331},{"id":330},"execution-error-handling",[332],{"type":44,"value":85},{"type":38,"tag":128,"props":334,"children":335},{},[336,338,344,346,352],{"type":44,"value":337},"Leverage the ",{"type":38,"tag":142,"props":339,"children":341},{"className":340},[],[342],{"type":44,"value":343},"io",{"type":44,"value":345}," and ",{"type":38,"tag":142,"props":347,"children":349},{"className":348},[],[350],{"type":44,"value":351},"stack_trace",{"type":44,"value":353}," packages to build robust, production-ready CLI tools.",{"type":38,"tag":54,"props":355,"children":356},{},[357,392,412,431,452,462],{"type":38,"tag":58,"props":358,"children":359},{},[360,362,367,369,375,377,383,385,391],{"type":44,"value":361},"Use the ",{"type":38,"tag":142,"props":363,"children":365},{"className":364},[],[366],{"type":44,"value":343},{"type":44,"value":368}," package's ",{"type":38,"tag":142,"props":370,"children":372},{"className":371},[],[373],{"type":44,"value":374},"ExitCode",{"type":44,"value":376}," enum to return standard POSIX exit codes (e.g., ",{"type":38,"tag":142,"props":378,"children":380},{"className":379},[],[381],{"type":44,"value":382},"ExitCode.success.code",{"type":44,"value":384},", ",{"type":38,"tag":142,"props":386,"children":388},{"className":387},[],[389],{"type":44,"value":390},"ExitCode.usage.code",{"type":44,"value":254},{"type":38,"tag":58,"props":393,"children":394},{},[395,397,403,405,410],{"type":44,"value":396},"Use ",{"type":38,"tag":142,"props":398,"children":400},{"className":399},[],[401],{"type":44,"value":402},"sharedStdIn",{"type":44,"value":404}," from the ",{"type":38,"tag":142,"props":406,"children":408},{"className":407},[],[409],{"type":44,"value":343},{"type":44,"value":411}," package if multiple asynchronous listeners need sequential access to standard input.",{"type":38,"tag":58,"props":413,"children":414},{},[415,417,423,424,429],{"type":44,"value":416},"Wrap the application execution in ",{"type":38,"tag":142,"props":418,"children":420},{"className":419},[],[421],{"type":44,"value":422},"Chain.capture()",{"type":44,"value":404},{"type":38,"tag":142,"props":425,"children":427},{"className":426},[],[428],{"type":44,"value":351},{"type":44,"value":430}," package to track asynchronous stack chains.",{"type":38,"tag":58,"props":432,"children":433},{},[434,436,442,444,450],{"type":44,"value":435},"Format output stack traces using ",{"type":38,"tag":142,"props":437,"children":439},{"className":438},[],[440],{"type":44,"value":441},"Trace.terse",{"type":44,"value":443}," or ",{"type":38,"tag":142,"props":445,"children":447},{"className":446},[],[448],{"type":44,"value":449},"Chain.terse",{"type":44,"value":451}," to strip noisy core library frames and present readable errors to the user.",{"type":38,"tag":58,"props":453,"children":454},{},[455,460],{"type":38,"tag":321,"props":456,"children":457},{},[458],{"type":44,"value":459},"Do not swallow exceptions",{"type":44,"value":461}," 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.",{"type":38,"tag":58,"props":463,"children":464},{},[465,470,472,478,480,486,488,493],{"type":38,"tag":321,"props":466,"children":467},{},[468],{"type":44,"value":469},"Fail fast and with non-zero exit codes",{"type":44,"value":471},": Ensure operation failures result in descriptive error messages to ",{"type":38,"tag":142,"props":473,"children":475},{"className":474},[],[476],{"type":44,"value":477},"stderr",{"type":44,"value":479}," and appropriate non-zero exit codes (e.g., using ",{"type":38,"tag":142,"props":481,"children":483},{"className":482},[],[484],{"type":44,"value":485},"exit(1)",{"type":44,"value":487}," or triggering a 64 exit code after a caught ",{"type":38,"tag":142,"props":489,"children":491},{"className":490},[],[492],{"type":44,"value":314},{"type":44,"value":254},{"type":38,"tag":47,"props":495,"children":497},{"id":496},"testing-cli-applications",[498],{"type":44,"value":94},{"type":38,"tag":500,"props":501,"children":502},"blockquote",{},[503],{"type":38,"tag":128,"props":504,"children":505},{},[506,512,517],{"type":38,"tag":507,"props":508,"children":509},"span",{},[510],{"type":44,"value":511},"!IMPORTANT",{"type":38,"tag":321,"props":513,"children":514},{},[515],{"type":44,"value":516},"All new commands and significant features must be covered by automated tests.",{"type":44,"value":518}," 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.",{"type":38,"tag":128,"props":520,"children":521},{},[522,523,529,530,536],{"type":44,"value":396},{"type":38,"tag":142,"props":524,"children":526},{"className":525},[],[527],{"type":44,"value":528},"test_process",{"type":44,"value":345},{"type":38,"tag":142,"props":531,"children":533},{"className":532},[],[534],{"type":44,"value":535},"test_descriptor",{"type":44,"value":537}," to write high-fidelity integration tests for your CLI.",{"type":38,"tag":54,"props":539,"children":540},{},[541,567,579,591,618,630],{"type":38,"tag":58,"props":542,"children":543},{},[544,546,551,553,559,560,566],{"type":44,"value":545},"Define expected filesystem states using ",{"type":38,"tag":142,"props":547,"children":549},{"className":548},[],[550],{"type":44,"value":535},{"type":44,"value":552}," (",{"type":38,"tag":142,"props":554,"children":556},{"className":555},[],[557],{"type":44,"value":558},"d.dir",{"type":44,"value":384},{"type":38,"tag":142,"props":561,"children":563},{"className":562},[],[564],{"type":44,"value":565},"d.file",{"type":44,"value":254},{"type":38,"tag":58,"props":568,"children":569},{},[570,572,578],{"type":44,"value":571},"Create the mock filesystem before execution using ",{"type":38,"tag":142,"props":573,"children":575},{"className":574},[],[576],{"type":44,"value":577},"await d.Descriptor.create()",{"type":44,"value":191},{"type":38,"tag":58,"props":580,"children":581},{},[582,584,590],{"type":44,"value":583},"Spawn the CLI process using ",{"type":38,"tag":142,"props":585,"children":587},{"className":586},[],[588],{"type":44,"value":589},"TestProcess.start('dart', ['run', 'bin\u002Fcli.dart', ...args])",{"type":44,"value":191},{"type":38,"tag":58,"props":592,"children":593},{},[594,596,602,604,610,611,617],{"type":44,"value":595},"Validate standard output and error streams using ",{"type":38,"tag":142,"props":597,"children":599},{"className":598},[],[600],{"type":44,"value":601},"StreamQueue",{"type":44,"value":603}," matchers (e.g., ",{"type":38,"tag":142,"props":605,"children":607},{"className":606},[],[608],{"type":44,"value":609},"emitsThrough",{"type":44,"value":384},{"type":38,"tag":142,"props":612,"children":614},{"className":613},[],[615],{"type":44,"value":616},"emits",{"type":44,"value":254},{"type":38,"tag":58,"props":619,"children":620},{},[621,623,629],{"type":44,"value":622},"Assert the final exit code using ",{"type":38,"tag":142,"props":624,"children":626},{"className":625},[],[627],{"type":44,"value":628},"await process.shouldExit(0)",{"type":44,"value":191},{"type":38,"tag":58,"props":631,"children":632},{},[633,635,641],{"type":44,"value":634},"Validate resulting filesystem mutations using ",{"type":38,"tag":142,"props":636,"children":638},{"className":637},[],[639],{"type":44,"value":640},"await d.Descriptor.validate()",{"type":44,"value":191},{"type":38,"tag":47,"props":643,"children":645},{"id":644},"compilation-distribution",[646],{"type":44,"value":103},{"type":38,"tag":128,"props":648,"children":649},{},[650],{"type":44,"value":651},"Select the appropriate compilation target based on your distribution requirements.",{"type":38,"tag":54,"props":653,"children":654},{},[655,673,697,714],{"type":38,"tag":58,"props":656,"children":657},{},[658,663,665,671],{"type":38,"tag":321,"props":659,"children":660},{},[661],{"type":44,"value":662},"If testing locally during development:",{"type":44,"value":664}," Use ",{"type":38,"tag":142,"props":666,"children":668},{"className":667},[],[669],{"type":44,"value":670},"dart run bin\u002Fcli.dart",{"type":44,"value":672},". This uses the JIT compiler for rapid iteration.",{"type":38,"tag":58,"props":674,"children":675},{},[676,681,682,688,690,696],{"type":38,"tag":321,"props":677,"children":678},{},[679],{"type":44,"value":680},"If bundling code assets and dynamic libraries:",{"type":44,"value":664},{"type":38,"tag":142,"props":683,"children":685},{"className":684},[],[686],{"type":44,"value":687},"dart build cli",{"type":44,"value":689},". This runs build hooks and outputs to ",{"type":38,"tag":142,"props":691,"children":693},{"className":692},[],[694],{"type":44,"value":695},"build\u002Fcli\u002F_\u002Fbundle\u002F",{"type":44,"value":191},{"type":38,"tag":58,"props":698,"children":699},{},[700,705,706,712],{"type":38,"tag":321,"props":701,"children":702},{},[703],{"type":44,"value":704},"If distributing a standalone native executable:",{"type":44,"value":664},{"type":38,"tag":142,"props":707,"children":709},{"className":708},[],[710],{"type":44,"value":711},"dart compile exe bin\u002Fcli.dart -o \u003Coutput_path>",{"type":44,"value":713},". This bundles the Dart runtime and machine code into a single file.",{"type":38,"tag":58,"props":715,"children":716},{},[717,722,723,729,731,737,739,745],{"type":38,"tag":321,"props":718,"children":719},{},[720],{"type":44,"value":721},"If distributing multiple apps with strict disk space limits:",{"type":44,"value":664},{"type":38,"tag":142,"props":724,"children":726},{"className":725},[],[727],{"type":44,"value":728},"dart compile aot-snapshot bin\u002Fcli.dart",{"type":44,"value":730},". Run the resulting ",{"type":38,"tag":142,"props":732,"children":734},{"className":733},[],[735],{"type":44,"value":736},".aot",{"type":44,"value":738}," file using ",{"type":38,"tag":142,"props":740,"children":742},{"className":741},[],[743],{"type":44,"value":744},"dartaotruntime",{"type":44,"value":191},{"type":38,"tag":747,"props":748,"children":749},"details",{},[750,756,790,848],{"type":38,"tag":751,"props":752,"children":753},"summary",{},[754],{"type":44,"value":755},"Cross-Compilation Targets (Linux Only)",{"type":38,"tag":128,"props":757,"children":758},{},[759,761,767,768,774,776,782,783,789],{"type":44,"value":760},"Dart supports cross-compiling to Linux from macOS, Windows, or Linux hosts.\nUse the ",{"type":38,"tag":142,"props":762,"children":764},{"className":763},[],[765],{"type":44,"value":766},"--target-os",{"type":44,"value":345},{"type":38,"tag":142,"props":769,"children":771},{"className":770},[],[772],{"type":44,"value":773},"--target-arch",{"type":44,"value":775}," flags with ",{"type":38,"tag":142,"props":777,"children":779},{"className":778},[],[780],{"type":44,"value":781},"dart compile exe",{"type":44,"value":443},{"type":38,"tag":142,"props":784,"children":786},{"className":785},[],[787],{"type":44,"value":788},"dart compile aot-snapshot",{"type":44,"value":191},{"type":38,"tag":54,"props":791,"children":792},{},[793,804,815,826,837],{"type":38,"tag":58,"props":794,"children":795},{},[796,802],{"type":38,"tag":142,"props":797,"children":799},{"className":798},[],[800],{"type":44,"value":801},"--target-os=linux",{"type":44,"value":803}," (Only Linux is currently supported as a cross-compilation target)",{"type":38,"tag":58,"props":805,"children":806},{},[807,813],{"type":38,"tag":142,"props":808,"children":810},{"className":809},[],[811],{"type":44,"value":812},"--target-arch=arm64",{"type":44,"value":814}," (64-bit ARM)",{"type":38,"tag":58,"props":816,"children":817},{},[818,824],{"type":38,"tag":142,"props":819,"children":821},{"className":820},[],[822],{"type":44,"value":823},"--target-arch=x64",{"type":44,"value":825}," (x86-64)",{"type":38,"tag":58,"props":827,"children":828},{},[829,835],{"type":38,"tag":142,"props":830,"children":832},{"className":831},[],[833],{"type":44,"value":834},"--target-arch=arm",{"type":44,"value":836}," (32-bit ARM)",{"type":38,"tag":58,"props":838,"children":839},{},[840,846],{"type":38,"tag":142,"props":841,"children":843},{"className":842},[],[844],{"type":44,"value":845},"--target-arch=riscv64",{"type":44,"value":847}," (64-bit RISC-V)",{"type":38,"tag":128,"props":849,"children":850},{},[851,853],{"type":44,"value":852},"Example: ",{"type":38,"tag":142,"props":854,"children":856},{"className":855},[],[857],{"type":44,"value":858},"dart compile exe --target-os=linux --target-arch=arm64 bin\u002Fcli.dart",{"type":38,"tag":47,"props":860,"children":862},{"id":861},"workflows",[863],{"type":44,"value":112},{"type":38,"tag":865,"props":866,"children":868},"h3",{"id":867},"task-progress-implement-a-new-cli-command",[869],{"type":44,"value":870},"Task Progress: Implement a New CLI Command",{"type":38,"tag":54,"props":872,"children":875},{"className":873},[874],"contains-task-list",[876,903,927,950,967,998,1022,1039],{"type":38,"tag":58,"props":877,"children":880},{"className":878},[879],"task-list-item",[881,887,889,894,896,902],{"type":38,"tag":882,"props":883,"children":886},"input",{"disabled":884,"type":885},true,"checkbox",[],{"type":44,"value":888}," Create a new class extending ",{"type":38,"tag":142,"props":890,"children":892},{"className":891},[],[893],{"type":44,"value":281},{"type":44,"value":895}," in ",{"type":38,"tag":142,"props":897,"children":899},{"className":898},[],[900],{"type":44,"value":901},"lib\u002Fsrc\u002Fcommands\u002F",{"type":44,"value":191},{"type":38,"tag":58,"props":904,"children":906},{"className":905},[879],[907,910,912,918,919,925],{"type":38,"tag":882,"props":908,"children":909},{"disabled":884,"type":885},[],{"type":44,"value":911}," Define the ",{"type":38,"tag":142,"props":913,"children":915},{"className":914},[],[916],{"type":44,"value":917},"name",{"type":44,"value":345},{"type":38,"tag":142,"props":920,"children":922},{"className":921},[],[923],{"type":44,"value":924},"description",{"type":44,"value":926}," properties.",{"type":38,"tag":58,"props":928,"children":930},{"className":929},[879],[931,934,936,942,943,949],{"type":38,"tag":882,"props":932,"children":933},{"disabled":884,"type":885},[],{"type":44,"value":935}," Register command-specific flags in the constructor using ",{"type":38,"tag":142,"props":937,"children":939},{"className":938},[],[940],{"type":44,"value":941},"argParser.addFlag()",{"type":44,"value":443},{"type":38,"tag":142,"props":944,"children":946},{"className":945},[],[947],{"type":44,"value":948},"argParser.addOption()",{"type":44,"value":191},{"type":38,"tag":58,"props":951,"children":953},{"className":952},[879],[954,957,959,965],{"type":38,"tag":882,"props":955,"children":956},{"disabled":884,"type":885},[],{"type":44,"value":958}," Implement the ",{"type":38,"tag":142,"props":960,"children":962},{"className":961},[],[963],{"type":44,"value":964},"run()",{"type":44,"value":966}," method with the core logic.",{"type":38,"tag":58,"props":968,"children":970},{"className":969},[879],[971,974,976,981,983,989,991,997],{"type":38,"tag":882,"props":972,"children":973},{"disabled":884,"type":885},[],{"type":44,"value":975}," Register the new command in the ",{"type":38,"tag":142,"props":977,"children":979},{"className":978},[],[980],{"type":44,"value":273},{"type":44,"value":982}," instance in ",{"type":38,"tag":142,"props":984,"children":986},{"className":985},[],[987],{"type":44,"value":988},"bin\u002Fcli.dart",{"type":44,"value":990}," using ",{"type":38,"tag":142,"props":992,"children":994},{"className":993},[],[995],{"type":44,"value":996},"addCommand()",{"type":44,"value":191},{"type":38,"tag":58,"props":999,"children":1001},{"className":1000},[879],[1002,1005,1007,1013,1015,1020],{"type":38,"tag":882,"props":1003,"children":1004},{"disabled":884,"type":885},[],{"type":44,"value":1006}," Create tests for the new command in the ",{"type":38,"tag":142,"props":1008,"children":1010},{"className":1009},[],[1011],{"type":44,"value":1012},"test\u002F",{"type":44,"value":1014}," directory using ",{"type":38,"tag":142,"props":1016,"children":1018},{"className":1017},[],[1019],{"type":44,"value":528},{"type":44,"value":1021}," or standard tests.",{"type":38,"tag":58,"props":1023,"children":1025},{"className":1024},[879],[1026,1029,1031,1037],{"type":38,"tag":882,"props":1027,"children":1028},{"disabled":884,"type":885},[],{"type":44,"value":1030}," Run validator -> Execute ",{"type":38,"tag":142,"props":1032,"children":1034},{"className":1033},[],[1035],{"type":44,"value":1036},"dart run bin\u002Fcli.dart help \u003Ccommand_name>",{"type":44,"value":1038}," to verify help text generation.",{"type":38,"tag":58,"props":1040,"children":1042},{"className":1041},[879],[1043,1046,1048,1053,1055,1061],{"type":38,"tag":882,"props":1044,"children":1045},{"disabled":884,"type":885},[],{"type":44,"value":1047}," Verify final UX: Compile the application using ",{"type":38,"tag":142,"props":1049,"children":1051},{"className":1050},[],[1052],{"type":44,"value":781},{"type":44,"value":1054}," and run the resulting executable to verify the target user experience (e.g., ",{"type":38,"tag":142,"props":1056,"children":1058},{"className":1057},[],[1059],{"type":44,"value":1060},".\u002Fbin\u002Fcli \u003Ccommand>",{"type":44,"value":254},{"type":38,"tag":865,"props":1063,"children":1065},{"id":1064},"task-progress-compile-and-release-native-executable",[1066],{"type":44,"value":1067},"Task Progress: Compile and Release Native Executable",{"type":38,"tag":54,"props":1069,"children":1071},{"className":1070},[874],[1072,1087,1103,1119,1134],{"type":38,"tag":58,"props":1073,"children":1075},{"className":1074},[879],[1076,1079,1080,1085],{"type":38,"tag":882,"props":1077,"children":1078},{"disabled":884,"type":885},[],{"type":44,"value":1030},{"type":38,"tag":142,"props":1081,"children":1083},{"className":1082},[],[1084],{"type":44,"value":202},{"type":44,"value":1086}," to ensure code formatting.",{"type":38,"tag":58,"props":1088,"children":1090},{"className":1089},[879],[1091,1094,1095,1101],{"type":38,"tag":882,"props":1092,"children":1093},{"disabled":884,"type":885},[],{"type":44,"value":1030},{"type":38,"tag":142,"props":1096,"children":1098},{"className":1097},[],[1099],{"type":44,"value":1100},"dart analyze",{"type":44,"value":1102}," to ensure no static analysis errors.",{"type":38,"tag":58,"props":1104,"children":1106},{"className":1105},[879],[1107,1110,1111,1117],{"type":38,"tag":882,"props":1108,"children":1109},{"disabled":884,"type":885},[],{"type":44,"value":1030},{"type":38,"tag":142,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":44,"value":1116},"dart test",{"type":44,"value":1118}," to pass all integration tests.",{"type":38,"tag":58,"props":1120,"children":1122},{"className":1121},[879],[1123,1126,1128],{"type":38,"tag":882,"props":1124,"children":1125},{"disabled":884,"type":885},[],{"type":44,"value":1127}," Compile for host OS: ",{"type":38,"tag":142,"props":1129,"children":1131},{"className":1130},[],[1132],{"type":44,"value":1133},"dart compile exe bin\u002Fcli.dart -o build\u002Fcli-host",{"type":38,"tag":58,"props":1135,"children":1137},{"className":1136},[879],[1138,1141,1143],{"type":38,"tag":882,"props":1139,"children":1140},{"disabled":884,"type":885},[],{"type":44,"value":1142}," Compile for Linux (if host is macOS\u002FWindows): ",{"type":38,"tag":142,"props":1144,"children":1146},{"className":1145},[],[1147],{"type":44,"value":1148},"dart compile exe --target-os=linux --target-arch=x64 bin\u002Fcli.dart -o build\u002Fcli-linux-x64",{"type":38,"tag":47,"props":1150,"children":1152},{"id":1151},"examples",[1153],{"type":44,"value":121},{"type":38,"tag":865,"props":1155,"children":1157},{"id":1156},"example-commandrunner-implementation",[1158],{"type":44,"value":1159},"Example: CommandRunner Implementation",{"type":38,"tag":1161,"props":1162,"children":1166},"pre",{"className":1163,"code":1164,"language":18,"meta":1165,"style":1165},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import 'dart:io';\nimport 'package:args\u002Fcommand_runner.dart';\nimport 'package:stack_trace\u002Fstack_trace.dart';\n\nclass CommitCommand extends Command {\n  @override\n  final String name = 'commit';\n  @override\n  final String description = 'Record changes to the repository.';\n\n  CommitCommand() {\n    argParser.addFlag('all', abbr: 'a', help: 'Commit all changed files.');\n  }\n\n  @override\n  Future\u003Cvoid> run() async {\n    final commitAll = argResults?['all'] as bool? ?? false;\n    print('Committing... (All: $commitAll)');\n  }\n}\n\nvoid main(List\u003CString> args) {\n  Chain.capture(() async {\n    final runner = CommandRunner('dgit', 'Distributed version control.')\n      ..addCommand(CommitCommand());\n\n    await runner.run(args);\n  }, onError: (error, chain) {\n    if (error is UsageException) {\n      stderr.writeln(error.message);\n      stderr.writeln(error.usage);\n      exit(64); \u002F\u002F ExitCode.usage.code\n    } else {\n      stderr.writeln('Fatal error: $error');\n      stderr.writeln(chain.terse);\n      exit(1);\n    }\n  });\n}\n","",[1167],{"type":38,"tag":142,"props":1168,"children":1169},{"__ignoreMap":1165},[1170,1180,1189,1198,1207,1216,1225,1234,1242,1251,1259,1268,1277,1286,1294,1302,1311,1320,1329,1337,1346,1354,1363,1372,1381,1390,1398,1407,1416,1425,1434,1443,1452,1461,1470,1479,1488,1497,1506],{"type":38,"tag":507,"props":1171,"children":1174},{"class":1172,"line":1173},"line",1,[1175],{"type":38,"tag":507,"props":1176,"children":1177},{},[1178],{"type":44,"value":1179},"import 'dart:io';\n",{"type":38,"tag":507,"props":1181,"children":1183},{"class":1172,"line":1182},2,[1184],{"type":38,"tag":507,"props":1185,"children":1186},{},[1187],{"type":44,"value":1188},"import 'package:args\u002Fcommand_runner.dart';\n",{"type":38,"tag":507,"props":1190,"children":1192},{"class":1172,"line":1191},3,[1193],{"type":38,"tag":507,"props":1194,"children":1195},{},[1196],{"type":44,"value":1197},"import 'package:stack_trace\u002Fstack_trace.dart';\n",{"type":38,"tag":507,"props":1199,"children":1201},{"class":1172,"line":1200},4,[1202],{"type":38,"tag":507,"props":1203,"children":1204},{"emptyLinePlaceholder":884},[1205],{"type":44,"value":1206},"\n",{"type":38,"tag":507,"props":1208,"children":1210},{"class":1172,"line":1209},5,[1211],{"type":38,"tag":507,"props":1212,"children":1213},{},[1214],{"type":44,"value":1215},"class CommitCommand extends Command {\n",{"type":38,"tag":507,"props":1217,"children":1219},{"class":1172,"line":1218},6,[1220],{"type":38,"tag":507,"props":1221,"children":1222},{},[1223],{"type":44,"value":1224},"  @override\n",{"type":38,"tag":507,"props":1226,"children":1228},{"class":1172,"line":1227},7,[1229],{"type":38,"tag":507,"props":1230,"children":1231},{},[1232],{"type":44,"value":1233},"  final String name = 'commit';\n",{"type":38,"tag":507,"props":1235,"children":1237},{"class":1172,"line":1236},8,[1238],{"type":38,"tag":507,"props":1239,"children":1240},{},[1241],{"type":44,"value":1224},{"type":38,"tag":507,"props":1243,"children":1245},{"class":1172,"line":1244},9,[1246],{"type":38,"tag":507,"props":1247,"children":1248},{},[1249],{"type":44,"value":1250},"  final String description = 'Record changes to the repository.';\n",{"type":38,"tag":507,"props":1252,"children":1254},{"class":1172,"line":1253},10,[1255],{"type":38,"tag":507,"props":1256,"children":1257},{"emptyLinePlaceholder":884},[1258],{"type":44,"value":1206},{"type":38,"tag":507,"props":1260,"children":1262},{"class":1172,"line":1261},11,[1263],{"type":38,"tag":507,"props":1264,"children":1265},{},[1266],{"type":44,"value":1267},"  CommitCommand() {\n",{"type":38,"tag":507,"props":1269,"children":1271},{"class":1172,"line":1270},12,[1272],{"type":38,"tag":507,"props":1273,"children":1274},{},[1275],{"type":44,"value":1276},"    argParser.addFlag('all', abbr: 'a', help: 'Commit all changed files.');\n",{"type":38,"tag":507,"props":1278,"children":1280},{"class":1172,"line":1279},13,[1281],{"type":38,"tag":507,"props":1282,"children":1283},{},[1284],{"type":44,"value":1285},"  }\n",{"type":38,"tag":507,"props":1287,"children":1289},{"class":1172,"line":1288},14,[1290],{"type":38,"tag":507,"props":1291,"children":1292},{"emptyLinePlaceholder":884},[1293],{"type":44,"value":1206},{"type":38,"tag":507,"props":1295,"children":1297},{"class":1172,"line":1296},15,[1298],{"type":38,"tag":507,"props":1299,"children":1300},{},[1301],{"type":44,"value":1224},{"type":38,"tag":507,"props":1303,"children":1305},{"class":1172,"line":1304},16,[1306],{"type":38,"tag":507,"props":1307,"children":1308},{},[1309],{"type":44,"value":1310},"  Future\u003Cvoid> run() async {\n",{"type":38,"tag":507,"props":1312,"children":1314},{"class":1172,"line":1313},17,[1315],{"type":38,"tag":507,"props":1316,"children":1317},{},[1318],{"type":44,"value":1319},"    final commitAll = argResults?['all'] as bool? ?? false;\n",{"type":38,"tag":507,"props":1321,"children":1323},{"class":1172,"line":1322},18,[1324],{"type":38,"tag":507,"props":1325,"children":1326},{},[1327],{"type":44,"value":1328},"    print('Committing... (All: $commitAll)');\n",{"type":38,"tag":507,"props":1330,"children":1332},{"class":1172,"line":1331},19,[1333],{"type":38,"tag":507,"props":1334,"children":1335},{},[1336],{"type":44,"value":1285},{"type":38,"tag":507,"props":1338,"children":1340},{"class":1172,"line":1339},20,[1341],{"type":38,"tag":507,"props":1342,"children":1343},{},[1344],{"type":44,"value":1345},"}\n",{"type":38,"tag":507,"props":1347,"children":1349},{"class":1172,"line":1348},21,[1350],{"type":38,"tag":507,"props":1351,"children":1352},{"emptyLinePlaceholder":884},[1353],{"type":44,"value":1206},{"type":38,"tag":507,"props":1355,"children":1357},{"class":1172,"line":1356},22,[1358],{"type":38,"tag":507,"props":1359,"children":1360},{},[1361],{"type":44,"value":1362},"void main(List\u003CString> args) {\n",{"type":38,"tag":507,"props":1364,"children":1366},{"class":1172,"line":1365},23,[1367],{"type":38,"tag":507,"props":1368,"children":1369},{},[1370],{"type":44,"value":1371},"  Chain.capture(() async {\n",{"type":38,"tag":507,"props":1373,"children":1375},{"class":1172,"line":1374},24,[1376],{"type":38,"tag":507,"props":1377,"children":1378},{},[1379],{"type":44,"value":1380},"    final runner = CommandRunner('dgit', 'Distributed version control.')\n",{"type":38,"tag":507,"props":1382,"children":1384},{"class":1172,"line":1383},25,[1385],{"type":38,"tag":507,"props":1386,"children":1387},{},[1388],{"type":44,"value":1389},"      ..addCommand(CommitCommand());\n",{"type":38,"tag":507,"props":1391,"children":1393},{"class":1172,"line":1392},26,[1394],{"type":38,"tag":507,"props":1395,"children":1396},{"emptyLinePlaceholder":884},[1397],{"type":44,"value":1206},{"type":38,"tag":507,"props":1399,"children":1401},{"class":1172,"line":1400},27,[1402],{"type":38,"tag":507,"props":1403,"children":1404},{},[1405],{"type":44,"value":1406},"    await runner.run(args);\n",{"type":38,"tag":507,"props":1408,"children":1410},{"class":1172,"line":1409},28,[1411],{"type":38,"tag":507,"props":1412,"children":1413},{},[1414],{"type":44,"value":1415},"  }, onError: (error, chain) {\n",{"type":38,"tag":507,"props":1417,"children":1419},{"class":1172,"line":1418},29,[1420],{"type":38,"tag":507,"props":1421,"children":1422},{},[1423],{"type":44,"value":1424},"    if (error is UsageException) {\n",{"type":38,"tag":507,"props":1426,"children":1428},{"class":1172,"line":1427},30,[1429],{"type":38,"tag":507,"props":1430,"children":1431},{},[1432],{"type":44,"value":1433},"      stderr.writeln(error.message);\n",{"type":38,"tag":507,"props":1435,"children":1437},{"class":1172,"line":1436},31,[1438],{"type":38,"tag":507,"props":1439,"children":1440},{},[1441],{"type":44,"value":1442},"      stderr.writeln(error.usage);\n",{"type":38,"tag":507,"props":1444,"children":1446},{"class":1172,"line":1445},32,[1447],{"type":38,"tag":507,"props":1448,"children":1449},{},[1450],{"type":44,"value":1451},"      exit(64); \u002F\u002F ExitCode.usage.code\n",{"type":38,"tag":507,"props":1453,"children":1455},{"class":1172,"line":1454},33,[1456],{"type":38,"tag":507,"props":1457,"children":1458},{},[1459],{"type":44,"value":1460},"    } else {\n",{"type":38,"tag":507,"props":1462,"children":1464},{"class":1172,"line":1463},34,[1465],{"type":38,"tag":507,"props":1466,"children":1467},{},[1468],{"type":44,"value":1469},"      stderr.writeln('Fatal error: $error');\n",{"type":38,"tag":507,"props":1471,"children":1473},{"class":1172,"line":1472},35,[1474],{"type":38,"tag":507,"props":1475,"children":1476},{},[1477],{"type":44,"value":1478},"      stderr.writeln(chain.terse);\n",{"type":38,"tag":507,"props":1480,"children":1482},{"class":1172,"line":1481},36,[1483],{"type":38,"tag":507,"props":1484,"children":1485},{},[1486],{"type":44,"value":1487},"      exit(1);\n",{"type":38,"tag":507,"props":1489,"children":1491},{"class":1172,"line":1490},37,[1492],{"type":38,"tag":507,"props":1493,"children":1494},{},[1495],{"type":44,"value":1496},"    }\n",{"type":38,"tag":507,"props":1498,"children":1500},{"class":1172,"line":1499},38,[1501],{"type":38,"tag":507,"props":1502,"children":1503},{},[1504],{"type":44,"value":1505},"  });\n",{"type":38,"tag":507,"props":1507,"children":1509},{"class":1172,"line":1508},39,[1510],{"type":38,"tag":507,"props":1511,"children":1512},{},[1513],{"type":44,"value":1345},{"type":38,"tag":865,"props":1515,"children":1517},{"id":1516},"example-integration-testing-with-subprocesses",[1518],{"type":44,"value":1519},"Example: Integration Testing with Subprocesses",{"type":38,"tag":1161,"props":1521,"children":1523},{"className":1163,"code":1522,"language":18,"meta":1165,"style":1165},"import 'package:test\u002Ftest.dart';\nimport 'package:test_process\u002Ftest_process.dart';\nimport 'package:test_descriptor\u002Ftest_descriptor.dart' as d;\n\nvoid main() {\n  test('CLI formats output correctly and modifies filesystem', () async {\n    \u002F\u002F 1. Setup mock filesystem\n    await d.dir('project', [\n      d.file('config.json', '{\"key\": \"value\"}')\n    ]).create();\n\n    \u002F\u002F 2. Spawn the CLI process\n    final process = await TestProcess.start(\n      'dart',\n      ['run', 'bin\u002Fcli.dart', 'process', '--path', '${d.sandbox}\u002Fproject']\n    );\n\n    \u002F\u002F 3. Validate stdout stream\n    await expectLater(process.stdout, emitsThrough('Processing complete.'));\n\n    \u002F\u002F 4. Validate exit code\n    await process.shouldExit(0);\n\n    \u002F\u002F 5. Validate filesystem mutations\n    await d.dir('project', [\n      d.file('config.json', '{\"key\": \"value\"}'),\n      d.file('output.log', 'Success')\n    ]).validate();\n  });\n}\n",[1524],{"type":38,"tag":142,"props":1525,"children":1526},{"__ignoreMap":1165},[1527,1535,1543,1551,1558,1566,1574,1582,1590,1598,1606,1613,1621,1629,1637,1645,1653,1660,1668,1676,1683,1691,1699,1706,1714,1721,1729,1737,1745,1752],{"type":38,"tag":507,"props":1528,"children":1529},{"class":1172,"line":1173},[1530],{"type":38,"tag":507,"props":1531,"children":1532},{},[1533],{"type":44,"value":1534},"import 'package:test\u002Ftest.dart';\n",{"type":38,"tag":507,"props":1536,"children":1537},{"class":1172,"line":1182},[1538],{"type":38,"tag":507,"props":1539,"children":1540},{},[1541],{"type":44,"value":1542},"import 'package:test_process\u002Ftest_process.dart';\n",{"type":38,"tag":507,"props":1544,"children":1545},{"class":1172,"line":1191},[1546],{"type":38,"tag":507,"props":1547,"children":1548},{},[1549],{"type":44,"value":1550},"import 'package:test_descriptor\u002Ftest_descriptor.dart' as d;\n",{"type":38,"tag":507,"props":1552,"children":1553},{"class":1172,"line":1200},[1554],{"type":38,"tag":507,"props":1555,"children":1556},{"emptyLinePlaceholder":884},[1557],{"type":44,"value":1206},{"type":38,"tag":507,"props":1559,"children":1560},{"class":1172,"line":1209},[1561],{"type":38,"tag":507,"props":1562,"children":1563},{},[1564],{"type":44,"value":1565},"void main() {\n",{"type":38,"tag":507,"props":1567,"children":1568},{"class":1172,"line":1218},[1569],{"type":38,"tag":507,"props":1570,"children":1571},{},[1572],{"type":44,"value":1573},"  test('CLI formats output correctly and modifies filesystem', () async {\n",{"type":38,"tag":507,"props":1575,"children":1576},{"class":1172,"line":1227},[1577],{"type":38,"tag":507,"props":1578,"children":1579},{},[1580],{"type":44,"value":1581},"    \u002F\u002F 1. Setup mock filesystem\n",{"type":38,"tag":507,"props":1583,"children":1584},{"class":1172,"line":1236},[1585],{"type":38,"tag":507,"props":1586,"children":1587},{},[1588],{"type":44,"value":1589},"    await d.dir('project', [\n",{"type":38,"tag":507,"props":1591,"children":1592},{"class":1172,"line":1244},[1593],{"type":38,"tag":507,"props":1594,"children":1595},{},[1596],{"type":44,"value":1597},"      d.file('config.json', '{\"key\": \"value\"}')\n",{"type":38,"tag":507,"props":1599,"children":1600},{"class":1172,"line":1253},[1601],{"type":38,"tag":507,"props":1602,"children":1603},{},[1604],{"type":44,"value":1605},"    ]).create();\n",{"type":38,"tag":507,"props":1607,"children":1608},{"class":1172,"line":1261},[1609],{"type":38,"tag":507,"props":1610,"children":1611},{"emptyLinePlaceholder":884},[1612],{"type":44,"value":1206},{"type":38,"tag":507,"props":1614,"children":1615},{"class":1172,"line":1270},[1616],{"type":38,"tag":507,"props":1617,"children":1618},{},[1619],{"type":44,"value":1620},"    \u002F\u002F 2. Spawn the CLI process\n",{"type":38,"tag":507,"props":1622,"children":1623},{"class":1172,"line":1279},[1624],{"type":38,"tag":507,"props":1625,"children":1626},{},[1627],{"type":44,"value":1628},"    final process = await TestProcess.start(\n",{"type":38,"tag":507,"props":1630,"children":1631},{"class":1172,"line":1288},[1632],{"type":38,"tag":507,"props":1633,"children":1634},{},[1635],{"type":44,"value":1636},"      'dart',\n",{"type":38,"tag":507,"props":1638,"children":1639},{"class":1172,"line":1296},[1640],{"type":38,"tag":507,"props":1641,"children":1642},{},[1643],{"type":44,"value":1644},"      ['run', 'bin\u002Fcli.dart', 'process', '--path', '${d.sandbox}\u002Fproject']\n",{"type":38,"tag":507,"props":1646,"children":1647},{"class":1172,"line":1304},[1648],{"type":38,"tag":507,"props":1649,"children":1650},{},[1651],{"type":44,"value":1652},"    );\n",{"type":38,"tag":507,"props":1654,"children":1655},{"class":1172,"line":1313},[1656],{"type":38,"tag":507,"props":1657,"children":1658},{"emptyLinePlaceholder":884},[1659],{"type":44,"value":1206},{"type":38,"tag":507,"props":1661,"children":1662},{"class":1172,"line":1322},[1663],{"type":38,"tag":507,"props":1664,"children":1665},{},[1666],{"type":44,"value":1667},"    \u002F\u002F 3. Validate stdout stream\n",{"type":38,"tag":507,"props":1669,"children":1670},{"class":1172,"line":1331},[1671],{"type":38,"tag":507,"props":1672,"children":1673},{},[1674],{"type":44,"value":1675},"    await expectLater(process.stdout, emitsThrough('Processing complete.'));\n",{"type":38,"tag":507,"props":1677,"children":1678},{"class":1172,"line":1339},[1679],{"type":38,"tag":507,"props":1680,"children":1681},{"emptyLinePlaceholder":884},[1682],{"type":44,"value":1206},{"type":38,"tag":507,"props":1684,"children":1685},{"class":1172,"line":1348},[1686],{"type":38,"tag":507,"props":1687,"children":1688},{},[1689],{"type":44,"value":1690},"    \u002F\u002F 4. Validate exit code\n",{"type":38,"tag":507,"props":1692,"children":1693},{"class":1172,"line":1356},[1694],{"type":38,"tag":507,"props":1695,"children":1696},{},[1697],{"type":44,"value":1698},"    await process.shouldExit(0);\n",{"type":38,"tag":507,"props":1700,"children":1701},{"class":1172,"line":1365},[1702],{"type":38,"tag":507,"props":1703,"children":1704},{"emptyLinePlaceholder":884},[1705],{"type":44,"value":1206},{"type":38,"tag":507,"props":1707,"children":1708},{"class":1172,"line":1374},[1709],{"type":38,"tag":507,"props":1710,"children":1711},{},[1712],{"type":44,"value":1713},"    \u002F\u002F 5. Validate filesystem mutations\n",{"type":38,"tag":507,"props":1715,"children":1716},{"class":1172,"line":1383},[1717],{"type":38,"tag":507,"props":1718,"children":1719},{},[1720],{"type":44,"value":1589},{"type":38,"tag":507,"props":1722,"children":1723},{"class":1172,"line":1392},[1724],{"type":38,"tag":507,"props":1725,"children":1726},{},[1727],{"type":44,"value":1728},"      d.file('config.json', '{\"key\": \"value\"}'),\n",{"type":38,"tag":507,"props":1730,"children":1731},{"class":1172,"line":1400},[1732],{"type":38,"tag":507,"props":1733,"children":1734},{},[1735],{"type":44,"value":1736},"      d.file('output.log', 'Success')\n",{"type":38,"tag":507,"props":1738,"children":1739},{"class":1172,"line":1409},[1740],{"type":38,"tag":507,"props":1741,"children":1742},{},[1743],{"type":44,"value":1744},"    ]).validate();\n",{"type":38,"tag":507,"props":1746,"children":1747},{"class":1172,"line":1418},[1748],{"type":38,"tag":507,"props":1749,"children":1750},{},[1751],{"type":44,"value":1505},{"type":38,"tag":507,"props":1753,"children":1754},{"class":1172,"line":1427},[1755],{"type":38,"tag":507,"props":1756,"children":1757},{},[1758],{"type":44,"value":1345},{"type":38,"tag":1760,"props":1761,"children":1762},"style",{},[1763],{"type":44,"value":1764},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1766,"total":1400},[1767,1778,1783,1795,1806,1815,1827,1839,1851,1863,1877,1887],{"slug":1768,"name":1768,"fn":1769,"description":1770,"org":1771,"tags":1772,"stars":19,"repoUrl":20,"updatedAt":1777},"dart-add-unit-test","write unit tests for Dart code","Write and organize unit tests for functions, methods, and classes using `package:test`. Use when creating new logic or fixing bugs to ensure code remains correct and regression-free.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1773,1774],{"name":17,"slug":18,"type":15},{"name":1775,"slug":1776,"type":15},"Testing","testing","2026-07-15T05:22:40.104823",{"slug":4,"name":4,"fn":5,"description":6,"org":1779,"tags":1780,"stars":19,"repoUrl":20,"updatedAt":21},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1781,1782],{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"slug":1784,"name":1784,"fn":1785,"description":1786,"org":1787,"tags":1788,"stars":19,"repoUrl":20,"updatedAt":1794},"dart-collect-coverage","collect Dart test coverage reports","Collect coverage using the coverage packge and create an LCOV report",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1789,1790,1793],{"name":17,"slug":18,"type":15},{"name":1791,"slug":1792,"type":15},"Reporting","reporting",{"name":1775,"slug":1776,"type":15},"2026-07-15T05:22:21.38636",{"slug":1796,"name":1796,"fn":1797,"description":1798,"org":1799,"tags":1800,"stars":19,"repoUrl":20,"updatedAt":1805},"dart-fix-runtime-errors","debug and fix Dart runtime errors","Uses get_runtime_errors and lsp to fetch an active stack trace, locate the failing line, apply a fix, and verify resolution via hot_reload.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1801,1802],{"name":17,"slug":18,"type":15},{"name":1803,"slug":1804,"type":15},"Debugging","debugging","2026-07-15T05:22:22.622501",{"slug":1807,"name":1807,"fn":1808,"description":1809,"org":1810,"tags":1811,"stars":19,"repoUrl":20,"updatedAt":1814},"dart-generate-test-mocks","generate mock objects for Dart tests","Define and generate mock objects for external dependencies using `package:mockito` and `build_runner`. Use when unit testing classes that depend on complex external services like APIs or databases.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1812,1813],{"name":17,"slug":18,"type":15},{"name":1775,"slug":1776,"type":15},"2026-07-15T05:22:42.607449",{"slug":1816,"name":1816,"fn":1817,"description":1818,"org":1819,"tags":1820,"stars":19,"repoUrl":20,"updatedAt":1826},"dart-migrate-to-checks-package","migrate test matchers to checks package","Replace the usage of `expect` and similar functions from `package:matcher`\nto `package:checks` equivalents.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1821,1822,1825],{"name":17,"slug":18,"type":15},{"name":1823,"slug":1824,"type":15},"Migration","migration",{"name":1775,"slug":1776,"type":15},"2026-07-15T05:22:31.276564",{"slug":1828,"name":1828,"fn":1829,"description":1830,"org":1831,"tags":1832,"stars":19,"repoUrl":20,"updatedAt":1838},"dart-resolve-package-conflicts","resolve Dart package version conflicts","Workflow for fixing package version conflicts. Use this when `pub get` fails due to incompatible package versions.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1833,1834,1835],{"name":17,"slug":18,"type":15},{"name":1803,"slug":1804,"type":15},{"name":1836,"slug":1837,"type":15},"Engineering","engineering","2026-07-15T05:22:30.059335",{"slug":1840,"name":1840,"fn":1841,"description":1842,"org":1843,"tags":1844,"stars":19,"repoUrl":20,"updatedAt":1850},"dart-run-static-analysis","run static analysis and apply fixes","Execute `dart analyze` to identify warnings and errors, and use `dart fix --apply` to automatically resolve mechanical lint issues. Use during development to ensure code quality and before committing changes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1845,1848,1849],{"name":1846,"slug":1847,"type":15},"Code Analysis","code-analysis",{"name":17,"slug":18,"type":15},{"name":1803,"slug":1804,"type":15},"2026-07-15T05:22:23.861119",{"slug":1852,"name":1852,"fn":1853,"description":1854,"org":1855,"tags":1856,"stars":19,"repoUrl":20,"updatedAt":1862},"dart-setup-ffi-assets","package C\u002FC++ assets for Dart","Guides agents in compiling and packaging C\u002FC++ source code into dynamic or static libraries (Code Assets) using Dart's Native Assets hook system (via hook\u002Fbuild.dart and hook\u002Flink.dart utilizing package:hooks and package:native_toolchain_c). Use when a user asks to: 'setup native assets', 'compile C\u002FC++ source code', 'bundle dynamic libraries', 'build native C code', 'link native assets', 'implement build.dart or link.dart hooks', or 'integrate C\u002FC++ interop in Dart\u002FFlutter'. Helps agents avoid manual toolchain orchestration and configures secure hash-validated binary downloads or advanced linker tree-shaking with package:record_use mapping.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1857,1858,1861],{"name":17,"slug":18,"type":15},{"name":1859,"slug":1860,"type":15},"Deployment","deployment",{"name":1836,"slug":1837,"type":15},"2026-07-15T05:22:20.138636",{"slug":1864,"name":1864,"fn":1865,"description":1866,"org":1867,"tags":1868,"stars":19,"repoUrl":20,"updatedAt":1876},"dart-skills-lint-setup","configure dart_skills_lint for Dart projects","Use this skill when you need to set up validation for AI agent skills in a Dart project for the first time.\nAdds the linter as a dev_dependency, creates a configuration file, and generates a baseline for legacy repos.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1869,1870,1873],{"name":17,"slug":18,"type":15},{"name":1871,"slug":1872,"type":15},"Plugin Development","plugin-development",{"name":1874,"slug":1875,"type":15},"QA","qa","2026-07-15T05:22:47.488998",{"slug":1878,"name":1878,"fn":1879,"description":1880,"org":1881,"tags":1882,"stars":19,"repoUrl":20,"updatedAt":1886},"dart-skills-lint-validation","validate agent skills with dart_skills_lint","Use this skill when you need to validate AI agent skills with dart_skills_lint — running the linter, interpreting failures, fixing violations, and authoring custom rules.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1883,1884,1885],{"name":17,"slug":18,"type":15},{"name":1871,"slug":1872,"type":15},{"name":1874,"slug":1875,"type":15},"2026-07-21T05:38:34.451024",{"slug":1888,"name":1888,"fn":1889,"description":1890,"org":1891,"tags":1892,"stars":19,"repoUrl":20,"updatedAt":1895},"dart-use-ffigen","generate FFI bindings with ffigen","Guide agents to use `package:ffigen` to automatically generate FFI bindings instead of writing them manually. Use this skill when a task involves writing new FFI bindings, extending C\u002FObjective-C\u002FSwift integrations, or replacing hand-crafted `dart:ffi` setups.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1893,1894],{"name":17,"slug":18,"type":15},{"name":1836,"slug":1837,"type":15},"2026-07-15T05:22:17.592351",{"items":1897,"total":1374},[1898,1903,1908,1914,1919,1924,1930],{"slug":1768,"name":1768,"fn":1769,"description":1770,"org":1899,"tags":1900,"stars":19,"repoUrl":20,"updatedAt":1777},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1901,1902],{"name":17,"slug":18,"type":15},{"name":1775,"slug":1776,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":1904,"tags":1905,"stars":19,"repoUrl":20,"updatedAt":21},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1906,1907],{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"slug":1784,"name":1784,"fn":1785,"description":1786,"org":1909,"tags":1910,"stars":19,"repoUrl":20,"updatedAt":1794},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1911,1912,1913],{"name":17,"slug":18,"type":15},{"name":1791,"slug":1792,"type":15},{"name":1775,"slug":1776,"type":15},{"slug":1796,"name":1796,"fn":1797,"description":1798,"org":1915,"tags":1916,"stars":19,"repoUrl":20,"updatedAt":1805},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1917,1918],{"name":17,"slug":18,"type":15},{"name":1803,"slug":1804,"type":15},{"slug":1807,"name":1807,"fn":1808,"description":1809,"org":1920,"tags":1921,"stars":19,"repoUrl":20,"updatedAt":1814},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1922,1923],{"name":17,"slug":18,"type":15},{"name":1775,"slug":1776,"type":15},{"slug":1816,"name":1816,"fn":1817,"description":1818,"org":1925,"tags":1926,"stars":19,"repoUrl":20,"updatedAt":1826},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1927,1928,1929],{"name":17,"slug":18,"type":15},{"name":1823,"slug":1824,"type":15},{"name":1775,"slug":1776,"type":15},{"slug":1828,"name":1828,"fn":1829,"description":1830,"org":1931,"tags":1932,"stars":19,"repoUrl":20,"updatedAt":1838},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1933,1934,1935],{"name":17,"slug":18,"type":15},{"name":1803,"slug":1804,"type":15},{"name":1836,"slug":1837,"type":15}]