Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Conventions for AI coding agents (Claude Code, Cursor, Codex, etc.) and human co

* `bin/shutter.dart` — minimal CLI entrypoint; defers to `lib/src/entry_point.dart`.
* `lib/shutter.dart` — the public library: `shot`, `diff`, `doctor`, and `prune` as functions, for Dart tools that shoot without starting a process. Everything else under `lib/src/` is private to the package.
* `lib/src/api/` — the library's functions and types (`shot.dart`, `diff.dart`, `doctor.dart`, `prune.dart`); `shoot.dart`, the run that `shutter shot` and `shot` share: it checks the arguments, which `shutter shot` builds from its options, and shoots; and `compare.dart`, the comparison `shutter diff` and `diff` share.
* `lib/src/api/` — the library's functions and types (`shot.dart`, `diff.dart`, `doctor.dart`, `prune.dart`); `shoot.dart`, the run that `shutter shot` and `shot` share: it checks the arguments, which `shutter shot` builds from its options, and shoots; `locale_codes.dart`, the language tag of `--locale`, read as `dart:ui`'s `Locale` reads it; and `compare.dart`, the comparison `shutter diff` and `diff` share.
* `lib/src/entry_point.dart` — `runApp` (guarded zone) and `runShutter` (exception → sysexits mapping). Tests drive `runShutter` with a `ShutterContext`.
* `lib/src/shutter_exception.dart` — expected failures with their sysexits code; `lib/src/version.dart` — `packageVersion`, generated from `pubspec.yaml` by `build_version` (`dart run build_runner build`); `lib/src/dart_literal.dart` — Dart string literals for generated code.
* `lib/src/cli/` — `CommandRunner` plus one file per subcommand. `context.dart` defines `ShutterContext`, which carries the working directory, clock, environment, and engine factory so commands run in tests without Flutter. `shot_options.dart` parses `shot`'s arguments; `shot_command.dart` is `semantics` too. `agent_text.dart` and `manual_text.dart` are const mirrors of `doc/agent.md` and `doc/manual.md`; `test/cli/text_parity_test.dart` enforces byte equality.
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The device a shot is drawn as.
* `shutter shot --pixel-ratio <ratio>` (and `semantics`, and `shot(pixelRatio:)`) draws every preview at that device pixel ratio instead of 2: the PNG is the shot's logical size times the ratio, and what reads the ratio, such as `MediaQuery.devicePixelRatioOf` and an `AssetImage` picking its variant, follows it as on the device. `shot` prints it, `manifest.json` records it, `diff` prints both runs' when they differ and returns it as `ShotSetup.pixelRatio`. It is not part of shot ids.
* `shutter shot --safe-area <top>,<bottom>` (and `semantics`, and `shot(safeArea: SafeAreaInsets(...))`) lays every preview out with those safe area insets in logical pixels, which `flutter test` reports as none: the view reports them as its padding and view padding, so an `AppBar` grows by the top inset and a `SafeArea` keeps out of them as on the device; with `--keyboard`, the keyboard absorbs the bottom inset from the padding. The status bar and home indicator are not drawn. `shot` prints the insets, `manifest.json` records them, `diff` prints both runs' when they differ and returns them as `ShotSetup.safeArea`. They are not part of shot ids.
* `shutter shot --brightness dark` and `--text-scale <scale>` (and `semantics`, and `shot(brightness:, textScale:)`) report that platform brightness and text scale, as a device's settings, to every preview that sets none of its own; a preview's `brightness` or `textScaleFactor` wins. A `--widget` shot, which has no `Preview` to set them, is shot dark or with larger text this way. `shot` prints them, `manifest.json` records them, `diff` prints both runs' when they differ and returns them as `ShotSetup.brightness` and `ShotSetup.textScale`. They are not part of shot ids.
* `shutter shot --locale <tag>` (and `semantics`, and `shot(locale:)`) reports that locale as the device's instead of en-US: a language, then an optional script and region, such as `ja-JP` or `zh-Hant-TW`. The shell's app widget resolves its locale from it against its `supportedLocales`, and so do a preview's `localizations` that set no `locale`. `shot` prints it, `manifest.json` records it as a language tag, `diff` prints both runs' when they differ and returns it as `ShotSetup.locale`. It is not part of shot ids.

## 1.3.0

