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
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,10 @@ class MetricCard extends StatelessWidget {

### Ack-Generated Args Wrappers

Ack can also generate typed extension wrappers over a validated `Map<String, Object?>`. This helps when you want typed getters without maintaining a manual args class. It does not change SuperDeck's widget factory contract; the factory still receives `Map<String, Object?> args`.
Ack can also generate immutable typed models from a top-level schema. This
avoids maintaining a manual args class while preserving SuperDeck's widget
factory contract: the factory still receives `Map<String, Object?> args` and
the generated model validates it at the boundary.

Use this pattern only when the target app already has Ack codegen configured, or when you are intentionally adding it:

Expand All @@ -191,20 +194,21 @@ import 'package:ack_annotations/ack_annotations.dart';
import 'package:flutter/widgets.dart';
import 'package:superdeck/superdeck.dart';

part 'metric_card.g.dart';
part 'metric_card.ack.dart';
part 'metric_card.ack.g.dart';

@AckType(name: 'MetricCardArgs')
@AckInfer()
final metricCardArgsSchema = Ack.object({
'label': Ack.string().notEmpty(),
'value': Ack.string().notEmpty(),
'trend': Ack.string().optional(),
});

class MetricCard extends StatelessWidget {
final MetricCardArgsType data;
final MetricCardArgs data;

MetricCard(Map<String, Object?> args, {super.key})
: data = MetricCardArgsType.parse(args);
: data = MetricCardArgs.parse(args);

@override
Widget build(BuildContext context) {
Expand All @@ -221,8 +225,13 @@ dart run build_runner build --delete-conflicting-outputs

Ack generation constraints that matter for SuperDeck widgets:

- Annotate top-level schema variables or getters with `@AckType()`.
- Generated extension types implement `Map<String, Object?>` and expose `parse`, `safeParse`, and typed getters.
- Annotate top-level schema variables or getters with `@AckInfer()` and include
both generated part files.
- Let Ack derive the model name when the schema declaration already expresses
it (`metricCardArgsSchema` generates `MetricCardArgs`). Use `name:` only when
the desired public type cannot be derived from the declaration.
- Generated immutable models expose `parse`, `safeParse`, `fromJson`, `toJson`,
and typed fields.
- Nested object fields should reference named top-level schemas when you need typed nested getters.
- Do not expect `Ack.any()`/`Ack.anyOf()` or inline anonymous object branches to generate useful typed wrappers.
- Keep `align`, `flex`, `margin`, `padding`, `scrollable`, and `name` out of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,10 @@ Widget does not render:
- Check that widget arguments do not collide with reserved block keys: `name`, `align`, `flex`, `margin`, `padding`, `scrollable`.
- Remember that reserved block keys are consumed by SuperDeck and are not passed to custom widget args.
- If using shorthand, verify the directive name exactly matches the registered widget name.
- If using Ack-generated args wrappers, confirm the schema is a top-level `@AckType()` declaration, the `part` file is present, generator dependencies are installed, and `build_runner` has regenerated the `.g.dart` file.
- If using Ack-generated args models, confirm the schema is a top-level
`@AckInfer()` declaration, both `.ack.dart` and `.ack.g.dart` part directives
are present, generator dependencies are installed, and `build_runner` has
regenerated both files.
- Let the on-slide error guide factory parse/build failures.

DartPad fails:
Expand Down
9 changes: 4 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fvm dart run melos run clean # Clean all Flutter build artifacts
8. `build` method (last)

### Generated Files
- Files matching `*.g.dart`, `*.mapper.dart` are auto-generated
- Files matching `*.g.dart` and `*.ack.dart` are auto-generated
- Regenerate with `melos run build_runner:build` before testing
- Commit generated files when they change and keep them synchronized with source updates

Expand Down Expand Up @@ -170,10 +170,9 @@ lib/src/

## Key Dependencies

- **dart_mappable**: Model serialization and discriminated unions
- **mix/remix**: UI styling framework used throughout
- **signals/signals_flutter**: Reactive state management
- **ack**: Schema validation for YAML configuration
- **ack**: Schema validation plus generated JSON models and discriminated unions
- **markdown**: Markdown parsing
- **go_router**: Navigation/routing

Expand All @@ -187,8 +186,8 @@ The project uses Signals for reactive state management. `DeckController` is the
Use the current stable Gemini model split for the Playground deck-generation
pipeline:

- `gemini-3.5-flash` for the single global outline/planning request
- `gemini-3.1-flash-lite` for concurrent narrative-section composition and
- `gemini-3.7-flash` for the single global outline/planning request
- `gemini-3.5-flash-lite` for concurrent narrative-section composition and
targeted outline/slide repair

Keep model thinking at the lowest supported setting for this latency-sensitive
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ SuperDeck is a monorepo; each package keeps its own changelog:
- [`superdeck_core`](packages/core/CHANGELOG.md) — parsing, models, and schema validation
- [`superdeck_cli`](packages/cli/CHANGELOG.md) — the `superdeck` command-line tool
- [`superdeck_builder`](packages/builder/CHANGELOG.md) — build_runner integration
- [`superdeck_pdf`](packages/plugins/pdf/CHANGELOG.md) — PDF export support
5 changes: 2 additions & 3 deletions demo/.superdeck/build_status.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"status": "success",
"timestamp": "2026-07-12T23:35:50.974090Z",
"slideCount": 34,
"error": null
"timestamp": "2026-08-25T18:24:50.927825Z",
"slideCount": 34
}
Loading
Loading