# install
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/fsa`, then injects `fluttersdk_artisan` into `pubspec.yaml` so every future `plugin:install` and `make:command` invocation resolves cleanly.
---
## Table of contents
- [Basic Usage](#basic-usage)
- [Synopsis](#synopsis)
- [What It Writes](#what-it-writes)
- [Pubspec Injection](#pubspec-injection)
- [Idempotency](#idempotency)
- [Fast-CLI Auto-Chain](#fast-cli-auto-chain)
- [Examples](#examples)
- [Related](#related)
---
## Basic Usage
```bash
dart run fluttersdk_artisan 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 artisan
```
or, after the fast-CLI build finishes:
```bash
./bin/fsa
```
---
## Synopsis
Full signature as declared in `lib/src/commands/install_command.dart`:
```
install
{--force : Overwrite files even when they already exist}
```
| Flag | Effect |
|---|---|
| `--force` | Overwrite `bin/dispatcher.dart`, the two generated barrels, and `bin/fsa` 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 artisan 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:/app/commands/_index.g.dart as consumer_commands`
- imports `package:/app/_plugins.g.dart as plugins`
- defines `_ConsumerCommandsProvider extends ArtisanServiceProvider` registering the consumer barrel
- `main(List args)` calls `runArtisan(args, baseProviders: [_ConsumerCommandsProvider(), ...plugins.autoDiscoveredProviders()], delegateToConsumer: false)`
### 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 `.artisan/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/fsa` (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](#fast-cli-auto-chain) for details.
---
## Pubspec Injection
`install` injects a `fluttersdk_artisan` dependency into `pubspec.yaml` after writing the four artefacts. Two injection modes:
**Path-dep mode (monorepo)**
When `.dart_tool/package_config.json` lists `fluttersdk_artisan` with a *relative* `rootUri` (sibling-package monorepo workflow), `install` resolves the path against the consumer root and writes a `path:` dependency:
```yaml
dependencies:
fluttersdk_artisan:
path: ../fluttersdk_artisan
```
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:
fluttersdk_artisan: 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.1`) once the consumer has chosen a baseline.
The injection is idempotent: if `pubspec.yaml` already contains a `fluttersdk_artisan:` 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 fluttersdk_artisan install --force
```
`--force` is forwarded to the `make:fast-cli` auto-chain as well, so `bin/fsa` 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/fsa`, compiles the AOT binary under `.artisan/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 fluttersdk_artisan ` (the slower fallback). Re-running `install --force` after fixing the underlying issue recompiles `bin/fsa` and the AOT cache.
See [make:fast-cli](make-fast-cli.md) for the full performance profile, cache-hit behavior, and POSIX-only caveat.
---
## Examples
### 1. Fresh install in a new Flutter project
```bash
flutter create my_app
cd my_app
dart run fluttersdk_artisan install
```
Output:
```
write bin/dispatcher.dart
write lib/app/_plugins.g.dart
write lib/app/commands/_index.g.dart
inject pubspec.yaml (fluttersdk_artisan: ^0.0.1)
write bin/fsa (Building artisan CLI, one-time ~8s...)
Done. Run './bin/fsa status' to verify.
```
### 2. Force-overwrite after project rename
```bash
dart run fluttersdk_artisan install --force
```
Regenerates `bin/dispatcher.dart` with the updated project name and recompiles `bin/fsa`.
### 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/fsa` is not written but the rest of the scaffold completes normally. Use `dart run artisan ` as the fallback invocation form on those environments.
### 4. Monorepo path-dep install
In a monorepo where `fluttersdk_artisan` lives at `../fluttersdk_artisan`, run `flutter pub get` once to populate `.dart_tool/package_config.json`, then:
```bash
dart run fluttersdk_artisan install
```
The path-dep form is detected automatically and written to `pubspec.yaml`. No flag needed.
---
## Related
- [make:command](make-command.md): scaffold a single `ArtisanCommand` subclass under `lib/app/commands/` and regenerate `_index.g.dart`.
- [plugin:install](plugin-install.md): register a third-party plugin after `flutter pub add`; requires the `lib/app/_plugins.g.dart` barrel that `install` writes.
- [make:fast-cli](make-fast-cli.md): the sub-command auto-chained by `install`; run it standalone to rebuild `bin/fsa` without touching the scaffold artefacts.
- [Getting Started: Installation](../getting-started/installation.md): step-by-step walkthrough from `dart pub add` to first `./bin/fsa status` for both vanilla Flutter and magic-stack projects.