Expand Down
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,19 +156,20 @@ Each is followed by `--settle` milliseconds; shoot again with another `--settle`
`--pixel-ratio 3` draws at the device pixel ratio of the device a screen is laid out for, instead of 2.
`--safe-area 59,34` lays a screen out with that device's safe area insets, top and bottom, which `flutter test` reports as none; the status bar and home indicator are not drawn.
`--brightness dark` and `--text-scale 1.3` report the device's settings to every preview that sets none of its own, and to a `--widget`.
`--locale ja-JP` reports the device's locale, which the app widget resolves its own from, instead of en-US.

## Subcommands

| Command | Purpose |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent` | The step-by-step playbook for AI agents. |
| `manual` | The reference: preview files, drawing model, engine, runs, ids, diff, output, exit codes. |
| `doctor` | Check the Flutter SDK version, its font cache, and the project's shell (`--shell`). |
| `init` | Write `<preview dir>/shell.dart`, or the `--shell` file. |
| `shot` | Render the named preview files, or one `--widget`, into a new run (`--widget`/`--import`/`--size`, `--settle`, `--shell`, `--tap`/`--enter`/`--press`/`--hover`/`--focus`, `--capture`/`--viewport`, `--keyboard`/`--keyboard-tint`, `--network-image`, `--platform`, `--pixel-ratio`, `--safe-area`, `--brightness`/`--text-scale`). |
| `semantics` | Draw the semantics tree of the same subjects into a new run, with the options of `shot` except `--keyboard-tint`. |
| `diff <a> <b>` | Compare two runs (`--images`, `--composite`). |
| `prune` | Delete every run but the newest `--keep <n>`. |
| Command | Purpose |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent` | The step-by-step playbook for AI agents. |
| `manual` | The reference: preview files, drawing model, engine, runs, ids, diff, output, exit codes. |
| `doctor` | Check the Flutter SDK version, its font cache, and the project's shell (`--shell`). |
| `init` | Write `<preview dir>/shell.dart`, or the `--shell` file. |
| `shot` | Render the named preview files, or one `--widget`, into a new run (`--widget`/`--import`/`--size`, `--settle`, `--shell`, `--tap`/`--enter`/`--press`/`--hover`/`--focus`, `--capture`/`--viewport`, `--keyboard`/`--keyboard-tint`, `--network-image`, `--platform`, `--pixel-ratio`, `--safe-area`, `--brightness`/`--text-scale`, `--locale`). |
| `semantics` | Draw the semantics tree of the same subjects into a new run, with the options of `shot` except `--keyboard-tint`. |
| `diff <a> <b>` | Compare two runs (`--images`, `--composite`). |
| `prune` | Delete every run but the newest `--keep <n>`. |

## Exit codes

Expand Down
1 change: 1 addition & 0 deletions doc/agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Widget settingsSignedOut() => const SettingsPage(user: null);
* Shots are drawn at a device pixel ratio of 2. For the device a screen is laid out for, pass its ratio to the before and after shots alike, `--pixel-ratio 3` for an iPhone: an `AssetImage` then picks that ratio's variant. The PNG is the shot's `size` times the ratio; when you post it, show it at `size`'s width. `diff` prints `pixel_ratio:` when the two runs differ in it.
* Shots are laid out without a safe area, as no phone is. For a screen, pass the device's insets, top and bottom in logical pixels, to the before and after shots alike, `--safe-area 59,34` for example (the device's `MediaQuery.viewPaddingOf(context)`): the `AppBar` then grows under the status bar and a `SafeArea` keeps out of the insets as on the device. The status bar and the home indicator are not drawn; say so when you post the image.
* For a change to a dark theme or to how text grows, shoot with `--brightness dark` or `--text-scale 1.3` as well, the same in the before and after runs. They reach every preview that sets no `brightness` or `textScaleFactor` of its own, and they are the only way to shoot a `--widget` dark or with larger text. A dark shot needs a shell that sets the app's `darkTheme`. The scale multiplies every font size, as iOS does; Android 14 and later scale their own way, so say so when you post an Android shot at a scale other than 1. `diff` prints `brightness:` and `text_scale:` when the two runs differ in them.
* Shots report en-US as the device's locale. For an app used in another language, pass `--locale ja-JP` (a language, then an optional script and region) to the before and after shots alike: the shell's app widget then resolves its locale from it, as on a device set to that language, if the shell sets the app's `supportedLocales` and `localizationsDelegates`. `diff` prints `locale:` when the two runs differ in it.

## Shell

Expand Down
Loading
Loading