Skip to content

install

View raw .md

Scaffold the canonical Flutter consumer project structure and install the fast-CLI wrapper in a single step. Running install produces bin/dispatcher.dart, the two generated barrels, and bin/dowel, then injects dowel into pubspec.yaml so every future plugin:install and make:command invocation resolves cleanly.

On this page

Prerequisites#

Add dowel to the project before invoking install. The package needs to resolve from pubspec.yaml so the substrate CLI is discoverable via dart run:

bash
dart pub add dowel

Equivalent manual edit, then dart pub get:

yaml
dependencies:
  dowel: ^0.0.21

install itself re-injects the dep at scaffold time (path-dep when .dart_tool/package_config.json resolves dowel to a relative rootUri, otherwise dowel: any), so the pub-add step is idempotent with the scaffold's own pubspec writes.


Basic Usage#

bash
dart run dowel install

Run once in a new Flutter project root. The command reads the project name from pubspec.yaml, writes the four artefacts listed below, and prints a summary. After this completes, use the consumer wrapper alias:

bash
dart run dowel <cmd>

or, after the fast-CLI build finishes:

bash
./bin/dowel <cmd>

Synopsis#

Full signature as declared in lib/src/commands/install_command.dart:

text
install
  {--force : Overwrite files even when they already exist}
Flag Effect
--force Overwrite bin/dispatcher.dart, the two generated barrels, and bin/dowel even when they are already present. Does not re-inject already-present pubspec entries.

What It Writes#

install produces four artefacts in this order:

1. bin/dispatcher.dart#

A generated CLI entry point that wires the consumer's own commands and plugin providers into the dowel runtime. The file is written from the dispatcher.dart.stub template with {{ name }} substituted to the pubspec.yaml project name. Header comment: GENERATED by 'install' command; DO NOT EDIT. Regenerate via 'make:command' or 'plugins:refresh'.

Structure:

  • imports package:<name>/app/commands/_index.g.dart as consumer_commands
  • imports package:<name>/app/_plugins.g.dart as plugins
  • defines _ConsumerCommandsProvider extends DowelServiceProvider registering the consumer barrel
  • main(List<String> args) calls runDowel(args, baseProviders: [_ConsumerCommandsProvider(), ...plugins.autoDiscoveredProviders()], delegateToConsumer: false, collectMcpTools: args.isNotEmpty && args.first == 'mcp:serve')

The collectMcpTools parameter is conditionally enabled only when the command is mcp:serve, so plugin providers' MCP tools register for the server without overhead on non-MCP CLI invocations.

2. lib/app/_plugins.g.dart#

The plugins codegen barrel. Written as an empty-but-valid barrel on first install. plugin:install and plugins:refresh regenerate this file when plugins are added or removed. Never edit by hand: the source of truth is .dowel/plugins.json.

3. lib/app/commands/_index.g.dart#

The commands codegen barrel. Written as an empty-but-valid barrel on first install. make:command and commands:refresh regenerate this file as new command files appear under lib/app/commands/. Never edit by hand.

4. bin/dowel (via Fast-CLI Auto-Chain)#

A POSIX shell wrapper written by the make:fast-cli sub-command, which install calls in-process at the end of the scaffold phase. See Fast-CLI Auto-Chain for details.


Pubspec Injection#

install injects a dowel dependency into pubspec.yaml after writing the four artefacts. Two injection modes:

Path-dep mode (monorepo)

When .dart_tool/package_config.json lists dowel with a relative rootUri (sibling-package monorepo workflow), install resolves the path against the consumer root and writes a path: dependency:

yaml
dependencies:
  dowel:
    path: ../dowel

A file:// absolute URI or any other absolute rootUri (the shape pub-cache produces) skips this branch and falls through to pub.dev mode.

Pub.dev mode

When no local relative-rootUri entry resolves, install injects the unconstrained version form so the next dart pub get (or flutter pub get) pulls the published package:

yaml
dependencies:
  dowel: any

Run dart pub get (or flutter pub get) after install completes to resolve to a concrete version. Tighten the constraint by hand (e.g. ^0.0.21) once the consumer has chosen a baseline.

The injection is idempotent: if pubspec.yaml already contains a dowel: key under dependencies:, neither form is written again (regardless of --force).


Idempotency#

Re-running install without --force is a no-op when the artefacts already exist. Each file goes through a _shouldWrite(path, force) guard: if the file exists and force is false, the write is skipped and a [skip] line is printed for that artefact. The pubspec injection is always idempotent (key presence check, independent of --force).

Pass --force to overwrite all four artefacts unconditionally. Useful after renaming the project or updating the stub template to a newer version:

bash
dart run dowel install --force

--force is forwarded to the make:fast-cli auto-chain as well, so bin/dowel is rewritten and the AOT binary is recompiled from scratch.


Fast-CLI Auto-Chain#

At the end of scaffoldInto, install calls MakeFastCliCommand.scaffoldInto(root, force, ctx) in-process. This produces bin/dowel, compiles the AOT binary under .dowel/cli-bundle/, and patches .gitignore. The call happens only after all scaffold writes and pubspec injection succeed, so a partial failure in the scaffold phase does not leave a compiled binary that references a missing dispatcher.

The fast-CLI step is not separately gated: if dart build cli fails (e.g. the Dart SDK is too old to support it, the toolchain is missing, or the build itself errors), make:fast-cli returns a non-zero exit code and install propagates that failure. The scaffold artefacts written before the failure remain on disk so the project is still usable via dart run dowel <cmd> (the slower fallback). Re-running install --force after fixing the underlying issue recompiles bin/dowel and the AOT cache.

See make:fast-cli for the full performance profile, cache-hit behaviour, and POSIX-only caveat.


Examples#

1. Fresh install in a new Flutter project#

bash
flutter create my_app
cd my_app
dart pub add dowel
dart run dowel install

Output:

text
  write   bin/dispatcher.dart
  write   lib/app/_plugins.g.dart
  write   lib/app/commands/_index.g.dart
  inject  pubspec.yaml (dowel: any)
  write   bin/dowel (Building dowel CLI, one-time ~8s...)
Done. Run './bin/dowel status' to verify.

2. Force-overwrite after project rename#

bash
dart run dowel install --force

Regenerates bin/dispatcher.dart with the updated project name and recompiles bin/dowel.

3. Native-asset hooks note#

install uses dart build cli (via the make:fast-cli auto-chain) to compile bin/dispatcher.dart into an AOT binary. This requires Dart 3.5 or later because transitive dependencies may declare hook/build.dart build hooks. On earlier SDKs, bin/dowel is not written but the rest of the scaffold completes normally. Use dart run dowel <cmd> as the fallback invocation form on those environments.

4. Monorepo path-dep install#

In a monorepo where dowel lives at ../dowel, run flutter pub get once to populate .dart_tool/package_config.json, then:

bash
dart run dowel install

The path-dep form is detected automatically and written to pubspec.yaml. No flag needed.


  • make:command: scaffold a single DowelCommand subclass under lib/app/commands/ and regenerate _index.g.dart.
  • plugin:install: register a third-party plugin after flutter pub add; requires the lib/app/_plugins.g.dart barrel that install writes.
  • make:fast-cli: the sub-command auto-chained by install; run it standalone to rebuild bin/dowel without touching the scaffold artefacts.
  • Getting Started: Installation: step-by-step walkthrough from dart pub add to first ./bin/dowel status for both vanilla Flutter and magic-stack projects.
esc

Search index did not load.

No match for "".

Try a class like rounded-lg or a widget like WButton.