From d5cc499a2e205d35db360f5119d019fa30187593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Baudet?= Date: Fri, 23 Oct 2026 21:12:01 -0600 Subject: [PATCH 1/3] feat(03): add the human-in-the-loop step, the agent asks you A generic askUser tool registered with CopilotHumanInTheLoop: the agent asks a question with two to four options, its run waits, and the option the person taps goes back as the tool result. The card is an AppDecisionCard in the chat. The tone check uses it: asked for a calaverita without a tone, the agent asks how to roast and then sets the tone in the shared state. While a question waits nothing shows as working and the message box points to the card. The runtime prompt says when to ask. setup.mjs and the README point step 03 here. Built on the branch of PR 1, which it needs for the password header, so it should merge after it. 03-custom-server is left as it is for now. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_015qwFeXxEAoB3sM6cdC3K4W --- .../apps/calaverita_app/analysis_options.yaml | 17 + .../apps/calaverita_app/lib/app/app.dart | 50 ++ .../calaverita_app/lib/app/app_config.dart | 56 ++ .../apps/calaverita_app/lib/main.dart | 8 + .../apps/calaverita_app/pubspec.yaml | 26 + .../apps/calaverita_app/test/app_test.dart | 43 ++ .../apps/calaverita_app/web/favicon.png | Bin 0 -> 917 bytes .../calaverita_app/web/icons/Icon-192.png | Bin 0 -> 5292 bytes .../calaverita_app/web/icons/Icon-512.png | Bin 0 -> 8252 bytes .../web/icons/Icon-maskable-192.png | Bin 0 -> 5594 bytes .../web/icons/Icon-maskable-512.png | Bin 0 -> 20998 bytes .../apps/calaverita_app/web/index.html | 46 ++ .../apps/calaverita_app/web/manifest.json | 35 + .../analysis_options.yaml | 17 + .../lib/assistant_presentation.dart | 1 + .../lib/chat/ask_user/ask_user_args.dart | 56 ++ .../lib/chat/ask_user/ask_user_card.dart | 48 ++ .../lib/chat/ask_user/ask_user_tool.dart | 54 ++ .../lib/chat/chat_module.dart | 43 ++ .../lib/chat/views/activity_line.dart | 28 + .../lib/chat/views/chat_panel.dart | 188 +++++ .../assistant_presentation/pubspec.yaml | 23 + .../chat/ask_user/ask_user_args_test.dart | 50 ++ .../chat/ask_user/ask_user_card_test.dart | 98 +++ .../chat/ask_user/ask_user_tool_test.dart | 51 ++ .../test/chat/chat_module_test.dart | 46 ++ .../calaverita_data/analysis_options.yaml | 17 + .../calaverita_data/lib/calaverita_data.dart | 1 + .../template_calaveritas_repository.dart | 41 ++ .../lib/templates/calaverita_templates.dart | 78 ++ .../calaverita/calaverita_data/pubspec.yaml | 15 + .../template_calaveritas_repository_test.dart | 45 ++ .../calaverita_domain/analysis_options.yaml | 17 + .../lib/calaverita_domain.dart | 6 + .../lib/models/calaverita.dart | 50 ++ .../lib/models/calaverita_draft.dart | 60 ++ .../lib/models/skull_part.dart | 18 + .../lib/models/skull_style.dart | 84 +++ .../calaverita_domain/lib/models/tone.dart | 11 + .../i_calaveritas_repository.dart | 10 + .../calaverita/calaverita_domain/pubspec.yaml | 15 + .../test/models/calaverita_draft_test.dart | 50 ++ .../test/models/calaverita_test.dart | 36 + .../test/models/skull_style_test.dart | 45 ++ .../analysis_options.yaml | 17 + .../assets/skull/base/round.svg | 4 + .../assets/skull/eyes/marigold.svg | 4 + .../assets/skull/flowers/crown.svg | 3 + .../assets/skull/flowers/side.svg | 3 + .../assets/skull/flowers/trio.svg | 3 + .../assets/skull/glasses/cateye.svg | 3 + .../assets/skull/glasses/heart.svg | 3 + .../assets/skull/glasses/round.svg | 3 + .../assets/skull/glasses/square.svg | 3 + .../assets/skull/hat/crown.svg | 3 + .../assets/skull/hat/party.svg | 3 + .../assets/skull/hat/sombrero.svg | 3 + .../assets/skull/hat/tophat.svg | 3 + .../assets/skull/mouth/stitched.svg | 3 + .../assets/skull/mustache/handlebar.svg | 3 + .../assets/skull/mustache/pencil.svg | 3 + .../assets/skull/mustache/walrus.svg | 3 + .../assets/skull/nose/heart.svg | 3 + .../assets/skull/pattern/swirls.svg | 3 + .../lib/calaverita/bloc/calaverita_cubit.dart | 40 + .../lib/calaverita/bloc/calaverita_state.dart | 28 + .../lib/calaverita/calaverita_module.dart | 44 ++ .../calaverita/shared_draft/draft_edits.dart | 54 ++ .../calaverita/shared_draft/shared_draft.dart | 29 + .../show_calaverita/show_calaverita_args.dart | 19 + .../show_calaverita/show_calaverita_card.dart | 58 ++ .../show_calaverita_handler.dart | 42 ++ .../show_calaverita/show_calaverita_tool.dart | 67 ++ .../lib/calaverita/skull/skull_art.dart | 170 +++++ .../lib/calaverita/views/calaverita_card.dart | 64 ++ .../lib/calaverita/views/calaverita_page.dart | 252 +++++++ .../lib/calaverita/views/details_panel.dart | 97 +++ .../lib/calaverita/views/skull_controls.dart | 215 ++++++ .../lib/calaverita/views/skull_view.dart | 52 ++ .../lib/calaverita/views/stage.dart | 51 ++ .../calaverita/views/synced_text_field.dart | 52 ++ .../lib/calaverita_presentation.dart | 7 + .../calaverita_presentation/pubspec.yaml | 40 + .../bloc/calaverita_cubit_test.dart | 76 ++ .../shared_draft/shared_draft_test.dart | 145 ++++ .../show_calaverita_handler_test.dart | 99 +++ .../show_calaverita_tool_test.dart | 95 +++ .../test/calaverita/skull/skull_art_test.dart | 43 ++ .../views/calaverita_card_test.dart | 72 ++ .../views/calaverita_page_test.dart | 131 ++++ .../calaverita/views/skull_view_test.dart | 46 ++ .../test/helpers/test_skull_art.dart | 27 + 03-human-in-the-loop/pubspec.lock | 696 ++++++++++++++++++ 03-human-in-the-loop/pubspec.yaml | 33 + 03-human-in-the-loop/shared/app_ui/.gitignore | 44 ++ 03-human-in-the-loop/shared/app_ui/LICENSE | 21 + 03-human-in-the-loop/shared/app_ui/README.md | 56 ++ .../shared/app_ui/analysis_options.yaml | 17 + .../assets/fonts/JetBrainsMono-Medium.ttf | Bin 0 -> 270316 bytes .../assets/fonts/JetBrainsMono-Regular.ttf | Bin 0 -> 270224 bytes .../app_ui/assets/fonts/OFL-JetBrainsMono.txt | 93 +++ .../shared/app_ui/assets/fonts/OFL.txt | 93 +++ .../app_ui/assets/fonts/Poppins-Medium.ttf | Bin 0 -> 158576 bytes .../app_ui/assets/fonts/Poppins-Regular.ttf | Bin 0 -> 160316 bytes .../app_ui/assets/fonts/Poppins-SemiBold.ttf | Bin 0 -> 157312 bytes .../app_ui/assets/images/copilotkit-logo.png | Bin 0 -> 32539 bytes .../app_ui/assets/images/unicorn-dark.svg | 4 + .../shared/app_ui/assets/images/unicorn.svg | 8 + .../app_ui/assets/images/vgv-lockup.svg | 20 + .../shared/app_ui/lib/app_ui.dart | 9 + .../app_ui/lib/src/theme/app_palette.dart | 258 +++++++ .../app_ui/lib/src/theme/app_theme.dart | 113 +++ .../shared/app_ui/lib/src/theme/theme.dart | 2 + .../app_ui/lib/src/tokens/app_colors.dart | 94 +++ .../app_ui/lib/src/tokens/app_elevation.dart | 37 + .../app_ui/lib/src/tokens/app_motion.dart | 28 + .../app_ui/lib/src/tokens/app_radii.dart | 46 ++ .../app_ui/lib/src/tokens/app_sizes.dart | 71 ++ .../app_ui/lib/src/tokens/app_spacing.dart | 38 + .../app_ui/lib/src/tokens/app_typography.dart | 157 ++++ .../shared/app_ui/lib/src/tokens/tokens.dart | 7 + .../app_ui/lib/src/widgets/app_brand.dart | 98 +++ .../app_ui/lib/src/widgets/app_button.dart | 253 +++++++ .../app_ui/lib/src/widgets/app_card.dart | 163 ++++ .../app_ui/lib/src/widgets/app_chat.dart | 357 +++++++++ .../app_ui/lib/src/widgets/app_chip.dart | 293 ++++++++ .../app_ui/lib/src/widgets/app_decision.dart | 223 ++++++ .../app_ui/lib/src/widgets/app_dialog.dart | 381 ++++++++++ .../app_ui/lib/src/widgets/app_icons.dart | 250 +++++++ .../app_ui/lib/src/widgets/app_order_row.dart | 209 ++++++ .../app_ui/lib/src/widgets/app_person.dart | 131 ++++ .../app_ui/lib/src/widgets/app_pressable.dart | 64 ++ .../app_ui/lib/src/widgets/app_progress.dart | 81 ++ .../app_ui/lib/src/widgets/app_segmented.dart | 113 +++ .../app_ui/lib/src/widgets/app_skeleton.dart | 76 ++ .../app_ui/lib/src/widgets/app_stat.dart | 204 +++++ .../app_ui/lib/src/widgets/app_toast.dart | 49 ++ .../app_ui/lib/src/widgets/app_tone.dart | 41 ++ .../app_ui/lib/src/widgets/widgets.dart | 17 + .../shared/app_ui/pubspec.yaml | 36 + .../shared/app_ui/test/helpers/helpers.dart | 1 + .../shared/app_ui/test/helpers/pump_app.dart | 25 + .../app_ui/test/src/theme/app_theme_test.dart | 80 ++ .../app_ui/test/src/tokens/tokens_test.dart | 55 ++ .../test/src/widgets/app_button_test.dart | 130 ++++ .../test/src/widgets/app_card_test.dart | 65 ++ .../test/src/widgets/app_chat_test.dart | 126 ++++ .../test/src/widgets/app_chip_test.dart | 94 +++ .../test/src/widgets/app_decision_test.dart | 123 ++++ .../test/src/widgets/app_dialog_test.dart | 145 ++++ .../test/src/widgets/app_misc_test.dart | 96 +++ .../test/src/widgets/app_order_row_test.dart | 124 ++++ .../app_runtime_constructors_test.dart | 41 ++ .../test/src/widgets/app_skeleton_test.dart | 20 + .../test/src/widgets/app_stat_test.dart | 102 +++ README.md | 43 +- runtime/server.ts | 4 + tool/setup.mjs | 10 +- 158 files changed, 10012 insertions(+), 30 deletions(-) create mode 100644 03-human-in-the-loop/apps/calaverita_app/analysis_options.yaml create mode 100644 03-human-in-the-loop/apps/calaverita_app/lib/app/app.dart create mode 100644 03-human-in-the-loop/apps/calaverita_app/lib/app/app_config.dart create mode 100644 03-human-in-the-loop/apps/calaverita_app/lib/main.dart create mode 100644 03-human-in-the-loop/apps/calaverita_app/pubspec.yaml create mode 100644 03-human-in-the-loop/apps/calaverita_app/test/app_test.dart create mode 100644 03-human-in-the-loop/apps/calaverita_app/web/favicon.png create mode 100644 03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-192.png create mode 100644 03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-512.png create mode 100644 03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-maskable-192.png create mode 100644 03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-maskable-512.png create mode 100644 03-human-in-the-loop/apps/calaverita_app/web/index.html create mode 100644 03-human-in-the-loop/apps/calaverita_app/web/manifest.json create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/analysis_options.yaml create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/lib/assistant_presentation.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_args.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_card.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_tool.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/chat_module.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/pubspec.yaml create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_args_test.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_card_test.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_tool_test.dart create mode 100644 03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/chat_module_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_data/analysis_options.yaml create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_data/lib/calaverita_data.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_data/pubspec.yaml create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/analysis_options.yaml create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/lib/calaverita_domain.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/calaverita.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/skull_part.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/skull_style.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/tone.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/pubspec.yaml create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/calaverita_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/skull_style_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/analysis_options.yaml create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/base/round.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/pubspec.yaml create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart create mode 100644 03-human-in-the-loop/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart create mode 100644 03-human-in-the-loop/pubspec.lock create mode 100644 03-human-in-the-loop/pubspec.yaml create mode 100644 03-human-in-the-loop/shared/app_ui/.gitignore create mode 100644 03-human-in-the-loop/shared/app_ui/LICENSE create mode 100644 03-human-in-the-loop/shared/app_ui/README.md create mode 100644 03-human-in-the-loop/shared/app_ui/analysis_options.yaml create mode 100644 03-human-in-the-loop/shared/app_ui/assets/fonts/JetBrainsMono-Medium.ttf create mode 100644 03-human-in-the-loop/shared/app_ui/assets/fonts/JetBrainsMono-Regular.ttf create mode 100644 03-human-in-the-loop/shared/app_ui/assets/fonts/OFL-JetBrainsMono.txt create mode 100644 03-human-in-the-loop/shared/app_ui/assets/fonts/OFL.txt create mode 100644 03-human-in-the-loop/shared/app_ui/assets/fonts/Poppins-Medium.ttf create mode 100644 03-human-in-the-loop/shared/app_ui/assets/fonts/Poppins-Regular.ttf create mode 100644 03-human-in-the-loop/shared/app_ui/assets/fonts/Poppins-SemiBold.ttf create mode 100644 03-human-in-the-loop/shared/app_ui/assets/images/copilotkit-logo.png create mode 100644 03-human-in-the-loop/shared/app_ui/assets/images/unicorn-dark.svg create mode 100644 03-human-in-the-loop/shared/app_ui/assets/images/unicorn.svg create mode 100644 03-human-in-the-loop/shared/app_ui/assets/images/vgv-lockup.svg create mode 100644 03-human-in-the-loop/shared/app_ui/lib/app_ui.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/theme/app_palette.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/theme/app_theme.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/theme/theme.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_colors.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_elevation.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_motion.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_radii.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_sizes.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_spacing.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_typography.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/tokens/tokens.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_brand.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_button.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_card.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_chat.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_chip.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_decision.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_dialog.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_icons.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_order_row.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_person.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_pressable.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_progress.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_segmented.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_skeleton.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_stat.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_toast.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_tone.dart create mode 100644 03-human-in-the-loop/shared/app_ui/lib/src/widgets/widgets.dart create mode 100644 03-human-in-the-loop/shared/app_ui/pubspec.yaml create mode 100644 03-human-in-the-loop/shared/app_ui/test/helpers/helpers.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/helpers/pump_app.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/theme/app_theme_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/tokens/tokens_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_button_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_card_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_chat_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_chip_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_decision_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_dialog_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_misc_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_order_row_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_skeleton_test.dart create mode 100644 03-human-in-the-loop/shared/app_ui/test/src/widgets/app_stat_test.dart diff --git a/03-human-in-the-loop/apps/calaverita_app/analysis_options.yaml b/03-human-in-the-loop/apps/calaverita_app/analysis_options.yaml new file mode 100644 index 0000000..317f632 --- /dev/null +++ b/03-human-in-the-loop/apps/calaverita_app/analysis_options.yaml @@ -0,0 +1,17 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - build/** + - web/** + - android/** + - ios/** + - windows/** + - macos/** + - linux/** +linter: + rules: + # The workshop uses classic constructors; Dart 3.13 offers shorthands. + prefer_initializing_formals: false + unnecessary_type_name_in_constructor: false + # A workshop app doesn't need an API reference. + public_member_api_docs: false diff --git a/03-human-in-the-loop/apps/calaverita_app/lib/app/app.dart b/03-human-in-the-loop/apps/calaverita_app/lib/app/app.dart new file mode 100644 index 0000000..69483e9 --- /dev/null +++ b/03-human-in-the-loop/apps/calaverita_app/lib/app/app.dart @@ -0,0 +1,50 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:assistant_presentation/assistant_presentation.dart'; +import 'package:calaverita_app/app/app_config.dart'; +import 'package:calaverita_data/calaverita_data.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; + +/// Composes the calaverita and assistant features into an app. +class App extends StatelessWidget { + const App({required this.skullArt, super.key}); + + /// The SVGs of the skull, loaded at startup. + final SkullArt skullArt; + + static const _suggestions = [ + 'Ana is a pilot, make it sarcastic', + 'Give the skull a sombrero and teal color', + 'Write a calaverita for Mario, a chef', + ]; + + @override + Widget build(BuildContext context) { + return CopilotKit( + runtimeUrl: AppConfig.runtimeUrl, + headers: AppConfig.headers, + child: MaterialApp( + title: 'Calaverita Generator', + debugShowCheckedModeBanner: false, + theme: AppTheme.light, + // One agent for the whole screen: the details and the stage read + // its shared state, and the chat talks to it. + home: CopilotAgentScope( + agentId: AppConfig.agentId, + child: CalaveritaModule( + calaveritasRepository: const TemplateCalaveritasRepository(), + skullArt: skullArt, + // The tool sits around the chat, so the cards of its calls draw + // there. + trailingPanel: const ShowCalaveritaTool( + child: ChatModule( + agentId: AppConfig.agentId, + suggestions: _suggestions, + ), + ), + ), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/apps/calaverita_app/lib/app/app_config.dart b/03-human-in-the-loop/apps/calaverita_app/lib/app/app_config.dart new file mode 100644 index 0000000..cbe99d5 --- /dev/null +++ b/03-human-in-the-loop/apps/calaverita_app/lib/app/app_config.dart @@ -0,0 +1,56 @@ +import 'dart:math'; + +/// The one place that says where the agent lives. +/// +/// To use the shared hosted backend, change [defaultRuntimeUrl] (or run with +/// `--dart-define=RUNTIME_URL=`). +class AppConfig { + const AppConfig._(); + + /// The Copilot Runtime of the `runtime/` folder of this repository. + static const defaultRuntimeUrl = 'http://localhost:8200/api/copilotkit'; + + /// The Copilot Runtime the app talks to. + static final Uri runtimeUrl = Uri.parse( + const String.fromEnvironment( + 'RUNTIME_URL', + defaultValue: defaultRuntimeUrl, + ), + ); + + /// The agent the app chats with. + /// + /// A runtime can serve several, so a different backend may use another id: + /// run with `--dart-define=AGENT_ID=`. + static const agentId = String.fromEnvironment( + 'AGENT_ID', + defaultValue: 'default', + ); + + /// The password of the shared backend, when it asks for one. + /// + /// Run with `--dart-define=WORKSHOP_CODE=`. A local runtime asks for + /// nothing, so leave it out there. + static const workshopCode = String.fromEnvironment('WORKSHOP_CODE'); + + /// A random id for this run of the app, so a server can tell sessions apart. + static final String sessionId = _randomId(); + + /// The headers sent with every run. + /// + /// Custom names on purpose: a runtime answers the browser's preflight with + /// `Access-Control-Allow-Headers: *`, which covers them but not + /// `Authorization`. A server that does not know them ignores them. + static Future> headers() async => { + 'X-Workshop-Session': sessionId, + if (workshopCode.isNotEmpty) 'X-Workshop-Code': workshopCode, + }; + + static String _randomId() { + final random = Random.secure(); + return List.generate( + 16, + (_) => random.nextInt(256).toRadixString(16).padLeft(2, '0'), + ).join(); + } +} diff --git a/03-human-in-the-loop/apps/calaverita_app/lib/main.dart b/03-human-in-the-loop/apps/calaverita_app/lib/main.dart new file mode 100644 index 0000000..777761e --- /dev/null +++ b/03-human-in-the-loop/apps/calaverita_app/lib/main.dart @@ -0,0 +1,8 @@ +import 'package:calaverita_app/app/app.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:flutter/widgets.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + runApp(App(skullArt: await SkullArt.load())); +} diff --git a/03-human-in-the-loop/apps/calaverita_app/pubspec.yaml b/03-human-in-the-loop/apps/calaverita_app/pubspec.yaml new file mode 100644 index 0000000..6a74b65 --- /dev/null +++ b/03-human-in-the-loop/apps/calaverita_app/pubspec.yaml @@ -0,0 +1,26 @@ +name: calaverita_app +description: Calaverita Generator, a Flutter web app that writes funny rhyming skulls. +version: 0.1.0+1 +publish_to: none +resolution: workspace + +environment: + sdk: ^3.13.0 + flutter: ^3.47.0 + +dependencies: + app_ui: any + assistant_presentation: any + calaverita_data: any + calaverita_presentation: any + copilotkit_flutter: any + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + very_good_analysis: ^11.0.0 + +flutter: + uses-material-design: true diff --git a/03-human-in-the-loop/apps/calaverita_app/test/app_test.dart b/03-human-in-the-loop/apps/calaverita_app/test/app_test.dart new file mode 100644 index 0000000..4eb0783 --- /dev/null +++ b/03-human-in-the-loop/apps/calaverita_app/test/app_test.dart @@ -0,0 +1,43 @@ +import 'package:calaverita_app/app/app.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + Future pumpApp(WidgetTester tester) async { + tester.view + ..devicePixelRatio = 1 + ..physicalSize = const Size(1600, 1000); + addTearDown(tester.view.reset); + await tester.pumpWidget(const App(skullArt: SkullArt.fromTemplates({}))); + await tester.pump(); + } + + testWidgets('shows the details, the stage and the copilot', (tester) async { + await pumpApp(tester); + + expect(find.text('Details'), findsOneWidget); + expect(find.text('Copilot'), findsOneWidget); + expect(find.byKey(const Key('calaverita_name_field')), findsOneWidget); + expect(find.text('Write a calaverita for Mario, a chef'), findsOneWidget); + }); + + testWidgets('writes a calaverita from the details', (tester) async { + await pumpApp(tester); + + await tester.enterText( + find.byKey(const Key('calaverita_name_field')), + 'Ana', + ); + await tester.enterText( + find.byKey(const Key('calaverita_job_field')), + 'Designer', + ); + await tester.pump(); + await tester.tap(find.byKey(const Key('calaverita_generate_button'))); + await tester.pump(const Duration(seconds: 1)); + await tester.pump(); + + expect(find.text('Calaverita for Ana'), findsOneWidget); + }); +} diff --git a/03-human-in-the-loop/apps/calaverita_app/web/favicon.png b/03-human-in-the-loop/apps/calaverita_app/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-192.png b/03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-512.png b/03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 zcmd5=2T+s!lYZ%-(h(2@5fr2dC?F^$C=i-}R6$UX8af(!je;W5yC_|HmujSgN*6?W z3knF*TL1$|?oD*=zPbBVex*RUIKsL<(&Rj9%^UD2IK3W?2j>D?eWQgvS-HLymHo9%~|N2Q{~j za?*X-{b9JRowv_*Mh|;*-kPFn>PI;r<#kFaxFqbn?aq|PduQg=2Q;~Qc}#z)_T%x9 zE|0!a70`58wjREmAH38H1)#gof)U3g9FZ^ zF7&-0^Hy{4XHWLoC*hOG(dg~2g6&?-wqcpf{ z&3=o8vw7lMi22jCG9RQbv8H}`+}9^zSk`nlR8?Z&G2dlDy$4#+WOlg;VHqzuE=fM@ z?OI6HEJH4&tA?FVG}9>jAnq_^tlw8NbjNhfqk2rQr?h(F&WiKy03Sn=-;ZJRh~JrD zbt)zLbnabttEZ>zUiu`N*u4sfQaLE8-WDn@tHp50uD(^r-}UsUUu)`!Rl1PozAc!a z?uj|2QDQ%oV-jxUJmJycySBINSKdX{kDYRS=+`HgR2GO19fg&lZKyBFbbXhQV~v~L za^U944F1_GtuFXtvDdDNDvp<`fqy);>Vw=ncy!NB85Tw{&sT5&Ox%-p%8fTS;OzlRBwErvO+ROe?{%q-Zge=%Up|D4L#>4K@Ke=x%?*^_^P*KD zgXueMiS63!sEw@fNLB-i^F|@Oib+S4bcy{eu&e}Xvb^(mA!=U=Xr3||IpV~3K zQWzEsUeX_qBe6fky#M zzOJm5b+l;~>=sdp%i}}0h zO?B?i*W;Ndn02Y0GUUPxERG`3Bjtj!NroLoYtyVdLtl?SE*CYpf4|_${ku2s`*_)k zN=a}V8_2R5QANlxsq!1BkT6$4>9=-Ix4As@FSS;1q^#TXPrBsw>hJ}$jZ{kUHoP+H zvoYiR39gX}2OHIBYCa~6ERRPJ#V}RIIZakUmuIoLF*{sO8rAUEB9|+A#C|@kw5>u0 zBd=F!4I)Be8ycH*)X1-VPiZ+Ts8_GB;YW&ZFFUo|Sw|x~ZajLsp+_3gv((Q#N>?Jz zFBf`~p_#^${zhPIIJY~yo!7$-xi2LK%3&RkFg}Ax)3+dFCjGgKv^1;lUzQlPo^E{K zmCnrwJ)NuSaJEmueEPO@(_6h3f5mFffhkU9r8A8(JC5eOkux{gPmx_$Uv&|hyj)gN zd>JP8l2U&81@1Hc>#*su2xd{)T`Yw< zN$dSLUN}dfx)Fu`NcY}TuZ)SdviT{JHaiYgP4~@`x{&h*Hd>c3K_To9BnQi@;tuoL z%PYQo&{|IsM)_>BrF1oB~+`2_uZQ48z9!)mtUR zdfKE+b*w8cPu;F6RYJiYyV;PRBbThqHBEu_(U{(gGtjM}Zi$pL8Whx}<JwE3RM0F8x7%!!s)UJVq|TVd#hf1zVLya$;mYp(^oZQ2>=ZXU1c$}f zm|7kfk>=4KoQoQ!2&SOW5|JP1)%#55C$M(u4%SP~tHa&M+=;YsW=v(Old9L3(j)`u z2?#fK&1vtS?G6aOt@E`gZ9*qCmyvc>Ma@Q8^I4y~f3gs7*d=ATlP>1S zyF=k&6p2;7dn^8?+!wZO5r~B+;@KXFEn^&C=6ma1J7Au6y29iMIxd7#iW%=iUzq&C=$aPLa^Q zncia$@TIy6UT@69=nbty5epP>*fVW@5qbUcb2~Gg75dNd{COFLdiz3}kODn^U*=@E z0*$7u7Rl2u)=%fk4m8EK1ctR!6%Ve`e!O20L$0LkM#f+)n9h^dn{n`T*^~d+l*Qlx z$;JC0P9+en2Wlxjwq#z^a6pdnD6fJM!GV7_%8%c)kc5LZs_G^qvw)&J#6WSp< zmsd~1-(GrgjC56Pdf6#!dt^y8Rg}!#UXf)W%~PeU+kU`FeSZHk)%sFv++#Dujk-~m zFHvVJC}UBn2jN& zs!@nZ?e(iyZPNo`p1i#~wsv9l@#Z|ag3JR>0#u1iW9M1RK1iF6-RbJ4KYg?B`dET9 zyR~DjZ>%_vWYm*Z9_+^~hJ_|SNTzBKx=U0l9 z9x(J96b{`R)UVQ$I`wTJ@$_}`)_DyUNOso6=WOmQKI1e`oyYy1C&%AQU<0-`(ow)1 zT}gYdwWdm4wW6|K)LcfMe&psE0XGhMy&xS`@vLi|1#Za{D6l@#D!?nW87wcscUZgELT{Cz**^;Zb~7 z(~WFRO`~!WvyZAW-8v!6n&j*PLm9NlN}BuUN}@E^TX*4Or#dMMF?V9KBeLSiLO4?B zcE3WNIa-H{ThrlCoN=XjOGk1dT=xwwrmt<1a)mrRzg{35`@C!T?&_;Q4Ce=5=>z^*zE_c(0*vWo2_#TD<2)pLXV$FlwP}Ik74IdDQU@yhkCr5h zn5aa>B7PWy5NQ!vf7@p_qtC*{dZ8zLS;JetPkHi>IvPjtJ#ThGQD|Lq#@vE2xdl%`x4A8xOln}BiQ92Po zW;0%A?I5CQ_O`@Ad=`2BLPPbBuPUp@Hb%a_OOI}y{Rwa<#h z5^6M}s7VzE)2&I*33pA>e71d78QpF>sNK;?lj^Kl#wU7G++`N_oL4QPd-iPqBhhs| z(uVM}$ItF-onXuuXO}o$t)emBO3Hjfyil@*+GF;9j?`&67GBM;TGkLHi>@)rkS4Nj zAEk;u)`jc4C$qN6WV2dVd#q}2X6nKt&X*}I@jP%Srs%%DS92lpDY^K*Sx4`l;aql$ zt*-V{U&$DM>pdO?%jt$t=vg5|p+Rw?SPaLW zB6nvZ69$ne4Z(s$3=Rf&RX8L9PWMV*S0@R zuIk&ba#s6sxVZ51^4Kon46X^9`?DC9mEhWB3f+o4#2EXFqy0(UTc>GU| zGCJmI|Dn-dX#7|_6(fT)>&YQ0H&&JX3cTvAq(a@ydM4>5Njnuere{J8p;3?1az60* z$1E7Yyxt^ytULeokgDnRVKQw9vzHg1>X@@jM$n$HBlveIrKP5-GJq%iWH#odVwV6cF^kKX(@#%%uQVb>#T6L^mC@)%SMd4DF? zVky!~ge27>cpUP1Vi}Z32lbLV+CQy+T5Wdmva6Fg^lKb!zrg|HPU=5Qu}k;4GVH+x z%;&pN1LOce0w@9i1Mo-Y|7|z}fbch@BPp2{&R-5{GLoeu8@limQmFF zaJRR|^;kW_nw~0V^ zfTnR!Ni*;-%oSHG1yItARs~uxra|O?YJxBzLjpeE-=~TO3Dn`JL5Gz;F~O1u3|FE- zvK2Vve`ylc`a}G`gpHg58Cqc9fMoy1L}7x7T>%~b&irrNMo?np3`q;d3d;zTK>nrK zOjPS{@&74-fA7j)8uT9~*g23uGnxwIVj9HorzUX#s0pcp2?GH6i}~+kv9fWChtPa_ z@T3m+$0pbjdQw7jcnHn;Pi85hk_u2-1^}c)LNvjdam8K-XJ+KgKQ%!?2n_!#{$H|| zLO=%;hRo6EDmnOBKCL9Cg~ETU##@u^W_5joZ%Et%X_n##%JDOcsO=0VL|Lkk!VdRJ z^|~2pB@PUspT?NOeO?=0Vb+fAGc!j%Ufn-cB`s2A~W{Zj{`wqWq_-w0wr@6VrM zbzni@8c>WS!7c&|ZR$cQ;`niRw{4kG#e z70e!uX8VmP23SuJ*)#(&R=;SxGAvq|&>geL&!5Z7@0Z(No*W561n#u$Uc`f9pD70# z=sKOSK|bF~#khTTn)B28h^a1{;>EaRnHj~>i=Fnr3+Fa4 z`^+O5_itS#7kPd20rq66_wH`%?HNzWk@XFK0n;Z@Cx{kx==2L22zWH$Yg?7 zvDj|u{{+NR3JvUH({;b*$b(U5U z7(lF!1bz2%06+|-v(D?2KgwNw7( zJB#Tz+ZRi&U$i?f34m7>uTzO#+E5cbaiQ&L}UxyOQq~afbNB4EI{E04ZWg53w0A{O%qo=lF8d zf~ktGvIgf-a~zQoWf>loF7pOodrd0a2|BzwwPDV}ShauTK8*fmF6NRbO>Iw9zZU}u zw8Ya}?seBnEGQDmH#XpUUkj}N49tP<2jYwTFp!P+&Fd(%Z#yo80|5@zN(D{_pNow*&4%ql zW~&yp@scb-+Qj-EmErY+Tu=dUmf@*BoXY2&oKT8U?8?s1d}4a`Aq>7SV800m$FE~? zjmz(LY+Xx9sDX$;vU`xgw*jLw7dWOnWWCO8o|;}f>cu0Q&`0I{YudMn;P;L3R-uz# zfns_mZED_IakFBPP2r_S8XM$X)@O-xVKi4`7373Jkd5{2$M#%cRhWer3M(vr{S6>h zj{givZJ3(`yFL@``(afn&~iNx@B1|-qfYiZu?-_&Z8+R~v`d6R-}EX9IVXWO-!hL5 z*k6T#^2zAXdardU3Ao~I)4DGdAv2bx{4nOK`20rJo>rmk3S2ZDu}))8Z1m}CKigf0 z3L`3Y`{huj`xj9@`$xTZzZc3je?n^yG<8sw$`Y%}9mUsjUR%T!?k^(q)6FH6Af^b6 zlPg~IEwg0y;`t9y;#D+uz!oE4VP&Je!<#q*F?m5L5?J3i@!0J6q#eu z!RRU`-)HeqGi_UJZ(n~|PSNsv+Wgl{P-TvaUQ9j?ZCtvb^37U$sFpBrkT{7Jpd?HpIvj2!}RIq zH{9~+gErN2+}J`>Jvng2hwM`=PLNkc7pkjblKW|+Fk9rc)G1R>Ww>RC=r-|!m-u7( zc(a$9NG}w#PjWNMS~)o=i~WA&4L(YIW25@AL9+H9!?3Y}sv#MOdY{bb9j>p`{?O(P zIvb`n?_(gP2w3P#&91JX*md+bBEr%xUHMVqfB;(f?OPtMnAZ#rm5q5mh;a2f_si2_ z3oXWB?{NF(JtkAn6F(O{z@b76OIqMC$&oJ_&S|YbFJ*)3qVX_uNf5b8(!vGX19hsG z(OP>RmZp29KH9Ge2kKjKigUmOe^K_!UXP`von)PR8Qz$%=EmOB9xS(ZxE_tnyzo}7 z=6~$~9k0M~v}`w={AeqF?_)9q{m8K#6M{a&(;u;O41j)I$^T?lx5(zlebpY@NT&#N zR+1bB)-1-xj}R8uwqwf=iP1GbxBjneCC%UrSdSxK1vM^i9;bUkS#iRZw2H>rS<2<$ zNT3|sDH>{tXb=zq7XZi*K?#Zsa1h1{h5!Tq_YbKFm_*=A5-<~j63he;4`77!|LBlo zR^~tR3yxcU=gDFbshyF6>o0bdp$qmHS7D}m3;^QZq9kBBU|9$N-~oU?G5;jyFR7>z hN`IR97YZXIo@y!QgFWddJ3|0`sjFx!m))><{BI=FK%f8s literal 0 HcmV?d00001 diff --git a/03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-maskable-192.png b/03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9b4d76e525556d5d89141648c724331630325d GIT binary patch literal 5594 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 X>c!)3PgKfL&lX^$Z>Cpu&6)6jvi^Z! literal 0 HcmV?d00001 diff --git a/03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-maskable-512.png b/03-human-in-the-loop/apps/calaverita_app/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..d69c56691fbdb0b7efa65097c7cc1edac12a6d3e GIT binary patch literal 20998 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 MPgg&ebxsLQ025IeI{*Lx literal 0 HcmV?d00001 diff --git a/03-human-in-the-loop/apps/calaverita_app/web/index.html b/03-human-in-the-loop/apps/calaverita_app/web/index.html new file mode 100644 index 0000000..19ed8ee --- /dev/null +++ b/03-human-in-the-loop/apps/calaverita_app/web/index.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + calaverita_app + + + + + + + diff --git a/03-human-in-the-loop/apps/calaverita_app/web/manifest.json b/03-human-in-the-loop/apps/calaverita_app/web/manifest.json new file mode 100644 index 0000000..2fc8ead --- /dev/null +++ b/03-human-in-the-loop/apps/calaverita_app/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "calaverita_app", + "short_name": "calaverita_app", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/analysis_options.yaml b/03-human-in-the-loop/features/assistant/assistant_presentation/analysis_options.yaml new file mode 100644 index 0000000..317f632 --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/analysis_options.yaml @@ -0,0 +1,17 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - build/** + - web/** + - android/** + - ios/** + - windows/** + - macos/** + - linux/** +linter: + rules: + # The workshop uses classic constructors; Dart 3.13 offers shorthands. + prefer_initializing_formals: false + unnecessary_type_name_in_constructor: false + # A workshop app doesn't need an API reference. + public_member_api_docs: false diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/lib/assistant_presentation.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/assistant_presentation.dart new file mode 100644 index 0000000..13bee2e --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/assistant_presentation.dart @@ -0,0 +1 @@ +export 'chat/chat_module.dart'; diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_args.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_args.dart new file mode 100644 index 0000000..70b158c --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_args.dart @@ -0,0 +1,56 @@ +import 'package:equatable/equatable.dart'; + +/// One answer the agent offers in an `askUser` question. +class AskUserOption extends Equatable { + const AskUserOption({required this.id, required this.label, this.hint}); + + /// Reads an option from JSON, or returns `null` without an id or a label. + static AskUserOption? tryFromJson(Object? json) { + if (json is! Map) return null; + final id = json['id']; + final label = json['label']; + final hint = json['hint']; + if (id is! String || id.isEmpty || label is! String || label.isEmpty) { + return null; + } + return AskUserOption( + id: id, + label: label, + hint: hint is String && hint.isNotEmpty ? hint : null, + ); + } + + /// What goes back to the agent when this option is picked. + final String id; + + /// What the person reads on the button. + final String label; + + /// A short line under the label, if the agent gave one. + final String? hint; + + @override + List get props => [id, label, hint]; +} + +/// The arguments of the `askUser` tool: a question and its options. +class AskUserArgs extends Equatable { + const AskUserArgs({this.question = '', this.options = const []}); + + factory AskUserArgs.fromJson(Map json) { + final question = json['question']; + final options = json['options']; + return AskUserArgs( + question: question is String ? question : '', + options: options is List + ? [for (final option in options) ?AskUserOption.tryFromJson(option)] + : const [], + ); + } + + final String question; + final List options; + + @override + List get props => [question, options]; +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_card.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_card.dart new file mode 100644 index 0000000..4579026 --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_card.dart @@ -0,0 +1,48 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:assistant_presentation/chat/ask_user/ask_user_args.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; + +/// The generative UI of an `askUser` call: the question with its options as +/// tiles. +/// +/// The tiles answer the call while it waits for the person (`respond` is set), +/// and the card flattens to show the answer once the call is complete. +class AskUserCard extends StatelessWidget { + const AskUserCard({ + required this.call, + required this.respond, + this.args, + super.key, + }); + + /// The call to show. + final ToolCallView call; + + /// Answers the call, or `null` unless it waits for the person. + final ToolCallResponder? respond; + + /// The arguments of [call], or `null` while they can't be decoded yet. + final AskUserArgs? args; + + @override + Widget build(BuildContext context) { + final answered = call.status == ToolCallStatus.complete; + final question = args?.question ?? ''; + return AppDecisionCard( + kindLabel: 'Question', + kindIcon: AppIcons.chat, + title: question.isEmpty ? null : question, + loading: question.isEmpty && !answered, + complete: answered, + children: [ + for (final option in args?.options ?? const []) + AppOptionTile( + label: option.label, + detail: option.hint, + selected: answered && call.result == option.id, + onTap: respond == null ? null : () => respond!(option.id), + ), + ], + ); + } +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_tool.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_tool.dart new file mode 100644 index 0000000..0d86614 --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/ask_user/ask_user_tool.dart @@ -0,0 +1,54 @@ +import 'package:ack/ack.dart'; +import 'package:assistant_presentation/chat/ask_user/ask_user_args.dart'; +import 'package:assistant_presentation/chat/ask_user/ask_user_card.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter/widgets.dart'; + +/// Gives the agent an `askUser` tool and draws its calls as an [AskUserCard] +/// in [child], e.g. the chat. +/// +/// This is human in the loop: the agent asks, its run waits, and the answer +/// the person taps goes back to the agent as the tool result. The answer is +/// the id of the option. +class AskUserTool extends StatefulWidget { + const AskUserTool({required this.child, super.key}); + + final Widget child; + + @override + State createState() => _AskUserToolState(); +} + +class _AskUserToolState extends State { + /// Kept in a field: the SDK compares tools to know whether to register + /// again. + late final _tool = HumanInTheLoopTool( + name: 'askUser', + description: + 'Ask the user to pick one of a few options, then wait for the answer. ' + 'It comes back as the id of the option they picked. Use it for a ' + 'choice that is theirs to make, one question at a time.', + // Keep in sync with AskUserArgs. + parameters: Ack.object({ + 'question': Ack.string().describe('The question, one short sentence'), + 'options': Ack.list( + Ack.object({ + 'id': Ack.string().describe('A short id, e.g. playful'), + 'label': Ack.string().describe('What the button says'), + 'hint': Ack.string().optional().describe('An optional short line'), + }), + ).describe('Two to four options'), + }), + decode: AskUserArgs.fromJson, + ); + + @override + Widget build(BuildContext context) { + return CopilotHumanInTheLoop( + tool: _tool, + builder: (context, call, args, respond) => + AskUserCard(call: call, args: args, respond: respond), + child: widget.child, + ); + } +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/chat_module.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/chat_module.dart new file mode 100644 index 0000000..424c33c --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/chat_module.dart @@ -0,0 +1,43 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:assistant_presentation/chat/ask_user/ask_user_tool.dart'; +import 'package:assistant_presentation/chat/views/activity_line.dart'; +import 'package:assistant_presentation/chat/views/chat_panel.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; + +/// The chat with the agent [agentId]. +/// +/// It must sit below a `CopilotKit`, which connects it to the runtime. +class ChatModule extends StatelessWidget { + const ChatModule({ + required this.agentId, + this.suggestions = const [], + super.key, + }); + + /// Id of the agent on the runtime, e.g. `default`. + final String agentId; + + /// Messages offered as chips while the chat is empty. + final List suggestions; + + @override + Widget build(BuildContext context) { + // The scope shares its agent with any other scope of the same id, so + // this is the agent the rest of the screen reads and edits. + return CopilotAgentScope( + agentId: agentId, + child: CopilotChatProvider( + agentId: agentId, + // The agent's own tool calls (changing the shared state) show as one + // quiet line instead of raw arguments. + child: AskUserTool( + child: ToolRenderer( + name: ToolRenderer.nameFallback, + builder: (context, call) => ActivityLine(call: call), + child: ChatPanel(suggestions: suggestions), + ), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart new file mode 100644 index 0000000..6b4cf12 --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart @@ -0,0 +1,28 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; + +/// A quiet line for a tool call of the agent that has no card of its own. +class ActivityLine extends StatelessWidget { + const ActivityLine({required this.call, super.key}); + + final ToolCallView call; + + @override + Widget build(BuildContext context) { + final label = switch (call.name) { + 'AGUISendStateDelta' || 'AGUISendStateSnapshot' => 'Updated the form', + _ => null, + }; + if (label == null) return const SizedBox.shrink(); + final p = context.palette; + return Align( + alignment: Alignment.centerLeft, + child: AppChip( + label: label, + icon: AppIcons.wrench, + foreground: p.onNavyMuted, + background: p.onNavyFill, + ), + ); + } +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart new file mode 100644 index 0000000..b9ec41f --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart @@ -0,0 +1,188 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +/// The conversation: the messages and tool calls, an empty state with +/// suggestions, and a composer. +class ChatPanel extends StatelessWidget { + const ChatPanel({required this.suggestions, super.key}); + + final List suggestions; + + @override + Widget build(BuildContext context) { + return AppPanel( + navy: true, + title: 'Copilot', + icon: AppIcons.sparkle, + trailing: const _StopButton(), + child: Column( + children: [ + Expanded(child: _Feed(suggestions: suggestions)), + const _Composer(), + ], + ), + ); + } +} + +class _StopButton extends StatelessWidget { + const _StopButton(); + + @override + Widget build(BuildContext context) { + return AgentStateBuilder( + // While a question waits for the person the run is open, but there is + // nothing to stop: the card has its own way out. + selector: (state) => state.isRunning && state.awaitingResponseIds.isEmpty, + builder: (context, busy) => busy + ? AppButton.ghost( + label: 'Stop', + size: AppButtonSize.compact, + onNavy: true, + onPressed: () => context.read().add( + const ChatStopRequested(), + ), + ) + : const SizedBox.shrink(), + ); + } +} + +class _Feed extends StatelessWidget { + const _Feed({required this.suggestions}); + + final List suggestions; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return BlocBuilder( + builder: (context, state) { + final rows = state.rows.reversed.toList(); + final last = rows.firstOrNull; + final working = + state.isRunning && + !(last is ChatMessageRow && last.message is AssistantMessage) && + !(last is ChatToolCallRow && last.call.awaitingResponse); + return Column( + children: [ + Expanded( + child: rows.isEmpty && !working + ? _Empty(suggestions: suggestions) + : ListView.separated( + // Newest first and anchored to the bottom, like a chat. + reverse: true, + padding: const EdgeInsets.all(AppSpacing.xl), + itemCount: rows.length + (working ? 1 : 0), + separatorBuilder: (_, _) => + const SizedBox(height: AppSpacing.lg), + itemBuilder: (context, index) { + if (working && index == 0) { + return const AppTypingBubble(onNavy: true); + } + return switch (rows[working ? index - 1 : index]) { + ChatMessageRow(:final message) => AppChatBubble( + key: ValueKey(message.id), + text: switch (message) { + UserMessage(:final content) => content, + AssistantMessage(:final content) => content ?? '', + _ => '', + }, + role: message is UserMessage + ? AppChatRole.manager + : AppChatRole.customer, + onNavy: true, + ), + ChatToolCallRow(:final call) => ToolCallWidget( + call: call, + ), + }; + }, + ), + ), + if (state.error != null) + Padding( + key: const Key('chat_error'), + padding: const EdgeInsets.all(AppSpacing.lg), + child: Text( + 'The copilot could not answer. Is the runtime running?', + style: AppTypography.small.copyWith(color: p.negative), + ), + ), + ], + ); + }, + ); + } +} + +class _Empty extends StatelessWidget { + const _Empty({required this.suggestions}); + + final List suggestions; + + @override + Widget build(BuildContext context) { + return Center( + child: Padding( + padding: const EdgeInsets.all(AppSpacing.x3l), + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: AppSpacing.x3l, + children: [ + Text( + 'Tell me about your friend or coworker. I fill in the details ' + 'and dress the skull, and you can edit them by hand too.', + textAlign: TextAlign.center, + style: AppTypography.small.copyWith( + color: context.palette.onNavyMuted, + ), + ), + Wrap( + alignment: WrapAlignment.center, + spacing: AppSpacing.md, + runSpacing: AppSpacing.md, + children: [ + for (final text in suggestions) + AppSuggestionChip( + label: text, + onTap: () => context.read().add( + ChatMessageSent(text), + ), + ), + ], + ), + ], + ), + ), + ); + } +} + +class _Composer extends StatelessWidget { + const _Composer(); + + @override + Widget build(BuildContext context) { + return AgentStateBuilder<({bool running, bool asking})>( + selector: (state) => ( + running: state.isRunning, + asking: state.awaitingResponseIds.isNotEmpty, + ), + builder: (context, state) => Padding( + padding: const EdgeInsets.all(AppSpacing.lg), + child: AppComposer( + onNavy: true, + compact: true, + enabled: !state.running, + hint: state.asking + ? 'Answer the question above' + : 'Tell me about your friend…', + onSend: (text) => + context.read().add(ChatMessageSent(text)), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/pubspec.yaml b/03-human-in-the-loop/features/assistant/assistant_presentation/pubspec.yaml new file mode 100644 index 0000000..51b3e57 --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/pubspec.yaml @@ -0,0 +1,23 @@ +name: assistant_presentation +description: The chat with the agent, a presentation-only feature. +version: 0.1.0 +publish_to: none +resolution: workspace + +environment: + sdk: ^3.13.0 + flutter: ^3.47.0 + +dependencies: + ack: ^1.7.0 + app_ui: any + copilotkit_flutter: any + equatable: ^3.0.0 + flutter: + sdk: flutter + flutter_bloc: ^9.1.1 + +dev_dependencies: + flutter_test: + sdk: flutter + very_good_analysis: ^11.0.0 diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_args_test.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_args_test.dart new file mode 100644 index 0000000..4734267 --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_args_test.dart @@ -0,0 +1,50 @@ +import 'package:assistant_presentation/chat/ask_user/ask_user_args.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group(AskUserArgs, () { + test('reads the question and the options', () { + final args = AskUserArgs.fromJson(const { + 'question': 'How should I roast Mario?', + 'options': [ + {'id': 'playful', 'label': 'Playful', 'hint': 'Friendly teasing'}, + {'id': 'sarcastic', 'label': 'Sarcastic'}, + ], + }); + + expect(args.question, 'How should I roast Mario?'); + expect(args.options, const [ + AskUserOption( + id: 'playful', + label: 'Playful', + hint: 'Friendly teasing', + ), + AskUserOption(id: 'sarcastic', label: 'Sarcastic'), + ]); + }); + + test('skips options without an id or a label', () { + final args = AskUserArgs.fromJson(const { + 'options': [ + {'id': 'a', 'label': 'A'}, + {'id': '', 'label': 'No id'}, + {'id': 'c'}, + 'not an option', + {'id': 'd', 'label': 'D', 'hint': ''}, + ], + }); + + expect(args.options, const [ + AskUserOption(id: 'a', label: 'A'), + AskUserOption(id: 'd', label: 'D'), + ]); + }); + + test('is empty while nothing has arrived', () { + final args = AskUserArgs.fromJson(const {}); + + expect(args.question, isEmpty); + expect(args.options, isEmpty); + }); + }); +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_card_test.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_card_test.dart new file mode 100644 index 0000000..8f4713f --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_card_test.dart @@ -0,0 +1,98 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:assistant_presentation/chat/ask_user/ask_user_args.dart'; +import 'package:assistant_presentation/chat/ask_user/ask_user_card.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + const args = AskUserArgs( + question: 'How should I roast Mario?', + options: [ + AskUserOption(id: 'playful', label: 'Playful'), + AskUserOption(id: 'sarcastic', label: 'Sarcastic', hint: 'A bit sharper'), + ], + ); + + ToolCallView call(ToolCallStatus status, {String? result}) => ToolCallView( + id: 'call-1', + name: 'askUser', + status: status, + result: result, + ); + + Future pump( + WidgetTester tester, { + required ToolCallView call, + AskUserArgs? args, + ToolCallResponder? respond, + }) { + return tester.pumpWidget( + MaterialApp( + theme: AppTheme.light, + home: Scaffold( + body: AskUserCard(call: call, args: args, respond: respond), + ), + ), + ); + } + + group(AskUserCard, () { + testWidgets('shows the question and answers with the id of the option', ( + tester, + ) async { + Object? answer; + await pump( + tester, + call: call(ToolCallStatus.executing), + args: args, + respond: (result) => answer = result, + ); + + expect(find.text('How should I roast Mario?'), findsOneWidget); + expect(find.text('A bit sharper'), findsOneWidget); + + await tester.tap(find.text('Sarcastic')); + + expect(answer, 'sarcastic'); + }); + + testWidgets('cannot be answered while it does not wait for the person', ( + tester, + ) async { + await pump(tester, call: call(ToolCallStatus.inProgress), args: args); + + // Nothing to call: tapping an option does nothing and does not throw. + await tester.tap(find.text('Playful')); + expect(tester.takeException(), isNull); + }); + + testWidgets('keeps a placeholder while the question is still arriving', ( + tester, + ) async { + await pump(tester, call: call(ToolCallStatus.inProgress)); + + expect(find.text('How should I roast Mario?'), findsNothing); + expect(find.byType(AppDecisionCard), findsOneWidget); + }); + + testWidgets('shows the answer once the call is complete', (tester) async { + await pump( + tester, + call: call(ToolCallStatus.complete, result: 'sarcastic'), + args: args, + ); + + final tiles = tester.widgetList( + find.byType(AppOptionTile), + ); + expect( + {for (final tile in tiles) tile.label: tile.selected}, + {'Playful': false, 'Sarcastic': true}, + ); + expect( + tester.widget(find.byType(AppDecisionCard)).complete, + isTrue, + ); + }); + }); +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_tool_test.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_tool_test.dart new file mode 100644 index 0000000..59cc584 --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/ask_user/ask_user_tool_test.dart @@ -0,0 +1,51 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:assistant_presentation/chat/ask_user/ask_user_card.dart'; +import 'package:assistant_presentation/chat/ask_user/ask_user_tool.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + /// Renders [call] the way the chat does: through a `ToolCallWidget` below + /// the tool. + Future pumpCall(WidgetTester tester, ToolCallView call) { + return tester.pumpWidget( + CopilotKit( + // Never called: nothing in these tests runs the agent. + runtimeUrl: Uri.parse('http://localhost:1/api/copilotkit'), + child: MaterialApp( + theme: AppTheme.light, + home: Scaffold( + body: AskUserTool(child: ToolCallWidget(call: call)), + ), + ), + ), + ); + } + + group(AskUserTool, () { + testWidgets('draws a call to askUser as a card with its options', ( + tester, + ) async { + await pumpCall( + tester, + const ToolCallView( + id: 'call-1', + name: 'askUser', + status: ToolCallStatus.executing, + awaitingResponse: true, + args: { + 'question': 'How should I roast Mario?', + 'options': [ + {'id': 'playful', 'label': 'Playful'}, + {'id': 'dramatic', 'label': 'Dramatic'}, + ], + }, + ), + ); + + expect(find.byType(AskUserCard), findsOneWidget); + expect(find.text('How should I roast Mario?'), findsOneWidget); + expect(find.text('Dramatic'), findsOneWidget); + }); + }); +} diff --git a/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/chat_module_test.dart b/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/chat_module_test.dart new file mode 100644 index 0000000..c97aa92 --- /dev/null +++ b/03-human-in-the-loop/features/assistant/assistant_presentation/test/chat/chat_module_test.dart @@ -0,0 +1,46 @@ +import 'package:assistant_presentation/assistant_presentation.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('offers the suggestions while the chat is empty', (tester) async { + await tester.pumpWidget( + CopilotKit( + // Never called: nothing in this test runs the agent. + runtimeUrl: Uri.parse('http://localhost:1/api/copilotkit'), + child: const MaterialApp( + home: Scaffold( + body: ChatModule(agentId: 'default', suggestions: ['Hola']), + ), + ), + ), + ); + + expect(find.text('Copilot'), findsOneWidget); + expect(find.text('Hola'), findsOneWidget); + }); + + testWidgets('sends a suggestion as a message', (tester) async { + await tester.pumpWidget( + CopilotKit( + runtimeUrl: Uri.parse('http://localhost:1/api/copilotkit'), + child: const MaterialApp( + home: Scaffold( + body: ChatModule(agentId: 'default', suggestions: ['Hola']), + ), + ), + ), + ); + + await tester.tap(find.text('Hola')); + await tester.pump(); + + expect(find.text('Hola'), findsOneWidget); + // The suggestion became a user bubble, so the empty state is gone. + expect( + find.textContaining('Tell me about your friend or coworker'), + findsNothing, + ); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_data/analysis_options.yaml b/03-human-in-the-loop/features/calaverita/calaverita_data/analysis_options.yaml new file mode 100644 index 0000000..317f632 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_data/analysis_options.yaml @@ -0,0 +1,17 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - build/** + - web/** + - android/** + - ios/** + - windows/** + - macos/** + - linux/** +linter: + rules: + # The workshop uses classic constructors; Dart 3.13 offers shorthands. + prefer_initializing_formals: false + unnecessary_type_name_in_constructor: false + # A workshop app doesn't need an API reference. + public_member_api_docs: false diff --git a/03-human-in-the-loop/features/calaverita/calaverita_data/lib/calaverita_data.dart b/03-human-in-the-loop/features/calaverita/calaverita_data/lib/calaverita_data.dart new file mode 100644 index 0000000..a920091 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_data/lib/calaverita_data.dart @@ -0,0 +1 @@ +export 'repositories/template_calaveritas_repository.dart'; diff --git a/03-human-in-the-loop/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart b/03-human-in-the-loop/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart new file mode 100644 index 0000000..6d58b98 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart @@ -0,0 +1,41 @@ +import 'package:calaverita_data/templates/calaverita_templates.dart'; +import 'package:calaverita_domain/calaverita_domain.dart'; + +/// Writes calaveritas from ready-made verses, with no network and no agent. +/// +/// The same draft always gets the same verse, so results are repeatable. +class TemplateCalaveritasRepository implements ICalaveritasRepository { + const TemplateCalaveritasRepository({ + CalaveritaTemplates templates = const CalaveritaTemplates(), + Duration delay = const Duration(milliseconds: 600), + }) : _templates = templates, + _delay = delay; + + final CalaveritaTemplates _templates; + + /// How long writing takes, so the loading state is visible. + final Duration _delay; + + @override + Future generate(CalaveritaDraft draft) async { + if (!draft.isComplete) { + throw ArgumentError.value(draft, 'draft', 'needs a name and a job'); + } + await Future.delayed(_delay); + final name = draft.name.trim(); + final job = draft.job.trim().toLowerCase(); + final verses = _templates.of(draft.tone); + final seed = '$name$job'.codeUnits.fold(0, (sum, unit) => sum + unit); + final verse = verses[seed % verses.length]; + return Calaverita( + name: name, + job: job, + tone: draft.tone, + skull: draft.skull, + lines: [ + for (final line in verse) + line.replaceAll('{name}', name).replaceAll('{job}', job), + ], + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart b/03-human-in-the-loop/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart new file mode 100644 index 0000000..9cbcaaf --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart @@ -0,0 +1,78 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; + +/// Four-line verses with `{name}` and `{job}` slots, per [Tone]. +/// +/// The rhymes sit on fixed words, so they hold for any name and job. +class CalaveritaTemplates { + const CalaveritaTemplates(); + + /// The verses written in [tone]. + List> of(Tone tone) => switch (tone) { + Tone.playful => _playful, + Tone.sarcastic => _sarcastic, + Tone.dramatic => _dramatic, + }; + + static const _playful = [ + [ + "Doña Calavera knocked on {name}'s door,", + '"Leave your {job} desk, there are tamales and more!"', + 'But {name} said, "One more email, por favor,"', + 'And that is why the skull still waits at the door.', + ], + [ + '{name} the {job}, so charming, so sweet,', + 'Danced with a skeleton, two left feet.', + 'The mariachis played and the skulls all cheered,', + '"Best {job} ever!" ... and then disappeared.', + ], + [ + 'Little skull {name}, with sugar so bright,', + 'Left the {job} life for a fiesta tonight.', + 'With cempasúchil crowns and a conga line, too,', + 'Even Death asked, "Hey {name}, can I come with you?"', + ], + ]; + + static const _sarcastic = [ + [ + '{name}, the {job}, so busy, so wise,', + 'Met Death in a meeting and rolled both eyes.', + '"Could this have been an email?" {name} replied,', + '"Too late," said La Muerte, "enjoy the ride."', + ], + [ + 'They say a {job} never truly rests,', + 'Yet {name} is napping, put that to the test.', + 'La Catrina brings flowers, and says with a grin,', + '"Finally on time, now let the party begin."', + ], + [ + 'Here lies {name}, the pride of the {job} crew,', + 'Who always knew best, and told us too.', + 'The skeleton asked, "Any last words, my friend?"', + '"Actually," said {name}... and that was not the end.', + ], + ]; + + static const _dramatic = [ + [ + 'Oh {name}, great {job} of tragic renown,', + 'The marigolds weep as the sun goes down.', + 'Yet fear not, dear soul, for the music will play,', + 'And your {job} legend will dance on the day.', + ], + [ + 'Beneath the moon, so pale and so wide,', + '{name} the {job} walks with Death side by side.', + 'They share pan de muerto, they laugh, they sing,', + 'And the underworld crowns them the {job} king.', + ], + [ + 'A candle for {name}, a flame in the night,', + 'The {job} who worked with all of their might.', + 'Now skulls made of sugar bring tears and delight,', + 'And {name} gets the last word, as is only right.', + ], + ]; +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_data/pubspec.yaml b/03-human-in-the-loop/features/calaverita/calaverita_data/pubspec.yaml new file mode 100644 index 0000000..9ac6151 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_data/pubspec.yaml @@ -0,0 +1,15 @@ +name: calaverita_data +description: Offline, template-based writer of calaveritas. +version: 0.1.0 +publish_to: none +resolution: workspace + +environment: + sdk: ^3.13.0 + +dependencies: + calaverita_domain: any + +dev_dependencies: + test: ^1.26.0 + very_good_analysis: ^11.0.0 diff --git a/03-human-in-the-loop/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart new file mode 100644 index 0000000..31c75c9 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart @@ -0,0 +1,45 @@ +import 'package:calaverita_data/calaverita_data.dart'; +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:test/test.dart'; + +void main() { + group(TemplateCalaveritasRepository, () { + const repository = TemplateCalaveritasRepository(delay: Duration.zero); + + test('fills the name and the job into every line', () async { + final calaverita = await repository.generate( + const CalaveritaDraft(name: 'Ana', job: 'Designer'), + ); + expect(calaverita.lines, hasLength(4)); + final text = calaverita.lines.join('\n'); + expect(text, contains('Ana')); + expect(text, contains('designer')); + expect(text, isNot(contains('{'))); + }); + + test('writes the same verse for the same draft', () async { + const draft = CalaveritaDraft(name: 'Ana', job: 'Chef'); + expect( + await repository.generate(draft), + await repository.generate(draft), + ); + }); + + test('writes a verse for every tone', () async { + for (final tone in Tone.values) { + final calaverita = await repository.generate( + CalaveritaDraft(name: 'Ana', job: 'Chef', tone: tone), + ); + expect(calaverita.tone, tone); + expect(calaverita.lines, hasLength(4)); + } + }); + + test('rejects an incomplete draft', () { + expect( + () => repository.generate(const CalaveritaDraft(name: 'Ana')), + throwsArgumentError, + ); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/analysis_options.yaml b/03-human-in-the-loop/features/calaverita/calaverita_domain/analysis_options.yaml new file mode 100644 index 0000000..317f632 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/analysis_options.yaml @@ -0,0 +1,17 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - build/** + - web/** + - android/** + - ios/** + - windows/** + - macos/** + - linux/** +linter: + rules: + # The workshop uses classic constructors; Dart 3.13 offers shorthands. + prefer_initializing_formals: false + unnecessary_type_name_in_constructor: false + # A workshop app doesn't need an API reference. + public_member_api_docs: false diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/calaverita_domain.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/calaverita_domain.dart new file mode 100644 index 0000000..1419bff --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/calaverita_domain.dart @@ -0,0 +1,6 @@ +export 'models/calaverita.dart'; +export 'models/calaverita_draft.dart'; +export 'models/skull_part.dart'; +export 'models/skull_style.dart'; +export 'models/tone.dart'; +export 'repositories/i_calaveritas_repository.dart'; diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/calaverita.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/calaverita.dart new file mode 100644 index 0000000..3fdf3df --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/calaverita.dart @@ -0,0 +1,50 @@ +import 'package:calaverita_domain/models/skull_style.dart'; +import 'package:calaverita_domain/models/tone.dart'; +import 'package:equatable/equatable.dart'; + +/// A finished rhyming "literary skull". +class Calaverita extends Equatable { + const Calaverita({ + required this.name, + required this.job, + required this.tone, + required this.lines, + this.skull = const SkullStyle(), + }); + + /// Reads a calaverita from JSON, ignoring unknown or invalid fields. + factory Calaverita.fromJson(Map json) { + final lines = json['lines']; + final skull = json['skull']; + return Calaverita( + name: json['name'] is String ? json['name']! as String : '', + job: json['job'] is String ? json['job']! as String : '', + tone: Tone.values.asNameMap()[json['tone']] ?? Tone.playful, + lines: lines is List ? lines.whereType().toList() : [], + skull: skull is Map + ? SkullStyle.fromJson(skull) + : const SkullStyle(), + ); + } + + final String name; + final String job; + final Tone tone; + + /// The portrait that goes with the verse. + final SkullStyle skull; + + /// The verse, one entry per line. + final List lines; + + Map toJson() => { + 'name': name, + 'job': job, + 'tone': tone.name, + 'lines': lines, + 'skull': skull.toJson(), + }; + + @override + List get props => [name, job, tone, lines, skull]; +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart new file mode 100644 index 0000000..49c74f7 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart @@ -0,0 +1,60 @@ +import 'package:calaverita_domain/models/skull_style.dart'; +import 'package:calaverita_domain/models/tone.dart'; +import 'package:equatable/equatable.dart'; + +/// What we know about the person a calaverita is written for. +/// +/// This is the shape of the form, and later the shape the agent shares with +/// the app, so it knows how to read and write itself as JSON. +class CalaveritaDraft extends Equatable { + const CalaveritaDraft({ + this.name = '', + this.job = '', + this.tone = Tone.playful, + this.skull = const SkullStyle(), + }); + + /// Reads a draft from JSON, ignoring unknown or invalid fields. + factory CalaveritaDraft.fromJson(Map json) { + final tone = json['tone']; + final skull = json['skull']; + return CalaveritaDraft( + name: json['name'] is String ? json['name']! as String : '', + job: json['job'] is String ? json['job']! as String : '', + tone: Tone.values.asNameMap()[tone] ?? Tone.playful, + skull: skull is Map + ? SkullStyle.fromJson(skull) + : const SkullStyle(), + ); + } + + final String name; + final String job; + final Tone tone; + final SkullStyle skull; + + /// Whether there is enough to write a calaverita. + bool get isComplete => name.trim().isNotEmpty && job.trim().isNotEmpty; + + CalaveritaDraft copyWith({ + String? name, + String? job, + Tone? tone, + SkullStyle? skull, + }) => CalaveritaDraft( + name: name ?? this.name, + job: job ?? this.job, + tone: tone ?? this.tone, + skull: skull ?? this.skull, + ); + + Map toJson() => { + 'name': name, + 'job': job, + 'tone': tone.name, + 'skull': skull.toJson(), + }; + + @override + List get props => [name, job, tone, skull]; +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/skull_part.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/skull_part.dart new file mode 100644 index 0000000..26d6783 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/skull_part.dart @@ -0,0 +1,18 @@ +/// An accessory the skull can wear, and the looks it comes in. +/// +/// Keep the variants in step with the SVGs of `calaverita_presentation` and +/// with the prompt of the runtime. +enum SkullPart { + hat('Hat', ['sombrero', 'tophat', 'party', 'crown']), + glasses('Glasses', ['round', 'square', 'cateye', 'heart']), + mustache('Mustache', ['handlebar', 'walrus', 'pencil']), + flowers('Flowers', ['crown', 'side', 'trio']); + + SkullPart(this.label, this.variants); + + /// The name shown to people. + final String label; + + /// The looks of this accessory, besides `none`. + final List variants; +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/skull_style.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/skull_style.dart new file mode 100644 index 0000000..a1cde9c --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/skull_style.dart @@ -0,0 +1,84 @@ +import 'package:calaverita_domain/models/skull_part.dart'; +import 'package:equatable/equatable.dart'; + +/// How the sugar skull looks: its color and what it wears. +/// +/// Each accessory is the id of one of its [SkullPart.variants], or +/// [SkullStyle.none]. +class SkullStyle extends Equatable { + const SkullStyle({ + this.color = defaultColor, + this.hat = none, + this.glasses = none, + this.mustache = none, + this.flowers = none, + }); + + /// Reads a style from JSON, ignoring unknown or invalid fields. + factory SkullStyle.fromJson(Map json) { + String variant(SkullPart part) { + final value = json[part.name]; + return value is String && part.variants.contains(value) ? value : none; + } + + final color = json['color']; + return SkullStyle( + color: color is String && _hex.hasMatch(color) + ? color.toLowerCase() + : defaultColor, + hat: variant(SkullPart.hat), + glasses: variant(SkullPart.glasses), + mustache: variant(SkullPart.mustache), + flowers: variant(SkullPart.flowers), + ); + } + + /// The id of an accessory the skull doesn't wear. + static const none = 'none'; + + /// Bone, the color of a plain skull. + static const defaultColor = '#f6efe0'; + + static final _hex = RegExp(r'^#[0-9a-fA-F]{6}$'); + + /// The skull color, as `#rrggbb`. + final String color; + final String hat; + final String glasses; + final String mustache; + final String flowers; + + /// The variant of [part] the skull wears, or [none]. + String of(SkullPart part) => switch (part) { + SkullPart.hat => hat, + SkullPart.glasses => glasses, + SkullPart.mustache => mustache, + SkullPart.flowers => flowers, + }; + + /// Returns this style with [part] set to [variant], or [none] to take it + /// off. + SkullStyle wearing(SkullPart part, String variant) => SkullStyle( + color: color, + hat: part == SkullPart.hat ? variant : hat, + glasses: part == SkullPart.glasses ? variant : glasses, + mustache: part == SkullPart.mustache ? variant : mustache, + flowers: part == SkullPart.flowers ? variant : flowers, + ); + + SkullStyle withColor(String color) => SkullStyle( + color: color, + hat: hat, + glasses: glasses, + mustache: mustache, + flowers: flowers, + ); + + Map toJson() => { + 'color': color, + for (final part in SkullPart.values) part.name: of(part), + }; + + @override + List get props => [color, hat, glasses, mustache, flowers]; +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/tone.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/tone.dart new file mode 100644 index 0000000..c779bf9 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/models/tone.dart @@ -0,0 +1,11 @@ +/// How a calaverita talks about its subject. +enum Tone { + playful('Playful'), + sarcastic('Sarcastic'), + dramatic('Dramatic'); + + Tone(this.label); + + /// The name shown to people. + final String label; +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart new file mode 100644 index 0000000..d32ac1b --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart @@ -0,0 +1,10 @@ +import 'package:calaverita_domain/models/calaverita.dart'; +import 'package:calaverita_domain/models/calaverita_draft.dart'; + +/// Writes calaveritas. +abstract interface class ICalaveritasRepository { + /// Writes a calaverita for [draft]. + /// + /// Throws an [ArgumentError] when [CalaveritaDraft.isComplete] is false. + Future generate(CalaveritaDraft draft); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/pubspec.yaml b/03-human-in-the-loop/features/calaverita/calaverita_domain/pubspec.yaml new file mode 100644 index 0000000..80f43e3 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/pubspec.yaml @@ -0,0 +1,15 @@ +name: calaverita_domain +description: Models and repository contract of the calaverita feature. +version: 0.1.0 +publish_to: none +resolution: workspace + +environment: + sdk: ^3.13.0 + +dependencies: + equatable: ^3.0.0 + +dev_dependencies: + test: ^1.26.0 + very_good_analysis: ^11.0.0 diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart new file mode 100644 index 0000000..0baed67 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart @@ -0,0 +1,50 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:test/test.dart'; + +void main() { + group(CalaveritaDraft, () { + test('is incomplete until it has a name and a job', () { + expect(const CalaveritaDraft().isComplete, isFalse); + expect(const CalaveritaDraft(name: 'Ana').isComplete, isFalse); + expect(const CalaveritaDraft(name: 'Ana', job: ' ').isComplete, isFalse); + expect( + const CalaveritaDraft(name: 'Ana', job: 'Designer').isComplete, + isTrue, + ); + }); + + test('round-trips through JSON', () { + const draft = CalaveritaDraft( + name: 'Ana', + job: 'Designer', + tone: Tone.sarcastic, + skull: SkullStyle(color: '#12a5a0', hat: 'sombrero', flowers: 'trio'), + ); + expect(CalaveritaDraft.fromJson(draft.toJson()), draft); + }); + + test('ignores invalid JSON fields', () { + final draft = CalaveritaDraft.fromJson(const { + 'name': 42, + 'job': 'Chef', + 'tone': 'grumpy', + 'skull': {'hat': 'helmet', 'color': 'red', 'glasses': 'heart'}, + }); + expect( + draft, + const CalaveritaDraft( + job: 'Chef', + skull: SkullStyle(glasses: 'heart'), + ), + ); + }); + + test('copyWith keeps what it is not given', () { + const draft = CalaveritaDraft(name: 'Ana', job: 'Chef'); + expect( + draft.copyWith(tone: Tone.dramatic), + const CalaveritaDraft(name: 'Ana', job: 'Chef', tone: Tone.dramatic), + ); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/calaverita_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/calaverita_test.dart new file mode 100644 index 0000000..98dc472 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/calaverita_test.dart @@ -0,0 +1,36 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:test/test.dart'; + +void main() { + group(Calaverita, () { + test('round-trips through JSON', () { + const calaverita = Calaverita( + name: 'Ana', + job: 'pilot', + tone: Tone.sarcastic, + lines: ['one', 'two', 'three', 'four'], + skull: SkullStyle(hat: 'crown', color: '#12a5a0'), + ); + expect(Calaverita.fromJson(calaverita.toJson()), calaverita); + }); + + test('ignores invalid JSON fields', () { + final calaverita = Calaverita.fromJson(const { + 'name': 7, + 'job': 'chef', + 'tone': 'grumpy', + 'lines': ['one', 2, 'three'], + 'skull': 'round', + }); + expect( + calaverita, + const Calaverita( + name: '', + job: 'chef', + tone: Tone.playful, + lines: ['one', 'three'], + ), + ); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/skull_style_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/skull_style_test.dart new file mode 100644 index 0000000..7457cbe --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_domain/test/models/skull_style_test.dart @@ -0,0 +1,45 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:test/test.dart'; + +void main() { + group(SkullStyle, () { + test('starts plain', () { + const style = SkullStyle(); + for (final part in SkullPart.values) { + expect(style.of(part), SkullStyle.none); + } + expect(style.color, SkullStyle.defaultColor); + }); + + test('wears one accessory at a time', () { + final style = const SkullStyle().wearing(SkullPart.hat, 'sombrero'); + expect(style.hat, 'sombrero'); + expect(style.glasses, SkullStyle.none); + expect(style.wearing(SkullPart.hat, SkullStyle.none), const SkullStyle()); + }); + + test('keeps the accessories when the color changes', () { + final style = const SkullStyle(hat: 'party').withColor('#12a5a0'); + expect(style.hat, 'party'); + expect(style.color, '#12a5a0'); + }); + + test('round-trips through JSON', () { + const style = SkullStyle(color: '#d6336c', glasses: 'cateye'); + expect(SkullStyle.fromJson(style.toJson()), style); + }); + + test('ignores unknown variants and invalid colors', () { + final style = SkullStyle.fromJson(const { + 'color': 'pink', + 'hat': 'helmet', + 'mustache': 'walrus', + }); + expect(style, const SkullStyle(mustache: 'walrus')); + }); + + test('keeps a valid color in lower case', () { + expect(SkullStyle.fromJson(const {'color': '#F5A524'}).color, '#f5a524'); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/analysis_options.yaml b/03-human-in-the-loop/features/calaverita/calaverita_presentation/analysis_options.yaml new file mode 100644 index 0000000..317f632 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/analysis_options.yaml @@ -0,0 +1,17 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - build/** + - web/** + - android/** + - ios/** + - windows/** + - macos/** + - linux/** +linter: + rules: + # The workshop uses classic constructors; Dart 3.13 offers shorthands. + prefer_initializing_formals: false + unnecessary_type_name_in_constructor: false + # A workshop app doesn't need an API reference. + public_member_api_docs: false diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/base/round.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/base/round.svg new file mode 100644 index 0000000..2045630 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/base/round.svg @@ -0,0 +1,4 @@ + + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg new file mode 100644 index 0000000..1f4f401 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg @@ -0,0 +1,4 @@ + + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg new file mode 100644 index 0000000..945318c --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg new file mode 100644 index 0000000..4feefe9 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg new file mode 100644 index 0000000..6110b8d --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg new file mode 100644 index 0000000..8962d64 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg new file mode 100644 index 0000000..94e0582 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg new file mode 100644 index 0000000..7b90822 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg new file mode 100644 index 0000000..5156ff7 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg new file mode 100644 index 0000000..7f56aee --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg new file mode 100644 index 0000000..40036e6 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg new file mode 100644 index 0000000..b871b3f --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg new file mode 100644 index 0000000..9c9ca93 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg new file mode 100644 index 0000000..e75174e --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg new file mode 100644 index 0000000..5554aed --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg new file mode 100644 index 0000000..eae7e7f --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg new file mode 100644 index 0000000..14f365a --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg new file mode 100644 index 0000000..42b0412 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg new file mode 100644 index 0000000..db33ebe --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg @@ -0,0 +1,3 @@ + + + diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart new file mode 100644 index 0000000..9b2deff --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart @@ -0,0 +1,40 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/bloc/calaverita_state.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +/// Writes the calaverita for the form. +/// +/// The form is the agent's shared state, so the caller hands the current +/// draft in. +class CalaveritaCubit extends Cubit { + CalaveritaCubit({required ICalaveritasRepository calaveritasRepository}) + : _calaveritasRepository = calaveritasRepository, + super(const CalaveritaState()); + + final ICalaveritasRepository _calaveritasRepository; + + /// Shows [calaverita], one the agent wrote, on the stage. + void calaveritaShown(Calaverita calaverita) => emit( + state.copyWith(status: GenerationStatus.success, calaverita: calaverita), + ); + + /// Writes a calaverita for [draft], if it is complete. + Future generate(CalaveritaDraft draft) async { + if (!draft.isComplete || state.status == GenerationStatus.generating) { + return; + } + emit(state.copyWith(status: GenerationStatus.generating)); + try { + final calaverita = await _calaveritasRepository.generate(draft); + emit( + state.copyWith( + status: GenerationStatus.success, + calaverita: calaverita, + ), + ); + } on Object catch (error, stackTrace) { + addError(error, stackTrace); + emit(state.copyWith(status: GenerationStatus.failure)); + } + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart new file mode 100644 index 0000000..5ba20aa --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart @@ -0,0 +1,28 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:equatable/equatable.dart'; + +/// Where writing a calaverita stands. +enum GenerationStatus { idle, generating, success, failure } + +/// The calaverita being written, or the last one written. +/// +/// The form itself is not here: it lives in the agent's shared state. +class CalaveritaState extends Equatable { + const CalaveritaState({this.status = GenerationStatus.idle, this.calaverita}); + + final GenerationStatus status; + + /// The last calaverita written, if any. + final Calaverita? calaverita; + + CalaveritaState copyWith({ + GenerationStatus? status, + Calaverita? calaverita, + }) => CalaveritaState( + status: status ?? this.status, + calaverita: calaverita ?? this.calaverita, + ); + + @override + List get props => [status, calaverita]; +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart new file mode 100644 index 0000000..ae8b53a --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart @@ -0,0 +1,44 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/bloc/calaverita_cubit.dart'; +import 'package:calaverita_presentation/calaverita/skull/skull_art.dart'; +import 'package:calaverita_presentation/calaverita/views/calaverita_page.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:provider/provider.dart'; + +/// The calaverita screen with everything it needs. +/// +/// It must sit below a `CopilotAgentScope`: the form is the agent's shared +/// state. +class CalaveritaModule extends StatelessWidget { + const CalaveritaModule({ + required this.calaveritasRepository, + required this.skullArt, + this.trailingPanel, + super.key, + }); + + final ICalaveritasRepository calaveritasRepository; + + /// The SVGs of the skull, loaded with [SkullArt.load]. + final SkullArt skullArt; + + /// Filled by the app: a panel beside the stage (below it on a narrow + /// screen). + final Widget? trailingPanel; + + @override + Widget build(BuildContext context) { + return MultiProvider( + providers: [ + Provider.value(value: calaveritasRepository), + Provider.value(value: skullArt), + ], + child: BlocProvider( + create: (context) => + CalaveritaCubit(calaveritasRepository: context.read()), + child: CalaveritaPage(trailingPanel: trailingPanel), + ), + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart new file mode 100644 index 0000000..dac72b0 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart @@ -0,0 +1,54 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/shared_draft/shared_draft.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter/widgets.dart'; + +/// What the person does to the form. Each edit patches the shared state, so +/// the next run of the agent receives it and the agent always sees what the +/// person changed. +class DraftEdits { + const DraftEdits._(this._agent); + + /// The edits of the agent of the nearest `CopilotAgentScope`. + factory DraftEdits.of(BuildContext context) => + DraftEdits._(CopilotAgentScope.of(context)); + + final CopilotAgent _agent; + + CalaveritaDraft get _draft => SharedDraft.draftOf(_agent.state); + + /// Shares the empty form if nothing is shared yet. + /// + /// The agent only sees state that is not empty, so the form has to be + /// there before the first message. + void ensureInitialized() { + if (_agent.state.sharedState == null) reset(); + } + + /// Clears the form. + void reset() => + _agent.setSharedState(SharedState(const CalaveritaDraft().toJson())); + + void nameChanged(String name) => _set('/name', name); + + void jobChanged(String job) => _set('/job', job); + + void toneChanged(Tone tone) => _set('/tone', tone.name); + + void skullPartChanged(SkullPart part, String variant) => + _set('/skull/${part.name}', variant); + + void skullColorChanged(String color) => _set('/skull/color', color); + + void _set(String path, String value) { + final operations = [StatePatchAdd(path: path, value: value)]; + try { + _agent.patchSharedState(operations); + } on FormatException { + // The agent replaced the state with one that lacks this path. Start + // again from the form as we can read it, which has every path. + _agent.setSharedState(SharedState(_draft.toJson())); + _agent.patchSharedState(operations); + } + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart new file mode 100644 index 0000000..0c5aeac --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart @@ -0,0 +1,29 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter/widgets.dart'; + +/// Rebuilds with the [CalaveritaDraft] in the agent's shared state, and only +/// when it changes. +/// +/// The form lives in the shared state: the agent changes it with state +/// updates and the app changes it with `DraftEdits`. Nothing else holds a +/// copy, so the details, the stage and the agent all see the same draft. +/// Needs a `CopilotAgentScope` above it. +class SharedDraft extends StatelessWidget { + const SharedDraft({required this.builder, super.key}); + + final Widget Function(BuildContext context, CalaveritaDraft draft) builder; + + @override + Widget build(BuildContext context) { + return AgentStateBuilder( + selector: draftOf, + builder: builder, + ); + } + + /// The draft in [state], or an empty one while the agent shares nothing. + static CalaveritaDraft draftOf(CopilotAgentState state) => + state.sharedState?.decode(CalaveritaDraft.fromJson) ?? + const CalaveritaDraft(); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart new file mode 100644 index 0000000..f9a8a9f --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart @@ -0,0 +1,19 @@ +import 'package:equatable/equatable.dart'; + +/// The arguments of the `showCalaverita` tool: the verse the agent wrote. +class ShowCalaveritaArgs extends Equatable { + const ShowCalaveritaArgs({this.lines = const []}); + + factory ShowCalaveritaArgs.fromJson(Map json) { + final lines = json['lines']; + return ShowCalaveritaArgs( + lines: lines is List ? lines.whereType().toList() : [], + ); + } + + /// The four lines of the verse. + final List lines; + + @override + List get props => [lines]; +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart new file mode 100644 index 0000000..8211377 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart @@ -0,0 +1,58 @@ +import 'dart:convert'; + +import 'package:app_ui/app_ui.dart'; +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/show_calaverita/show_calaverita_args.dart'; +import 'package:calaverita_presentation/calaverita/views/calaverita_card.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; + +/// The generative UI of a `showCalaverita` call: a card in the chat. +/// +/// While the agent is still writing it shows a placeholder, and once the +/// call is done the finished [CalaveritaCard]. +class ShowCalaveritaCard extends StatelessWidget { + const ShowCalaveritaCard({required this.call, this.args, super.key}); + + /// The call to show. + final ToolCallView call; + + /// The arguments of [call], or `null` while they can't be decoded yet. + final ShowCalaveritaArgs? args; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return switch (call.status) { + ToolCallStatus.inProgress || ToolCallStatus.executing => AppChip( + label: 'Writing the calaverita…', + icon: AppIcons.sparkle, + foreground: p.onNavyMuted, + background: p.onNavyFill, + ), + ToolCallStatus.complete => _finished(context, call.result), + }; + } + + Widget _finished(BuildContext context, String? result) { + final calaverita = _calaveritaFrom(result); + if (calaverita != null) return CalaveritaCard(calaverita: calaverita); + return Text( + result ?? '', + style: AppTypography.small.copyWith(color: context.palette.onNavyMuted), + ); + } + + /// Decodes the JSON-encoded calaverita in [result], or returns `null` when + /// it isn't one, e.g. a message saying the form is incomplete. + Calaverita? _calaveritaFrom(String? result) { + if (result == null) return null; + try { + return switch (jsonDecode(result)) { + final Map json => Calaverita.fromJson(json), + _ => null, + }; + } on FormatException { + return null; + } + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart new file mode 100644 index 0000000..e034f24 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart @@ -0,0 +1,42 @@ +import 'dart:convert'; + +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/show_calaverita/show_calaverita_args.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; + +/// Runs the `showCalaverita` tool: puts the verse the agent wrote together +/// with the form and the skull as they are right now, and hands the result to +/// the stage. +class ShowCalaveritaHandler { + const ShowCalaveritaHandler({ + required CalaveritaDraft Function() readDraft, + required void Function(Calaverita calaverita) onWritten, + }) : _readDraft = readDraft, + _onWritten = onWritten; + + final CalaveritaDraft Function() _readDraft; + final void Function(Calaverita calaverita) _onWritten; + + /// Returns the calaverita as JSON, or a sentence saying what is missing. + /// + /// The card of the tool shows the result, and the agent gets it back too. + Future handle( + ShowCalaveritaArgs args, { + required CancellationSignal signal, + }) async { + final draft = _readDraft(); + if (!draft.isComplete) { + return 'The form still needs a name and a job, so nothing was shown.'; + } + if (args.lines.isEmpty) return 'There was no verse to show.'; + final calaverita = Calaverita( + name: draft.name.trim(), + job: draft.job.trim().toLowerCase(), + tone: draft.tone, + lines: args.lines, + skull: draft.skull, + ); + _onWritten(calaverita); + return jsonEncode(calaverita.toJson()); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart new file mode 100644 index 0000000..5c0f3b1 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart @@ -0,0 +1,67 @@ +import 'package:ack/ack.dart'; +import 'package:calaverita_presentation/calaverita/bloc/calaverita_cubit.dart'; +import 'package:calaverita_presentation/calaverita/shared_draft/shared_draft.dart'; +import 'package:calaverita_presentation/calaverita/show_calaverita/show_calaverita_args.dart'; +import 'package:calaverita_presentation/calaverita/show_calaverita/show_calaverita_card.dart'; +import 'package:calaverita_presentation/calaverita/show_calaverita/show_calaverita_handler.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +/// Gives the agent a `showCalaverita` tool and draws its calls as a +/// [ShowCalaveritaCard] in [child], e.g. the chat. +/// +/// The agent writes the verse and calls the tool, the tool adds the form and +/// the skull as they are right now, and the card in the chat shows the +/// result. The stage shows it too, so the verse the agent wrote is the one on +/// the main screen. Needs a `CopilotAgentScope` and the calaverita screen's +/// cubit above it. +class ShowCalaveritaTool extends StatefulWidget { + const ShowCalaveritaTool({required this.child, super.key}); + + final Widget child; + + @override + State createState() => _ShowCalaveritaToolState(); +} + +class _ShowCalaveritaToolState extends State { + /// Kept in a field: the SDK compares tools to know whether to register + /// again. + FrontendTool? _tool; + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + if (_tool != null) return; + final agent = CopilotAgentScope.of(context); + final cubit = context.read(); + _tool = FrontendTool( + name: 'showCalaverita', + description: + 'Show a finished calaverita to the user as a card in the chat, with ' + 'the skull portrait that is on screen. Call it once the name and ' + 'the job are filled in and the user asks for the calaverita.', + // Keep in sync with ShowCalaveritaArgs. + parameters: Ack.object({ + 'lines': Ack.list(Ack.string()) + .describe('The four rhyming lines of the calaverita, in order'), + }), + decode: ShowCalaveritaArgs.fromJson, + handler: ShowCalaveritaHandler( + readDraft: () => SharedDraft.draftOf(agent.state), + onWritten: cubit.calaveritaShown, + ).handle, + ); + } + + @override + Widget build(BuildContext context) { + return CopilotTool( + tool: _tool!, + builder: (context, call, args) => + ShowCalaveritaCard(call: call, args: args), + child: widget.child, + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart new file mode 100644 index 0000000..2e95caf --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart @@ -0,0 +1,170 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:flutter/services.dart'; + +/// One piece of the skull: which SVG it draws and in which colors. +/// +/// Each SVG is a template: `{{fill}}`, `{{stroke}}`, `{{strokeWidth}}` and +/// `{{accent}}` are replaced with the colors below. +class SkullLayer { + const SkullLayer( + this.kind, { + required this.fill, + this.stroke = '#191817', + this.strokeWidth = 3, + this.accent = '#191817', + }); + + /// The folder of the SVGs, e.g. `hat`. + final String kind; + final String fill; + final String stroke; + final double strokeWidth; + final String accent; + + /// Returns this layer with [fill] as its main color. + SkullLayer withFill(String fill) => SkullLayer( + kind, + fill: fill, + stroke: stroke, + strokeWidth: strokeWidth, + accent: accent, + ); +} + +/// The SVGs of the skull, loaded once at startup so a piece draws the moment +/// its look changes. +class SkullArt { + /// Creates the art from SVG `templates`, keyed by `kind/variant`. + const SkullArt.fromTemplates(this._templates); + + /// Loads every SVG the skull can use. + static Future load([AssetBundle? bundle]) async { + final assets = bundle ?? rootBundle; + final templates = {}; + for (final path in _paths) { + templates[path] = await assets.loadString( + 'packages/calaverita_presentation/assets/skull/$path.svg', + ); + } + return SkullArt.fromTemplates(templates); + } + + /// The pieces of the skull that never change. + static const base = SkullLayer( + 'base', + fill: '#f6efe0', + strokeWidth: 5, + accent: '#ff8fb1', + ); + static const pattern = SkullLayer( + 'pattern', + fill: '#d6336c', + strokeWidth: 0, + accent: '#f5a524', + ); + static const eyes = SkullLayer('eyes', fill: '#191817', accent: '#f5a524'); + static const nose = SkullLayer('nose', fill: '#191817', strokeWidth: 2); + static const mouth = SkullLayer( + 'mouth', + fill: '#191817', + strokeWidth: 4, + accent: '#f6efe0', + ); + + /// How each accessory is colored. + static const hat = SkullLayer( + 'hat', + fill: '#e0353b', + strokeWidth: 4, + accent: '#f5a524', + ); + static const glasses = SkullLayer( + 'glasses', + fill: '#8fa8ff', + strokeWidth: 5, + accent: '#ffffff', + ); + static const mustache = SkullLayer( + 'mustache', + fill: '#2b1d3a', + strokeWidth: 2, + ); + static const flowers = SkullLayer( + 'flowers', + fill: '#f5a524', + strokeWidth: 2, + accent: '#d6336c', + ); + + /// How [part] is colored. + static SkullLayer layerOf(SkullPart part) => switch (part) { + SkullPart.hat => hat, + SkullPart.glasses => glasses, + SkullPart.mustache => mustache, + SkullPart.flowers => flowers, + }; + + /// The rectangle of the 400 x 500 canvas where [part] sits. + static Rect focusOf(SkullPart part) => switch (part) { + SkullPart.hat => const Rect.fromLTWH(10, 0, 380, 110), + SkullPart.glasses => const Rect.fromLTWH(60, 160, 280, 110), + SkullPart.mustache => const Rect.fromLTWH(115, 295, 170, 50), + SkullPart.flowers => const Rect.fromLTWH(20, 40, 360, 130), + }; + + /// The variant of each fixed piece. + static const _fixed = { + 'base': 'round', + 'pattern': 'swirls', + 'eyes': 'marigold', + 'nose': 'heart', + 'mouth': 'stitched', + }; + + static const _paths = [ + 'base/round', + 'pattern/swirls', + 'eyes/marigold', + 'nose/heart', + 'mouth/stitched', + 'hat/sombrero', + 'hat/tophat', + 'hat/party', + 'hat/crown', + 'glasses/round', + 'glasses/square', + 'glasses/cateye', + 'glasses/heart', + 'mustache/handlebar', + 'mustache/walrus', + 'mustache/pencil', + 'flowers/crown', + 'flowers/side', + 'flowers/trio', + ]; + + final Map _templates; + + /// The SVG of [layer] in [variant], or `null` when there is none. + /// + /// A fixed piece ignores [variant]. + String? svg(SkullLayer layer, [String? variant]) { + final template = + _templates['${layer.kind}/${_fixed[layer.kind] ?? variant}']; + if (template == null) return null; + return template + .replaceAll('{{fill}}', layer.fill) + .replaceAll('{{stroke}}', layer.stroke) + .replaceAll('{{strokeWidth}}', layer.strokeWidth.toStringAsFixed(1)) + .replaceAll('{{accent}}', layer.accent); + } + + /// Like [svg], cropped to [crop], a rectangle of the 400 x 500 canvas. + String? thumbnail(SkullLayer layer, String variant, Rect crop) { + final out = svg(layer, variant); + return out?.replaceFirst( + RegExp('viewBox="[^"]*" width="[^"]*" height="[^"]*"'), + 'viewBox="${crop.left} ${crop.top} ${crop.width} ${crop.height}"', + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart new file mode 100644 index 0000000..7e67811 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart @@ -0,0 +1,64 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/views/skull_view.dart'; + +/// A finished calaverita: the verse, and the skull portrait that goes with +/// it. +class CalaveritaCard extends StatelessWidget { + const CalaveritaCard({ + required this.calaverita, + this.showPortrait = true, + super.key, + }); + + final Calaverita calaverita; + + /// Whether the skull is drawn next to the verse. The stage turns it off + /// because the skull is already there. + final bool showPortrait; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return AppCard( + // The wash is see-through, so on its own it takes the color of what is + // behind it: bluish on the stage, navy in the chat. Lay it on the + // surface to get the same card anywhere. + color: Color.alphaBlend(p.accentWash, p.surface), + padding: const EdgeInsets.all(AppSpacing.x4l), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: AppSpacing.x4l, + children: [ + if (showPortrait) + SizedBox(width: 96, child: SkullView(style: calaverita.skull)), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Calaverita for ${calaverita.name}', + style: AppTypography.title.copyWith(color: p.heading), + ), + const SizedBox(height: AppSpacing.xs), + Text( + '${calaverita.job} · ${calaverita.tone.label}', + style: AppTypography.small.copyWith(color: p.inkTertiary), + ), + const Divider(height: AppSpacing.x5l * 2), + for (final line in calaverita.lines) + Text( + line, + style: AppTypography.body.copyWith( + color: p.ink, + fontStyle: FontStyle.italic, + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart new file mode 100644 index 0000000..669a754 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart @@ -0,0 +1,252 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:calaverita_presentation/calaverita/bloc/calaverita_cubit.dart'; +import 'package:calaverita_presentation/calaverita/bloc/calaverita_state.dart'; +import 'package:calaverita_presentation/calaverita/shared_draft/draft_edits.dart'; +import 'package:calaverita_presentation/calaverita/shared_draft/shared_draft.dart'; +import 'package:calaverita_presentation/calaverita/views/details_panel.dart'; +import 'package:calaverita_presentation/calaverita/views/stage.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +/// Width at or above which the columns are side by side. +const _desktopBreakpoint = 1000.0; + +/// The one screen: the details on the left and the stage in the middle, +/// with [trailingPanel] on the right. +/// +/// The details and the stage read the form from the agent's shared state, so +/// the page needs a `CopilotAgentScope` above it. +class CalaveritaPage extends StatefulWidget { + const CalaveritaPage({this.trailingPanel, super.key}); + + /// A panel the app puts beside the stage, or below it on a narrow screen. + final Widget? trailingPanel; + + @override + State createState() => _CalaveritaPageState(); +} + +class _CalaveritaPageState extends State { + @override + void initState() { + super.initState(); + // Waits a frame: sharing state while the tree builds would rebuild + // widgets that are still building. + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) DraftEdits.of(context).ensureInitialized(); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: context.palette.ground, + body: SafeArea( + child: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 1680), + child: Padding( + padding: const EdgeInsets.fromLTRB( + AppSpacing.x4l, + AppSpacing.x3l, + AppSpacing.x4l, + AppSpacing.x4l, + ), + child: Column( + children: [ + const _Header(), + const SizedBox(height: AppSpacing.x3l), + Expanded(child: _Layout(trailingPanel: widget.trailingPanel)), + ], + ), + ), + ), + ), + ), + ); + } +} + +class _Header extends StatelessWidget { + const _Header(); + + @override + Widget build(BuildContext context) { + final p = context.palette; + return DecoratedBox( + decoration: BoxDecoration( + gradient: LinearGradient(colors: [p.navy, p.navyAlt]), + borderRadius: AppRadii.cardBorder, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.x5l, + vertical: AppSpacing.xl, + ), + child: Row( + spacing: AppSpacing.x5l, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Calaverita Generator', + style: AppTypography.title.copyWith(color: p.onNavy), + ), + Text( + 'A funny rhyming skull for someone you love.', + style: AppTypography.small.copyWith(color: p.onNavyMuted), + ), + ], + ), + ), + const _Logos(), + ], + ), + ), + ); + } +} + +class _Layout extends StatelessWidget { + const _Layout({this.trailingPanel}); + + final Widget? trailingPanel; + + @override + Widget build(BuildContext context) { + final panel = trailingPanel; + return LayoutBuilder( + builder: (context, constraints) { + if (constraints.maxWidth >= _desktopBreakpoint) { + return Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + spacing: AppSpacing.x3l, + children: [ + const SizedBox(width: 380, child: _Details()), + const Expanded(child: _Stage()), + if (panel != null) SizedBox(width: 420, child: panel), + ], + ); + } + return SingleChildScrollView( + child: Column( + spacing: AppSpacing.x3l, + children: [ + const SizedBox(height: 640, child: _Stage()), + if (panel != null) SizedBox(height: 520, child: panel), + const SizedBox(height: 760, child: _Details()), + ], + ), + ); + }, + ); + } +} + +class _Details extends StatelessWidget { + const _Details(); + + @override + Widget build(BuildContext context) { + final cubit = context.read(); + final edits = DraftEdits.of(context); + return SharedDraft( + builder: (context, draft) => + BlocBuilder( + builder: (context, state) { + final isGenerating = state.status == GenerationStatus.generating; + return DetailsPanel( + draft: draft, + canGenerate: draft.isComplete && !isGenerating, + isGenerating: isGenerating, + onNameChanged: edits.nameChanged, + onJobChanged: edits.jobChanged, + onToneChanged: edits.toneChanged, + onSkullPartChanged: edits.skullPartChanged, + onSkullColorChanged: edits.skullColorChanged, + onGenerate: () => cubit.generate(draft), + ); + }, + ), + ); + } +} + +class _Stage extends StatelessWidget { + const _Stage(); + + @override + Widget build(BuildContext context) { + return SharedDraft( + builder: (context, draft) => + BlocBuilder( + builder: (context, state) => Stage( + skull: draft.skull, + status: state.status, + calaverita: state.calaverita, + badge: const _AgentBadge(), + ), + ), + ); + } +} + +/// "Copilot is working…" while the agent handles a request. +class _AgentBadge extends StatelessWidget { + const _AgentBadge(); + + @override + Widget build(BuildContext context) { + return AgentStateBuilder( + selector: (state) => state.isRunning && state.awaitingResponseIds.isEmpty, + builder: (context, busy) => AnimatedOpacity( + duration: AppMotion.quick, + opacity: busy ? 1 : 0, + child: const AppChip( + label: 'Copilot is working…', + icon: AppIcons.sparkle, + tone: AppTone.accent, + ), + ), + ); + } +} + +/// The CopilotKit and VGV logos on the right of the banner. They make way for +/// the title on a narrow screen. +class _Logos extends StatelessWidget { + const _Logos(); + + /// Width of the screen from which the logos are shown. + static const _minWidth = 640.0; + + @override + Widget build(BuildContext context) { + if (MediaQuery.sizeOf(context).width < _minWidth) { + return const SizedBox.shrink(); + } + final p = context.palette; + return Row( + mainAxisSize: MainAxisSize.min, + spacing: AppSpacing.x4l, + children: [ + const DecoratedBox( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: AppRadii.pillBorder, + ), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: AppSpacing.xl, + vertical: AppSpacing.md, + ), + child: AppCopilotKitLogo(height: 26), + ), + ), + AppVgvLockup(height: 28, color: p.onNavy), + ], + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart new file mode 100644 index 0000000..1c572f7 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart @@ -0,0 +1,97 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/views/skull_controls.dart'; +import 'package:calaverita_presentation/calaverita/views/synced_text_field.dart'; + +/// The form: who the calaverita is for, how it sounds and how the skull +/// looks, and the button that writes it. +/// +/// It draws the [draft] it is given and reports what the person does through +/// callbacks, so it doesn't care where the draft lives. +class DetailsPanel extends StatelessWidget { + const DetailsPanel({ + required this.draft, + required this.canGenerate, + required this.isGenerating, + required this.onNameChanged, + required this.onJobChanged, + required this.onToneChanged, + required this.onSkullPartChanged, + required this.onSkullColorChanged, + required this.onGenerate, + super.key, + }); + + final CalaveritaDraft draft; + final bool canGenerate; + final bool isGenerating; + final ValueChanged onNameChanged; + final ValueChanged onJobChanged; + final ValueChanged onToneChanged; + final void Function(SkullPart part, String variant) onSkullPartChanged; + final ValueChanged onSkullColorChanged; + final VoidCallback onGenerate; + + @override + Widget build(BuildContext context) { + return AppPanel( + title: 'Details', + icon: AppIcons.package, + child: Column( + children: [ + Expanded( + child: ListView( + padding: const EdgeInsets.fromLTRB( + AppSpacing.x3l, + 0, + AppSpacing.x3l, + AppSpacing.x3l, + ), + children: [ + SyncedTextField( + key: const Key('calaverita_name_field'), + label: 'Name', + hint: 'Who is the calaverita for?', + value: draft.name, + onChanged: onNameChanged, + ), + const SizedBox(height: AppSpacing.xl), + SyncedTextField( + key: const Key('calaverita_job_field'), + label: 'Job', + hint: 'What do they do all day?', + value: draft.job, + onChanged: onJobChanged, + ), + const SizedBox(height: AppSpacing.xl), + AppSegmented( + key: const Key('calaverita_tone_selector'), + segments: {for (final tone in Tone.values) tone: tone.label}, + value: draft.tone, + onChanged: onToneChanged, + compact: true, + ), + const SizedBox(height: AppSpacing.x4l), + SkullControls( + style: draft.skull, + onPartChanged: onSkullPartChanged, + onColorChanged: onSkullColorChanged, + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(AppSpacing.x3l), + child: AppButton.primary( + key: const Key('calaverita_generate_button'), + label: isGenerating ? 'Writing…' : 'Write my calaverita', + icon: AppIcons.sparkle, + expanded: true, + onPressed: canGenerate ? onGenerate : null, + ), + ), + ], + ), + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart new file mode 100644 index 0000000..511e834 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart @@ -0,0 +1,215 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/skull/skull_art.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +/// What the person can do to the skull: take an accessory off or put one on, +/// and paint it. +class SkullControls extends StatelessWidget { + const SkullControls({ + required this.style, + required this.onPartChanged, + required this.onColorChanged, + super.key, + }); + + final SkullStyle style; + final void Function(SkullPart part, String variant) onPartChanged; + final ValueChanged onColorChanged; + + /// Bone, white and the festive colors of the art. + static const swatches = { + '#f6efe0': 'Bone', + '#ffffff': 'White', + '#12a5a0': 'Teal', + '#1fa567': 'Green', + '#f5a524': 'Marigold', + '#ff8fb1': 'Pink', + '#8fa8ff': 'Sky', + '#7048e8': 'Violet', + }; + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: AppSpacing.xl, + children: [ + for (final part in SkullPart.values) + _PartPicker( + part: part, + selected: style.of(part), + onChanged: (variant) => onPartChanged(part, variant), + ), + _ColorPicker(value: style.color, onChanged: onColorChanged), + ], + ); + } +} + +class _Label extends StatelessWidget { + const _Label(this.text); + + final String text; + + @override + Widget build(BuildContext context) => Text( + text, + style: AppTypography.smallMedium.copyWith( + color: context.palette.inkSecondary, + ), + ); +} + +class _PartPicker extends StatelessWidget { + const _PartPicker({ + required this.part, + required this.selected, + required this.onChanged, + }); + + final SkullPart part; + final String selected; + final ValueChanged onChanged; + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: AppSpacing.md, + children: [ + _Label(part.label), + Wrap( + spacing: AppSpacing.md, + runSpacing: AppSpacing.md, + children: [ + for (final variant in [SkullStyle.none, ...part.variants]) + _Option( + part: part, + variant: variant, + selected: variant == selected, + onTap: () => onChanged(variant), + ), + ], + ), + ], + ); + } +} + +class _Option extends StatelessWidget { + const _Option({ + required this.part, + required this.variant, + required this.selected, + required this.onTap, + }); + + final SkullPart part; + final String variant; + final bool selected; + final VoidCallback onTap; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final art = context.read(); + final svg = variant == SkullStyle.none + ? null + : art.thumbnail( + SkullArt.layerOf(part), + variant, + SkullArt.focusOf(part), + ); + return Semantics( + button: true, + selected: selected, + label: '${part.label} $variant', + child: AppPressable( + onTap: onTap, + pressedScale: 0.97, + child: AnimatedContainer( + duration: AppMotion.quick, + width: 62, + padding: const EdgeInsets.all(AppSpacing.md), + decoration: BoxDecoration( + color: selected ? p.accentWash : p.cardGround, + borderRadius: BorderRadius.circular(AppRadii.option), + border: Border.all( + color: selected ? p.accent : Colors.transparent, + width: 2, + ), + ), + child: Column( + spacing: AppSpacing.xs, + children: [ + SizedBox( + height: 44, + child: svg == null + ? Icon(Icons.block, color: p.inkTertiary) + : SvgPicture.string(svg), + ), + Text( + variant == SkullStyle.none ? 'None' : variant, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: AppTypography.micro.copyWith(color: p.inkSecondary), + ), + ], + ), + ), + ), + ); + } +} + +class _ColorPicker extends StatelessWidget { + const _ColorPicker({required this.value, required this.onChanged}); + + final String value; + final ValueChanged onChanged; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: AppSpacing.md, + children: [ + const _Label('Skull color'), + Wrap( + spacing: AppSpacing.md, + runSpacing: AppSpacing.md, + children: [ + for (final MapEntry(key: hex, value: name) + in SkullControls.swatches.entries) + Semantics( + button: true, + label: name, + selected: hex == value, + child: GestureDetector( + onTap: () => onChanged(hex), + child: AnimatedContainer( + duration: AppMotion.quick, + width: 28, + height: 28, + decoration: BoxDecoration( + color: Color( + int.parse('ff${hex.substring(1)}', radix: 16), + ), + shape: BoxShape.circle, + border: Border.all( + color: hex == value ? p.accent : p.hairline, + width: hex == value ? 3 : 1, + ), + ), + ), + ), + ), + ], + ), + ], + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart new file mode 100644 index 0000000..689b482 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart @@ -0,0 +1,52 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/skull/skull_art.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +/// Draws the skull: its fixed pieces and the accessories it wears, stacked +/// bottom first. +/// +/// It only reads [style], so it draws the same wherever it is: the stage, a +/// card in the chat. Needs a [SkullArt] above it. +class SkullView extends StatelessWidget { + const SkullView({required this.style, super.key}); + + final SkullStyle style; + + @override + Widget build(BuildContext context) { + final art = context.read(); + final pieces = <(String, String?)>[ + ('base', art.svg(SkullArt.base.withFill(style.color))), + ('pattern', art.svg(SkullArt.pattern)), + ('eyes', art.svg(SkullArt.eyes)), + ('nose', art.svg(SkullArt.nose)), + _accessory(art, SkullPart.mustache), + ('mouth', art.svg(SkullArt.mouth)), + _accessory(art, SkullPart.glasses), + _accessory(art, SkullPart.flowers), + _accessory(art, SkullPart.hat), + ]; + return AspectRatio( + aspectRatio: 400 / 500, + child: Stack( + fit: StackFit.expand, + children: [ + for (final (key, svg) in pieces) + if (svg != null) SvgPicture.string(svg, key: ValueKey(key)), + ], + ), + ); + } + + (String, String?) _accessory(SkullArt art, SkullPart part) { + final variant = style.of(part); + return ( + part.name, + variant == SkullStyle.none + ? null + : art.svg(SkullArt.layerOf(part), variant), + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart new file mode 100644 index 0000000..eeb440b --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart @@ -0,0 +1,51 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/bloc/calaverita_state.dart'; +import 'package:calaverita_presentation/calaverita/views/calaverita_card.dart'; +import 'package:calaverita_presentation/calaverita/views/skull_view.dart'; + +/// The skull as it looks right now, and the calaverita once it is written. +class Stage extends StatelessWidget { + const Stage({ + required this.skull, + required this.status, + this.calaverita, + this.badge, + super.key, + }); + + final SkullStyle skull; + final GenerationStatus status; + + /// The last calaverita written, if any. + final Calaverita? calaverita; + + /// A small widget in the top left corner, e.g. what the agent is doing. + final Widget? badge; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final calaverita = this.calaverita; + return AppCard( + padding: const EdgeInsets.all(AppSpacing.x4l), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + spacing: AppSpacing.x3l, + children: [ + Expanded( + child: Center(child: SkullView(style: skull)), + ), + if (status == GenerationStatus.failure) + Text( + 'The skull lost its voice. Try again.', + textAlign: TextAlign.center, + style: AppTypography.small.copyWith(color: p.negative), + ) + else if (calaverita != null) + CalaveritaCard(calaverita: calaverita, showPortrait: false), + ], + ), + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart new file mode 100644 index 0000000..1a12292 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; + +/// A text field that shows [value], even when it changes from outside. +/// +/// The text the person types and the [value] stay in step, so whatever sets +/// the state (the keyboard, later an agent) shows up in the field. A field +/// that is being typed in is left alone. +class SyncedTextField extends StatefulWidget { + const SyncedTextField({ + required this.label, + required this.hint, + required this.value, + required this.onChanged, + super.key, + }); + + final String label; + final String hint; + final String value; + final ValueChanged onChanged; + + @override + State createState() => _SyncedTextFieldState(); +} + +class _SyncedTextFieldState extends State { + late final _controller = TextEditingController(text: widget.value); + + @override + void didUpdateWidget(SyncedTextField oldWidget) { + super.didUpdateWidget(oldWidget); + if (_controller.text != widget.value) _controller.text = widget.value; + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return TextField( + controller: _controller, + onChanged: widget.onChanged, + decoration: InputDecoration( + labelText: widget.label, + hintText: widget.hint, + ), + ); + } +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart new file mode 100644 index 0000000..a891146 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart @@ -0,0 +1,7 @@ +export 'calaverita/bloc/calaverita_cubit.dart'; +export 'calaverita/bloc/calaverita_state.dart'; +export 'calaverita/calaverita_module.dart'; +export 'calaverita/show_calaverita/show_calaverita_tool.dart'; +export 'calaverita/skull/skull_art.dart'; +export 'calaverita/views/calaverita_card.dart'; +export 'calaverita/views/skull_view.dart'; diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/pubspec.yaml b/03-human-in-the-loop/features/calaverita/calaverita_presentation/pubspec.yaml new file mode 100644 index 0000000..e5ecdaf --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/pubspec.yaml @@ -0,0 +1,40 @@ +name: calaverita_presentation +description: The details, the stage and the skull portrait of the calaverita screen. +version: 0.1.0 +publish_to: none +resolution: workspace + +environment: + sdk: ^3.13.0 + flutter: ^3.47.0 + +dependencies: + ack: ^1.7.0 + app_ui: any + calaverita_domain: any + copilotkit_flutter: any + equatable: ^3.0.0 + flutter: + sdk: flutter + flutter_bloc: ^9.1.1 + flutter_svg: ^2.2.4 + provider: ^6.1.5 + +dev_dependencies: + bloc_test: ^10.0.0 + flutter_test: + sdk: flutter + mocktail: ^1.0.5 + very_good_analysis: ^11.0.0 + +flutter: + assets: + - assets/skull/base/ + - assets/skull/pattern/ + - assets/skull/eyes/ + - assets/skull/nose/ + - assets/skull/mouth/ + - assets/skull/mustache/ + - assets/skull/glasses/ + - assets/skull/flowers/ + - assets/skull/hat/ diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart new file mode 100644 index 0000000..3d3be48 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart @@ -0,0 +1,76 @@ +import 'package:bloc_test/bloc_test.dart'; +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; + +class _MockRepository extends Mock implements ICalaveritasRepository; + +void main() { + const draft = CalaveritaDraft(name: 'Ana', job: 'Chef'); + const calaverita = Calaverita( + name: 'Ana', + job: 'chef', + tone: Tone.playful, + lines: ['a', 'b', 'c', 'd'], + ); + + late _MockRepository repository; + + setUpAll(() => registerFallbackValue(draft)); + setUp(() => repository = _MockRepository()); + + CalaveritaCubit build() => CalaveritaCubit(calaveritasRepository: repository); + + group(CalaveritaCubit, () { + blocTest( + 'writes a calaverita for a complete draft', + setUp: () => + when(() => repository.generate(any())) + .thenAnswer((_) async => calaverita), + build: build, + act: (cubit) => cubit.generate(draft), + expect: () => const [ + CalaveritaState(status: GenerationStatus.generating), + CalaveritaState( + status: GenerationStatus.success, + calaverita: calaverita, + ), + ], + verify: (_) => verify(() => repository.generate(draft)).called(1), + ); + + blocTest( + 'shows a calaverita the agent wrote', + build: build, + act: (cubit) => cubit.calaveritaShown(calaverita), + expect: () => const [ + CalaveritaState( + status: GenerationStatus.success, + calaverita: calaverita, + ), + ], + ); + + blocTest( + 'does nothing while the draft is incomplete', + build: build, + act: (cubit) => cubit.generate(const CalaveritaDraft(name: 'Ana')), + expect: () => const [], + verify: (_) => verifyNever(() => repository.generate(any())), + ); + + blocTest( + 'fails when the repository throws', + setUp: () => + when(() => repository.generate(any())).thenThrow(StateError('no')), + build: build, + act: (cubit) => cubit.generate(draft), + errors: () => [isA()], + expect: () => const [ + CalaveritaState(status: GenerationStatus.generating), + CalaveritaState(status: GenerationStatus.failure), + ], + ); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart new file mode 100644 index 0000000..abc41d7 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart @@ -0,0 +1,145 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/shared_draft/draft_edits.dart'; +import 'package:calaverita_presentation/calaverita/shared_draft/shared_draft.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + const agentId = 'default'; + late DraftEdits edits; + late CopilotAgent agent; + CalaveritaDraft? shown; + + Future settle(WidgetTester tester) async { + await tester.runAsync(pumpEventQueue); + await tester.pump(); + } + + Future pumpScope(WidgetTester tester) async { + shown = null; + await tester.pumpWidget( + CopilotKit( + // Never called: nothing in these tests runs the agent. + runtimeUrl: Uri.parse('http://localhost:1/api/copilotkit'), + child: MaterialApp( + home: CopilotAgentScope( + agentId: agentId, + child: SharedDraft( + builder: (context, draft) { + shown = draft; + edits = DraftEdits.of(context); + return const SizedBox(); + }, + ), + ), + ), + ), + ); + agent = CopilotKit.of(tester.element(find.byType(SizedBox))).agent(agentId); + } + + Map? shared() => agent.state.sharedState?.toJson(); + + group(DraftEdits, () { + testWidgets('shares the empty form once', (tester) async { + await pumpScope(tester); + expect(shared(), isNull); + + edits.ensureInitialized(); + expect(shared(), const CalaveritaDraft().toJson()); + + edits + ..nameChanged('Ana') + ..ensureInitialized(); + expect(shared()!['name'], 'Ana'); + }); + + testWidgets('patches one field at a time', (tester) async { + await pumpScope(tester); + edits + ..ensureInitialized() + ..nameChanged('Ana') + ..jobChanged('Pilot') + ..toneChanged(Tone.sarcastic) + ..skullPartChanged(SkullPart.hat, 'sombrero') + ..skullColorChanged('#12a5a0'); + + expect( + shared(), + const CalaveritaDraft( + name: 'Ana', + job: 'Pilot', + tone: Tone.sarcastic, + skull: SkullStyle(color: '#12a5a0', hat: 'sombrero'), + ).toJson(), + ); + }); + + testWidgets('recovers when the agent shares a state without the path', ( + tester, + ) async { + await pumpScope(tester); + agent.setSharedState(const SharedState({'name': 'Luz'})); + + edits.skullPartChanged(SkullPart.glasses, 'heart'); + + expect( + shared(), + const CalaveritaDraft( + name: 'Luz', + skull: SkullStyle(glasses: 'heart'), + ).toJson(), + ); + }); + + testWidgets('resets the form', (tester) async { + await pumpScope(tester); + edits + ..nameChanged('Ana') + ..reset(); + + expect(shared(), const CalaveritaDraft().toJson()); + }); + }); + + group(SharedDraft, () { + testWidgets('shows an empty draft while nothing is shared', (tester) async { + await pumpScope(tester); + + expect(shown, const CalaveritaDraft()); + }); + + testWidgets('shows what the agent shares', (tester) async { + await pumpScope(tester); + + agent.patchSharedState(const [ + StatePatchAdd(path: '/name', value: 'Ana'), + StatePatchAdd(path: '/skull', value: {'hat': 'crown'}), + ]); + await settle(tester); + + expect( + shown, + const CalaveritaDraft( + name: 'Ana', + skull: SkullStyle(hat: 'crown'), + ), + ); + }); + + testWidgets('shows a snapshot of the agent', (tester) async { + await pumpScope(tester); + + agent.setSharedState( + const SharedState({'name': 'Luz', 'job': 'Pilot', 'tone': 'dramatic'}), + ); + await settle(tester); + + expect( + shown, + const CalaveritaDraft(name: 'Luz', job: 'Pilot', tone: Tone.dramatic), + ); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart new file mode 100644 index 0000000..0cd6ba4 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart @@ -0,0 +1,99 @@ +import 'dart:convert'; + +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita/show_calaverita/show_calaverita_args.dart'; +import 'package:calaverita_presentation/calaverita/show_calaverita/show_calaverita_handler.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + const args = ShowCalaveritaArgs(lines: ['one', 'two', 'three', 'four']); + + final written = []; + setUp(written.clear); + + Future run(CalaveritaDraft draft, ShowCalaveritaArgs args) => + ShowCalaveritaHandler( + readDraft: () => draft, + onWritten: written.add, + ).handle(args, signal: CancellationSignal()); + + group(ShowCalaveritaHandler, () { + test('puts the verse together with the form and the skull', () async { + final result = await run( + const CalaveritaDraft( + name: ' Ana ', + job: 'Pilot', + tone: Tone.sarcastic, + skull: SkullStyle(hat: 'crown'), + ), + args, + ); + + expect( + Calaverita.fromJson(jsonDecode(result) as Map), + const Calaverita( + name: 'Ana', + job: 'pilot', + tone: Tone.sarcastic, + lines: ['one', 'two', 'three', 'four'], + skull: SkullStyle(hat: 'crown'), + ), + ); + }); + + test('hands the calaverita to the stage', () async { + await run(const CalaveritaDraft(name: 'Ana', job: 'Pilot'), args); + + expect(written, [ + const Calaverita( + name: 'Ana', + job: 'pilot', + tone: Tone.playful, + lines: ['one', 'two', 'three', 'four'], + ), + ]); + }); + + test('hands the calaverita to the stage', () async { + await run(const CalaveritaDraft(name: 'Ana', job: 'Pilot'), args); + + expect(written, [ + const Calaverita( + name: 'Ana', + job: 'pilot', + tone: Tone.playful, + lines: ['one', 'two', 'three', 'four'], + ), + ]); + }); + + test('says so when the form is incomplete', () async { + final result = await run(const CalaveritaDraft(name: 'Ana'), args); + + expect(result, contains('name and a job')); + expect(written, isEmpty); + }); + + test('says so when there is no verse', () async { + final result = await run( + const CalaveritaDraft(name: 'Ana', job: 'Pilot'), + const ShowCalaveritaArgs(), + ); + + expect(result, contains('no verse')); + expect(written, isEmpty); + }); + }); + + group(ShowCalaveritaArgs, () { + test('reads the lines and ignores what is not text', () { + final args = ShowCalaveritaArgs.fromJson(const { + 'lines': ['one', 2, 'three'], + }); + + expect(args.lines, ['one', 'three']); + expect(ShowCalaveritaArgs.fromJson(const {}).lines, isEmpty); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart new file mode 100644 index 0000000..b6f4b9d --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart @@ -0,0 +1,95 @@ +import 'dart:convert'; + +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:provider/provider.dart'; + +import '../../helpers/test_skull_art.dart'; + +class _MockRepository extends Mock implements ICalaveritasRepository; + +void main() { + const calaverita = Calaverita( + name: 'Ana', + job: 'pilot', + tone: Tone.sarcastic, + lines: ['one', 'two', 'three', 'four'], + ); + + /// Renders [call] the way the chat does: through a `ToolCallWidget` below + /// the tool. + Future pumpCall(WidgetTester tester, ToolCallView call) { + return tester.pumpWidget( + CopilotKit( + // Never called: nothing in these tests runs the agent. + runtimeUrl: Uri.parse('http://localhost:1/api/copilotkit'), + child: MaterialApp( + home: Provider.value( + value: TestSkullArt.build(), + child: CopilotAgentScope( + agentId: 'default', + child: BlocProvider( + create: (_) => + CalaveritaCubit(calaveritasRepository: _MockRepository()), + child: Scaffold( + body: ShowCalaveritaTool(child: ToolCallWidget(call: call)), + ), + ), + ), + ), + ), + ), + ); + } + + ToolCallView callWith(ToolCallStatus status, {String? result}) => + ToolCallView( + id: 'call-1', + name: 'showCalaverita', + status: status, + result: result, + ); + + group(ShowCalaveritaTool, () { + testWidgets('shows a placeholder while the agent writes', (tester) async { + await pumpCall(tester, callWith(ToolCallStatus.inProgress)); + + expect(find.text('Writing the calaverita…'), findsOneWidget); + expect(find.byType(CalaveritaCard), findsNothing); + }); + + testWidgets('shows the card once the call is complete', (tester) async { + await pumpCall( + tester, + callWith( + ToolCallStatus.complete, + result: jsonEncode(calaverita.toJson()), + ), + ); + + expect(find.byType(CalaveritaCard), findsOneWidget); + expect(find.text('Calaverita for Ana'), findsOneWidget); + expect(find.text('three'), findsOneWidget); + }); + + testWidgets('shows the message when the result is not a calaverita', ( + tester, + ) async { + await pumpCall( + tester, + callWith( + ToolCallStatus.complete, + result: 'The form still needs a name and a job.', + ), + ); + + expect(find.byType(CalaveritaCard), findsNothing); + expect(find.textContaining('still needs a name'), findsOneWidget); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart new file mode 100644 index 0000000..6d34c81 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart @@ -0,0 +1,43 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:flutter/painting.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/test_skull_art.dart'; + +void main() { + group(SkullArt, () { + final art = TestSkullArt.build(); + + test('fills the colors into the template', () { + final svg = art.svg(SkullArt.hat, 'sombrero')!; + expect(svg, contains('fill="#e0353b"')); + expect(svg, contains('stroke-width="4.0"')); + expect(svg, isNot(contains('{{'))); + }); + + test('draws a fixed piece whatever the variant', () { + expect(art.svg(SkullArt.base.withFill('#12a5a0')), contains('#12a5a0')); + }); + + test('has no SVG for a variant it was not given', () { + expect(art.svg(SkullArt.hat, 'crown'), isNull); + }); + + test('crops a thumbnail to where the part sits', () { + final svg = art.thumbnail( + SkullArt.glasses, + 'heart', + SkullArt.focusOf(SkullPart.glasses), + )!; + expect(svg, contains('viewBox="60.0 160.0 280.0 110.0"')); + }); + + test('knows where every accessory sits', () { + for (final part in SkullPart.values) { + expect(SkullArt.focusOf(part), isNot(Rect.zero)); + expect(SkullArt.layerOf(part).kind, part.name); + } + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart new file mode 100644 index 0000000..aa96fce --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart @@ -0,0 +1,72 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:provider/provider.dart'; + +import '../../helpers/test_skull_art.dart'; + +void main() { + const calaverita = Calaverita( + name: 'Ana', + job: 'chef', + tone: Tone.sarcastic, + lines: ['one', 'two', 'three', 'four'], + ); + + Future pumpCard(WidgetTester tester, {required bool showPortrait}) { + return tester.pumpWidget( + Provider.value( + value: TestSkullArt.build(), + child: MaterialApp( + home: Scaffold( + body: CalaveritaCard( + calaverita: calaverita, + showPortrait: showPortrait, + ), + ), + ), + ), + ); + } + + group(CalaveritaCard, () { + testWidgets('shows the title, the subject and every line', (tester) async { + await pumpCard(tester, showPortrait: true); + + expect(find.text('Calaverita for Ana'), findsOneWidget); + expect(find.text('chef · Sarcastic'), findsOneWidget); + for (final line in calaverita.lines) { + expect(find.text(line), findsOneWidget); + } + }); + + testWidgets('has the same opaque background on any surface', ( + tester, + ) async { + await pumpCard(tester, showPortrait: false); + + final decoration = + tester + .widget( + find + .descendant( + of: find.byType(CalaveritaCard), + matching: find.byType(DecoratedBox), + ) + .first, + ) + .decoration + as BoxDecoration; + expect(decoration.color!.a, 1); + }); + + testWidgets('shows the portrait unless asked not to', (tester) async { + await pumpCard(tester, showPortrait: true); + expect(find.byType(SkullView), findsOneWidget); + + await pumpCard(tester, showPortrait: false); + expect(find.byType(SkullView), findsNothing); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart new file mode 100644 index 0000000..f8aa2e0 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart @@ -0,0 +1,131 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:copilotkit_flutter/copilotkit_flutter.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; + +import '../../helpers/test_skull_art.dart'; + +class _MockRepository extends Mock implements ICalaveritasRepository; + +void main() { + const agentId = 'default'; + late _MockRepository repository; + + setUpAll(() => registerFallbackValue(const CalaveritaDraft())); + setUp(() => repository = _MockRepository()); + + /// Lets the agent's stream deliver its last state, then rebuilds. + Future settle(WidgetTester tester) async { + await tester.runAsync(pumpEventQueue); + await tester.pump(); + } + + Future pumpPage(WidgetTester tester) async { + tester.view + ..devicePixelRatio = 1 + ..physicalSize = const Size(1400, 1000); + addTearDown(tester.view.reset); + await tester.pumpWidget( + CopilotKit( + // Never called: nothing in these tests runs the agent. + runtimeUrl: Uri.parse('http://localhost:1/api/copilotkit'), + child: MaterialApp( + home: CopilotAgentScope( + agentId: agentId, + child: CalaveritaModule( + calaveritasRepository: repository, + skullArt: TestSkullArt.build(), + ), + ), + ), + ), + ); + await tester.pump(); + return CopilotKit.of(tester.element(find.byType(CalaveritaModule))) + .agent(agentId); + } + + String textOf(WidgetTester tester, String key) => tester + .widget( + find.descendant( + of: find.byKey(Key(key)), + matching: find.byType(TextField), + ), + ) + .controller! + .text; + + group(CalaveritaModule, () { + testWidgets('shares the empty form with the agent', (tester) async { + final agent = await pumpPage(tester); + + expect( + agent.state.sharedState?.toJson(), + const CalaveritaDraft().toJson(), + ); + }); + + testWidgets('fills the details from what the agent shares', (tester) async { + final agent = await pumpPage(tester); + + agent.patchSharedState(const [ + StatePatchReplace(path: '/name', value: 'Ana'), + StatePatchReplace(path: '/job', value: 'Chef'), + StatePatchReplace(path: '/skull/hat', value: 'sombrero'), + ]); + await settle(tester); + + expect(textOf(tester, 'calaverita_name_field'), 'Ana'); + expect(textOf(tester, 'calaverita_job_field'), 'Chef'); + expect(find.byKey(const ValueKey('hat')), findsOneWidget); + }); + + testWidgets('writes what the person types into the shared state', ( + tester, + ) async { + final agent = await pumpPage(tester); + + await tester.enterText( + find.byKey(const Key('calaverita_name_field')), + 'Ana', + ); + await tester.tap(find.bySemanticsLabel('Glasses heart')); + await tester.pump(); + + expect(agent.state.sharedState!.toJson(), { + ...const CalaveritaDraft().toJson(), + 'name': 'Ana', + 'skull': const SkullStyle(glasses: 'heart').toJson(), + }); + }); + + testWidgets('writes the calaverita for the shared draft', (tester) async { + when(() => repository.generate(any())).thenAnswer( + (_) async => const Calaverita( + name: 'Ana', + job: 'chef', + tone: Tone.playful, + lines: ['one', 'two', 'three', 'four'], + ), + ); + final agent = await pumpPage(tester); + agent.patchSharedState(const [ + StatePatchReplace(path: '/name', value: 'Ana'), + StatePatchReplace(path: '/job', value: 'Chef'), + ]); + await settle(tester); + + await tester.tap(find.byKey(const Key('calaverita_generate_button'))); + await settle(tester); + + verify( + () => repository.generate( + const CalaveritaDraft(name: 'Ana', job: 'Chef'), + ), + ).called(1); + expect(find.text('Calaverita for Ana'), findsOneWidget); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart new file mode 100644 index 0000000..fe2e9e0 --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart @@ -0,0 +1,46 @@ +import 'package:calaverita_domain/calaverita_domain.dart'; +import 'package:calaverita_presentation/calaverita_presentation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:provider/provider.dart'; + +import '../../helpers/test_skull_art.dart'; + +void main() { + Future pumpSkull(WidgetTester tester, SkullStyle style) { + return tester.pumpWidget( + Provider.value( + value: TestSkullArt.build(), + child: MaterialApp( + home: Scaffold(body: SkullView(style: style)), + ), + ), + ); + } + + group(SkullView, () { + testWidgets('draws the five fixed pieces on a plain skull', (tester) async { + await pumpSkull(tester, const SkullStyle()); + + expect(find.byType(SvgPicture), findsNWidgets(5)); + }); + + testWidgets('adds what the skull wears', (tester) async { + await pumpSkull( + tester, + const SkullStyle(hat: 'sombrero', glasses: 'heart'), + ); + + expect(find.byType(SvgPicture), findsNWidgets(7)); + expect(find.byKey(const ValueKey('hat')), findsOneWidget); + expect(find.byKey(const ValueKey('glasses')), findsOneWidget); + }); + + testWidgets('skips an accessory it has no art for', (tester) async { + await pumpSkull(tester, const SkullStyle(mustache: 'walrus')); + + expect(find.byType(SvgPicture), findsNWidgets(5)); + }); + }); +} diff --git a/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart new file mode 100644 index 0000000..57f337a --- /dev/null +++ b/03-human-in-the-loop/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart @@ -0,0 +1,27 @@ +import 'package:calaverita_presentation/calaverita_presentation.dart'; + +/// A few one-rectangle SVGs, enough to tell which pieces are drawn. +class TestSkullArt { + const TestSkullArt._(); + + static String _svg(String id) => [ + '', + '', + '', + ].join(); + + static SkullArt build() => SkullArt.fromTemplates({ + for (final path in [ + 'base/round', + 'pattern/swirls', + 'eyes/marigold', + 'nose/heart', + 'mouth/stitched', + 'hat/sombrero', + 'glasses/heart', + ]) + path: _svg(path.replaceAll('/', '-')), + }); +} diff --git a/03-human-in-the-loop/pubspec.lock b/03-human-in-the-loop/pubspec.lock new file mode 100644 index 0000000..40e2733 --- /dev/null +++ b/03-human-in-the-loop/pubspec.lock @@ -0,0 +1,696 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "1b0e6a07425a3e460666e88bf1c949ccc7bb0116ad562ce94a1eca60fe820725" + url: "https://pub.dev" + source: hosted + version: "103.0.0" + ack: + dependency: transitive + description: + name: ack + sha256: "58546330839c455e5816c31be0b708a33f6b57ecd580d61f86d21c3df612f081" + url: "https://pub.dev" + source: hosted + version: "1.7.0" + ag_ui: + dependency: transitive + description: + name: ag_ui + sha256: f963810252e5c080af0ff779b03949ac8d45362042bf2ec2b7c711737d3e6457 + url: "https://pub.dev" + source: hosted + version: "0.3.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "61c04d0c1bfed555c681ea079519933f071a5a026578ff73c4ff0df2d3462e5e" + url: "https://pub.dev" + source: hosted + version: "13.3.0" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + async: + dependency: transitive + description: + name: async + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + url: "https://pub.dev" + source: hosted + version: "2.13.1" + bloc: + dependency: transitive + description: + name: bloc + sha256: e03b235924e4f509c27b5d6b2f949200e0a91149a9818b4f65eeb56662b75413 + url: "https://pub.dev" + source: hosted + version: "9.2.1" + bloc_concurrency: + dependency: transitive + description: + name: bloc_concurrency + sha256: "86b7b17a0a78f77fca0d7c030632b59b593b22acea2d96972588f40d4ef53a94" + url: "https://pub.dev" + source: hosted + version: "0.3.0" + bloc_test: + dependency: transitive + description: + name: bloc_test + sha256: "1dd549e58be35148bc22a9135962106aa29334bc1e3f285994946a1057b29d7b" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + characters: + dependency: transitive + description: + name: characters + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + url: "https://pub.dev" + source: hosted + version: "1.4.1" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: "89b8801ba49f8b593fbf2d3e59efd0f566c46cd4ba6837ae2610c72b52a0f899" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + clock: + dependency: transitive + description: + name: clock + sha256: e51d50bca3217c9a9fa2b41a30e4a38971133f5f9ec7a3d57bae095007f1d28e + url: "https://pub.dev" + source: hosted + version: "1.1.3" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + copilotkit: + dependency: "direct overridden" + description: + path: "packages/copilotkit" + ref: e52039c1729d57358ddac9c956fd2a2052928bbd + resolved-ref: e52039c1729d57358ddac9c956fd2a2052928bbd + url: "https://github.com/VGVentures/copilotkit_flutter_sdk.git" + source: git + version: "0.1.0+1" + copilotkit_flutter: + dependency: "direct overridden" + description: + path: "packages/copilotkit_flutter" + ref: e52039c1729d57358ddac9c956fd2a2052928bbd + resolved-ref: e52039c1729d57358ddac9c956fd2a2052928bbd + url: "https://github.com/VGVentures/copilotkit_flutter_sdk.git" + source: git + version: "0.1.0+1" + coverage: + dependency: transitive + description: + name: coverage + sha256: ff89e37c19355194e279d26dafe8e4bece46c9ea63a30be4dc68214f5bc290d3 + url: "https://pub.dev" + source: hosted + version: "1.16.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" + diff_match_patch: + dependency: transitive + description: + name: diff_match_patch + sha256: "2efc9e6e8f449d0abe15be240e2c2a3bcd977c8d126cfd70598aee60af35c0a4" + url: "https://pub.dev" + source: hosted + version: "0.4.1" + equatable: + dependency: transitive + description: + name: equatable + sha256: ea36e500cbf0ec18361deabca755434f73e42fe53c5130021c7e2d6b5ebe1702 + url: "https://pub.dev" + source: hosted + version: "3.0.0" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" + flutter: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_bloc: + dependency: transitive + description: + name: flutter_bloc + sha256: cf51747952201a455a1c840f8171d273be009b932c75093020f9af64f2123e38 + url: "https://pub.dev" + source: hosted + version: "9.1.1" + flutter_svg: + dependency: transitive + description: + name: flutter_svg + sha256: "35882981abcbfb8c15b286f0cd690ff25bac12d95eff3e25ee207f37d4c42e7f" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + flutter_test: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "2b56423afc7651a81da53ed3a4f9f51e92572293f54d0d54e19b759f13714849" + url: "https://pub.dev" + source: hosted + version: "4.2.0" + glob: + dependency: transitive + description: + name: glob + sha256: "218aeb56050c714f62a3182775320dfa04602b55074873e24e31bbd39bda96fb" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + http: + dependency: transitive + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "361668bdd71f0ae2dc6d17b75a593520f3c414af6534f9eed1aa72049dd71d18" + url: "https://pub.dev" + source: hosted + version: "3.2.3" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + io: + dependency: transitive + description: + name: io + sha256: "2635216ca6a737e60de577ffa1a48a0bec76ca8a62917cfc1bb88c14c570646f" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "2a743920d81b7910627f68ee2c9ac1fc0bfee32b9fc3403587d7c6791ca12f80" + url: "https://pub.dev" + source: hosted + version: "4.12.0" + json_utils: + dependency: "direct overridden" + description: + path: "packages/json_utils" + ref: e52039c1729d57358ddac9c956fd2a2052928bbd + resolved-ref: e52039c1729d57358ddac9c956fd2a2052928bbd + url: "https://github.com/VGVentures/copilotkit_flutter_sdk.git" + source: git + version: "0.1.0+1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" + url: "https://pub.dev" + source: hosted + version: "0.12.20" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + url: "https://pub.dev" + source: hosted + version: "0.13.0" + meta: + dependency: transitive + description: + name: meta + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" + url: "https://pub.dev" + source: hosted + version: "1.19.0" + mime: + dependency: transitive + description: + name: mime + sha256: bd47de35f07e27267e69c8c8b22edf9473bfee170a60d60fcc93730c5144b7f6 + url: "https://pub.dev" + source: hosted + version: "2.1.0" + mocktail: + dependency: transitive + description: + name: mocktail + sha256: "5e1bf53cc7baa8062a33b84424deb61513858ea05c601b8509e683815b5914aa" + url: "https://pub.dev" + source: hosted + version: "1.0.5" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "2f1564aadb14215e478563b5406cb80729d022158c01dc50c96013c2f7eb4790" + url: "https://pub.dev" + source: hosted + version: "7.1.0" + pool: + dependency: transitive + description: + name: pool + sha256: "4177f68c237ea2128d1bee66ac17b2ce05ba3dbaafcbdd54c5d40a39d0b6b11c" + url: "https://pub.dev" + source: hosted + version: "1.5.3" + provider: + dependency: transitive + description: + name: provider + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" + url: "https://pub.dev" + source: hosted + version: "6.1.5+1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "261236774e8b1d69cfc6b9eabbc96c40f25e7a2d6b171f3385d4f65d5734fb24" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: e75e9cf311d7fd712048038cc17c25199c38536c20330d53e7db058b543d5a48 + url: "https://pub.dev" + source: hosted + version: "1.4.3" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: "480504af9e5323899c5be26a4f6c2fc4437d50954d39842f0290f4ae733d57b4" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "14c2945847669b44089bb1222f66873d7ff7103c58911917f2a63c5a62327898" + url: "https://pub.dev" + source: hosted + version: "0.10.14" + source_span: + dependency: transitive + description: + name: source_span + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" + url: "https://pub.dev" + source: hosted + version: "1.10.2" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "277654b3034d17ac6f9f1cb5595db011b1d5d41e8806866db28e0abaa101c490" + url: "https://pub.dev" + source: hosted + version: "1.12.2" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: a00e5f18bffc764f923e7dec1038527f7fe7a1791361a7117f0358193f13d53a + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test: + dependency: transitive + description: + name: test + sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f + url: "https://pub.dev" + source: hosted + version: "1.31.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" + url: "https://pub.dev" + source: hosted + version: "0.7.12" + test_core: + dependency: transitive + description: + name: test_core + sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5 + url: "https://pub.dev" + source: hosted + version: "0.6.18" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + uuid: + dependency: transitive + description: + name: uuid + sha256: "9b129329f58692f6e6578329498a8fe9fbe98f090beb764ffbb8ee2eadd01dcd" + url: "https://pub.dev" + source: hosted + version: "4.6.0" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: "0964703d02677ac8636b4aef95de0b7e816224ff0082908c2c950529cb9a2f5e" + url: "https://pub.dev" + source: hosted + version: "1.2.4" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" + url: "https://pub.dev" + source: hosted + version: "1.1.13" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: a8e2c19796144da2f81bcc96dad1bb19c4677b561c452081b97ee737b9faed65 + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "92b9910f66ed1057fd4da7b040ae7c74cafacf885bdc81be496928d5049b032d" + url: "https://pub.dev" + source: hosted + version: "2.4.3" + very_good_analysis: + dependency: transitive + description: + name: very_good_analysis + sha256: "0bd5eb8d6be76aa0d71e70cbdae6cac8f784f761170568e3c2214a6948c7f6d3" + url: "https://pub.dev" + source: hosted + version: "11.0.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "89b11d62e1040ee681af3b4f1c97a803ecbf010c6e8b9c5896ee5b08c3bf7b78" + url: "https://pub.dev" + source: hosted + version: "15.4.0" + watcher: + dependency: transitive + description: + name: watcher + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + web: + dependency: transitive + description: + name: web + sha256: e119e82ac4795c7925103b7cf3768191f33941b99e7ccffbd6c645201d9f606b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + xml: + dependency: transitive + description: + name: xml + sha256: "67f0aff7be013d107995e9b75bf4e7f2c3ef2dfdb2c8e68024bba0a7fd5756a4" + url: "https://pub.dev" + source: hosted + version: "7.0.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: f67cdd8e07d3c6329146aaef1ba043542b3134c12489f553ca9a7435d1068aea + url: "https://pub.dev" + source: hosted + version: "3.1.4" +sdks: + dart: ">=3.13.0 <4.0.0" + flutter: ">=3.47.0 <4.0.0" diff --git a/03-human-in-the-loop/pubspec.yaml b/03-human-in-the-loop/pubspec.yaml new file mode 100644 index 0000000..37721f1 --- /dev/null +++ b/03-human-in-the-loop/pubspec.yaml @@ -0,0 +1,33 @@ +name: calaverita_workspace +publish_to: none + +environment: + sdk: ^3.13.0 + +workspace: + - apps/calaverita_app + - features/assistant/assistant_presentation + - features/calaverita/calaverita_domain + - features/calaverita/calaverita_data + - features/calaverita/calaverita_presentation + - shared/app_ui + +# The CopilotKit Flutter SDK is not on pub.dev yet. Its packages depend on +# each other through a workspace, so pub needs every one of them pinned to +# the same commit. +dependency_overrides: + copilotkit: + git: + url: https://github.com/VGVentures/copilotkit_flutter_sdk.git + path: packages/copilotkit + ref: e52039c1729d57358ddac9c956fd2a2052928bbd + copilotkit_flutter: + git: + url: https://github.com/VGVentures/copilotkit_flutter_sdk.git + path: packages/copilotkit_flutter + ref: e52039c1729d57358ddac9c956fd2a2052928bbd + json_utils: + git: + url: https://github.com/VGVentures/copilotkit_flutter_sdk.git + path: packages/json_utils + ref: e52039c1729d57358ddac9c956fd2a2052928bbd diff --git a/03-human-in-the-loop/shared/app_ui/.gitignore b/03-human-in-the-loop/shared/app_ui/.gitignore new file mode 100644 index 0000000..06ef8e6 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# VSCode related +.vscode/* + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ +pubspec.lock + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Test related +coverage \ No newline at end of file diff --git a/03-human-in-the-loop/shared/app_ui/LICENSE b/03-human-in-the-loop/shared/app_ui/LICENSE new file mode 100644 index 0000000..650d32a --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Very Good Ventures + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/03-human-in-the-loop/shared/app_ui/README.md b/03-human-in-the-loop/shared/app_ui/README.md new file mode 100644 index 0000000..706ef94 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/README.md @@ -0,0 +1,56 @@ +# app_ui + +Design system of the **Very Good Coffee Manager** Flutter demo, ported from the +React demo's `styles.css`. Presentational and domain-free: widgets take plain +strings, numbers and enums, and the app maps its own models onto them. + +```dart +import 'package:app_ui/app_ui.dart'; + +MaterialApp(theme: AppTheme.light, darkTheme: AppTheme.dark, ...); +``` + +`app_ui.dart` also re-exports `package:flutter/material.dart`. + +Run the gallery: `cd example && flutter run -d chrome`. + +## Tokens + +| Class | Contents | +| --- | --- | +| `AppColors` | Raw brand constants: navy `#0C1A45`, accent `#2A48DE`, ground `#E9EDF8`, stage colors, wash colors, on-navy tints. | +| `AppPalette` | `ThemeExtension` of semantic roles (`ground`, `surface`, `cardGround`, `navy`, `ink`, `inkSecondary`, `inkTertiary`, `heading`, `accent`, `accentWash`, `positive`, `negative`, ...). Light and dark. Read with `context.palette`. | +| `AppSpacing` | `xxs` 2, `xs` 4, `sm` 6, `md` 8, `lg` 10, `xl` 12, `xxl` 14, `x3l` 16, `x4l` 20, `x5l` 24, `x6l` 28, `x7l` 32. | +| `AppRadii` | `card` 28, `dialog` 32, `proposal` 24, `row` 18, `option` 16, `chip` 14, `pill`, plus `BorderRadius` constants. | +| `AppTypography` | Poppins (bundled): `big`, `display`, `headline`, `brand`, `title`, `subtitle`, `bodyLarge`, `body`, `bodyMedium`, `small`, `smallMedium`, `micro`, `chip`, `tag`, `button`, `buttonBig`, `mono` (tabular figures). | +| `AppElevation` | `card`, `dialog`, `segment`, `iconButton` shadows; `scrim`, `brandScrim`, `resultScrim`. | +| `AppMotion` | Durations and the `ease` curve `cubic-bezier(0.2, 0.8, 0.2, 1)`. | +| `AppSizes` | Control heights, icon sizes, dot, bar, avatar, dialog widths. | + +`AppTheme.light` / `AppTheme.dark` are Material 3 themes built from these. + +## Widgets + +- Buttons: `AppButton` (`.primary`, `.ghost`, `size`, `icon`, `onNavy`, `expanded`), `AppIconButton`, `AppSegmented`. +- Labels: `AppChip` (+ `AppTone`), `AppVerdictChip`, `AppSeverityChip`, `AppCountBadge`, `AppStageDot`, `AppStepPill`, `AppGoalChip`. +- Surfaces: `AppCard`, `AppPanel`, `AppSectionHeader`. +- Data: `AppStatTile`, `AppProgressBar`, `AppKeyValueRow`, `AppAvatar`, `AppPersonRow`, `AppSkeleton`, `AppSkeletonBlock`. +- Orders: `AppOrderRow` (`AppUrgency`: normal, warn, urgent, done). +- Chat: `AppChatBubble` (`AppChatRole`: customer, courier, manager), `AppTypingBubble`, `AppComposer`, `AppSuggestionChip`. +- Copilot: `AppDecisionCard`, `AppOptionTile`. +- Overlays: `showAppDialog`, `AppDialogScaffold`, `AppWelcomeDialog`, `AppDialogStep`, `AppResultDialog`, `AppToast`. +- Brand: `AppUnicorn`, `AppVgvLockup`, `AppAssets` (SVGs bundled under `assets/images`). +- Icons: `AppIcons` + `AppIcon` (Material rounded glyphs; see below). + +## Notes + +- `phosphor_flutter` 2.1.0 (latest) does not compile on Flutter 3.47 (`IconData` + is a final class), so icons use Material. `AppIcons` is the single seam to swap + Phosphor back in later. +- Poppins is bundled as a font asset (no network). JetBrains Mono is not + bundled; `AppTypography.mono` falls back to the platform monospace with + tabular figures. + +## Tests + +`flutter test --coverage` (tests live in `test/src`, one file per widget group). diff --git a/03-human-in-the-loop/shared/app_ui/analysis_options.yaml b/03-human-in-the-loop/shared/app_ui/analysis_options.yaml new file mode 100644 index 0000000..317f632 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/analysis_options.yaml @@ -0,0 +1,17 @@ +include: package:very_good_analysis/analysis_options.yaml +analyzer: + exclude: + - build/** + - web/** + - android/** + - ios/** + - windows/** + - macos/** + - linux/** +linter: + rules: + # The workshop uses classic constructors; Dart 3.13 offers shorthands. + prefer_initializing_formals: false + unnecessary_type_name_in_constructor: false + # A workshop app doesn't need an API reference. + public_member_api_docs: false diff --git a/03-human-in-the-loop/shared/app_ui/assets/fonts/JetBrainsMono-Medium.ttf b/03-human-in-the-loop/shared/app_ui/assets/fonts/JetBrainsMono-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..dc2e5d08677d603b6755dc6c34fc8ad9aa6fc8a5 GIT binary patch literal 270316 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 z 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

{Qq;dYoLXG*oL7!{wrG%~aKb=FoR7{s=k| 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 literal 0 HcmV?d00001 diff --git a/03-human-in-the-loop/shared/app_ui/assets/images/copilotkit-logo.png b/03-human-in-the-loop/shared/app_ui/assets/images/copilotkit-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8b878b685f672725ced4dc5b379121bee77d3a2e GIT binary patch literal 32539 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

6l)*1D$l18iLXkNx518u6i60#=N@e+% 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 b{Oen67S8(&dWrhyV0u|eMG3H&zW@IL)hc`o literal 0 HcmV?d00001 diff --git a/03-human-in-the-loop/shared/app_ui/assets/images/unicorn-dark.svg b/03-human-in-the-loop/shared/app_ui/assets/images/unicorn-dark.svg new file mode 100644 index 0000000..89a9896 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/assets/images/unicorn-dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/03-human-in-the-loop/shared/app_ui/assets/images/unicorn.svg b/03-human-in-the-loop/shared/app_ui/assets/images/unicorn.svg new file mode 100644 index 0000000..06fecf6 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/assets/images/unicorn.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/03-human-in-the-loop/shared/app_ui/assets/images/vgv-lockup.svg b/03-human-in-the-loop/shared/app_ui/assets/images/vgv-lockup.svg new file mode 100644 index 0000000..ab2bbe3 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/assets/images/vgv-lockup.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/03-human-in-the-loop/shared/app_ui/lib/app_ui.dart b/03-human-in-the-loop/shared/app_ui/lib/app_ui.dart new file mode 100644 index 0000000..774d173 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/app_ui.dart @@ -0,0 +1,9 @@ +/// Design system of the Very Good Coffee Manager: tokens, themes and +/// presentational widgets. +library; + +export 'package:flutter/material.dart'; + +export 'src/theme/theme.dart'; +export 'src/tokens/tokens.dart'; +export 'src/widgets/widgets.dart'; diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/theme/app_palette.dart b/03-human-in-the-loop/shared/app_ui/lib/src/theme/app_palette.dart new file mode 100644 index 0000000..e254384 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/theme/app_palette.dart @@ -0,0 +1,258 @@ +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:flutter/material.dart'; + +/// Semantic color roles that adapt to light and dark mode. +/// +/// Read it with `context.palette`. +@immutable +class AppPalette extends ThemeExtension { + /// Creates a palette. + const AppPalette({ + required this.ground, + required this.cardGround, + required this.surface, + required this.navy, + required this.navyAlt, + required this.onNavy, + required this.onNavyMuted, + required this.onNavyFill, + required this.sky, + required this.ink, + required this.heading, + required this.inkSecondary, + required this.inkTertiary, + required this.fill, + required this.hairline, + required this.accent, + required this.accentWash, + required this.positive, + required this.negative, + required this.warning, + required this.incident, + required this.warningWash, + required this.negativeWash, + required this.positiveWash, + required this.slowWash, + required this.scrim, + }); + + /// Light palette taken from the React demo. + const AppPalette.light() + : this( + ground: AppColors.ground, + cardGround: AppColors.cardGround, + surface: AppColors.surface, + navy: AppColors.navy, + navyAlt: AppColors.navy2, + onNavy: const Color(0xFFFFFFFF), + onNavyMuted: const Color(0x8FFFFFFF), + onNavyFill: const Color(0x24FFFFFF), + sky: AppColors.sky, + ink: AppColors.ink, + heading: AppColors.navy, + inkSecondary: const Color(0xC7191817), + inkTertiary: const Color(0x8F191817), + fill: const Color(0x0F191817), + hairline: const Color(0x1A191817), + accent: AppColors.accent, + accentWash: const Color(0x1F2A48DE), + positive: AppColors.positive, + negative: AppColors.negative, + warning: AppColors.warning, + incident: AppColors.incident, + warningWash: AppColors.warningWash, + negativeWash: AppColors.negativeWash, + positiveWash: AppColors.positiveWash, + slowWash: AppColors.slowWash, + scrim: AppElevation.scrim, + ); + + /// Dark palette derived from the brand navy. + const AppPalette.dark() + : this( + ground: AppColors.darkGround, + cardGround: AppColors.darkCardGround, + surface: AppColors.darkSurface, + navy: const Color(0xFF050B22), + navyAlt: AppColors.navy2, + onNavy: const Color(0xFFFFFFFF), + onNavyMuted: const Color(0x8FFFFFFF), + onNavyFill: const Color(0x24FFFFFF), + sky: AppColors.sky, + ink: AppColors.darkInk, + heading: AppColors.darkInk, + inkSecondary: const Color(0xC7F3F4F8), + inkTertiary: const Color(0x8FF3F4F8), + fill: const Color(0x14FFFFFF), + hairline: const Color(0x24FFFFFF), + accent: AppColors.darkAccent, + accentWash: const Color(0x2E7C93FF), + positive: AppColors.positiveOnNavy, + negative: AppColors.negativeOnNavy, + warning: AppColors.warning, + incident: const Color(0xFFFF9A5C), + warningWash: const Color(0x33F5A524), + negativeWash: const Color(0x33E0353B), + positiveWash: const Color(0x331FA567), + slowWash: const Color(0x29E0353B), + scrim: const Color(0x99000000), + ); + + /// Page background. + final Color ground; + + /// Inset background for rows inside cards. + final Color cardGround; + + /// Card surface. + final Color surface; + + /// Navy panel background. + final Color navy; + + /// Secondary navy. + final Color navyAlt; + + /// Primary content on navy. + final Color onNavy; + + /// Muted content on navy. + final Color onNavyMuted; + + /// Translucent fill on navy. + final Color onNavyFill; + + /// Periwinkle highlight on navy. + final Color sky; + + /// Primary text. + final Color ink; + + /// Heading color (navy in light mode). + final Color heading; + + /// Secondary text. + final Color inkSecondary; + + /// Tertiary text. + final Color inkTertiary; + + /// Subtle fill (ghost buttons, skeletons, tracks). + final Color fill; + + /// Hairline borders. + final Color hairline; + + /// Brand accent. + final Color accent; + + /// Translucent accent background. + final Color accentWash; + + /// Positive state. + final Color positive; + + /// Negative state. + final Color negative; + + /// Warning state. + final Color warning; + + /// Incident tag color. + final Color incident; + + /// Warning background. + final Color warningWash; + + /// Negative background. + final Color negativeWash; + + /// Positive background. + final Color positiveWash; + + /// Slow courier background. + final Color slowWash; + + /// Plain dialog scrim. + final Color scrim; + + @override + AppPalette copyWith({ + Color? ground, + Color? cardGround, + Color? surface, + Color? navy, + Color? accent, + Color? ink, + }) { + return AppPalette( + ground: ground ?? this.ground, + cardGround: cardGround ?? this.cardGround, + surface: surface ?? this.surface, + navy: navy ?? this.navy, + navyAlt: navyAlt, + onNavy: onNavy, + onNavyMuted: onNavyMuted, + onNavyFill: onNavyFill, + sky: sky, + ink: ink ?? this.ink, + heading: heading, + inkSecondary: inkSecondary, + inkTertiary: inkTertiary, + fill: fill, + hairline: hairline, + accent: accent ?? this.accent, + accentWash: accentWash, + positive: positive, + negative: negative, + warning: warning, + incident: incident, + warningWash: warningWash, + negativeWash: negativeWash, + positiveWash: positiveWash, + slowWash: slowWash, + scrim: scrim, + ); + } + + @override + AppPalette lerp(ThemeExtension? other, double t) { + if (other is! AppPalette) return this; + Color l(Color a, Color b) => Color.lerp(a, b, t)!; + return AppPalette( + ground: l(ground, other.ground), + cardGround: l(cardGround, other.cardGround), + surface: l(surface, other.surface), + navy: l(navy, other.navy), + navyAlt: l(navyAlt, other.navyAlt), + onNavy: l(onNavy, other.onNavy), + onNavyMuted: l(onNavyMuted, other.onNavyMuted), + onNavyFill: l(onNavyFill, other.onNavyFill), + sky: l(sky, other.sky), + ink: l(ink, other.ink), + heading: l(heading, other.heading), + inkSecondary: l(inkSecondary, other.inkSecondary), + inkTertiary: l(inkTertiary, other.inkTertiary), + fill: l(fill, other.fill), + hairline: l(hairline, other.hairline), + accent: l(accent, other.accent), + accentWash: l(accentWash, other.accentWash), + positive: l(positive, other.positive), + negative: l(negative, other.negative), + warning: l(warning, other.warning), + incident: l(incident, other.incident), + warningWash: l(warningWash, other.warningWash), + negativeWash: l(negativeWash, other.negativeWash), + positiveWash: l(positiveWash, other.positiveWash), + slowWash: l(slowWash, other.slowWash), + scrim: l(scrim, other.scrim), + ); + } +} + +/// Shortcut to [AppPalette] from a [BuildContext]. +extension AppPaletteContext on BuildContext { + /// The active [AppPalette]. + AppPalette get palette => + Theme.of(this).extension() ?? const AppPalette.light(); +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/theme/app_theme.dart b/03-human-in-the-loop/shared/app_ui/lib/src/theme/app_theme.dart new file mode 100644 index 0000000..ca675fb --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/theme/app_theme.dart @@ -0,0 +1,113 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:flutter/material.dart'; + +/// Material 3 themes built from the design tokens. +abstract final class AppTheme { + /// Light theme. + static ThemeData get light => + _build(Brightness.light, const AppPalette.light()); + + /// Dark theme. + static ThemeData get dark => _build(Brightness.dark, const AppPalette.dark()); + + static ThemeData _build(Brightness brightness, AppPalette p) { + final scheme = + ColorScheme.fromSeed( + seedColor: AppColors.accent, + brightness: brightness, + ).copyWith( + primary: p.accent, + onPrimary: brightness == Brightness.light + ? AppColors.surface + : AppColors.darkGround, + primaryContainer: p.accentWash, + onPrimaryContainer: p.accent, + secondary: p.navy, + onSecondary: p.onNavy, + surface: p.surface, + onSurface: p.ink, + onSurfaceVariant: p.inkSecondary, + outline: p.hairline, + outlineVariant: p.hairline, + error: p.negative, + surfaceContainerHighest: p.cardGround, + ); + final textTheme = _textTheme(p); + const inputBorder = OutlineInputBorder( + borderRadius: AppRadii.pillBorder, + borderSide: BorderSide.none, + ); + return ThemeData( + useMaterial3: true, + brightness: brightness, + colorScheme: scheme, + scaffoldBackgroundColor: p.ground, + canvasColor: p.ground, + fontFamily: AppTypography.fontFamily, + textTheme: textTheme, + dividerColor: p.hairline, + extensions: [p], + splashFactory: NoSplash.splashFactory, + cardTheme: CardThemeData( + color: p.surface, + elevation: 0, + margin: EdgeInsets.zero, + shape: const RoundedRectangleBorder(borderRadius: AppRadii.cardBorder), + ), + dialogTheme: DialogThemeData( + backgroundColor: p.surface, + shape: const RoundedRectangleBorder(borderRadius: AppRadii.cardBorder), + ), + inputDecorationTheme: InputDecorationTheme( + filled: true, + fillColor: p.fill, + hintStyle: AppTypography.body.copyWith(color: p.inkTertiary), + contentPadding: const EdgeInsets.symmetric( + horizontal: AppSpacing.x4l - AppSpacing.xs / 2, + ), + border: inputBorder, + enabledBorder: inputBorder, + focusedBorder: inputBorder.copyWith( + borderSide: BorderSide(color: p.ink, width: 2), + ), + ), + snackBarTheme: SnackBarThemeData( + behavior: SnackBarBehavior.floating, + backgroundColor: p.surface, + contentTextStyle: AppTypography.bodyMedium.copyWith(color: p.navy), + shape: const StadiumBorder(), + ), + filledButtonTheme: FilledButtonThemeData( + style: FilledButton.styleFrom( + backgroundColor: p.accent, + foregroundColor: scheme.onPrimary, + minimumSize: const Size(0, AppSizes.control), + shape: const StadiumBorder(), + textStyle: AppTypography.button, + ), + ), + ); + } + + static TextTheme _textTheme(AppPalette p) { + TextStyle s(TextStyle base, Color c) => base.copyWith(color: c); + return TextTheme( + displayLarge: s(AppTypography.display, p.ink), + displayMedium: s(AppTypography.headline, p.ink), + displaySmall: s(AppTypography.big, p.ink), + headlineLarge: s(AppTypography.headline, p.heading), + headlineMedium: s(AppTypography.brand, p.ink), + headlineSmall: s(AppTypography.title, p.ink), + titleLarge: s(AppTypography.title, p.ink), + titleMedium: s(AppTypography.subtitle, p.ink), + titleSmall: s(AppTypography.bodyMedium, p.ink), + bodyLarge: s(AppTypography.bodyLarge, p.inkSecondary), + bodyMedium: s(AppTypography.body, p.ink), + bodySmall: s(AppTypography.small, p.inkTertiary), + labelLarge: s(AppTypography.button, p.ink), + labelMedium: s(AppTypography.smallMedium, p.ink), + labelSmall: s(AppTypography.chip, p.ink), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/theme/theme.dart b/03-human-in-the-loop/shared/app_ui/lib/src/theme/theme.dart new file mode 100644 index 0000000..0b957bf --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/theme/theme.dart @@ -0,0 +1,2 @@ +export 'app_palette.dart'; +export 'app_theme.dart'; diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_colors.dart b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_colors.dart new file mode 100644 index 0000000..d183ed3 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_colors.dart @@ -0,0 +1,94 @@ +import 'dart:ui'; + +/// Raw brand colors of the Very Good Coffee Manager. +/// +/// These are theme-independent constants. Widgets should prefer the semantic +/// roles in `AppPalette`, which adapt to light and dark mode. +abstract final class AppColors { + /// Deep navy used by the score bar, agent panel and dialog heroes. + static const Color navy = Color(0xFF0C1A45); + + /// Lighter navy used for gradients and raised navy surfaces. + static const Color navy2 = Color(0xFF16296B); + + /// Soft periwinkle used for fills on navy. + static const Color sky = Color(0xFF8FA8FF); + + /// Primary brand blue. + static const Color accent = Color(0xFF2A48DE); + + /// Light page ground. + static const Color ground = Color(0xFFE9EDF8); + + /// Slightly lighter ground used for rows inside white cards. + static const Color cardGround = Color(0xFFF1F4FB); + + /// White card surface. + static const Color surface = Color(0xFFFFFFFF); + + /// Primary text ink (warm near-black). + static const Color ink = Color(0xFF191817); + + /// Positive / success green. + static const Color positive = Color(0xFF1FA567); + + /// Negative / error red. + static const Color negative = Color(0xFFE0353B); + + /// Warning amber (urgency stripe). + static const Color warning = Color(0xFFF5A524); + + /// Burnt orange used for incident and urgent tags. + static const Color incident = Color(0xFFC4551A); + + /// Background wash for a warning order row. + static const Color warningWash = Color(0xFFFFF3D6); + + /// Background wash for an urgent order row. + static const Color negativeWash = Color(0xFFFFE1E2); + + /// Pulse target of the urgent order row animation. + static const Color negativeWashPulse = Color(0xFFFFD0D2); + + /// Background wash for a done order row. + static const Color positiveWash = Color(0xFFD9F5E6); + + /// Background wash for a slow courier row. + static const Color slowWash = Color(0xFFFFE9EA); + + /// Positive text color on navy. + static const Color positiveOnNavy = Color(0xFF4FDC9A); + + /// Negative text color on navy. + static const Color negativeOnNavy = Color(0xFFFF7B80); + + /// Warning text color on navy. + static const Color warningOnNavy = Color(0xFFFFE08A); + + /// Stage color: order requested. + static const Color stageRequested = Color(0xFF8FA8FF); + + /// Stage color: barista is preparing. + static const Color stageBarista = Color(0xFF4F6EF0); + + /// Stage color: out for delivery. + static const Color stageDelivery = Color(0xFF2A48DE); + + /// Stage color: delivered. + static const Color stageDelivered = Color(0xFF1FA567); + + /// Dark mode page ground. + static const Color darkGround = Color(0xFF070E26); + + /// Dark mode card surface. + static const Color darkSurface = Color(0xFF111D4A); + + /// Dark mode inset ground for rows inside cards. + static const Color darkCardGround = Color(0xFF1A2A63); + + /// Dark mode accent, lifted for contrast on navy. + static const Color darkAccent = Color(0xFF7C93FF); + + /// Dark mode ink. + static const Color darkInk = Color(0xFFF3F4F8); +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_elevation.dart b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_elevation.dart new file mode 100644 index 0000000..addbd17 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_elevation.dart @@ -0,0 +1,37 @@ +import 'package:flutter/painting.dart'; + +/// Shadow tokens. +abstract final class AppElevation { + /// Soft shadow under cards, panels and primary buttons. + static const List card = [ + BoxShadow(color: Color(0x0D0C1A45), blurRadius: 2, offset: Offset(0, 1)), + BoxShadow(color: Color(0x140C1A45), blurRadius: 24, offset: Offset(0, 8)), + ]; + + /// Heavy shadow under the welcome dialog. + static const List dialog = [ + BoxShadow(color: Color(0x660C1A45), blurRadius: 80, offset: Offset(0, 24)), + ]; + + /// Shadow under the selected segment of a segmented control. + static const List segment = [ + BoxShadow(color: Color(0x1F191817), blurRadius: 2, offset: Offset(0, 1)), + ]; + + /// Shadow under the primary icon button. + static const List iconButton = [ + BoxShadow(color: Color(0x330C1A45), blurRadius: 14, offset: Offset(0, 4)), + ]; + + /// Scrim color behind plain dialogs. + static const Color scrim = Color(0x66191817); + + /// Scrim color behind branded dialogs. + static const Color brandScrim = Color(0x8C0C1A45); + + /// Scrim color behind result dialogs. + static const Color resultScrim = Color(0x990C1A45); + + /// Blur sigma behind branded dialogs. + static const double scrimBlur = 4; +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_motion.dart b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_motion.dart new file mode 100644 index 0000000..2290dbf --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_motion.dart @@ -0,0 +1,28 @@ +import 'package:flutter/animation.dart'; + +/// Durations and curves. +abstract final class AppMotion { + /// Press feedback. + static const Duration press = Duration(milliseconds: 120); + + /// Hover / outline transitions. + static const Duration quick = Duration(milliseconds: 200); + + /// Entrance animations. + static const Duration enter = Duration(milliseconds: 400); + + /// Progress bar fills. + static const Duration progress = Duration(milliseconds: 400); + + /// Skeleton pulse period. + static const Duration pulse = Duration(milliseconds: 1200); + + /// Typing indicator period. + static const Duration typing = Duration(milliseconds: 1100); + + /// Urgent pulse period. + static const Duration urgent = Duration(milliseconds: 1600); + + /// The design system's ease curve, `cubic-bezier(0.2, 0.8, 0.2, 1)`. + static const Curve ease = Cubic(0.2, 0.8, 0.2, 1); +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_radii.dart b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_radii.dart new file mode 100644 index 0000000..fc33b8c --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_radii.dart @@ -0,0 +1,46 @@ +import 'package:flutter/painting.dart'; + +/// Corner radii. +abstract final class AppRadii { + /// Radius of cards and panels. + static const double card = 28; + + /// Radius of dialogs with a hero. + static const double dialog = 32; + + /// Radius of a nested decision card. + static const double proposal = 24; + + /// Radius of order rows and nested blocks. + static const double row = 18; + + /// Radius of options and person rows. + static const double option = 16; + + /// Radius of small chips and text fields. + static const double chip = 14; + + /// Radius of tiny elements (skeleton lines). + static const double tiny = 6; + + /// Radius large enough to make any box a pill. + static const double pill = 999; + + /// Pill border radius. + static const BorderRadius pillBorder = BorderRadius.all( + Radius.circular(pill), + ); + + /// Card border radius. + static const BorderRadius cardBorder = BorderRadius.all( + Radius.circular(card), + ); + + /// Row border radius. + static const BorderRadius rowBorder = BorderRadius.all(Radius.circular(row)); + + /// Chip border radius. + static const BorderRadius chipBorder = BorderRadius.all( + Radius.circular(chip), + ); +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_sizes.dart b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_sizes.dart new file mode 100644 index 0000000..ea35be4 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_sizes.dart @@ -0,0 +1,71 @@ +/// Fixed component dimensions that are not part of the spacing scale. +abstract final class AppSizes { + /// Minimum height of a button or text field. + static const double control = 44; + + /// Minimum height of a big button. + static const double controlBig = 52; + + /// Compact control height used in mini panels. + static const double controlCompact = 36; + + /// Side of a round icon button. + static const double iconButton = 44; + + /// Side of a primary round icon button. + static const double iconButtonPrimary = 48; + + /// Small icon. + static const double iconSmall = 16; + + /// Regular icon. + static const double icon = 20; + + /// Large icon. + static const double iconLarge = 24; + + /// Hero icon of the result dialog. + static const double iconHero = 56; + + /// Status dot diameter. + static const double dot = 8; + + /// Height of progress bars and meters. + static const double bar = 6; + + /// Width of the target marker on a progress bar. + static const double barMarker = 2; + + /// Height of the target marker on a progress bar. + static const double barMarkerHeight = 12; + + /// Avatar diameter. + static const double avatar = 34; + + /// Step number badge diameter. + static const double stepBadge = 18; + + /// Typing dot diameter. + static const double typingDot = 6; + + /// Width of the urgency stripe on an order row. + static const double stripe = 4; + + /// Maximum width of a dialog. + static const double dialogWidth = 440; + + /// Maximum width of a welcome dialog. + static const double welcomeWidth = 560; + + /// Maximum width of a result dialog. + static const double resultWidth = 500; + + /// Unicorn mark in the score bar. + static const double logoSmall = 44; + + /// Unicorn mark in the welcome hero. + static const double logoLarge = 120; + + /// Fraction of the available width taken by a chat bubble. + static const double bubbleWidthFactor = 0.86; +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_spacing.dart b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_spacing.dart new file mode 100644 index 0000000..ae280a6 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_spacing.dart @@ -0,0 +1,38 @@ +/// Spacing scale shared by every widget. +abstract final class AppSpacing { + /// 2 logical pixels. + static const double xxs = 2; + + /// 4 logical pixels. + static const double xs = 4; + + /// 6 logical pixels. + static const double sm = 6; + + /// 8 logical pixels. + static const double md = 8; + + /// 10 logical pixels. + static const double lg = 10; + + /// 12 logical pixels. + static const double xl = 12; + + /// 14 logical pixels. + static const double xxl = 14; + + /// 16 logical pixels. + static const double x3l = 16; + + /// 20 logical pixels. + static const double x4l = 20; + + /// 24 logical pixels. + static const double x5l = 24; + + /// 28 logical pixels. + static const double x6l = 28; + + /// 32 logical pixels. + static const double x7l = 32; +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_typography.dart b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_typography.dart new file mode 100644 index 0000000..70ece15 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/app_typography.dart @@ -0,0 +1,157 @@ +import 'package:flutter/painting.dart'; + +/// Text styles of the design system, set in Poppins. +abstract final class AppTypography { + /// Font family, bundled with the package. + static const String fontFamily = 'packages/app_ui/Poppins'; + + /// Monospace family, bundled with the package. + static const String monoFamily = 'packages/app_ui/JetBrainsMono'; + + /// Fallbacks used by [mono]. + static const List monoFallback = [ + 'Menlo', + 'Roboto Mono', + 'monospace', + ]; + + static const double _tracking = -0.005; + + /// 28px / 500, for big numbers. + static const TextStyle big = TextStyle( + fontFamily: fontFamily, + fontSize: 28, + fontWeight: FontWeight.w500, + letterSpacing: -0.56, + height: 1.15, + ); + + /// 32px / 500, for result headlines. + static const TextStyle display = TextStyle( + fontFamily: fontFamily, + fontSize: 32, + fontWeight: FontWeight.w500, + letterSpacing: -0.64, + height: 1.15, + ); + + /// 28px / 600, for dialog titles. + static const TextStyle headline = TextStyle( + fontFamily: fontFamily, + fontSize: 28, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + height: 1.15, + ); + + /// 22px / 600, brand name. + static const TextStyle brand = TextStyle( + fontFamily: fontFamily, + fontSize: 22, + fontWeight: FontWeight.w600, + letterSpacing: -0.44, + ); + + /// 18px / 600, section titles. + static const TextStyle title = TextStyle( + fontFamily: fontFamily, + fontSize: 18, + fontWeight: FontWeight.w600, + letterSpacing: -0.18, + ); + + /// 16px / 600, card titles. + static const TextStyle subtitle = TextStyle( + fontFamily: fontFamily, + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.16, + ); + + /// 15px / 400, long copy. + static const TextStyle bodyLarge = TextStyle( + fontFamily: fontFamily, + fontSize: 15, + height: 1.55, + letterSpacing: _tracking * 15, + ); + + /// 14px / 400, the default body. + static const TextStyle body = TextStyle( + fontFamily: fontFamily, + fontSize: 14, + height: 1.4, + letterSpacing: _tracking * 14, + ); + + /// 14px / 500, emphasized body. + static const TextStyle bodyMedium = TextStyle( + fontFamily: fontFamily, + fontSize: 14, + fontWeight: FontWeight.w500, + height: 1.4, + letterSpacing: _tracking * 14, + ); + + /// 12px / 400, secondary info. + static const TextStyle small = TextStyle( + fontFamily: fontFamily, + fontSize: 12, + height: 1.4, + ); + + /// 12px / 500, labels and counts. + static const TextStyle smallMedium = TextStyle( + fontFamily: fontFamily, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1.4, + ); + + /// 11px / 400, micro captions. + static const TextStyle micro = TextStyle( + fontFamily: fontFamily, + fontSize: 11, + height: 1.4, + ); + + /// 11px / 500, chips. + static const TextStyle chip = TextStyle( + fontFamily: fontFamily, + fontSize: 11, + fontWeight: FontWeight.w500, + height: 1.3, + ); + + /// 10px / 600 uppercase, tiny tags such as "Recommended". + static const TextStyle tag = TextStyle( + fontFamily: fontFamily, + fontSize: 10, + fontWeight: FontWeight.w600, + letterSpacing: 0.4, + ); + + /// Button label, 14px / 500. + static const TextStyle button = TextStyle( + fontFamily: fontFamily, + fontSize: 14, + fontWeight: FontWeight.w500, + height: 1.2, + ); + + /// Big button label, 16px / 500. + static const TextStyle buttonBig = TextStyle( + fontFamily: fontFamily, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.2, + ); + + /// Monospace with tabular figures, for money, clocks and scores. + static const TextStyle mono = TextStyle( + fontFamily: monoFamily, + fontFamilyFallback: monoFallback, + fontSize: 12, + fontFeatures: [FontFeature.tabularFigures()], + ); +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/tokens/tokens.dart b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/tokens.dart new file mode 100644 index 0000000..65a829f --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/tokens/tokens.dart @@ -0,0 +1,7 @@ +export 'app_colors.dart'; +export 'app_elevation.dart'; +export 'app_motion.dart'; +export 'app_radii.dart'; +export 'app_sizes.dart'; +export 'app_spacing.dart'; +export 'app_typography.dart'; diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_brand.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_brand.dart new file mode 100644 index 0000000..8d23541 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_brand.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +/// Paths of the bundled SVG assets (package `app_ui`). +abstract final class AppAssets { + /// Package name used to resolve assets. + static const String package = 'app_ui'; + + /// Unicorn mark drawn for navy backgrounds (white body). + static const String unicorn = 'assets/images/unicorn.svg'; + + /// Unicorn mark drawn for light backgrounds (black). + static const String unicornDark = 'assets/images/unicorn-dark.svg'; + + /// Very Good Ventures lockup (black wordmark). + static const String vgvLockup = 'assets/images/vgv-lockup.svg'; + + /// The CopilotKit logo, dark on a transparent-free white background: show it + /// on a light surface. + static const String copilotKitLogo = 'assets/images/copilotkit-logo.png'; +} + +/// The VGV unicorn. +class AppUnicorn extends StatelessWidget { + /// Creates the unicorn at [size]. + const AppUnicorn({ + required this.size, + this.onNavy = true, + this.semanticLabel, + super.key, + }); + + /// Width and height. + final double size; + + /// Pick the white variant for navy backgrounds (default) or the black one + /// for light backgrounds. + final bool onNavy; + + /// Accessibility label. + final String? semanticLabel; + + @override + Widget build(BuildContext context) { + return SvgPicture.asset( + onNavy ? AppAssets.unicorn : AppAssets.unicornDark, + package: AppAssets.package, + width: size, + height: size, + semanticsLabel: semanticLabel, + ); + } +} + +/// The Very Good Ventures lockup, optionally tinted. +class AppVgvLockup extends StatelessWidget { + /// Creates the lockup at [height]. + const AppVgvLockup({required this.height, this.color, super.key}); + + /// Height; width follows the 2209:765 aspect ratio. + final double height; + + /// Tint (e.g. white on navy). Null keeps the black artwork. + final Color? color; + + @override + Widget build(BuildContext context) { + return SvgPicture.asset( + AppAssets.vgvLockup, + package: AppAssets.package, + height: height, + semanticsLabel: 'Very Good Ventures', + colorFilter: color == null + ? null + : ColorFilter.mode(color!, BlendMode.srcIn), + ); + } +} + +/// The CopilotKit logo: a dark wordmark on white, so it belongs on a light +/// surface, like a pill on the navy banner. +class AppCopilotKitLogo extends StatelessWidget { + /// Creates the logo [height] logical pixels tall. + const AppCopilotKitLogo({required this.height, super.key}); + + /// Height of the logo. + final double height; + + @override + Widget build(BuildContext context) { + return Image.asset( + AppAssets.copilotKitLogo, + package: AppAssets.package, + height: height, + semanticLabel: 'CopilotKit', + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_button.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_button.dart new file mode 100644 index 0000000..04cd6fe --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_button.dart @@ -0,0 +1,253 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_icons.dart'; +import 'package:app_ui/src/widgets/app_pressable.dart'; +import 'package:flutter/material.dart'; + +/// Visual variants of [AppButton]. +enum AppButtonVariant { + /// Solid brand blue. + primary, + + /// Subtle fill. + ghost, +} + +/// Size presets of [AppButton]. +enum AppButtonSize { + /// 44px tall. + regular, + + /// 52px tall with a larger label. + big, + + /// 36px tall, for mini panels. + compact, +} + +/// Pill button of the design system. +class AppButton extends StatelessWidget { + /// Creates a button. + const AppButton({ + required this.label, + required this.onPressed, + this.variant = AppButtonVariant.primary, + this.size = AppButtonSize.regular, + this.icon, + this.onNavy = false, + this.expanded = false, + super.key, + }); + + /// Solid brand button. + const AppButton.primary({ + required String label, + required VoidCallback? onPressed, + AppIconSet? icon, + AppButtonSize size = AppButtonSize.regular, + bool onNavy = false, + bool expanded = false, + Key? key, + }) : this( + label: label, + onPressed: onPressed, + icon: icon, + size: size, + onNavy: onNavy, + expanded: expanded, + key: key, + ); + + /// Subtle button. + const AppButton.ghost({ + required String label, + required VoidCallback? onPressed, + AppIconSet? icon, + AppButtonSize size = AppButtonSize.regular, + bool onNavy = false, + bool expanded = false, + Key? key, + }) : this( + label: label, + onPressed: onPressed, + icon: icon, + size: size, + onNavy: onNavy, + expanded: expanded, + variant: AppButtonVariant.ghost, + key: key, + ); + + /// Text shown on the button. + final String label; + + /// Tap callback; null disables the button. + final VoidCallback? onPressed; + + /// Visual variant. + final AppButtonVariant variant; + + /// Size preset. + final AppButtonSize size; + + /// Optional leading icon. + final AppIconSet? icon; + + /// Restyle for placement on a navy surface. + final bool onNavy; + + /// Whether the button fills the available width. + final bool expanded; + + static const double _disabledOpacity = 0.4; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final primary = variant == AppButtonVariant.primary; + final Color background; + final Color foreground; + if (onNavy) { + background = primary ? p.onNavy : p.onNavyFill; + foreground = primary ? p.navy : p.onNavy; + } else { + background = primary ? p.accent : p.fill; + foreground = primary ? p.surface : p.ink; + } + final (height, style) = switch (size) { + AppButtonSize.regular => (AppSizes.control, AppTypography.button), + AppButtonSize.big => (AppSizes.controlBig, AppTypography.buttonBig), + AppButtonSize.compact => (AppSizes.controlCompact, AppTypography.button), + }; + final shadow = primary && !onNavy ? AppElevation.card : null; + return AppOpacityWhen( + dim: onPressed == null, + opacity: _disabledOpacity, + child: AppPressable( + onTap: onPressed, + semanticLabel: label, + child: Container( + constraints: BoxConstraints(minHeight: height), + padding: const EdgeInsets.symmetric(horizontal: AppSpacing.x4l), + decoration: BoxDecoration( + color: background, + borderRadius: AppRadii.pillBorder, + boxShadow: shadow, + ), + child: Row( + mainAxisSize: expanded ? MainAxisSize.max : MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (icon != null) ...[ + AppIcon(icon!, style: AppIconStyle.fill, color: foreground), + const SizedBox(width: AppSpacing.md), + ], + Flexible( + child: Text( + label, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: style.copyWith(color: foreground), + ), + ), + ], + ), + ), + ), + ); + } +} + +/// Fades its child when [dim] is true. +class AppOpacityWhen extends StatelessWidget { + /// Creates the wrapper. + const AppOpacityWhen({ + required this.dim, + required this.opacity, + required this.child, + super.key, + }); + + /// Whether to apply [opacity]. + final bool dim; + + /// Opacity applied when dimmed. + final double opacity; + + /// Content. + final Widget child; + + @override + Widget build(BuildContext context) { + return Opacity(opacity: dim ? opacity : 1, child: child); + } +} + +/// Round icon-only button, used for play, pause and restart. +class AppIconButton extends StatelessWidget { + /// Creates an icon button. + const AppIconButton({ + required this.icon, + required this.onPressed, + required this.semanticLabel, + this.primary = false, + this.onNavy = true, + this.style = AppIconStyle.regular, + super.key, + }); + + /// Glyph. + final AppIconSet icon; + + /// Tap callback; null disables it. + final VoidCallback? onPressed; + + /// Accessibility label. + final String semanticLabel; + + /// Highlighted variant (white disc, brand icon). + final bool primary; + + /// Whether it sits on navy (default) or on a light surface. + final bool onNavy; + + /// Glyph weight. + final AppIconStyle style; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final side = primary ? AppSizes.iconButtonPrimary : AppSizes.iconButton; + final background = primary + ? (onNavy ? p.onNavy : p.accent) + : (onNavy ? p.onNavyFill : p.fill); + final foreground = primary + ? (onNavy ? p.accent : p.surface) + : (onNavy ? p.onNavy : p.ink); + return AppOpacityWhen( + dim: onPressed == null, + opacity: 0.4, + child: AppPressable( + onTap: onPressed, + semanticLabel: semanticLabel, + pressedScale: 0.92, + child: Container( + width: side, + height: side, + decoration: BoxDecoration( + color: background, + shape: BoxShape.circle, + boxShadow: primary ? AppElevation.iconButton : null, + ), + alignment: Alignment.center, + child: AppIcon( + icon, + style: style, + size: AppSizes.icon, + color: foreground, + ), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_card.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_card.dart new file mode 100644 index 0000000..b37cf0c --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_card.dart @@ -0,0 +1,163 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_icons.dart'; +import 'package:flutter/material.dart'; + +/// White rounded surface with the design system shadow. +class AppCard extends StatelessWidget { + /// Creates a card. + const AppCard({ + required this.child, + this.padding = EdgeInsets.zero, + this.color, + this.radius = AppRadii.card, + this.shadow = true, + this.clip = true, + super.key, + }); + + /// Card content. + final Widget child; + + /// Inner padding. + final EdgeInsetsGeometry padding; + + /// Background; defaults to the palette surface. + final Color? color; + + /// Corner radius. + final double radius; + + /// Whether to paint the card shadow. + final bool shadow; + + /// Whether to clip children to the rounded rectangle. + final bool clip; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return DecoratedBox( + decoration: BoxDecoration( + color: color ?? p.surface, + borderRadius: BorderRadius.circular(radius), + boxShadow: shadow ? AppElevation.card : null, + ), + child: ClipRRect( + clipBehavior: clip ? Clip.antiAlias : Clip.none, + borderRadius: BorderRadius.circular(radius), + child: Padding(padding: padding, child: child), + ), + ); + } +} + +/// Section title row: optional icon, title and trailing widget. +class AppSectionHeader extends StatelessWidget { + /// Creates a section header. + const AppSectionHeader({ + required this.title, + this.icon, + this.trailing, + this.onNavy = false, + this.padding = const EdgeInsets.fromLTRB( + AppSpacing.x4l, + AppSpacing.x3l, + AppSpacing.x4l, + AppSpacing.md, + ), + super.key, + }); + + /// Title text. + final String title; + + /// Optional leading icon, drawn duotone in the accent color. + final AppIconSet? icon; + + /// Optional trailing widget (count badge, chip, hint). + final Widget? trailing; + + /// Restyle for navy surfaces. + final bool onNavy; + + /// Outer padding. + final EdgeInsetsGeometry padding; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final color = onNavy ? p.onNavy : p.heading; + return Padding( + padding: padding, + child: Row( + children: [ + if (icon != null) ...[ + AppIcon( + icon!, + style: AppIconStyle.duotone, + color: onNavy ? p.onNavy : p.accent, + ), + const SizedBox(width: AppSpacing.lg), + ], + Expanded( + child: Text( + title, + overflow: TextOverflow.ellipsis, + style: AppTypography.bodyMedium.copyWith(color: color), + ), + ), + ?trailing, + ], + ), + ); + } +} + +/// Titled card. The navy variant is used by the agent panel. +class AppPanel extends StatelessWidget { + /// Creates a panel. + const AppPanel({ + required this.title, + required this.child, + this.icon, + this.trailing, + this.navy = false, + super.key, + }); + + /// Panel title. + final String title; + + /// Panel body. + final Widget child; + + /// Optional header icon. + final AppIconSet? icon; + + /// Optional header trailing widget. + final Widget? trailing; + + /// Whether the panel is drawn on the navy background. + final bool navy; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return AppCard( + color: navy ? p.navy : p.surface, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + AppSectionHeader( + title: title, + icon: icon, + trailing: trailing, + onNavy: navy, + ), + Expanded(child: child), + ], + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_chat.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_chat.dart new file mode 100644 index 0000000..2389495 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_chat.dart @@ -0,0 +1,357 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_icons.dart'; +import 'package:app_ui/src/widgets/app_pressable.dart'; +import 'package:flutter/material.dart'; + +/// Who wrote a chat message. +enum AppChatRole { + /// The customer: left aligned, neutral. + customer, + + /// The courier: left aligned, accent wash. + courier, + + /// The manager (the user): right aligned, navy or accent. + manager, +} + +/// Chat bubble. Customer and courier sit left, the manager sits right. +class AppChatBubble extends StatelessWidget { + /// Creates a chat bubble. + const AppChatBubble({ + required this.text, + required this.role, + this.timestamp, + this.sender, + this.onNavy = false, + this.accent = false, + super.key, + }); + + /// Message text. + final String text; + + /// Author role. + final AppChatRole role; + + /// Optional faded timestamp under the text. + final String? timestamp; + + /// Optional sender name above the text. + final String? sender; + + /// Restyle for navy surfaces (the agent panel). + final bool onNavy; + + /// Use the accent color for manager bubbles instead of navy. + final bool accent; + + static const double _smallCorner = 6; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final mine = role == AppChatRole.manager; + final Color background; + final Color foreground; + if (mine) { + background = (accent || onNavy) ? p.accent : p.navy; + foreground = onNavy || accent ? p.surface : p.onNavy; + } else if (role == AppChatRole.courier) { + background = onNavy ? p.onNavy.withValues(alpha: 0.2) : p.accentWash; + foreground = onNavy ? p.onNavy : p.accent; + } else { + background = onNavy ? p.onNavyFill : p.cardGround; + foreground = onNavy ? p.onNavy : p.ink; + } + const big = Radius.circular(20); + const small = Radius.circular(_smallCorner); + return Align( + alignment: mine ? Alignment.centerRight : Alignment.centerLeft, + child: FractionallySizedBox( + widthFactor: AppSizes.bubbleWidthFactor, + alignment: mine ? Alignment.centerRight : Alignment.centerLeft, + child: Align( + alignment: mine ? Alignment.centerRight : Alignment.centerLeft, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.xxl, + vertical: AppSpacing.lg, + ), + decoration: BoxDecoration( + color: background, + borderRadius: BorderRadius.only( + topLeft: big, + topRight: big, + bottomLeft: mine ? big : small, + bottomRight: mine ? small : big, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (sender != null) + Text( + sender!, + style: AppTypography.chip.copyWith( + color: foreground.withValues(alpha: 0.7), + ), + ), + Text( + text, + style: AppTypography.body.copyWith( + color: foreground, + height: 1.45, + ), + ), + if (timestamp != null) + Opacity( + opacity: 0.6, + child: Text( + timestamp!, + style: AppTypography.micro.copyWith(color: foreground), + ), + ), + ], + ), + ), + ), + ), + ); + } +} + +/// Three bouncing dots shown while someone is typing. +class AppTypingBubble extends StatefulWidget { + /// Creates a typing indicator. + const AppTypingBubble({this.onNavy = false, super.key}); + + /// Restyle for navy surfaces. + final bool onNavy; + + @override + State createState() => _AppTypingBubbleState(); +} + +class _AppTypingBubbleState extends State + with SingleTickerProviderStateMixin { + late final AnimationController _controller = AnimationController( + vsync: this, + duration: AppMotion.typing, + )..repeat(); + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final p = context.palette; + final color = widget.onNavy ? p.onNavy : p.ink; + return Align( + alignment: Alignment.centerLeft, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.x3l, + vertical: AppSpacing.xxl - 1, + ), + decoration: BoxDecoration( + color: widget.onNavy ? p.onNavyFill : p.cardGround, + borderRadius: BorderRadius.circular(20), + ), + child: AnimatedBuilder( + animation: _controller, + builder: (context, _) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + for (var i = 0; i < 3; i++) ...[ + if (i > 0) const SizedBox(width: AppSpacing.xs + 1), + _dot(color, i), + ], + ], + ); + }, + ), + ), + ); + } + + Widget _dot(Color color, int index) { + // Each dot is offset by 0.15 of the period, peaking at 30% of its cycle. + final t = (_controller.value - index * 0.15) % 1.0; + final peak = t < 0.3 ? t / 0.3 : (t < 0.6 ? (0.6 - t) / 0.3 : 0.0); + return Transform.translate( + offset: Offset(0, -3 * peak), + child: Container( + width: AppSizes.typingDot, + height: AppSizes.typingDot, + decoration: BoxDecoration( + color: color.withValues(alpha: 0.3 + 0.7 * peak), + shape: BoxShape.circle, + ), + ), + ); + } +} + +/// Pill text field with a send button. +class AppComposer extends StatefulWidget { + /// Creates a composer. + const AppComposer({ + required this.onSend, + this.hint = 'Type a message', + this.enabled = true, + this.onNavy = false, + this.compact = false, + super.key, + }); + + /// Called with the trimmed text when sent. Empty text is ignored. + final ValueChanged onSend; + + /// Placeholder text. + final String hint; + + /// Whether input is enabled. + final bool enabled; + + /// Restyle for navy surfaces. + final bool onNavy; + + /// Smaller control height. + final bool compact; + + @override + State createState() => _AppComposerState(); +} + +class _AppComposerState extends State { + final _controller = TextEditingController(); + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + void _submit([String? _]) { + final text = _controller.text.trim(); + if (text.isEmpty || !widget.enabled) return; + widget.onSend(text); + _controller.clear(); + } + + @override + Widget build(BuildContext context) { + final p = context.palette; + final height = widget.compact ? AppSizes.controlCompact : AppSizes.control; + final fg = widget.onNavy ? p.onNavy : p.ink; + final fillColor = widget.onNavy ? p.onNavyFill : p.fill; + final focus = widget.onNavy ? p.sky : p.ink; + OutlineInputBorder border(Color c, double w) => OutlineInputBorder( + borderRadius: AppRadii.pillBorder, + borderSide: BorderSide(color: c, width: w), + ); + return Row( + children: [ + Expanded( + child: SizedBox( + height: height, + child: TextField( + controller: _controller, + enabled: widget.enabled, + onSubmitted: _submit, + style: AppTypography.body.copyWith(color: fg), + cursorColor: fg, + decoration: InputDecoration( + hintText: widget.hint, + hintStyle: AppTypography.body.copyWith( + color: widget.onNavy ? p.onNavyMuted : p.inkTertiary, + ), + filled: true, + fillColor: fillColor, + contentPadding: const EdgeInsets.symmetric( + horizontal: AppSpacing.x4l - 2, + ), + border: border(Colors.transparent, 0), + enabledBorder: border(Colors.transparent, 0), + disabledBorder: border(Colors.transparent, 0), + focusedBorder: border(focus, 2), + ), + ), + ), + ), + const SizedBox(width: AppSpacing.md), + AppPressable( + onTap: widget.enabled ? _submit : null, + semanticLabel: 'Send', + child: Container( + width: height, + height: height, + decoration: BoxDecoration( + color: widget.onNavy ? p.onNavyFill : p.accent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: AppIcon( + AppIcons.send, + style: AppIconStyle.fill, + color: widget.onNavy ? p.onNavy : p.surface, + ), + ), + ), + ], + ); + } +} + +/// Suggestion pill shown above the composer on navy. +class AppSuggestionChip extends StatelessWidget { + /// Creates a suggestion chip. + const AppSuggestionChip({ + required this.label, + required this.onTap, + this.onNavy = true, + super.key, + }); + + /// Suggestion text. + final String label; + + /// Tap callback. + final VoidCallback? onTap; + + /// Restyle for navy surfaces. + final bool onNavy; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return AppPressable( + onTap: onTap, + child: DecoratedBox( + decoration: BoxDecoration( + color: onNavy ? p.onNavy.withValues(alpha: 0.12) : p.fill, + borderRadius: AppRadii.pillBorder, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.xl, + vertical: AppSpacing.sm, + ), + child: Text( + label, + style: AppTypography.micro.copyWith( + color: onNavy ? p.onNavy : p.ink, + ), + ), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_chip.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_chip.dart new file mode 100644 index 0000000..ce9811c --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_chip.dart @@ -0,0 +1,293 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_icons.dart'; +import 'package:app_ui/src/widgets/app_tone.dart'; +import 'package:flutter/material.dart'; + +/// Small rounded label, the base of every status pill. +class AppChip extends StatelessWidget { + /// Creates a chip. + const AppChip({ + required this.label, + this.tone = AppTone.neutral, + this.icon, + this.foreground, + this.background, + super.key, + }); + + /// Text of the chip. + final String label; + + /// Semantic tone that picks the colors. + final AppTone tone; + + /// Optional leading icon. + final AppIconSet? icon; + + /// Overrides the tone's foreground. + final Color? foreground; + + /// Overrides the tone's background. + final Color? background; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final fg = foreground ?? tone.foreground(p); + return DecoratedBox( + decoration: BoxDecoration( + color: background ?? tone.background(p), + borderRadius: AppRadii.chipBorder, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.lg, + vertical: AppSpacing.xxs + 1, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (icon != null) ...[ + AppIcon(icon!, style: AppIconStyle.fill, size: 13, color: fg), + const SizedBox(width: AppSpacing.xs), + ], + Text(label, style: AppTypography.chip.copyWith(color: fg)), + ], + ), + ), + ); + } +} + +/// How the copilot judges a decision. +enum AppVerdict { + /// Approved as proposed. + approve, + + /// Approved with edits. + edit, + + /// Rejected. + reject, +} + +/// Chip for an [AppVerdict]. +class AppVerdictChip extends StatelessWidget { + /// Creates a verdict chip. + const AppVerdictChip({required this.verdict, this.label, super.key}); + + /// The verdict to show. + final AppVerdict verdict; + + /// Overrides the default label ("Approved", "Edited", "Rejected"). + final String? label; + + @override + Widget build(BuildContext context) { + final (tone, text) = switch (verdict) { + AppVerdict.approve => (AppTone.positive, 'Approved'), + AppVerdict.edit => (AppTone.accent, 'Edited'), + AppVerdict.reject => (AppTone.negative, 'Rejected'), + }; + return AppChip(label: label ?? text, tone: tone); + } +} + +/// Severity of an incident. +enum AppSeverity { + /// Needs action now. + high, + + /// Needs attention. + medium, + + /// Informational. + low, +} + +/// Chip for an [AppSeverity]. +class AppSeverityChip extends StatelessWidget { + /// Creates a severity chip. + const AppSeverityChip({required this.severity, this.label, super.key}); + + /// The severity to show. + final AppSeverity severity; + + /// Overrides the default label. + final String? label; + + @override + Widget build(BuildContext context) { + final (tone, text) = switch (severity) { + AppSeverity.high => (AppTone.negative, 'High'), + AppSeverity.medium => (AppTone.accent, 'Medium'), + AppSeverity.low => (AppTone.accent, 'Low'), + }; + return AppChip(label: label ?? text, tone: tone); + } +} + +/// Rounded count bubble used in column headers. +class AppCountBadge extends StatelessWidget { + /// Creates a count badge. + const AppCountBadge({required this.count, super.key}); + + /// Number shown. + final int count; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return DecoratedBox( + decoration: BoxDecoration( + color: p.accentWash, + borderRadius: AppRadii.pillBorder, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.lg, + vertical: AppSpacing.xxs, + ), + child: Text( + '$count', + style: AppTypography.smallMedium.copyWith(color: p.accent), + ), + ), + ); + } +} + +/// Stage of an order on the board. +enum AppStage { + /// Customer requested it. + requested, + + /// Barista is preparing it. + barista, + + /// Courier is delivering it. + delivery, + + /// Delivered. + delivered, +} + +/// Colored dot identifying an [AppStage]. +class AppStageDot extends StatelessWidget { + /// Creates a stage dot. + const AppStageDot({required this.stage, super.key}); + + /// Stage to color the dot for. + final AppStage stage; + + /// Color of [stage]. + static Color colorOf(AppStage stage) => switch (stage) { + AppStage.requested => AppColors.stageRequested, + AppStage.barista => AppColors.stageBarista, + AppStage.delivery => AppColors.stageDelivery, + AppStage.delivered => AppColors.stageDelivered, + }; + + @override + Widget build(BuildContext context) { + return Container( + width: AppSizes.dot, + height: AppSizes.dot, + decoration: BoxDecoration(color: colorOf(stage), shape: BoxShape.circle), + ); + } +} + +/// Progress state of an [AppStepPill]. +enum AppStepState { + /// Already completed. + past, + + /// Current step. + now, + + /// Not reached yet. + upcoming, +} + +/// Numbered pill of the day tracker, shown on navy. +class AppStepPill extends StatelessWidget { + /// Creates a step pill. + const AppStepPill({ + required this.number, + required this.label, + required this.state, + super.key, + }); + + /// Step number. + final int number; + + /// Step label. + final String label; + + /// Progress state. + final AppStepState state; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final (background, foreground, badge, badgeText) = switch (state) { + AppStepState.now => (p.onNavy, p.navy, p.accent, p.onNavy), + AppStepState.past => ( + p.onNavy.withValues(alpha: 0.1), + AppColors.positiveOnNavy, + Colors.transparent, + AppColors.positiveOnNavy, + ), + AppStepState.upcoming => ( + p.onNavy.withValues(alpha: 0.1), + p.onNavyMuted, + p.onNavy.withValues(alpha: 0.16), + p.onNavyMuted, + ), + }; + return DecoratedBox( + decoration: BoxDecoration( + color: background, + borderRadius: AppRadii.pillBorder, + ), + child: Padding( + padding: const EdgeInsets.fromLTRB( + AppSpacing.xs, + AppSpacing.xxs + 1, + AppSpacing.md, + AppSpacing.xxs + 1, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: AppSizes.stepBadge, + height: AppSizes.stepBadge, + decoration: BoxDecoration(color: badge, shape: BoxShape.circle), + alignment: Alignment.center, + child: state == AppStepState.past + ? AppIcon( + AppIcons.check, + style: AppIconStyle.fill, + size: 12, + color: badgeText, + ) + : Text( + '$number', + style: AppTypography.tag.copyWith( + color: badgeText, + letterSpacing: 0, + ), + ), + ), + const SizedBox(width: AppSpacing.sm - 1), + Text(label, style: AppTypography.chip.copyWith(color: foreground)), + ], + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_decision.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_decision.dart new file mode 100644 index 0000000..c873700 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_decision.dart @@ -0,0 +1,223 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_icons.dart'; +import 'package:app_ui/src/widgets/app_pressable.dart'; +import 'package:app_ui/src/widgets/app_skeleton.dart'; +import 'package:flutter/material.dart'; + +/// Card the copilot uses to ask the manager for a decision. +/// +/// Compose it with [AppOptionTile]s and buttons as [children]. +class AppDecisionCard extends StatelessWidget { + /// Creates a decision card. + const AppDecisionCard({ + required this.kindLabel, + required this.title, + required this.children, + this.kindIcon, + this.trailing, + this.diagnosis, + this.urgent = false, + this.complete = false, + this.loading = false, + super.key, + }); + + /// Small label above the title (e.g. "Incident"). + final String kindLabel; + + /// Optional icon beside [kindLabel]. + final AppIconSet? kindIcon; + + /// Card title. Null while it is still arriving: see [loading]. + final String? title; + + /// Optional chip shown on the right of the header. + final Widget? trailing; + + /// Optional explanatory paragraph. Null while it is still arriving: see + /// [loading]. + final String? diagnosis; + + /// Warms the tag color and border (urgent category). + final bool urgent; + + /// Flattens the card once the decision was made. + final bool complete; + + /// Whether the card is still being written: a missing [title] or + /// [diagnosis] shows as a skeleton line instead of being left out. + final bool loading; + + /// Body widgets. + final List children; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final tagColor = urgent ? p.incident : p.accent; + return Container( + padding: const EdgeInsets.all(AppSpacing.x3l), + decoration: BoxDecoration( + color: complete ? p.cardGround : p.surface, + borderRadius: BorderRadius.circular(AppRadii.proposal), + border: Border.all( + color: complete + ? Colors.transparent + : (urgent ? p.incident.withValues(alpha: 0.35) : p.hairline), + ), + boxShadow: complete ? null : AppElevation.card, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + if (kindIcon != null) ...[ + AppIcon(kindIcon!, style: AppIconStyle.fill, color: tagColor), + const SizedBox(width: AppSpacing.sm), + ], + Expanded( + child: Text( + kindLabel, + style: AppTypography.smallMedium.copyWith(color: tagColor), + ), + ), + ?trailing, + ], + ), + if (title != null) ...[ + const SizedBox(height: AppSpacing.lg), + Text( + title!, + style: AppTypography.subtitle.copyWith(color: p.heading), + ), + ] else if (loading) ...[ + const SizedBox(height: AppSpacing.lg), + const AppSkeleton(height: 20), + ], + if (diagnosis != null) ...[ + const SizedBox(height: AppSpacing.lg), + Text( + diagnosis!, + style: AppTypography.body.copyWith( + fontSize: 13, + color: p.inkSecondary, + ), + ), + ] else if (loading) ...[ + const SizedBox(height: AppSpacing.lg), + const AppSkeleton(), + const SizedBox(height: AppSpacing.sm), + const FractionallySizedBox(widthFactor: 0.7, child: AppSkeleton()), + ], + for (final child in children) ...[ + const SizedBox(height: AppSpacing.lg), + child, + ], + ], + ), + ); + } +} + +/// Selectable option inside an [AppDecisionCard]. +class AppOptionTile extends StatelessWidget { + /// Creates an option tile. + const AppOptionTile({ + required this.label, + this.detail, + this.cost, + this.recommended = false, + this.recommendedLabel = 'Recommended', + this.selected = false, + this.onTap, + super.key, + }); + + /// Option title. + final String label; + + /// Optional description. + final String? detail; + + /// Optional right-aligned cost text. + final String? cost; + + /// Show the "Recommended" tag. + final bool recommended; + + /// Text of the recommended tag. + final String recommendedLabel; + + /// Whether the option is chosen. + final bool selected; + + /// Tap callback; null makes the tile read-only. + final VoidCallback? onTap; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return Opacity( + opacity: onTap == null && !selected ? 0.7 : 1, + child: AppPressable( + onTap: onTap, + pressedScale: 0.99, + child: AnimatedContainer( + duration: AppMotion.quick, + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.xxl, + vertical: AppSpacing.lg, + ), + decoration: BoxDecoration( + color: selected ? p.accentWash : p.cardGround, + borderRadius: BorderRadius.circular(AppRadii.option), + border: Border.all( + color: selected ? p.accent : Colors.transparent, + width: 2, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (recommended) + Padding( + padding: const EdgeInsets.only(bottom: AppSpacing.xxs), + child: Text( + recommendedLabel.toUpperCase(), + style: AppTypography.tag.copyWith(color: p.accent), + ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + Expanded( + child: Text( + label, + style: AppTypography.bodyMedium.copyWith(color: p.ink), + ), + ), + if (cost != null) + Text( + cost!, + style: AppTypography.small.copyWith( + color: p.inkSecondary, + ), + ), + ], + ), + if (detail != null) + Text( + detail!, + style: AppTypography.small.copyWith(color: p.inkTertiary), + ), + ], + ), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_dialog.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_dialog.dart new file mode 100644 index 0000000..abe7ff7 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_dialog.dart @@ -0,0 +1,381 @@ +import 'dart:ui'; + +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_button.dart'; +import 'package:app_ui/src/widgets/app_icons.dart'; +import 'package:app_ui/src/widgets/app_tone.dart'; +import 'package:flutter/material.dart'; + +/// Shows [builder] as a modal overlay with the design system scrim. +/// +/// Set [branded] for the navy blurred scrim used by welcome and result +/// dialogs. +Future showAppDialog({ + required BuildContext context, + required WidgetBuilder builder, + bool branded = true, + bool dismissible = false, +}) { + final p = context.palette; + return showGeneralDialog( + context: context, + barrierDismissible: dismissible, + barrierLabel: 'Dismiss', + barrierColor: branded ? AppElevation.brandScrim : p.scrim, + transitionDuration: AppMotion.enter, + pageBuilder: (context, _, _) => SafeArea( + child: Center( + child: Padding( + padding: const EdgeInsets.all(AppSpacing.x3l), + child: builder(context), + ), + ), + ), + transitionBuilder: (context, animation, _, child) { + final curved = CurvedAnimation(parent: animation, curve: AppMotion.ease); + Widget result = FadeTransition( + opacity: curved, + child: ScaleTransition( + scale: Tween(begin: 0.94, end: 1).animate(curved), + child: child, + ), + ); + if (branded) { + result = BackdropFilter( + filter: ImageFilter.blur( + sigmaX: AppElevation.scrimBlur * animation.value, + sigmaY: AppElevation.scrimBlur * animation.value, + ), + child: result, + ); + } + return result; + }, + ); +} + +/// Dialog frame: rounded surface, optional navy [hero] and a padded body. +class AppDialogScaffold extends StatelessWidget { + /// Creates a dialog scaffold. + const AppDialogScaffold({ + required this.children, + this.hero, + this.maxWidth = AppSizes.dialogWidth, + this.radius = AppRadii.card, + this.crossAxisAlignment = CrossAxisAlignment.start, + this.padding = const EdgeInsets.all(AppSpacing.x6l), + super.key, + }); + + /// Optional hero shown above the body on navy. + final Widget? hero; + + /// Body children, separated by 14px. + final List children; + + /// Maximum dialog width. + final double maxWidth; + + /// Corner radius. + final double radius; + + /// Cross axis alignment of the body. + final CrossAxisAlignment crossAxisAlignment; + + /// Body padding. + final EdgeInsetsGeometry padding; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return ConstrainedBox( + constraints: BoxConstraints(maxWidth: maxWidth), + child: DecoratedBox( + decoration: BoxDecoration( + color: p.surface, + borderRadius: BorderRadius.circular(radius), + boxShadow: hero == null ? AppElevation.card : AppElevation.dialog, + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(radius), + child: Material( + type: MaterialType.transparency, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ?hero, + Padding( + padding: padding, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: crossAxisAlignment, + children: [ + for (var i = 0; i < children.length; i++) ...[ + if (i > 0) const SizedBox(height: AppSpacing.xxl), + children[i], + ], + ], + ), + ), + ], + ), + ), + ), + ), + ), + ); + } +} + +/// Welcome dialog: navy hero with brand, then title, copy and actions. +class AppWelcomeDialog extends StatelessWidget { + /// Creates a welcome dialog. + const AppWelcomeDialog({ + required this.hero, + required this.title, + required this.actionLabel, + required this.onAction, + this.brand, + this.paragraphs = const [], + this.steps = const [], + this.goals = const [], + this.footnote, + super.key, + }); + + /// Hero artwork, usually an `AppUnicorn`. + final Widget hero; + + /// Brand line under the artwork. + final String? brand; + + /// Dialog headline. + final String title; + + /// Body paragraphs. + final List paragraphs; + + /// Numbered-style steps rendered as inset rows. + final List steps; + + /// Goal chips (see `AppGoalChip`). + final List goals; + + /// Muted note above the action. + final String? footnote; + + /// Label of the big action button. + final String actionLabel; + + /// Action callback. + final VoidCallback? onAction; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return AppDialogScaffold( + maxWidth: AppSizes.welcomeWidth, + radius: AppRadii.dialog, + padding: const EdgeInsets.fromLTRB( + AppSpacing.x7l, + AppSpacing.x5l, + AppSpacing.x7l, + AppSpacing.x7l, + ), + hero: Container( + color: p.navy, + padding: const EdgeInsets.fromLTRB( + AppSpacing.x5l, + AppSpacing.x6l, + AppSpacing.x5l, + AppSpacing.x4l, + ), + child: Column( + children: [ + hero, + if (brand != null) ...[ + const SizedBox(height: AppSpacing.xs), + Text( + brand!, + style: AppTypography.brand.copyWith( + color: p.onNavy, + fontSize: 24, + ), + ), + ], + ], + ), + ), + children: [ + Text(title, style: AppTypography.headline.copyWith(color: p.heading)), + for (final text in paragraphs) + Text( + text, + style: AppTypography.bodyLarge.copyWith(color: p.inkSecondary), + ), + if (steps.isNotEmpty) + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + for (var i = 0; i < steps.length; i++) ...[ + if (i > 0) const SizedBox(height: AppSpacing.sm), + steps[i], + ], + ], + ), + if (goals.isNotEmpty) + Wrap( + spacing: AppSpacing.md, + runSpacing: AppSpacing.md, + children: goals, + ), + if (footnote != null) + Text( + footnote!, + style: AppTypography.bodyLarge.copyWith(color: p.inkTertiary), + ), + SizedBox( + width: double.infinity, + child: AppButton( + label: actionLabel, + onPressed: onAction, + size: AppButtonSize.big, + expanded: true, + ), + ), + ], + ); + } +} + +/// Inset step row for [AppWelcomeDialog.steps]. +class AppDialogStep extends StatelessWidget { + /// Creates a step row with an optional bold [strong] prefix. + const AppDialogStep({required this.text, this.strong, super.key}); + + /// Regular text. + final String text; + + /// Bold lead-in. + final String? strong; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return DecoratedBox( + decoration: BoxDecoration( + color: p.cardGround, + borderRadius: AppRadii.chipBorder, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.xxl, + vertical: AppSpacing.md, + ), + child: Text.rich( + TextSpan( + children: [ + if (strong != null) + TextSpan( + text: '$strong ', + style: TextStyle( + fontWeight: FontWeight.w600, + color: p.heading, + ), + ), + TextSpan(text: text), + ], + ), + style: AppTypography.body.copyWith(color: p.inkSecondary), + ), + ), + ); + } +} + +/// Result dialog: big icon, headline, message, check rows and actions. +class AppResultDialog extends StatelessWidget { + /// Creates a result dialog. + const AppResultDialog({ + required this.title, + required this.actionLabel, + required this.onAction, + this.won = true, + this.message, + this.checks = const [], + this.extra, + super.key, + }); + + /// Whether the outcome was a win (green check) or a loss (red cross). + final bool won; + + /// Headline. + final String title; + + /// Optional paragraph. + final String? message; + + /// Check rows, typically `AppKeyValueRow`s. + final List checks; + + /// Optional extra block under the checks (e.g. a week summary). + final Widget? extra; + + /// Primary action label. + final String actionLabel; + + /// Primary action callback. + final VoidCallback? onAction; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final tone = won ? AppTone.positive : AppTone.negative; + return AppDialogScaffold( + maxWidth: AppSizes.resultWidth, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + AppIcon( + won ? AppIcons.trophy : AppIcons.xCircle, + style: AppIconStyle.fill, + size: AppSizes.iconHero, + color: tone.foreground(p), + ), + Text( + title, + textAlign: TextAlign.center, + style: AppTypography.headline.copyWith(color: p.heading), + ), + if (message != null) + Text( + message!, + textAlign: TextAlign.center, + style: AppTypography.body.copyWith( + height: 1.5, + color: p.inkSecondary, + ), + ), + if (checks.isNotEmpty) + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + for (var i = 0; i < checks.length; i++) ...[ + if (i > 0) const SizedBox(height: AppSpacing.md), + checks[i], + ], + ], + ), + ?extra, + AppButton( + label: actionLabel, + onPressed: onAction, + icon: AppIcons.restart, + ), + ], + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_icons.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_icons.dart new file mode 100644 index 0000000..684a087 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_icons.dart @@ -0,0 +1,250 @@ +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:flutter/material.dart'; + +/// Visual weights available for an [AppIcon]. +/// +/// Phosphor Icons (`phosphor_flutter` 2.1.0) does not compile on Flutter 3.47 +/// because `IconData` became a final class, so the set is backed by Material +/// icons. `fill` and `duotone` currently share the solid rounded glyph. +enum AppIconStyle { + /// Outline. + regular, + + /// Solid. + fill, + + /// Same solid glyph as [fill]; kept so a duotone set can be swapped in. + duotone, +} + +/// One icon in three weights. +@immutable +class AppIconSet { + /// Creates an icon set. + const AppIconSet(this.regular, this.fill, this.duotone); + + /// Outline glyph. + final IconData regular; + + /// Solid glyph. + final IconData fill; + + /// Duotone glyph. + final IconData duotone; + + /// Glyph for [style]. + IconData resolve(AppIconStyle style) => switch (style) { + AppIconStyle.regular => regular, + AppIconStyle.fill => fill, + AppIconStyle.duotone => duotone, + }; +} + +/// The icon vocabulary of the Coffee Manager. +abstract final class AppIcons { + /// Coffee cup. + static const coffee = AppIconSet( + Icons.coffee_outlined, + Icons.coffee_rounded, + Icons.coffee_rounded, + ); + + /// Parcel. + static const package = AppIconSet( + Icons.inventory_2_outlined, + Icons.inventory_2_rounded, + Icons.inventory_2_rounded, + ); + + /// Scooter. + static const moped = AppIconSet( + Icons.moped_outlined, + Icons.moped_rounded, + Icons.moped_rounded, + ); + + /// Map pin. + static const mapPin = AppIconSet( + Icons.location_on_outlined, + Icons.location_on_rounded, + Icons.location_on_rounded, + ); + + /// Check in a circle. + static const checkCircle = AppIconSet( + Icons.check_circle_outline_rounded, + Icons.check_circle_rounded, + Icons.check_circle_rounded, + ); + + /// Cross in a circle. + static const xCircle = AppIconSet( + Icons.cancel_outlined, + Icons.cancel_rounded, + Icons.cancel_rounded, + ); + + /// Warning triangle. + static const warning = AppIconSet( + Icons.warning_amber_rounded, + Icons.warning_rounded, + Icons.warning_rounded, + ); + + /// Star. + static const star = AppIconSet( + Icons.star_outline_rounded, + Icons.star_rounded, + Icons.star_rounded, + ); + + /// Receipt. + static const receipt = AppIconSet( + Icons.receipt_long_outlined, + Icons.receipt_long_rounded, + Icons.receipt_long_rounded, + ); + + /// Dollar coin. + static const currencyDollar = AppIconSet( + Icons.attach_money_rounded, + Icons.paid_rounded, + Icons.paid_rounded, + ); + + /// Group of people. + static const usersThree = AppIconSet( + Icons.groups_outlined, + Icons.groups_rounded, + Icons.groups_rounded, + ); + + /// Chat bubble. + static const chat = AppIconSet( + Icons.chat_bubble_outline_rounded, + Icons.chat_bubble_rounded, + Icons.chat_bubble_rounded, + ); + + /// Play. + static const play = AppIconSet( + Icons.play_arrow_rounded, + Icons.play_arrow_rounded, + Icons.play_arrow_rounded, + ); + + /// Pause. + static const pause = AppIconSet( + Icons.pause_rounded, + Icons.pause_rounded, + Icons.pause_rounded, + ); + + /// Sign out. + static const signOut = AppIconSet( + Icons.logout_rounded, + Icons.logout_rounded, + Icons.logout_rounded, + ); + + /// Restart arrow. + static const restart = AppIconSet( + Icons.restart_alt_rounded, + Icons.restart_alt_rounded, + Icons.restart_alt_rounded, + ); + + /// Lightning bolt. + static const lightning = AppIconSet( + Icons.bolt_outlined, + Icons.bolt_rounded, + Icons.bolt_rounded, + ); + + /// Wrench. + static const wrench = AppIconSet( + Icons.build_outlined, + Icons.build_rounded, + Icons.build_rounded, + ); + + /// Paper plane (send). + static const send = AppIconSet( + Icons.send_outlined, + Icons.send_rounded, + Icons.send_rounded, + ); + + /// Trophy. + static const trophy = AppIconSet( + Icons.emoji_events_outlined, + Icons.emoji_events_rounded, + Icons.emoji_events_rounded, + ); + + /// Sparkle. + static const sparkle = AppIconSet( + Icons.auto_awesome_outlined, + Icons.auto_awesome_rounded, + Icons.auto_awesome_rounded, + ); + + /// Clock. + static const clock = AppIconSet( + Icons.schedule_outlined, + Icons.schedule_rounded, + Icons.schedule_rounded, + ); + + /// Arrow pointing right. + static const arrowRight = AppIconSet( + Icons.arrow_forward_rounded, + Icons.arrow_forward_rounded, + Icons.arrow_forward_rounded, + ); + + /// Check mark. + static const check = AppIconSet( + Icons.check_rounded, + Icons.check_rounded, + Icons.check_rounded, + ); +} + +/// Renders an [AppIconSet] at a given weight. +class AppIcon extends StatelessWidget { + /// Creates an icon. + const AppIcon( + this.icon, { + this.style = AppIconStyle.regular, + this.size = AppSizes.iconSmall, + this.color, + this.semanticLabel, + super.key, + }); + + /// Which glyph. + final AppIconSet icon; + + /// Which weight. + final AppIconStyle style; + + /// Icon size. + final double size; + + /// Color; defaults to the ambient icon theme. + final Color? color; + + /// Accessibility label. + final String? semanticLabel; + + @override + Widget build(BuildContext context) { + return Icon( + icon.resolve(style), + size: size, + color: color, + semanticLabel: semanticLabel, + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_order_row.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_order_row.dart new file mode 100644 index 0000000..8278431 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_order_row.dart @@ -0,0 +1,209 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_icons.dart'; +import 'package:app_ui/src/widgets/app_pressable.dart'; +import 'package:flutter/material.dart'; + +/// How urgent an order is, which drives the row's color and stripe. +enum AppUrgency { + /// Nothing special. + normal, + + /// Getting late. + warn, + + /// Late: pulses red. + urgent, + + /// Delivered successfully. + done, +} + +/// Board row for one order. Pass plain strings; map your model outside. +class AppOrderRow extends StatefulWidget { + /// Creates an order row. + const AppOrderRow({ + required this.title, + required this.subtitle, + this.trailing, + this.urgency = AppUrgency.normal, + this.selected = false, + this.unread = false, + this.onTap, + super.key, + }); + + /// Primary line, usually the customer name. + final String title; + + /// Secondary line, usually the items. + final String subtitle; + + /// Right-aligned text on the title line (e.g. a countdown). + final String? trailing; + + /// Urgency level. + final AppUrgency urgency; + + /// Whether the row shows the selection outline. + final bool selected; + + /// Whether to show the unread-message icon. + final bool unread; + + /// Tap callback. + final VoidCallback? onTap; + + @override + State createState() => _AppOrderRowState(); +} + +class _AppOrderRowState extends State + with SingleTickerProviderStateMixin { + late final AnimationController _pulse = AnimationController( + vsync: this, + duration: AppMotion.urgent, + ); + + @override + void initState() { + super.initState(); + _syncPulse(); + } + + @override + void didUpdateWidget(AppOrderRow oldWidget) { + super.didUpdateWidget(oldWidget); + _syncPulse(); + } + + void _syncPulse() { + if (widget.urgency == AppUrgency.urgent) { + if (!_pulse.isAnimating) _pulse.repeat(reverse: true); + } else { + _pulse.stop(); + } + } + + @override + void dispose() { + _pulse.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final p = context.palette; + final (background, stripe) = switch (widget.urgency) { + AppUrgency.normal => (p.cardGround, null), + AppUrgency.warn => (p.warningWash, p.warning), + AppUrgency.urgent => (p.negativeWash, p.negative), + AppUrgency.done => (p.positiveWash, p.positive), + }; + final done = widget.urgency == AppUrgency.done; + return AppPressable( + onTap: widget.onTap, + pressedScale: 0.99, + child: AnimatedBuilder( + animation: _pulse, + builder: (context, child) { + final color = widget.urgency == AppUrgency.urgent + ? Color.lerp( + background, + AppColors.negativeWashPulse, + _pulse.value, + )! + : background; + return AnimatedContainer( + duration: AppMotion.quick, + decoration: BoxDecoration( + color: color, + borderRadius: AppRadii.rowBorder, + border: Border.all( + color: widget.selected ? p.accent : Colors.transparent, + width: 2, + ), + ), + child: child, + ); + }, + child: ClipRRect( + borderRadius: AppRadii.rowBorder, + child: Stack( + children: [ + if (stripe != null) + Positioned( + left: 0, + top: 0, + bottom: 0, + child: Container( + key: const Key('appOrderRow_stripe'), + width: AppSizes.stripe, + color: stripe, + ), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.xxl, + vertical: AppSpacing.lg, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Text( + widget.title, + overflow: TextOverflow.ellipsis, + style: AppTypography.bodyMedium.copyWith( + color: p.ink, + ), + ), + ), + if (widget.unread) ...[ + AppIcon( + AppIcons.chat, + style: AppIconStyle.fill, + size: 18, + color: p.accent, + semanticLabel: 'Unread message', + ), + const SizedBox(width: AppSpacing.sm), + ], + if (done) + AppIcon( + AppIcons.checkCircle, + style: AppIconStyle.fill, + size: AppSizes.iconLarge, + color: p.positive, + ) + else if (widget.trailing != null) + Text( + widget.trailing!, + style: AppTypography.mono.copyWith( + color: p.inkTertiary, + ), + ), + ], + ), + const SizedBox(height: AppSpacing.xxs), + Text( + widget.subtitle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: AppTypography.body.copyWith( + color: done ? p.positive : p.inkSecondary, + fontWeight: done ? FontWeight.w500 : null, + ), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_person.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_person.dart new file mode 100644 index 0000000..800452c --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_person.dart @@ -0,0 +1,131 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_progress.dart'; +import 'package:flutter/material.dart'; + +/// Round avatar showing initials. +class AppAvatar extends StatelessWidget { + /// Creates an avatar from a [name]; the first letter is shown. + const AppAvatar({required this.name, this.alert = false, super.key}); + + /// Name to take the initial from. + final String name; + + /// Paint in the negative color. + final bool alert; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final initial = name.isEmpty ? '?' : name.characters.first.toUpperCase(); + return Container( + width: AppSizes.avatar, + height: AppSizes.avatar, + decoration: BoxDecoration( + color: alert ? p.negative : p.accent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + initial, + style: AppTypography.bodyMedium.copyWith( + color: p.surface, + fontWeight: FontWeight.w600, + ), + ), + ); + } +} + +/// Staff row: avatar, name, caption, meter and a trailing load figure. +class AppPersonRow extends StatelessWidget { + /// Creates a person row. + const AppPersonRow({ + required this.name, + required this.caption, + required this.meter, + this.trailing, + this.alert = false, + this.meterTarget, + super.key, + }); + + /// Person name. + final String name; + + /// Right-aligned caption on the name line. + final String caption; + + /// Meter fraction (0..1). + final double meter; + + /// Optional target marker on the meter. + final double? meterTarget; + + /// Trailing text (e.g. current load). + final String? trailing; + + /// Highlights a slow or struggling person. + final bool alert; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return DecoratedBox( + decoration: BoxDecoration( + color: alert ? p.slowWash : p.cardGround, + borderRadius: BorderRadius.circular(AppRadii.option), + ), + child: Padding( + padding: const EdgeInsets.fromLTRB( + AppSpacing.md, + AppSpacing.md, + AppSpacing.xl, + AppSpacing.md, + ), + child: Row( + children: [ + AppAvatar(name: name, alert: alert), + const SizedBox(width: AppSpacing.lg), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Text( + name, + overflow: TextOverflow.ellipsis, + style: AppTypography.bodyMedium.copyWith( + color: p.ink, + ), + ), + ), + Text( + caption, + style: AppTypography.small.copyWith( + color: p.inkTertiary, + ), + ), + ], + ), + const SizedBox(height: AppSpacing.xs), + AppProgressBar(value: meter, target: meterTarget, low: alert), + ], + ), + ), + if (trailing != null) ...[ + const SizedBox(width: AppSpacing.lg), + Text( + trailing!, + style: AppTypography.mono.copyWith(color: p.inkSecondary), + ), + ], + ], + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_pressable.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_pressable.dart new file mode 100644 index 0000000..9f25bf8 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_pressable.dart @@ -0,0 +1,64 @@ +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:flutter/material.dart'; + +/// Scale-on-press and pointer cursor wrapper used by tappable widgets. +class AppPressable extends StatefulWidget { + /// Creates a pressable area. A null [onTap] renders it inert. + const AppPressable({ + required this.child, + this.onTap, + this.semanticLabel, + this.pressedScale = 0.96, + super.key, + }); + + /// Content. + final Widget child; + + /// Called when tapped. + final VoidCallback? onTap; + + /// Optional accessibility label. + final String? semanticLabel; + + /// Scale applied while pressed. + final double pressedScale; + + @override + State createState() => _AppPressableState(); +} + +class _AppPressableState extends State { + bool _down = false; + + void _set({required bool down}) { + if (widget.onTap != null) setState(() => _down = down); + } + + @override + Widget build(BuildContext context) { + return Semantics( + button: true, + enabled: widget.onTap != null, + label: widget.semanticLabel, + child: MouseRegion( + cursor: widget.onTap == null + ? MouseCursor.defer + : SystemMouseCursors.click, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: widget.onTap, + onTapDown: (_) => _set(down: true), + onTapUp: (_) => _set(down: false), + onTapCancel: () => _set(down: false), + child: AnimatedScale( + scale: _down ? widget.pressedScale : 1, + duration: AppMotion.press, + curve: AppMotion.ease, + child: widget.child, + ), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_progress.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_progress.dart new file mode 100644 index 0000000..7a3fdf3 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_progress.dart @@ -0,0 +1,81 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:flutter/material.dart'; + +/// Thin progress bar with an optional target marker. +class AppProgressBar extends StatelessWidget { + /// Creates a progress bar. [value] and [target] are fractions in 0..1. + const AppProgressBar({ + required this.value, + this.target, + this.onNavy = false, + this.low = false, + super.key, + }); + + /// Filled fraction. + final double value; + + /// Optional target marker position. + final double? target; + + /// Restyle for navy surfaces. + final bool onNavy; + + /// Paint the fill in the negative color (a courier below target). + final bool low; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final track = onNavy ? p.onNavy.withValues(alpha: 0.16) : p.fill; + final fill = low ? p.negative : (onNavy ? p.sky : p.accent); + final marker = onNavy ? p.onNavy : p.heading.withValues(alpha: 0.5); + return SizedBox( + height: AppSizes.barMarkerHeight, + child: LayoutBuilder( + builder: (context, box) { + final width = box.maxWidth; + final clamped = value.clamp(0.0, 1.0); + return Stack( + alignment: Alignment.centerLeft, + children: [ + Container( + height: AppSizes.bar, + decoration: BoxDecoration( + color: track, + borderRadius: AppRadii.pillBorder, + ), + ), + AnimatedContainer( + duration: AppMotion.progress, + curve: AppMotion.ease, + height: AppSizes.bar, + width: width * clamped, + decoration: BoxDecoration( + color: fill, + borderRadius: AppRadii.pillBorder, + ), + ), + if (target != null) + Positioned( + left: + (width * target!.clamp(0.0, 1.0)) - + AppSizes.barMarker / 2, + child: Container( + key: const Key('appProgressBar_target'), + width: AppSizes.barMarker, + height: AppSizes.barMarkerHeight, + decoration: BoxDecoration( + color: marker, + borderRadius: BorderRadius.circular(AppSizes.barMarker), + ), + ), + ), + ], + ); + }, + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_segmented.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_segmented.dart new file mode 100644 index 0000000..b37cba9 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_segmented.dart @@ -0,0 +1,113 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_button.dart'; +import 'package:app_ui/src/widgets/app_pressable.dart'; +import 'package:flutter/material.dart'; + +/// Pill-shaped segmented control (speed, difficulty, chat target...). +class AppSegmented extends StatelessWidget { + /// Creates a segmented control. + const AppSegmented({ + required this.segments, + required this.value, + required this.onChanged, + this.onNavy = false, + this.compact = false, + super.key, + }); + + /// Selectable values mapped to their labels, in display order. + final Map segments; + + /// Currently selected value. + final T value; + + /// Called with the tapped value; null disables the control. + final ValueChanged? onChanged; + + /// Restyle for navy surfaces. + final bool onNavy; + + /// Tighter padding for mini panels. + final bool compact; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return AppOpacityWhen( + dim: onChanged == null, + opacity: 0.4, + child: Container( + padding: const EdgeInsets.all(AppSpacing.xxs + 1), + decoration: BoxDecoration( + color: onNavy ? p.onNavyFill : p.fill, + borderRadius: AppRadii.pillBorder, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + for (final entry in segments.entries) + _Segment( + label: entry.value, + selected: entry.key == value, + onNavy: onNavy, + compact: compact, + onTap: onChanged == null ? null : () => onChanged!(entry.key), + ), + ], + ), + ), + ); + } +} + +class _Segment extends StatelessWidget { + const _Segment({ + required this.label, + required this.selected, + required this.onNavy, + required this.compact, + required this.onTap, + }); + + final String label; + final bool selected; + final bool onNavy; + final bool compact; + final VoidCallback? onTap; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final Color background; + final Color foreground; + if (selected) { + background = onNavy ? p.onNavy : p.surface; + foreground = onNavy ? p.navy : p.ink; + } else { + background = Colors.transparent; + foreground = onNavy ? p.onNavy.withValues(alpha: 0.78) : p.inkSecondary; + } + return AppPressable( + onTap: onTap, + pressedScale: 0.97, + child: AnimatedContainer( + duration: AppMotion.quick, + padding: EdgeInsets.symmetric( + horizontal: compact ? AppSpacing.lg : AppSpacing.xxl, + vertical: compact ? AppSpacing.sm - 1 : AppSpacing.md, + ), + decoration: BoxDecoration( + color: background, + borderRadius: AppRadii.pillBorder, + boxShadow: selected && !onNavy ? AppElevation.segment : null, + ), + child: Text( + label, + style: (compact ? AppTypography.chip : AppTypography.smallMedium) + .copyWith(color: foreground), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_skeleton.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_skeleton.dart new file mode 100644 index 0000000..fc04d6e --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_skeleton.dart @@ -0,0 +1,76 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:flutter/material.dart'; + +/// Pulsing placeholder line shown while the agent is thinking. +class AppSkeleton extends StatefulWidget { + /// Creates a skeleton line of fixed [width], or full width when null. + const AppSkeleton({this.width, this.height = 12, super.key}); + + /// Width in logical pixels, or null to fill the parent. + final double? width; + + /// Line height. + final double height; + + @override + State createState() => _AppSkeletonState(); +} + +class _AppSkeletonState extends State + with SingleTickerProviderStateMixin { + late final AnimationController _controller = AnimationController( + vsync: this, + duration: AppMotion.pulse, + )..repeat(reverse: true); + + static const double _minOpacity = 0.4; + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final p = context.palette; + return FadeTransition( + opacity: Tween(begin: 1, end: _minOpacity).animate(_controller), + child: Container( + width: widget.width, + height: widget.height, + decoration: BoxDecoration( + color: p.fill, + borderRadius: BorderRadius.circular(AppRadii.tiny), + ), + ), + ); + } +} + +/// Stack of skeleton lines (a "40px / 60% / 90%" loading block). +class AppSkeletonBlock extends StatelessWidget { + /// Creates a block of skeleton lines. + const AppSkeletonBlock({this.fractions = const [0.4, 0.9, 0.6], super.key}); + + /// Width of each line as a fraction of the available width. + final List fractions; + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (final f in fractions) + Padding( + padding: const EdgeInsets.only(bottom: AppSpacing.lg), + child: FractionallySizedBox( + widthFactor: f, + child: const AppSkeleton(), + ), + ), + ], + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_stat.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_stat.dart new file mode 100644 index 0000000..a5d8b8a --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_stat.dart @@ -0,0 +1,204 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:app_ui/src/widgets/app_progress.dart'; +import 'package:app_ui/src/widgets/app_tone.dart'; +import 'package:flutter/material.dart'; + +/// Score tile: caption, big value, optional suffix and progress bar. +class AppStatTile extends StatelessWidget { + /// Creates a stat tile. + const AppStatTile({ + required this.label, + required this.value, + this.suffix, + this.tone = AppTone.neutral, + this.progress, + this.target, + this.onNavy = true, + this.mono = true, + super.key, + }); + + /// Caption above the value. + final String label; + + /// Main value text. + final String value; + + /// Muted text after the value (e.g. "/ 30"). + final String? suffix; + + /// Tone of the value. Neutral uses the surface's primary color. + final AppTone tone; + + /// Optional progress fraction (0..1) drawn below. + final double? progress; + + /// Optional target marker fraction (0..1). + final double? target; + + /// Whether the tile sits on navy (default) or on a light surface. + final bool onNavy; + + /// Whether the value uses tabular monospace figures. + final bool mono; + + Color _valueColor(AppPalette p) { + if (onNavy) { + return switch (tone) { + AppTone.neutral => p.onNavy, + AppTone.accent => p.sky, + AppTone.positive => AppColors.positiveOnNavy, + AppTone.warning => AppColors.warningOnNavy, + AppTone.negative => AppColors.negativeOnNavy, + }; + } + return tone == AppTone.neutral ? p.heading : tone.foreground(p); + } + + @override + Widget build(BuildContext context) { + final p = context.palette; + final muted = onNavy ? p.onNavyMuted : p.inkTertiary; + final valueStyle = + (mono + ? AppTypography.mono.copyWith( + fontSize: AppTypography.big.fontSize, + fontWeight: FontWeight.w500, + letterSpacing: AppTypography.big.letterSpacing, + ) + : AppTypography.big) + .copyWith(color: _valueColor(p)); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text(label, style: AppTypography.small.copyWith(color: muted)), + const SizedBox(height: AppSpacing.xs), + Row( + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + mainAxisSize: MainAxisSize.min, + children: [ + Text(value, style: valueStyle), + if (suffix != null) ...[ + const SizedBox(width: AppSpacing.sm), + Text(suffix!, style: AppTypography.mono.copyWith(color: muted)), + ], + ], + ), + if (progress != null) ...[ + const SizedBox(height: AppSpacing.xs), + AppProgressBar(value: progress!, target: target, onNavy: onNavy), + ], + ], + ); + } +} + +/// Goal chip: a bold figure with a label, on an accent wash. +class AppGoalChip extends StatelessWidget { + /// Creates a goal chip, e.g. `AppGoalChip(strong: '30', label: 'orders')`. + const AppGoalChip({required this.strong, required this.label, super.key}); + + /// Bold part. + final String strong; + + /// Regular part. + final String label; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return DecoratedBox( + decoration: BoxDecoration( + color: p.accentWash, + borderRadius: AppRadii.pillBorder, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.xxl, + vertical: AppSpacing.md, + ), + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: strong, + style: const TextStyle(fontWeight: FontWeight.w600), + ), + TextSpan(text: ' $label'), + ], + ), + style: AppTypography.body.copyWith(color: p.accent, fontSize: 13), + ), + ), + ); + } +} + +/// Label on the left, value on the right, on an inset rounded row. +class AppKeyValueRow extends StatelessWidget { + /// Creates a key-value row. + const AppKeyValueRow({ + required this.label, + required this.value, + this.valueTone = AppTone.neutral, + this.inset = true, + this.mono = false, + super.key, + }); + + /// Left text. + final String label; + + /// Right text. + final String value; + + /// Tone of the value. + final AppTone valueTone; + + /// Whether the row has the inset card-ground background. + final bool inset; + + /// Whether the value uses tabular monospace figures. + final bool mono; + + @override + Widget build(BuildContext context) { + final p = context.palette; + final valueColor = valueTone == AppTone.neutral + ? p.ink + : valueTone.foreground(p); + final base = mono + ? AppTypography.mono.copyWith(fontSize: 14) + : AppTypography.bodyMedium; + return DecoratedBox( + decoration: BoxDecoration( + color: inset ? p.cardGround : null, + borderRadius: AppRadii.rowBorder, + ), + child: Padding( + padding: inset + ? const EdgeInsets.symmetric( + horizontal: AppSpacing.x3l, + vertical: AppSpacing.xl, + ) + : const EdgeInsets.symmetric(vertical: AppSpacing.xs), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Text( + label, + style: AppTypography.body.copyWith(color: p.inkSecondary), + ), + ), + const SizedBox(width: AppSpacing.md), + Text(value, style: base.copyWith(color: valueColor)), + ], + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_toast.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_toast.dart new file mode 100644 index 0000000..9c38d00 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_toast.dart @@ -0,0 +1,49 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:app_ui/src/tokens/tokens.dart'; +import 'package:flutter/material.dart'; + +/// Floating pill banner, e.g. "Day 2 begins". +class AppToast extends StatelessWidget { + /// Creates a toast. + const AppToast({required this.message, super.key}); + + /// Message shown. + final String message; + + @override + Widget build(BuildContext context) { + final p = context.palette; + return TweenAnimationBuilder( + tween: Tween(begin: 0, end: 1), + duration: AppMotion.enter, + curve: AppMotion.ease, + builder: (context, t, child) => Opacity( + opacity: t, + child: Transform.translate( + offset: Offset(0, (1 - t) * AppSpacing.sm), + child: child, + ), + ), + child: Semantics( + liveRegion: true, + child: DecoratedBox( + decoration: BoxDecoration( + color: p.surface, + borderRadius: AppRadii.pillBorder, + boxShadow: AppElevation.card, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.x4l, + vertical: AppSpacing.md, + ), + child: Text( + message, + style: AppTypography.bodyMedium.copyWith(color: p.heading), + ), + ), + ), + ), + ); + } +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_tone.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_tone.dart new file mode 100644 index 0000000..31fc007 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/app_tone.dart @@ -0,0 +1,41 @@ +import 'package:app_ui/src/theme/app_palette.dart'; +import 'package:flutter/material.dart'; + +/// Semantic emphasis shared by chips, tiles and banners. +enum AppTone { + /// Quiet gray. + neutral, + + /// Brand blue. + accent, + + /// Success green. + positive, + + /// Warning amber. + warning, + + /// Error red. + negative, +} + +/// Resolves [AppTone] into concrete colors. +extension AppToneColors on AppTone { + /// Foreground (text and icon) color of the tone. + Color foreground(AppPalette p) => switch (this) { + AppTone.neutral => p.inkSecondary, + AppTone.accent => p.accent, + AppTone.positive => p.positive, + AppTone.warning => p.incident, + AppTone.negative => p.negative, + }; + + /// Background wash of the tone. + Color background(AppPalette p) => switch (this) { + AppTone.neutral => p.fill, + AppTone.accent => p.accentWash, + AppTone.positive => p.positive.withValues(alpha: 0.14), + AppTone.warning => p.warningWash, + AppTone.negative => p.negative.withValues(alpha: 0.12), + }; +} diff --git a/03-human-in-the-loop/shared/app_ui/lib/src/widgets/widgets.dart b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/widgets.dart new file mode 100644 index 0000000..d861300 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/lib/src/widgets/widgets.dart @@ -0,0 +1,17 @@ +export 'app_brand.dart'; +export 'app_button.dart'; +export 'app_card.dart'; +export 'app_chat.dart'; +export 'app_chip.dart'; +export 'app_decision.dart'; +export 'app_dialog.dart'; +export 'app_icons.dart'; +export 'app_order_row.dart'; +export 'app_person.dart'; +export 'app_pressable.dart'; +export 'app_progress.dart'; +export 'app_segmented.dart'; +export 'app_skeleton.dart'; +export 'app_stat.dart'; +export 'app_toast.dart'; +export 'app_tone.dart'; diff --git a/03-human-in-the-loop/shared/app_ui/pubspec.yaml b/03-human-in-the-loop/shared/app_ui/pubspec.yaml new file mode 100644 index 0000000..1efdd04 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/pubspec.yaml @@ -0,0 +1,36 @@ +name: app_ui +description: Design system for the Calaverita Builder (tokens, themes and widgets from the CopilotKit demo) +version: 0.1.0+1 +publish_to: none +resolution: workspace + +environment: + sdk: ^3.13.0 + flutter: ^3.47.0 + +dependencies: + flutter: + sdk: flutter + flutter_svg: ^2.2.4 + +dev_dependencies: + flutter_test: + sdk: flutter + very_good_analysis: ^11.0.0 + +flutter: + assets: + - assets/images/ + fonts: + - family: Poppins + fonts: + - asset: assets/fonts/Poppins-Regular.ttf + - asset: assets/fonts/Poppins-Medium.ttf + weight: 500 + - asset: assets/fonts/Poppins-SemiBold.ttf + weight: 600 + - family: JetBrainsMono + fonts: + - asset: assets/fonts/JetBrainsMono-Regular.ttf + - asset: assets/fonts/JetBrainsMono-Medium.ttf + weight: 500 diff --git a/03-human-in-the-loop/shared/app_ui/test/helpers/helpers.dart b/03-human-in-the-loop/shared/app_ui/test/helpers/helpers.dart new file mode 100644 index 0000000..b15fe65 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/helpers/helpers.dart @@ -0,0 +1 @@ +export 'pump_app.dart'; diff --git a/03-human-in-the-loop/shared/app_ui/test/helpers/pump_app.dart b/03-human-in-the-loop/shared/app_ui/test/helpers/pump_app.dart new file mode 100644 index 0000000..c4c4f45 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/helpers/pump_app.dart @@ -0,0 +1,25 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +extension PumpApp on WidgetTester { + /// Pumps [widget] inside an [AppTheme] material app. + Future pumpApp( + Widget widget, { + bool dark = false, + bool settle = true, + }) async { + await pumpWidget( + MaterialApp( + theme: AppTheme.light, + darkTheme: AppTheme.dark, + themeMode: dark ? ThemeMode.dark : ThemeMode.light, + home: Scaffold(body: Center(child: widget)), + ), + ); + if (settle) { + await pump(const Duration(milliseconds: 500)); + } else { + await pump(); + } + } +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/theme/app_theme_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/theme/app_theme_test.dart new file mode 100644 index 0000000..ef84ffb --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/theme/app_theme_test.dart @@ -0,0 +1,80 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppTheme', () { + test('light is a Material 3 light theme with the palette', () { + final theme = AppTheme.light; + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.light); + expect(theme.colorScheme.primary, AppColors.accent); + expect(theme.scaffoldBackgroundColor, AppColors.ground); + expect(theme.extension(), isNotNull); + expect(theme.textTheme.bodyMedium?.fontFamily, AppTypography.fontFamily); + }); + + test('dark is a Material 3 dark theme with the dark palette', () { + final theme = AppTheme.dark; + expect(theme.brightness, Brightness.dark); + expect(theme.scaffoldBackgroundColor, AppColors.darkGround); + expect(theme.colorScheme.primary, AppColors.darkAccent); + }); + }); + + group('AppPalette', () { + test('lerp blends two palettes and ignores foreign extensions', () { + const a = AppPalette.light(); + const b = AppPalette.dark(); + expect(a.lerp(b, 0).ground, a.ground); + expect(a.lerp(b, 1).ground, b.ground); + expect(a.lerp(null, 0.5), same(a)); + }); + + test('copyWith overrides selected roles', () { + const a = AppPalette.light(); + final b = a.copyWith( + ground: AppColors.navy, + cardGround: AppColors.navy, + surface: AppColors.navy, + navy: AppColors.ground, + accent: AppColors.negative, + ink: AppColors.negative, + ); + expect(b.ground, AppColors.navy); + expect(b.accent, AppColors.negative); + expect(b.copyWith().navy, b.navy); + }); + + testWidgets('context.palette falls back to light without a theme ' + 'extension', (tester) async { + late AppPalette palette; + await tester.pumpWidget( + MaterialApp( + home: Builder( + builder: (context) { + palette = context.palette; + return const SizedBox(); + }, + ), + ), + ); + expect(palette.ground, AppColors.ground); + }); + + testWidgets('context.palette reads the dark theme', (tester) async { + late AppPalette palette; + await tester.pumpApp( + Builder( + builder: (context) { + palette = context.palette; + return const SizedBox(); + }, + ), + dark: true, + ); + expect(palette.ground, AppColors.darkGround); + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/tokens/tokens_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/tokens/tokens_test.dart new file mode 100644 index 0000000..aa8d2a4 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/tokens/tokens_test.dart @@ -0,0 +1,55 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('tokens', () { + test('spacing scale is ascending', () { + final scale = [ + AppSpacing.xxs, + AppSpacing.xs, + AppSpacing.sm, + AppSpacing.md, + AppSpacing.lg, + AppSpacing.xl, + AppSpacing.xxl, + AppSpacing.x3l, + AppSpacing.x4l, + AppSpacing.x5l, + AppSpacing.x6l, + AppSpacing.x7l, + ]; + expect([...scale]..sort(), scale); + }); + + test('radii borders match their radius', () { + expect(AppRadii.cardBorder.topLeft.x, AppRadii.card); + expect(AppRadii.rowBorder.topLeft.x, AppRadii.row); + expect(AppRadii.chipBorder.topLeft.x, AppRadii.chip); + expect(AppRadii.pillBorder.topLeft.x, AppRadii.pill); + }); + + test('ease curve starts at 0 and ends at 1', () { + expect(AppMotion.ease.transform(0), 0); + expect(AppMotion.ease.transform(1), closeTo(1, 1e-6)); + }); + + test('typography uses Poppins and mono uses tabular figures', () { + expect(AppTypography.body.fontFamily, AppTypography.fontFamily); + expect(AppTypography.mono.fontFeatures, isNotEmpty); + expect(AppTypography.mono.fontFamilyFallback, AppTypography.monoFallback); + }); + + test('elevation tokens are non-empty and sizes are positive', () { + expect(AppElevation.card, isNotEmpty); + expect(AppElevation.dialog, isNotEmpty); + expect(AppElevation.segment, isNotEmpty); + expect(AppElevation.iconButton, isNotEmpty); + expect(AppSizes.control, greaterThan(0)); + }); + + test('stage colors are distinct', () { + final colors = AppStage.values.map(AppStageDot.colorOf).toSet(); + expect(colors, hasLength(AppStage.values.length)); + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_button_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_button_test.dart new file mode 100644 index 0000000..54fa769 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_button_test.dart @@ -0,0 +1,130 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppButton', () { + testWidgets('renders label and fires onPressed', (tester) async { + var taps = 0; + await tester.pumpApp(AppButton(label: 'Start', onPressed: () => taps++)); + expect(find.text('Start'), findsOneWidget); + await tester.tap(find.byType(AppButton)); + await tester.pump(const Duration(milliseconds: 200)); + expect(taps, 1); + }); + + testWidgets('is dimmed and inert when disabled', (tester) async { + await tester.pumpApp(const AppButton.ghost(label: 'No', onPressed: null)); + final opacity = tester.widget(find.byType(Opacity).first); + expect(opacity.opacity, lessThan(1)); + }); + + testWidgets('shows icon and supports every size / variant', (tester) async { + for (final size in AppButtonSize.values) { + for (final onNavy in [false, true]) { + await tester.pumpApp( + Column( + children: [ + AppButton.primary( + label: 'P', + onPressed: () {}, + icon: AppIcons.play, + size: size, + onNavy: onNavy, + expanded: true, + ), + AppButton.ghost( + label: 'G', + onPressed: () {}, + size: size, + onNavy: onNavy, + ), + ], + ), + ); + expect(find.byType(AppIcon), findsOneWidget); + } + } + }); + + testWidgets('press scales down and releases', (tester) async { + await tester.pumpApp(AppButton(label: 'Go', onPressed: () {})); + final gesture = await tester.startGesture( + tester.getCenter(find.byType(AppButton)), + ); + await tester.pump(const Duration(milliseconds: 200)); + expect( + tester.widget(find.byType(AnimatedScale)).scale, + lessThan(1), + ); + await gesture.cancel(); + await tester.pump(const Duration(milliseconds: 200)); + expect(tester.widget(find.byType(AnimatedScale)).scale, 1); + }); + }); + + group('AppIconButton', () { + testWidgets('fires onPressed in all variants', (tester) async { + var taps = 0; + for (final primary in [false, true]) { + for (final onNavy in [false, true]) { + await tester.pumpApp( + AppIconButton( + icon: AppIcons.pause, + semanticLabel: 'Pause', + onPressed: () => taps++, + primary: primary, + onNavy: onNavy, + ), + ); + await tester.tap(find.byType(AppIconButton)); + } + } + expect(taps, 4); + }); + + testWidgets('is dimmed when disabled', (tester) async { + await tester.pumpApp( + const AppIconButton( + icon: AppIcons.pause, + semanticLabel: 'Pause', + onPressed: null, + ), + ); + expect( + tester.widget(find.byType(Opacity).first).opacity, + lessThan(1), + ); + }); + }); + + group('AppSegmented', () { + testWidgets('reports taps and highlights selection', (tester) async { + String? picked; + await tester.pumpApp( + AppSegmented( + segments: const {'a': 'Slow', 'b': 'Fast'}, + value: 'a', + onChanged: (v) => picked = v, + ), + ); + await tester.tap(find.text('Fast')); + expect(picked, 'b'); + }); + + testWidgets('supports navy, compact and disabled', (tester) async { + await tester.pumpApp( + const AppSegmented( + segments: {1: 'One', 2: 'Two'}, + value: 2, + onChanged: null, + onNavy: true, + compact: true, + ), + ); + expect(find.text('One'), findsOneWidget); + await tester.tap(find.text('One')); + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_card_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_card_test.dart new file mode 100644 index 0000000..678ddc8 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_card_test.dart @@ -0,0 +1,65 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppCard', () { + testWidgets('renders child with and without shadow/clip', (tester) async { + await tester.pumpApp( + const Column( + children: [ + AppCard(child: Text('a')), + AppCard(shadow: false, clip: false, child: Text('b')), + ], + ), + ); + expect(find.text('a'), findsOneWidget); + expect(find.text('b'), findsOneWidget); + }); + }); + + group('AppSectionHeader', () { + testWidgets('shows title, icon and trailing', (tester) async { + await tester.pumpApp( + const AppSectionHeader( + title: 'Requested', + icon: AppIcons.coffee, + trailing: AppCountBadge(count: 2), + ), + ); + expect(find.text('Requested'), findsOneWidget); + expect(find.byType(AppIcon), findsOneWidget); + expect(find.byType(AppCountBadge), findsOneWidget); + }); + + testWidgets('works on navy without icon', (tester) async { + await tester.pumpApp( + const AppSectionHeader(title: 'Copilot', onNavy: true), + ); + expect(find.byType(AppIcon), findsNothing); + }); + }); + + group('AppPanel', () { + testWidgets('renders a titled body in both styles', (tester) async { + for (final navy in [false, true]) { + await tester.pumpApp( + SizedBox( + height: 200, + width: 300, + child: AppPanel( + title: 'Panel', + icon: AppIcons.usersThree, + trailing: const AppChip(label: 'x'), + navy: navy, + child: const Text('body'), + ), + ), + ); + expect(find.text('Panel'), findsOneWidget); + expect(find.text('body'), findsOneWidget); + } + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_chat_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_chat_test.dart new file mode 100644 index 0000000..81eb3df --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_chat_test.dart @@ -0,0 +1,126 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppChatBubble', () { + testWidgets('renders text, sender and timestamp', (tester) async { + await tester.pumpApp( + const SizedBox( + width: 400, + child: AppChatBubble( + text: 'Where is my latte?', + role: AppChatRole.customer, + sender: 'Ana', + timestamp: '09:12', + ), + ), + ); + expect(find.text('Where is my latte?'), findsOneWidget); + expect(find.text('Ana'), findsOneWidget); + expect(find.text('09:12'), findsOneWidget); + }); + + testWidgets('renders every role on light and navy', (tester) async { + for (final onNavy in [false, true]) { + for (final accent in [false, true]) { + await tester.pumpApp( + SizedBox( + width: 400, + child: Column( + children: [ + for (final role in AppChatRole.values) + AppChatBubble( + text: role.name, + role: role, + onNavy: onNavy, + accent: accent, + ), + ], + ), + ), + ); + expect(find.byType(AppChatBubble), findsNWidgets(3)); + } + } + }); + }); + + group('AppTypingBubble', () { + testWidgets('animates three dots', (tester) async { + for (final onNavy in [false, true]) { + await tester.pumpApp(AppTypingBubble(onNavy: onNavy), settle: false); + for (var i = 0; i < 6; i++) { + await tester.pump(const Duration(milliseconds: 200)); + } + expect(find.byType(AppTypingBubble), findsOneWidget); + } + }); + }); + + group('AppComposer', () { + testWidgets('sends trimmed text on tap and clears the field', ( + tester, + ) async { + final sent = []; + await tester.pumpApp( + SizedBox(width: 400, child: AppComposer(onSend: sent.add)), + ); + await tester.enterText(find.byType(TextField), ' hello '); + await tester.tap(find.bySemanticsLabel('Send')); + await tester.pump(); + expect(sent, ['hello']); + expect( + tester.widget(find.byType(TextField)).controller!.text, + isEmpty, + ); + }); + + testWidgets('sends on keyboard submit and ignores empty text', ( + tester, + ) async { + final sent = []; + await tester.pumpApp( + SizedBox( + width: 400, + child: AppComposer(onSend: sent.add, onNavy: true, compact: true), + ), + ); + await tester.tap(find.bySemanticsLabel('Send')); + expect(sent, isEmpty); + await tester.enterText(find.byType(TextField), 'go'); + await tester.testTextInput.receiveAction(TextInputAction.done); + expect(sent, ['go']); + }); + + testWidgets('does nothing when disabled', (tester) async { + final sent = []; + await tester.pumpApp( + SizedBox( + width: 400, + child: AppComposer(onSend: sent.add, enabled: false), + ), + ); + await tester.tap(find.bySemanticsLabel('Send')); + expect(sent, isEmpty); + }); + }); + + group('AppSuggestionChip', () { + testWidgets('fires onTap on navy and light', (tester) async { + var taps = 0; + for (final onNavy in [true, false]) { + await tester.pumpApp( + AppSuggestionChip( + label: 'Who is slow?', + onTap: () => taps++, + onNavy: onNavy, + ), + ); + await tester.tap(find.text('Who is slow?')); + } + expect(taps, 2); + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_chip_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_chip_test.dart new file mode 100644 index 0000000..6625db9 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_chip_test.dart @@ -0,0 +1,94 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppChip', () { + testWidgets('renders every tone with and without icon', (tester) async { + await tester.pumpApp( + Column( + children: [ + for (final tone in AppTone.values) + AppChip(label: tone.name, tone: tone), + const AppChip(label: 'icon', icon: AppIcons.coffee), + const AppChip( + label: 'custom', + foreground: AppColors.navy, + background: AppColors.ground, + ), + ], + ), + ); + expect(find.byType(AppChip), findsNWidgets(AppTone.values.length + 2)); + expect(find.byType(AppIcon), findsOneWidget); + }); + }); + + group('AppVerdictChip', () { + testWidgets('shows default labels and accepts overrides', (tester) async { + await tester.pumpApp( + Column( + children: [ + for (final v in AppVerdict.values) AppVerdictChip(verdict: v), + const AppVerdictChip(verdict: AppVerdict.approve, label: 'Yes'), + ], + ), + ); + expect(find.text('Approved'), findsOneWidget); + expect(find.text('Edited'), findsOneWidget); + expect(find.text('Rejected'), findsOneWidget); + expect(find.text('Yes'), findsOneWidget); + }); + }); + + group('AppSeverityChip', () { + testWidgets('shows default labels and accepts overrides', (tester) async { + await tester.pumpApp( + Column( + children: [ + for (final s in AppSeverity.values) AppSeverityChip(severity: s), + const AppSeverityChip(severity: AppSeverity.low, label: 'Meh'), + ], + ), + ); + expect(find.text('High'), findsOneWidget); + expect(find.text('Medium'), findsOneWidget); + expect(find.text('Low'), findsOneWidget); + expect(find.text('Meh'), findsOneWidget); + }); + }); + + testWidgets('AppCountBadge shows the count', (tester) async { + await tester.pumpApp(const AppCountBadge(count: 7)); + expect(find.text('7'), findsOneWidget); + }); + + testWidgets('AppStageDot paints the stage color', (tester) async { + await tester.pumpApp( + Column( + children: [for (final s in AppStage.values) AppStageDot(stage: s)], + ), + ); + expect(find.byType(AppStageDot), findsNWidgets(4)); + }); + + group('AppStepPill', () { + testWidgets('renders the three states', (tester) async { + await tester.pumpApp( + const Column( + children: [ + AppStepPill(number: 1, label: 'Past', state: AppStepState.past), + AppStepPill(number: 2, label: 'Now', state: AppStepState.now), + AppStepPill(number: 3, label: 'Next', state: AppStepState.upcoming), + ], + ), + ); + expect(find.text('Past'), findsOneWidget); + expect(find.text('2'), findsOneWidget); + expect(find.text('3'), findsOneWidget); + expect(find.text('1'), findsNothing); + expect(find.byType(AppIcon), findsOneWidget); + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_decision_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_decision_test.dart new file mode 100644 index 0000000..70d9530 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_decision_test.dart @@ -0,0 +1,123 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppDecisionCard', () { + testWidgets('renders header, diagnosis and children', (tester) async { + await tester.pumpApp( + const SizedBox( + width: 360, + child: AppDecisionCard( + kindLabel: 'Incident', + kindIcon: AppIcons.warning, + title: 'Machine down', + diagnosis: 'Grinder jammed.', + trailing: AppSeverityChip(severity: AppSeverity.high), + urgent: true, + children: [Text('child')], + ), + ), + ); + expect(find.text('Incident'), findsOneWidget); + expect(find.text('Machine down'), findsOneWidget); + expect(find.text('Grinder jammed.'), findsOneWidget); + expect(find.text('child'), findsOneWidget); + }); + + testWidgets('renders minimal and complete states', (tester) async { + await tester.pumpApp( + const SizedBox( + width: 360, + child: AppDecisionCard( + kindLabel: 'Systemic', + title: 'T', + complete: true, + children: [], + ), + ), + ); + expect(find.text('Systemic'), findsOneWidget); + }); + }); + + group('AppDecisionCard loading', () { + testWidgets('draws skeletons for a missing title and diagnosis', ( + tester, + ) async { + await tester.pumpApp( + const SizedBox( + width: 360, + child: AppDecisionCard( + kindLabel: 'Proposal', + title: null, + loading: true, + children: [], + ), + ), + ); + expect(find.byType(AppSkeleton), findsNWidgets(3)); + }); + + testWidgets('keeps the arrived text and skeletons only the rest', ( + tester, + ) async { + await tester.pumpApp( + const SizedBox( + width: 360, + child: AppDecisionCard( + kindLabel: 'Proposal', + title: 'Machine down', + loading: true, + children: [], + ), + ), + ); + expect(find.text('Machine down'), findsOneWidget); + expect(find.byType(AppSkeleton), findsNWidgets(2)); + }); + + testWidgets('leaves missing text out when not loading', (tester) async { + await tester.pumpApp( + const SizedBox( + width: 360, + child: AppDecisionCard( + kindLabel: 'Proposal', + title: null, + children: [], + ), + ), + ); + expect(find.byType(AppSkeleton), findsNothing); + }); + }); + + group('AppOptionTile', () { + testWidgets('shows details and handles taps', (tester) async { + var taps = 0; + await tester.pumpApp( + SizedBox( + width: 360, + child: AppOptionTile( + label: 'Add courier', + detail: 'Faster', + cost: r'$12', + recommended: true, + selected: true, + onTap: () => taps++, + ), + ), + ); + expect(find.text('RECOMMENDED'), findsOneWidget); + expect(find.text(r'$12'), findsOneWidget); + await tester.tap(find.byType(AppOptionTile)); + expect(taps, 1); + }); + + testWidgets('is dimmed when read-only and unselected', (tester) async { + await tester.pumpApp(const AppOptionTile(label: 'Skip')); + expect(tester.widget(find.byType(Opacity).first).opacity, 0.7); + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_dialog_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_dialog_test.dart new file mode 100644 index 0000000..4ff0d4f --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_dialog_test.dart @@ -0,0 +1,145 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppDialogScaffold', () { + testWidgets('renders hero and children', (tester) async { + await tester.pumpApp( + const AppDialogScaffold( + hero: Text('hero'), + children: [Text('one'), Text('two')], + ), + ); + expect(find.text('hero'), findsOneWidget); + expect(find.text('one'), findsOneWidget); + expect(find.text('two'), findsOneWidget); + }); + + testWidgets('renders without hero', (tester) async { + await tester.pumpApp(const AppDialogScaffold(children: [Text('one')])); + expect(find.text('one'), findsOneWidget); + }); + }); + + group('AppWelcomeDialog', () { + testWidgets('renders all sections and fires the action', (tester) async { + var taps = 0; + tester.view.physicalSize = const Size(900, 1600); + tester.view.devicePixelRatio = 1; + addTearDown(tester.view.reset); + await tester.pumpApp( + AppWelcomeDialog( + hero: const AppUnicorn(size: 80), + brand: 'Very Good Coffee', + title: 'Welcome', + paragraphs: const ['Run the shop.'], + steps: const [AppDialogStep(strong: '1.', text: 'Watch')], + goals: const [AppGoalChip(strong: '30', label: 'orders')], + footnote: 'Good luck', + actionLabel: 'Start', + onAction: () => taps++, + ), + ); + expect(find.text('Welcome'), findsOneWidget); + expect(find.text('Very Good Coffee'), findsOneWidget); + expect(find.text('Run the shop.'), findsOneWidget); + expect(find.text('Good luck'), findsOneWidget); + await tester.tap(find.text('Start')); + expect(taps, 1); + }); + + testWidgets('renders with only required parts', (tester) async { + await tester.pumpApp( + AppWelcomeDialog( + hero: const SizedBox(), + title: 'Hi', + actionLabel: 'Go', + onAction: () {}, + ), + ); + expect(find.text('Hi'), findsOneWidget); + }); + }); + + group('AppDialogStep', () { + testWidgets('renders with and without a bold lead-in', (tester) async { + await tester.pumpApp( + const Column( + children: [ + AppDialogStep(strong: 'Bold', text: 'rest'), + AppDialogStep(text: 'plain'), + ], + ), + ); + expect(find.textContaining('rest', findRichText: true), findsOneWidget); + expect(find.textContaining('plain', findRichText: true), findsOneWidget); + }); + }); + + group('AppResultDialog', () { + testWidgets('won state shows a trophy and fires the action', ( + tester, + ) async { + var taps = 0; + await tester.pumpApp( + AppResultDialog( + title: 'You won', + message: 'Nice', + checks: const [AppKeyValueRow(label: 'Orders', value: '30')], + extra: const Text('week'), + actionLabel: 'Again', + onAction: () => taps++, + ), + ); + expect(find.text('You won'), findsOneWidget); + expect(find.text('Orders'), findsOneWidget); + expect(find.text('week'), findsOneWidget); + await tester.tap(find.text('Again')); + expect(taps, 1); + }); + + testWidgets('lost state renders without optional parts', (tester) async { + await tester.pumpApp( + AppResultDialog( + title: 'Closed', + won: false, + actionLabel: 'Retry', + onAction: () {}, + ), + ); + expect(find.text('Closed'), findsOneWidget); + }); + }); + + group('showAppDialog', () { + for (final branded in [true, false]) { + testWidgets('opens a modal (branded: $branded) and dismisses it', ( + tester, + ) async { + await tester.pumpApp( + Builder( + builder: (context) => AppButton( + label: 'Open', + onPressed: () => showAppDialog( + context: context, + branded: branded, + dismissible: true, + builder: (_) => const Text('modal'), + ), + ), + ), + ); + await tester.tap(find.text('Open')); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 500)); + expect(find.text('modal'), findsOneWidget); + await tester.tapAt(const Offset(2, 2)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 500)); + expect(find.text('modal'), findsNothing); + }); + } + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_misc_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_misc_test.dart new file mode 100644 index 0000000..c7a8708 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_misc_test.dart @@ -0,0 +1,96 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppToast', () { + testWidgets('fades in the message', (tester) async { + await tester.pumpApp(const AppToast(message: 'Day 2'), settle: false); + await tester.pump(const Duration(milliseconds: 500)); + expect(find.text('Day 2'), findsOneWidget); + }); + }); + + group('AppIcon', () { + testWidgets('resolves every style', (tester) async { + await tester.pumpApp( + Column( + children: [ + for (final style in AppIconStyle.values) + AppIcon(AppIcons.coffee, style: style, semanticLabel: style.name), + ], + ), + ); + expect(find.byType(AppIcon), findsNWidgets(3)); + }); + + test('every icon set has three distinct glyphs', () { + const sets = [ + AppIcons.coffee, + AppIcons.package, + AppIcons.moped, + AppIcons.mapPin, + AppIcons.checkCircle, + AppIcons.xCircle, + AppIcons.warning, + AppIcons.star, + AppIcons.receipt, + AppIcons.currencyDollar, + AppIcons.usersThree, + AppIcons.chat, + AppIcons.play, + AppIcons.pause, + AppIcons.signOut, + AppIcons.restart, + AppIcons.lightning, + AppIcons.wrench, + AppIcons.send, + AppIcons.trophy, + AppIcons.sparkle, + AppIcons.clock, + AppIcons.arrowRight, + AppIcons.check, + ]; + for (final set in sets) { + expect(set.resolve(AppIconStyle.regular), set.regular); + expect(set.resolve(AppIconStyle.fill), set.fill); + expect(set.resolve(AppIconStyle.duotone), set.duotone); + } + }); + }); + + group('brand', () { + testWidgets('AppUnicorn picks the asset for the background', ( + tester, + ) async { + await tester.pumpApp( + const Column( + children: [ + AppUnicorn(size: 40), + AppUnicorn(size: 40, onNavy: false, semanticLabel: 'VGV'), + ], + ), + ); + expect(find.byType(AppUnicorn), findsNWidgets(2)); + }); + + testWidgets('AppVgvLockup renders plain and tinted', (tester) async { + await tester.pumpApp( + const Column( + children: [ + AppVgvLockup(height: 40), + AppVgvLockup(height: 40, color: AppColors.accent), + ], + ), + ); + expect(find.byType(AppVgvLockup), findsNWidgets(2)); + }); + + test('asset paths point into the package', () { + expect(AppAssets.unicorn, endsWith('unicorn.svg')); + expect(AppAssets.unicornDark, endsWith('unicorn-dark.svg')); + expect(AppAssets.vgvLockup, endsWith('vgv-lockup.svg')); + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_order_row_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_order_row_test.dart new file mode 100644 index 0000000..c6da23d --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_order_row_test.dart @@ -0,0 +1,124 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppOrderRow', () { + testWidgets('shows texts and fires onTap', (tester) async { + var taps = 0; + await tester.pumpApp( + SizedBox( + width: 300, + child: AppOrderRow( + title: 'Ana', + subtitle: '2x Latte', + trailing: '0:42', + onTap: () => taps++, + ), + ), + ); + expect(find.text('Ana'), findsOneWidget); + expect(find.text('2x Latte'), findsOneWidget); + expect(find.text('0:42'), findsOneWidget); + expect(find.byKey(const Key('appOrderRow_stripe')), findsNothing); + await tester.tap(find.byType(AppOrderRow)); + expect(taps, 1); + }); + + testWidgets('draws a stripe for warn, urgent and done', (tester) async { + for (final urgency in [ + AppUrgency.warn, + AppUrgency.urgent, + AppUrgency.done, + ]) { + await tester.pumpApp( + SizedBox( + width: 300, + child: AppOrderRow( + title: 'Ana', + subtitle: 'Latte', + urgency: urgency, + selected: true, + unread: true, + ), + ), + settle: false, + ); + await tester.pump(const Duration(milliseconds: 800)); + expect(find.byKey(const Key('appOrderRow_stripe')), findsOneWidget); + } + }); + + testWidgets('done shows a check and hides trailing text', (tester) async { + await tester.pumpApp( + const SizedBox( + width: 300, + child: AppOrderRow( + title: 'Ana', + subtitle: 'Latte', + trailing: '0:10', + urgency: AppUrgency.done, + ), + ), + ); + expect(find.text('0:10'), findsNothing); + expect(find.byType(AppIcon), findsOneWidget); + }); + + testWidgets('stops pulsing when no longer urgent', (tester) async { + Widget row(AppUrgency u) => SizedBox( + width: 300, + child: AppOrderRow(title: 'A', subtitle: 'B', urgency: u), + ); + await tester.pumpApp(row(AppUrgency.urgent), settle: false); + await tester.pump(const Duration(milliseconds: 300)); + await tester.pumpApp(row(AppUrgency.urgent), settle: false); + await tester.pumpApp(row(AppUrgency.normal)); + expect(find.text('A'), findsOneWidget); + }); + }); + + group('AppAvatar / AppPersonRow', () { + testWidgets('avatar shows the uppercase initial or ?', (tester) async { + await tester.pumpApp( + const Column( + children: [ + AppAvatar(name: 'bea'), + AppAvatar(name: '', alert: true), + ], + ), + ); + expect(find.text('B'), findsOneWidget); + expect(find.text('?'), findsOneWidget); + }); + + testWidgets('person row shows caption, meter and trailing', (tester) async { + await tester.pumpApp( + const SizedBox( + width: 300, + child: Column( + children: [ + AppPersonRow( + name: 'Bea', + caption: '3 min', + meter: 0.6, + meterTarget: 0.7, + trailing: '4', + ), + AppPersonRow( + name: 'Cy', + caption: 'slow', + meter: 0.1, + alert: true, + ), + ], + ), + ), + ); + expect(find.text('3 min'), findsOneWidget); + expect(find.text('4'), findsOneWidget); + expect(find.byType(AppProgressBar), findsNWidgets(2)); + }); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart new file mode 100644 index 0000000..0388648 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart @@ -0,0 +1,41 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +/// Widgets are usually built with `const`, which never runs the constructor. +/// Building them from runtime values keeps constructor lines covered and +/// proves non-const usage works. +void main() { + testWidgets('widgets build from runtime values', (tester) async { + final n = DateTime.now().millisecond; + final label = 'v$n'; + await tester.pumpApp( + SizedBox( + width: 400, + child: Column( + children: [ + AppUnicorn(size: 10 + n * 0), + AppVgvLockup(height: 10 + n * 0), + AppCountBadge(count: n), + AppStageDot(stage: AppStage.values[n % 4]), + AppDecisionCard(kindLabel: label, title: label, children: const []), + AppDialogStep(text: label), + AppAvatar(name: label), + AppPersonRow(name: label, caption: label, meter: 0.5), + AppSkeleton(width: 10 + n * 0.0), + AppStatTile(label: label, value: label), + AppKeyValueRow(label: label, value: label), + AppToast(message: label), + AppStepPill(number: n, label: label, state: AppStepState.now), + AppSkeletonBlock(fractions: [0.5 + n * 0]), + AppGoalChip(strong: label, label: label), + ], + ), + ), + settle: false, + ); + await tester.pump(const Duration(milliseconds: 500)); + expect(find.byType(AppToast), findsOneWidget); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_skeleton_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_skeleton_test.dart new file mode 100644 index 0000000..2c3be45 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_skeleton_test.dart @@ -0,0 +1,20 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + testWidgets('AppSkeleton pulses with a fixed width', (tester) async { + await tester.pumpApp(const AppSkeleton(width: 40), settle: false); + await tester.pump(const Duration(milliseconds: 600)); + expect(tester.getSize(find.byType(AppSkeleton)).width, 40); + }); + + testWidgets('AppSkeletonBlock renders one line per fraction', (tester) async { + await tester.pumpApp( + const SizedBox(width: 200, child: AppSkeletonBlock()), + settle: false, + ); + expect(find.byType(AppSkeleton), findsNWidgets(3)); + }); +} diff --git a/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_stat_test.dart b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_stat_test.dart new file mode 100644 index 0000000..865da03 --- /dev/null +++ b/03-human-in-the-loop/shared/app_ui/test/src/widgets/app_stat_test.dart @@ -0,0 +1,102 @@ +import 'package:app_ui/app_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/helpers.dart'; + +void main() { + group('AppStatTile', () { + testWidgets('shows label, value and suffix', (tester) async { + await tester.pumpApp( + const AppStatTile(label: 'Orders', value: '12', suffix: '/ 30'), + ); + expect(find.text('Orders'), findsOneWidget); + expect(find.text('12'), findsOneWidget); + expect(find.text('/ 30'), findsOneWidget); + expect(find.byType(AppProgressBar), findsNothing); + }); + + testWidgets('renders every tone on navy and on light', (tester) async { + for (final onNavy in [true, false]) { + await tester.pumpApp( + Column( + children: [ + for (final tone in AppTone.values) + AppStatTile( + label: tone.name, + value: '1', + tone: tone, + onNavy: onNavy, + mono: false, + ), + ], + ), + ); + expect(find.byType(AppStatTile), findsNWidgets(AppTone.values.length)); + } + }); + + testWidgets('draws progress with target', (tester) async { + await tester.pumpApp( + const SizedBox( + width: 200, + child: AppStatTile( + label: 'Score', + value: '4.5', + progress: 0.5, + target: 0.8, + ), + ), + ); + expect(find.byType(AppProgressBar), findsOneWidget); + }); + }); + + group('AppProgressBar', () { + testWidgets('fills proportionally and clamps', (tester) async { + await tester.pumpApp( + const SizedBox(width: 200, child: AppProgressBar(value: 2, target: -1)), + ); + expect(find.byKey(const Key('appProgressBar_target')), findsOneWidget); + }); + + testWidgets('supports low and navy styles without target', (tester) async { + await tester.pumpApp( + const SizedBox( + width: 200, + child: Column( + children: [ + AppProgressBar(value: 0.2, low: true), + AppProgressBar(value: 0.2, onNavy: true, target: 0.5), + ], + ), + ), + ); + expect(find.byKey(const Key('appProgressBar_target')), findsOneWidget); + }); + }); + + testWidgets('AppGoalChip renders bold and regular parts', (tester) async { + await tester.pumpApp(const AppGoalChip(strong: '30', label: 'orders')); + expect(find.textContaining('orders', findRichText: true), findsOneWidget); + }); + + group('AppKeyValueRow', () { + testWidgets('renders inset and plain rows with tones', (tester) async { + await tester.pumpApp( + const Column( + children: [ + AppKeyValueRow(label: 'Revenue', value: r'$40', mono: true), + AppKeyValueRow( + label: 'Late', + value: '3', + valueTone: AppTone.negative, + inset: false, + ), + ], + ), + ); + expect(find.text('Revenue'), findsOneWidget); + expect(find.text('3'), findsOneWidget); + }); + }); +} diff --git a/README.md b/README.md index ad60598..e975340 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ before it, so compare two folders to see exactly what changed. | [`00-foundations`](00-foundations) | The app with local state and no agent. You fill the form, dress the skull and press a button. | The architecture: a domain, a data and a presentation package per feature. | | [`01-shared-state`](01-shared-state) | A copilot panel appears. You tell it about your friend and it fills the form and dresses the skull. | **Shared state**: `AgentStateBuilder`, `patchSharedState` and `setSharedState`. | | [`02-generative-ui`](02-generative-ui) | You ask for the calaverita and the agent writes it: a card with the skull appears in the chat and the verse shows under the skull on the stage. | **Generative UI**: a frontend tool registered with `CopilotTool` whose builder renders a widget. | -| [`03-custom-server`](03-custom-server) | The same app, talking to a small server of its own instead of the built-in agent. *Optional.* | **Server logic**: validating what the agent changes and shaping its prompt. | +| [`03-human-in-the-loop`](03-human-in-the-loop) | You ask for a calaverita without a tone and the agent asks you how to roast, with buttons in the chat. | **Human in the loop**: a tool registered with `CopilotHumanInTheLoop`, whose run waits for your answer. | ## Quick start @@ -82,8 +82,7 @@ node tool/doctor.mjs ## Run a step The app talks to a *Copilot Runtime*, a small server that sits between the app -and the model. Steps 01 and 02 use the one in [`runtime/`](runtime); step 03 has -its own. +and the model. Steps 01 to 03 use the one in [`runtime/`](runtime). **1. Start the runtime** (steps 01 and 02) in a first terminal: @@ -127,7 +126,7 @@ fvm flutter run -d chrome Each step adds one thing the one before it couldn't do. The **Write my calaverita** button always uses the offline template, so it works in every step. -In steps 02 and 03 the agent can write a verse too. +From step 02 the agent can write a verse too. #### 00 · Foundations (no agent) @@ -163,25 +162,20 @@ shows under the skull on the stage. If the name or the job is missing, the agent asks for it instead. -#### 03 · Custom server (optional) +#### 03 · Human in the loop (the agent asks you) -Start the server in a first terminal. It uses port 4100, so the runtime of steps -01 and 02 can keep running: +Type a request **without a tone**: *"Write a calaverita for Mario, a chef"*. You +can also click that suggestion. -```sh -cd 03-custom-server/server -cp .env.example .env # set ANTHROPIC_API_KEY -npm install -npm start # http://localhost:4100/api/copilotkit -``` - -Then run the app from `03-custom-server` as above and try the same messages as -in step 02. +**You should see:** the form fill in with Mario and chef, then a **Question** +card in the chat: *"How should I roast Mario?"* with **Playful**, **Sarcastic** +and **Dramatic**. The agent waits. Tap one, and it sets the tone, writes the +calaverita and shows it in the chat and on the stage. -**What's different:** this server checks every change the agent makes to the -form and tells the model what it rejected, so it can fix it and try again. It -also puts the current form in the prompt on every run. `npm run smoke` runs its -checks offline, with no key. +Name a tone in your message (*"Write a sarcastic calaverita for Mario, a chef"*) +and it doesn't ask. While the question waits, the copilot isn't "working": the +**Stop** button and the typing dots go away, and the message box points to the +card. ## Point the app at another backend @@ -242,12 +236,15 @@ packages. - Give the skull more parts: a beard, a different pattern, a bandana. Add the SVG and the variant in `SkullPart`, and teach the agent in the prompt. -- Let the agent ask before it guesses, with a human-in-the-loop tool - (`CopilotHumanInTheLoop`): *"make it fancier"* could offer three options. +- Let the agent ask more: *"make it fancier"* could offer three skull styles with + the `askUser` tool of step 03. - Replace the template repository with a call to the agent, so the *Write my calaverita* button uses the model too. - Save the calaverita as an image, or share it. -- Move the step 03 server somewhere public and point `AppConfig` at it. +- Run your own agent server. `03-custom-server/server` is a small custom one that + checks every change the agent makes to the form. Start it (`npm install`, then + `npm start`) and point the app at it with + `node tool/setup.mjs --backend custom --url http://localhost:4100/api/copilotkit --agent calaverita`. ## Troubleshooting diff --git a/runtime/server.ts b/runtime/server.ts index 6f0faad..8c16bc8 100644 --- a/runtime/server.ts +++ b/runtime/server.ts @@ -37,6 +37,10 @@ Keep your replies to one or two short, warm sentences. After you fill the form, If you have a showCalaverita tool and the user asks for the calaverita, call it once the form is complete: write four rhyming lines (two couplets) that fit the name, the job and the tone, and pass them to the tool. +If you have an askUser tool, use it when the answer is one of a few options and the choice is the user's: one question at a time, with two to four options, each with a short id and a label, and nothing else in that turn. The answer comes back as the id of the option. Ask a free-text question (a name, a job) in your reply instead. Do not ask when a sensible choice exists, and never ask again about something the user already answered. + +Tone check: the tone in the form starts as "playful", so treat it as not chosen unless the user named one in this conversation. If you have askUser and the user asks for a calaverita without naming a tone, ask first, once the name and the job are filled in: the question is "How should I roast ?", the options have the ids playful, sarcastic and dramatic and the labels Playful, Sarcastic and Dramatic. When the answer comes back, set the tone in the form with a state update, then write the calaverita. + If you do not have a showCalaverita tool, you cannot write the calaverita yourself. Whenever the form is complete, end your reply by telling the user to press the "Write my calaverita" button to see it. Do not write the verse in the chat.`; const runtime = new CopilotRuntime({ diff --git a/tool/setup.mjs b/tool/setup.mjs index 65ceb6f..c6be697 100644 --- a/tool/setup.mjs +++ b/tool/setup.mjs @@ -11,7 +11,7 @@ // // Options (everything is asked when left out): // --step <00|01|02|03> which step to run -// --backend which backend to use (step 03 always runs its own server) +// --backend which backend to use // --url the runtime URL, for a custom backend // --agent the agent id, when the backend has more than one // --code the workshop password of the shared backend (or set WORKSHOP_CODE) @@ -36,7 +36,7 @@ const STEPS = { "00": { dir: "00-foundations", title: "Foundations, no agent" }, "01": { dir: "01-shared-state", title: "Shared state, the agent fills the form" }, "02": { dir: "02-generative-ui", title: "Generative UI, the agent writes the calaverita" }, - "03": { dir: "03-custom-server", title: "Custom server, optional", server: { dir: "server", port: 4100, agent: "calaverita" } }, + "03": { dir: "03-human-in-the-loop", title: "Human in the loop, the agent asks you" }, }; const LOCAL_RUNTIME = { dir: "runtime", port: 8200, agent: "default" }; const config = JSON.parse(readFileSync(`${root}tool/workshop.config.json`, "utf8")); @@ -245,11 +245,7 @@ async function useExternal(url, defaultAgent) { backend = { url: base, agent }; } -if (stepKey !== "00" && step.server) { - heading("2. Backend"); - say(`Step 03 has a server of its own, in ${step.dir}/${step.server.dir}.`); - await useOwnServer({ ...step.server, dir: `${step.dir}/${step.server.dir}` }); -} else if (stepKey !== "00") { +if (stepKey !== "00") { heading("2. Backend"); const choices = [ ...(config.sharedBackendUrl ? [{ key: "shared", label: "The shared backend, nothing to set up" }] : []), From c692314dc3deb17cd8ac84c0e999b332c33af964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Baudet?= Date: Fri, 23 Oct 2026 21:20:46 -0600 Subject: [PATCH 2/3] fix(runtime): call showCalaverita only when a calaverita is asked for Asked only to fill in the form, the agent also wrote and showed a calaverita. The prompt now says to call the tool only when the user asks for one in the conversation, and that a filled form or a dressed skull is not such a request. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_015qwFeXxEAoB3sM6cdC3K4W --- runtime/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/server.ts b/runtime/server.ts index 8c16bc8..8b95273 100644 --- a/runtime/server.ts +++ b/runtime/server.ts @@ -35,7 +35,7 @@ Language: answer in the language the user writes in, English by default, and nev Keep your replies to one or two short, warm sentences. After you fill the form, say in one sentence what you filled in or changed. -If you have a showCalaverita tool and the user asks for the calaverita, call it once the form is complete: write four rhyming lines (two couplets) that fit the name, the job and the tone, and pass them to the tool. +If you have a showCalaverita tool, call it only when the user asks for a calaverita in this conversation ("write", "show", "make me a calaverita"), never because the form is complete. Filling in the form or dressing the skull is not a request for one. When they ask and the form is complete, call it: write four rhyming lines (two couplets) that fit the name, the job and the tone, and pass them to the tool. If you have an askUser tool, use it when the answer is one of a few options and the choice is the user's: one question at a time, with two to four options, each with a short id and a label, and nothing else in that turn. The answer comes back as the id of the option. Ask a free-text question (a name, a job) in your reply instead. Do not ask when a sensible choice exists, and never ask again about something the user already answered. From 80782064db36bdda0437449d66ed337a1035bb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Baudet?= Date: Wed, 28 Oct 2026 18:49:32 -0600 Subject: [PATCH 3/3] refactor: move the custom server to extras/ Step 03 is now human in the loop, so the custom server is no longer a workshop step. It moves unchanged to extras/custom-server, and the README points to its new place. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015qwFeXxEAoB3sM6cdC3K4W --- README.md | 4 ++-- .../apps/calaverita_app/analysis_options.yaml | 0 .../apps/calaverita_app/lib/app/app.dart | 0 .../apps/calaverita_app/lib/app/app_config.dart | 0 .../apps/calaverita_app/lib/main.dart | 0 .../custom-server}/apps/calaverita_app/pubspec.yaml | 0 .../apps/calaverita_app/test/app_test.dart | 0 .../apps/calaverita_app/web/favicon.png | Bin .../apps/calaverita_app/web/icons/Icon-192.png | Bin .../apps/calaverita_app/web/icons/Icon-512.png | Bin .../calaverita_app/web/icons/Icon-maskable-192.png | Bin .../calaverita_app/web/icons/Icon-maskable-512.png | Bin .../apps/calaverita_app/web/index.html | 0 .../apps/calaverita_app/web/manifest.json | 0 .../assistant_presentation/analysis_options.yaml | 0 .../lib/assistant_presentation.dart | 0 .../lib/chat/chat_module.dart | 0 .../lib/chat/views/activity_line.dart | 0 .../lib/chat/views/chat_panel.dart | 0 .../assistant/assistant_presentation/pubspec.yaml | 0 .../test/chat/chat_module_test.dart | 0 .../calaverita_data/analysis_options.yaml | 0 .../calaverita_data/lib/calaverita_data.dart | 0 .../template_calaveritas_repository.dart | 0 .../lib/templates/calaverita_templates.dart | 0 .../calaverita/calaverita_data/pubspec.yaml | 0 .../template_calaveritas_repository_test.dart | 0 .../calaverita_domain/analysis_options.yaml | 0 .../calaverita_domain/lib/calaverita_domain.dart | 0 .../calaverita_domain/lib/models/calaverita.dart | 0 .../lib/models/calaverita_draft.dart | 0 .../calaverita_domain/lib/models/skull_part.dart | 0 .../calaverita_domain/lib/models/skull_style.dart | 0 .../calaverita_domain/lib/models/tone.dart | 0 .../lib/repositories/i_calaveritas_repository.dart | 0 .../calaverita/calaverita_domain/pubspec.yaml | 0 .../test/models/calaverita_draft_test.dart | 0 .../test/models/calaverita_test.dart | 0 .../test/models/skull_style_test.dart | 0 .../calaverita_presentation/analysis_options.yaml | 0 .../assets/skull/base/round.svg | 0 .../assets/skull/eyes/marigold.svg | 0 .../assets/skull/flowers/crown.svg | 0 .../assets/skull/flowers/side.svg | 0 .../assets/skull/flowers/trio.svg | 0 .../assets/skull/glasses/cateye.svg | 0 .../assets/skull/glasses/heart.svg | 0 .../assets/skull/glasses/round.svg | 0 .../assets/skull/glasses/square.svg | 0 .../assets/skull/hat/crown.svg | 0 .../assets/skull/hat/party.svg | 0 .../assets/skull/hat/sombrero.svg | 0 .../assets/skull/hat/tophat.svg | 0 .../assets/skull/mouth/stitched.svg | 0 .../assets/skull/mustache/handlebar.svg | 0 .../assets/skull/mustache/pencil.svg | 0 .../assets/skull/mustache/walrus.svg | 0 .../assets/skull/nose/heart.svg | 0 .../assets/skull/pattern/swirls.svg | 0 .../lib/calaverita/bloc/calaverita_cubit.dart | 0 .../lib/calaverita/bloc/calaverita_state.dart | 0 .../lib/calaverita/calaverita_module.dart | 0 .../lib/calaverita/shared_draft/draft_edits.dart | 0 .../lib/calaverita/shared_draft/shared_draft.dart | 0 .../show_calaverita/show_calaverita_args.dart | 0 .../show_calaverita/show_calaverita_card.dart | 0 .../show_calaverita/show_calaverita_handler.dart | 0 .../show_calaverita/show_calaverita_tool.dart | 0 .../lib/calaverita/skull/skull_art.dart | 0 .../lib/calaverita/views/calaverita_card.dart | 0 .../lib/calaverita/views/calaverita_page.dart | 0 .../lib/calaverita/views/details_panel.dart | 0 .../lib/calaverita/views/skull_controls.dart | 0 .../lib/calaverita/views/skull_view.dart | 0 .../lib/calaverita/views/stage.dart | 0 .../lib/calaverita/views/synced_text_field.dart | 0 .../lib/calaverita_presentation.dart | 0 .../calaverita/calaverita_presentation/pubspec.yaml | 0 .../test/calaverita/bloc/calaverita_cubit_test.dart | 0 .../calaverita/shared_draft/shared_draft_test.dart | 0 .../show_calaverita_handler_test.dart | 0 .../show_calaverita/show_calaverita_tool_test.dart | 0 .../test/calaverita/skull/skull_art_test.dart | 0 .../test/calaverita/views/calaverita_card_test.dart | 0 .../test/calaverita/views/calaverita_page_test.dart | 0 .../test/calaverita/views/skull_view_test.dart | 0 .../test/helpers/test_skull_art.dart | 0 .../custom-server}/pubspec.lock | 0 .../custom-server}/pubspec.yaml | 0 .../custom-server}/server/.env.example | 0 .../custom-server}/server/.gitignore | 0 .../custom-server}/server/package-lock.json | 0 .../custom-server}/server/package.json | 0 .../custom-server}/server/src/agent.ts | 0 .../custom-server}/server/src/catalog.ts | 0 .../custom-server}/server/src/env.ts | 0 .../custom-server}/server/src/index.ts | 0 .../custom-server}/server/src/prompt.ts | 0 .../custom-server}/server/src/smoke.ts | 0 .../custom-server}/server/src/state.ts | 0 .../custom-server}/server/src/tools.ts | 0 .../custom-server}/server/tsconfig.json | 0 .../custom-server}/shared/app_ui/.gitignore | 0 .../custom-server}/shared/app_ui/LICENSE | 0 .../custom-server}/shared/app_ui/README.md | 0 .../shared/app_ui/analysis_options.yaml | 0 .../app_ui/assets/fonts/JetBrainsMono-Medium.ttf | Bin .../app_ui/assets/fonts/JetBrainsMono-Regular.ttf | Bin .../app_ui/assets/fonts/OFL-JetBrainsMono.txt | 0 .../shared/app_ui/assets/fonts/OFL.txt | 0 .../shared/app_ui/assets/fonts/Poppins-Medium.ttf | Bin .../shared/app_ui/assets/fonts/Poppins-Regular.ttf | Bin .../shared/app_ui/assets/fonts/Poppins-SemiBold.ttf | Bin .../shared/app_ui/assets/images/copilotkit-logo.png | Bin .../shared/app_ui/assets/images/unicorn-dark.svg | 0 .../shared/app_ui/assets/images/unicorn.svg | 0 .../shared/app_ui/assets/images/vgv-lockup.svg | 0 .../custom-server}/shared/app_ui/lib/app_ui.dart | 0 .../shared/app_ui/lib/src/theme/app_palette.dart | 0 .../shared/app_ui/lib/src/theme/app_theme.dart | 0 .../shared/app_ui/lib/src/theme/theme.dart | 0 .../shared/app_ui/lib/src/tokens/app_colors.dart | 0 .../shared/app_ui/lib/src/tokens/app_elevation.dart | 0 .../shared/app_ui/lib/src/tokens/app_motion.dart | 0 .../shared/app_ui/lib/src/tokens/app_radii.dart | 0 .../shared/app_ui/lib/src/tokens/app_sizes.dart | 0 .../shared/app_ui/lib/src/tokens/app_spacing.dart | 0 .../app_ui/lib/src/tokens/app_typography.dart | 0 .../shared/app_ui/lib/src/tokens/tokens.dart | 0 .../shared/app_ui/lib/src/widgets/app_brand.dart | 0 .../shared/app_ui/lib/src/widgets/app_button.dart | 0 .../shared/app_ui/lib/src/widgets/app_card.dart | 0 .../shared/app_ui/lib/src/widgets/app_chat.dart | 0 .../shared/app_ui/lib/src/widgets/app_chip.dart | 0 .../shared/app_ui/lib/src/widgets/app_decision.dart | 0 .../shared/app_ui/lib/src/widgets/app_dialog.dart | 0 .../shared/app_ui/lib/src/widgets/app_icons.dart | 0 .../app_ui/lib/src/widgets/app_order_row.dart | 0 .../shared/app_ui/lib/src/widgets/app_person.dart | 0 .../app_ui/lib/src/widgets/app_pressable.dart | 0 .../shared/app_ui/lib/src/widgets/app_progress.dart | 0 .../app_ui/lib/src/widgets/app_segmented.dart | 0 .../shared/app_ui/lib/src/widgets/app_skeleton.dart | 0 .../shared/app_ui/lib/src/widgets/app_stat.dart | 0 .../shared/app_ui/lib/src/widgets/app_toast.dart | 0 .../shared/app_ui/lib/src/widgets/app_tone.dart | 0 .../shared/app_ui/lib/src/widgets/widgets.dart | 0 .../custom-server}/shared/app_ui/pubspec.yaml | 0 .../shared/app_ui/test/helpers/helpers.dart | 0 .../shared/app_ui/test/helpers/pump_app.dart | 0 .../app_ui/test/src/theme/app_theme_test.dart | 0 .../shared/app_ui/test/src/tokens/tokens_test.dart | 0 .../app_ui/test/src/widgets/app_button_test.dart | 0 .../app_ui/test/src/widgets/app_card_test.dart | 0 .../app_ui/test/src/widgets/app_chat_test.dart | 0 .../app_ui/test/src/widgets/app_chip_test.dart | 0 .../app_ui/test/src/widgets/app_decision_test.dart | 0 .../app_ui/test/src/widgets/app_dialog_test.dart | 0 .../app_ui/test/src/widgets/app_misc_test.dart | 0 .../app_ui/test/src/widgets/app_order_row_test.dart | 0 .../src/widgets/app_runtime_constructors_test.dart | 0 .../app_ui/test/src/widgets/app_skeleton_test.dart | 0 .../app_ui/test/src/widgets/app_stat_test.dart | 0 163 files changed, 2 insertions(+), 2 deletions(-) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/analysis_options.yaml (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/lib/app/app.dart (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/lib/app/app_config.dart (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/lib/main.dart (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/pubspec.yaml (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/test/app_test.dart (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/web/favicon.png (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/web/icons/Icon-192.png (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/web/icons/Icon-512.png (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/web/icons/Icon-maskable-192.png (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/web/icons/Icon-maskable-512.png (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/web/index.html (100%) rename {03-custom-server => extras/custom-server}/apps/calaverita_app/web/manifest.json (100%) rename {03-custom-server => extras/custom-server}/features/assistant/assistant_presentation/analysis_options.yaml (100%) rename {03-custom-server => extras/custom-server}/features/assistant/assistant_presentation/lib/assistant_presentation.dart (100%) rename {03-custom-server => extras/custom-server}/features/assistant/assistant_presentation/lib/chat/chat_module.dart (100%) rename {03-custom-server => extras/custom-server}/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart (100%) rename {03-custom-server => extras/custom-server}/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart (100%) rename {03-custom-server => extras/custom-server}/features/assistant/assistant_presentation/pubspec.yaml (100%) rename {03-custom-server => extras/custom-server}/features/assistant/assistant_presentation/test/chat/chat_module_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_data/analysis_options.yaml (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_data/lib/calaverita_data.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_data/pubspec.yaml (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/analysis_options.yaml (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/lib/calaverita_domain.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/lib/models/calaverita.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/lib/models/skull_part.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/lib/models/skull_style.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/lib/models/tone.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/pubspec.yaml (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/test/models/calaverita_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_domain/test/models/skull_style_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/analysis_options.yaml (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/base/round.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/pubspec.yaml (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart (100%) rename {03-custom-server => extras/custom-server}/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart (100%) rename {03-custom-server => extras/custom-server}/pubspec.lock (100%) rename {03-custom-server => extras/custom-server}/pubspec.yaml (100%) rename {03-custom-server => extras/custom-server}/server/.env.example (100%) rename {03-custom-server => extras/custom-server}/server/.gitignore (100%) rename {03-custom-server => extras/custom-server}/server/package-lock.json (100%) rename {03-custom-server => extras/custom-server}/server/package.json (100%) rename {03-custom-server => extras/custom-server}/server/src/agent.ts (100%) rename {03-custom-server => extras/custom-server}/server/src/catalog.ts (100%) rename {03-custom-server => extras/custom-server}/server/src/env.ts (100%) rename {03-custom-server => extras/custom-server}/server/src/index.ts (100%) rename {03-custom-server => extras/custom-server}/server/src/prompt.ts (100%) rename {03-custom-server => extras/custom-server}/server/src/smoke.ts (100%) rename {03-custom-server => extras/custom-server}/server/src/state.ts (100%) rename {03-custom-server => extras/custom-server}/server/src/tools.ts (100%) rename {03-custom-server => extras/custom-server}/server/tsconfig.json (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/.gitignore (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/LICENSE (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/README.md (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/analysis_options.yaml (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/fonts/JetBrainsMono-Medium.ttf (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/fonts/JetBrainsMono-Regular.ttf (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/fonts/OFL-JetBrainsMono.txt (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/fonts/OFL.txt (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/fonts/Poppins-Medium.ttf (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/fonts/Poppins-Regular.ttf (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/fonts/Poppins-SemiBold.ttf (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/images/copilotkit-logo.png (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/images/unicorn-dark.svg (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/images/unicorn.svg (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/assets/images/vgv-lockup.svg (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/app_ui.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/theme/app_palette.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/theme/app_theme.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/theme/theme.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/tokens/app_colors.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/tokens/app_elevation.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/tokens/app_motion.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/tokens/app_radii.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/tokens/app_sizes.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/tokens/app_spacing.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/tokens/app_typography.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/tokens/tokens.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_brand.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_button.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_card.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_chat.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_chip.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_decision.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_dialog.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_icons.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_order_row.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_person.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_pressable.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_progress.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_segmented.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_skeleton.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_stat.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_toast.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/app_tone.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/lib/src/widgets/widgets.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/pubspec.yaml (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/helpers/helpers.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/helpers/pump_app.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/theme/app_theme_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/tokens/tokens_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_button_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_card_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_chat_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_chip_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_decision_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_dialog_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_misc_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_order_row_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_skeleton_test.dart (100%) rename {03-custom-server => extras/custom-server}/shared/app_ui/test/src/widgets/app_stat_test.dart (100%) diff --git a/README.md b/README.md index e975340..21b1d43 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ To use another model, set `COPILOTKIT_MODEL` in `runtime/.env`. The default is **2. Run the app** in a second terminal. `00-foundations` needs no runtime. ```sh -cd 01-shared-state # or 00-foundations, 02-generative-ui +cd 01-shared-state # or 00-foundations, 02-generative-ui, 03-human-in-the-loop fvm flutter pub get cd apps/calaverita_app fvm flutter run -d chrome @@ -241,7 +241,7 @@ packages. - Replace the template repository with a call to the agent, so the *Write my calaverita* button uses the model too. - Save the calaverita as an image, or share it. -- Run your own agent server. `03-custom-server/server` is a small custom one that +- Run your own agent server. `extras/custom-server/server` is a small custom one that checks every change the agent makes to the form. Start it (`npm install`, then `npm start`) and point the app at it with `node tool/setup.mjs --backend custom --url http://localhost:4100/api/copilotkit --agent calaverita`. diff --git a/03-custom-server/apps/calaverita_app/analysis_options.yaml b/extras/custom-server/apps/calaverita_app/analysis_options.yaml similarity index 100% rename from 03-custom-server/apps/calaverita_app/analysis_options.yaml rename to extras/custom-server/apps/calaverita_app/analysis_options.yaml diff --git a/03-custom-server/apps/calaverita_app/lib/app/app.dart b/extras/custom-server/apps/calaverita_app/lib/app/app.dart similarity index 100% rename from 03-custom-server/apps/calaverita_app/lib/app/app.dart rename to extras/custom-server/apps/calaverita_app/lib/app/app.dart diff --git a/03-custom-server/apps/calaverita_app/lib/app/app_config.dart b/extras/custom-server/apps/calaverita_app/lib/app/app_config.dart similarity index 100% rename from 03-custom-server/apps/calaverita_app/lib/app/app_config.dart rename to extras/custom-server/apps/calaverita_app/lib/app/app_config.dart diff --git a/03-custom-server/apps/calaverita_app/lib/main.dart b/extras/custom-server/apps/calaverita_app/lib/main.dart similarity index 100% rename from 03-custom-server/apps/calaverita_app/lib/main.dart rename to extras/custom-server/apps/calaverita_app/lib/main.dart diff --git a/03-custom-server/apps/calaverita_app/pubspec.yaml b/extras/custom-server/apps/calaverita_app/pubspec.yaml similarity index 100% rename from 03-custom-server/apps/calaverita_app/pubspec.yaml rename to extras/custom-server/apps/calaverita_app/pubspec.yaml diff --git a/03-custom-server/apps/calaverita_app/test/app_test.dart b/extras/custom-server/apps/calaverita_app/test/app_test.dart similarity index 100% rename from 03-custom-server/apps/calaverita_app/test/app_test.dart rename to extras/custom-server/apps/calaverita_app/test/app_test.dart diff --git a/03-custom-server/apps/calaverita_app/web/favicon.png b/extras/custom-server/apps/calaverita_app/web/favicon.png similarity index 100% rename from 03-custom-server/apps/calaverita_app/web/favicon.png rename to extras/custom-server/apps/calaverita_app/web/favicon.png diff --git a/03-custom-server/apps/calaverita_app/web/icons/Icon-192.png b/extras/custom-server/apps/calaverita_app/web/icons/Icon-192.png similarity index 100% rename from 03-custom-server/apps/calaverita_app/web/icons/Icon-192.png rename to extras/custom-server/apps/calaverita_app/web/icons/Icon-192.png diff --git a/03-custom-server/apps/calaverita_app/web/icons/Icon-512.png b/extras/custom-server/apps/calaverita_app/web/icons/Icon-512.png similarity index 100% rename from 03-custom-server/apps/calaverita_app/web/icons/Icon-512.png rename to extras/custom-server/apps/calaverita_app/web/icons/Icon-512.png diff --git a/03-custom-server/apps/calaverita_app/web/icons/Icon-maskable-192.png b/extras/custom-server/apps/calaverita_app/web/icons/Icon-maskable-192.png similarity index 100% rename from 03-custom-server/apps/calaverita_app/web/icons/Icon-maskable-192.png rename to extras/custom-server/apps/calaverita_app/web/icons/Icon-maskable-192.png diff --git a/03-custom-server/apps/calaverita_app/web/icons/Icon-maskable-512.png b/extras/custom-server/apps/calaverita_app/web/icons/Icon-maskable-512.png similarity index 100% rename from 03-custom-server/apps/calaverita_app/web/icons/Icon-maskable-512.png rename to extras/custom-server/apps/calaverita_app/web/icons/Icon-maskable-512.png diff --git a/03-custom-server/apps/calaverita_app/web/index.html b/extras/custom-server/apps/calaverita_app/web/index.html similarity index 100% rename from 03-custom-server/apps/calaverita_app/web/index.html rename to extras/custom-server/apps/calaverita_app/web/index.html diff --git a/03-custom-server/apps/calaverita_app/web/manifest.json b/extras/custom-server/apps/calaverita_app/web/manifest.json similarity index 100% rename from 03-custom-server/apps/calaverita_app/web/manifest.json rename to extras/custom-server/apps/calaverita_app/web/manifest.json diff --git a/03-custom-server/features/assistant/assistant_presentation/analysis_options.yaml b/extras/custom-server/features/assistant/assistant_presentation/analysis_options.yaml similarity index 100% rename from 03-custom-server/features/assistant/assistant_presentation/analysis_options.yaml rename to extras/custom-server/features/assistant/assistant_presentation/analysis_options.yaml diff --git a/03-custom-server/features/assistant/assistant_presentation/lib/assistant_presentation.dart b/extras/custom-server/features/assistant/assistant_presentation/lib/assistant_presentation.dart similarity index 100% rename from 03-custom-server/features/assistant/assistant_presentation/lib/assistant_presentation.dart rename to extras/custom-server/features/assistant/assistant_presentation/lib/assistant_presentation.dart diff --git a/03-custom-server/features/assistant/assistant_presentation/lib/chat/chat_module.dart b/extras/custom-server/features/assistant/assistant_presentation/lib/chat/chat_module.dart similarity index 100% rename from 03-custom-server/features/assistant/assistant_presentation/lib/chat/chat_module.dart rename to extras/custom-server/features/assistant/assistant_presentation/lib/chat/chat_module.dart diff --git a/03-custom-server/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart b/extras/custom-server/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart similarity index 100% rename from 03-custom-server/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart rename to extras/custom-server/features/assistant/assistant_presentation/lib/chat/views/activity_line.dart diff --git a/03-custom-server/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart b/extras/custom-server/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart similarity index 100% rename from 03-custom-server/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart rename to extras/custom-server/features/assistant/assistant_presentation/lib/chat/views/chat_panel.dart diff --git a/03-custom-server/features/assistant/assistant_presentation/pubspec.yaml b/extras/custom-server/features/assistant/assistant_presentation/pubspec.yaml similarity index 100% rename from 03-custom-server/features/assistant/assistant_presentation/pubspec.yaml rename to extras/custom-server/features/assistant/assistant_presentation/pubspec.yaml diff --git a/03-custom-server/features/assistant/assistant_presentation/test/chat/chat_module_test.dart b/extras/custom-server/features/assistant/assistant_presentation/test/chat/chat_module_test.dart similarity index 100% rename from 03-custom-server/features/assistant/assistant_presentation/test/chat/chat_module_test.dart rename to extras/custom-server/features/assistant/assistant_presentation/test/chat/chat_module_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_data/analysis_options.yaml b/extras/custom-server/features/calaverita/calaverita_data/analysis_options.yaml similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_data/analysis_options.yaml rename to extras/custom-server/features/calaverita/calaverita_data/analysis_options.yaml diff --git a/03-custom-server/features/calaverita/calaverita_data/lib/calaverita_data.dart b/extras/custom-server/features/calaverita/calaverita_data/lib/calaverita_data.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_data/lib/calaverita_data.dart rename to extras/custom-server/features/calaverita/calaverita_data/lib/calaverita_data.dart diff --git a/03-custom-server/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart b/extras/custom-server/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart rename to extras/custom-server/features/calaverita/calaverita_data/lib/repositories/template_calaveritas_repository.dart diff --git a/03-custom-server/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart b/extras/custom-server/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart rename to extras/custom-server/features/calaverita/calaverita_data/lib/templates/calaverita_templates.dart diff --git a/03-custom-server/features/calaverita/calaverita_data/pubspec.yaml b/extras/custom-server/features/calaverita/calaverita_data/pubspec.yaml similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_data/pubspec.yaml rename to extras/custom-server/features/calaverita/calaverita_data/pubspec.yaml diff --git a/03-custom-server/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart b/extras/custom-server/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart rename to extras/custom-server/features/calaverita/calaverita_data/test/repositories/template_calaveritas_repository_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/analysis_options.yaml b/extras/custom-server/features/calaverita/calaverita_domain/analysis_options.yaml similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/analysis_options.yaml rename to extras/custom-server/features/calaverita/calaverita_domain/analysis_options.yaml diff --git a/03-custom-server/features/calaverita/calaverita_domain/lib/calaverita_domain.dart b/extras/custom-server/features/calaverita/calaverita_domain/lib/calaverita_domain.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/lib/calaverita_domain.dart rename to extras/custom-server/features/calaverita/calaverita_domain/lib/calaverita_domain.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/lib/models/calaverita.dart b/extras/custom-server/features/calaverita/calaverita_domain/lib/models/calaverita.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/lib/models/calaverita.dart rename to extras/custom-server/features/calaverita/calaverita_domain/lib/models/calaverita.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart b/extras/custom-server/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart rename to extras/custom-server/features/calaverita/calaverita_domain/lib/models/calaverita_draft.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/lib/models/skull_part.dart b/extras/custom-server/features/calaverita/calaverita_domain/lib/models/skull_part.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/lib/models/skull_part.dart rename to extras/custom-server/features/calaverita/calaverita_domain/lib/models/skull_part.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/lib/models/skull_style.dart b/extras/custom-server/features/calaverita/calaverita_domain/lib/models/skull_style.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/lib/models/skull_style.dart rename to extras/custom-server/features/calaverita/calaverita_domain/lib/models/skull_style.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/lib/models/tone.dart b/extras/custom-server/features/calaverita/calaverita_domain/lib/models/tone.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/lib/models/tone.dart rename to extras/custom-server/features/calaverita/calaverita_domain/lib/models/tone.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart b/extras/custom-server/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart rename to extras/custom-server/features/calaverita/calaverita_domain/lib/repositories/i_calaveritas_repository.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/pubspec.yaml b/extras/custom-server/features/calaverita/calaverita_domain/pubspec.yaml similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/pubspec.yaml rename to extras/custom-server/features/calaverita/calaverita_domain/pubspec.yaml diff --git a/03-custom-server/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart b/extras/custom-server/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart rename to extras/custom-server/features/calaverita/calaverita_domain/test/models/calaverita_draft_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/test/models/calaverita_test.dart b/extras/custom-server/features/calaverita/calaverita_domain/test/models/calaverita_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/test/models/calaverita_test.dart rename to extras/custom-server/features/calaverita/calaverita_domain/test/models/calaverita_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_domain/test/models/skull_style_test.dart b/extras/custom-server/features/calaverita/calaverita_domain/test/models/skull_style_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_domain/test/models/skull_style_test.dart rename to extras/custom-server/features/calaverita/calaverita_domain/test/models/skull_style_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/analysis_options.yaml b/extras/custom-server/features/calaverita/calaverita_presentation/analysis_options.yaml similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/analysis_options.yaml rename to extras/custom-server/features/calaverita/calaverita_presentation/analysis_options.yaml diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/base/round.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/base/round.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/base/round.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/base/round.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/eyes/marigold.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/crown.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/side.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/flowers/trio.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/cateye.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/heart.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/round.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/glasses/square.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/crown.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/party.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/sombrero.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/hat/tophat.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/mouth/stitched.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/handlebar.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/pencil.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/mustache/walrus.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/nose/heart.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg b/extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg rename to extras/custom-server/features/calaverita/calaverita_presentation/assets/skull/pattern/swirls.svg diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_cubit.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/bloc/calaverita_state.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/calaverita_module.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/draft_edits.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/shared_draft/shared_draft.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_args.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_card.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_handler.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/show_calaverita/show_calaverita_tool.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/skull/skull_art.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_card.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/calaverita_page.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/details_panel.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_controls.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/skull_view.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/stage.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita/views/synced_text_field.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart b/extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/lib/calaverita_presentation.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/pubspec.yaml b/extras/custom-server/features/calaverita/calaverita_presentation/pubspec.yaml similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/pubspec.yaml rename to extras/custom-server/features/calaverita/calaverita_presentation/pubspec.yaml diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/bloc/calaverita_cubit_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/shared_draft/shared_draft_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_handler_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/show_calaverita/show_calaverita_tool_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/skull/skull_art_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_card_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/calaverita_page_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/calaverita/views/skull_view_test.dart diff --git a/03-custom-server/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart b/extras/custom-server/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart similarity index 100% rename from 03-custom-server/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart rename to extras/custom-server/features/calaverita/calaverita_presentation/test/helpers/test_skull_art.dart diff --git a/03-custom-server/pubspec.lock b/extras/custom-server/pubspec.lock similarity index 100% rename from 03-custom-server/pubspec.lock rename to extras/custom-server/pubspec.lock diff --git a/03-custom-server/pubspec.yaml b/extras/custom-server/pubspec.yaml similarity index 100% rename from 03-custom-server/pubspec.yaml rename to extras/custom-server/pubspec.yaml diff --git a/03-custom-server/server/.env.example b/extras/custom-server/server/.env.example similarity index 100% rename from 03-custom-server/server/.env.example rename to extras/custom-server/server/.env.example diff --git a/03-custom-server/server/.gitignore b/extras/custom-server/server/.gitignore similarity index 100% rename from 03-custom-server/server/.gitignore rename to extras/custom-server/server/.gitignore diff --git a/03-custom-server/server/package-lock.json b/extras/custom-server/server/package-lock.json similarity index 100% rename from 03-custom-server/server/package-lock.json rename to extras/custom-server/server/package-lock.json diff --git a/03-custom-server/server/package.json b/extras/custom-server/server/package.json similarity index 100% rename from 03-custom-server/server/package.json rename to extras/custom-server/server/package.json diff --git a/03-custom-server/server/src/agent.ts b/extras/custom-server/server/src/agent.ts similarity index 100% rename from 03-custom-server/server/src/agent.ts rename to extras/custom-server/server/src/agent.ts diff --git a/03-custom-server/server/src/catalog.ts b/extras/custom-server/server/src/catalog.ts similarity index 100% rename from 03-custom-server/server/src/catalog.ts rename to extras/custom-server/server/src/catalog.ts diff --git a/03-custom-server/server/src/env.ts b/extras/custom-server/server/src/env.ts similarity index 100% rename from 03-custom-server/server/src/env.ts rename to extras/custom-server/server/src/env.ts diff --git a/03-custom-server/server/src/index.ts b/extras/custom-server/server/src/index.ts similarity index 100% rename from 03-custom-server/server/src/index.ts rename to extras/custom-server/server/src/index.ts diff --git a/03-custom-server/server/src/prompt.ts b/extras/custom-server/server/src/prompt.ts similarity index 100% rename from 03-custom-server/server/src/prompt.ts rename to extras/custom-server/server/src/prompt.ts diff --git a/03-custom-server/server/src/smoke.ts b/extras/custom-server/server/src/smoke.ts similarity index 100% rename from 03-custom-server/server/src/smoke.ts rename to extras/custom-server/server/src/smoke.ts diff --git a/03-custom-server/server/src/state.ts b/extras/custom-server/server/src/state.ts similarity index 100% rename from 03-custom-server/server/src/state.ts rename to extras/custom-server/server/src/state.ts diff --git a/03-custom-server/server/src/tools.ts b/extras/custom-server/server/src/tools.ts similarity index 100% rename from 03-custom-server/server/src/tools.ts rename to extras/custom-server/server/src/tools.ts diff --git a/03-custom-server/server/tsconfig.json b/extras/custom-server/server/tsconfig.json similarity index 100% rename from 03-custom-server/server/tsconfig.json rename to extras/custom-server/server/tsconfig.json diff --git a/03-custom-server/shared/app_ui/.gitignore b/extras/custom-server/shared/app_ui/.gitignore similarity index 100% rename from 03-custom-server/shared/app_ui/.gitignore rename to extras/custom-server/shared/app_ui/.gitignore diff --git a/03-custom-server/shared/app_ui/LICENSE b/extras/custom-server/shared/app_ui/LICENSE similarity index 100% rename from 03-custom-server/shared/app_ui/LICENSE rename to extras/custom-server/shared/app_ui/LICENSE diff --git a/03-custom-server/shared/app_ui/README.md b/extras/custom-server/shared/app_ui/README.md similarity index 100% rename from 03-custom-server/shared/app_ui/README.md rename to extras/custom-server/shared/app_ui/README.md diff --git a/03-custom-server/shared/app_ui/analysis_options.yaml b/extras/custom-server/shared/app_ui/analysis_options.yaml similarity index 100% rename from 03-custom-server/shared/app_ui/analysis_options.yaml rename to extras/custom-server/shared/app_ui/analysis_options.yaml diff --git a/03-custom-server/shared/app_ui/assets/fonts/JetBrainsMono-Medium.ttf b/extras/custom-server/shared/app_ui/assets/fonts/JetBrainsMono-Medium.ttf similarity index 100% rename from 03-custom-server/shared/app_ui/assets/fonts/JetBrainsMono-Medium.ttf rename to extras/custom-server/shared/app_ui/assets/fonts/JetBrainsMono-Medium.ttf diff --git a/03-custom-server/shared/app_ui/assets/fonts/JetBrainsMono-Regular.ttf b/extras/custom-server/shared/app_ui/assets/fonts/JetBrainsMono-Regular.ttf similarity index 100% rename from 03-custom-server/shared/app_ui/assets/fonts/JetBrainsMono-Regular.ttf rename to extras/custom-server/shared/app_ui/assets/fonts/JetBrainsMono-Regular.ttf diff --git a/03-custom-server/shared/app_ui/assets/fonts/OFL-JetBrainsMono.txt b/extras/custom-server/shared/app_ui/assets/fonts/OFL-JetBrainsMono.txt similarity index 100% rename from 03-custom-server/shared/app_ui/assets/fonts/OFL-JetBrainsMono.txt rename to extras/custom-server/shared/app_ui/assets/fonts/OFL-JetBrainsMono.txt diff --git a/03-custom-server/shared/app_ui/assets/fonts/OFL.txt b/extras/custom-server/shared/app_ui/assets/fonts/OFL.txt similarity index 100% rename from 03-custom-server/shared/app_ui/assets/fonts/OFL.txt rename to extras/custom-server/shared/app_ui/assets/fonts/OFL.txt diff --git a/03-custom-server/shared/app_ui/assets/fonts/Poppins-Medium.ttf b/extras/custom-server/shared/app_ui/assets/fonts/Poppins-Medium.ttf similarity index 100% rename from 03-custom-server/shared/app_ui/assets/fonts/Poppins-Medium.ttf rename to extras/custom-server/shared/app_ui/assets/fonts/Poppins-Medium.ttf diff --git a/03-custom-server/shared/app_ui/assets/fonts/Poppins-Regular.ttf b/extras/custom-server/shared/app_ui/assets/fonts/Poppins-Regular.ttf similarity index 100% rename from 03-custom-server/shared/app_ui/assets/fonts/Poppins-Regular.ttf rename to extras/custom-server/shared/app_ui/assets/fonts/Poppins-Regular.ttf diff --git a/03-custom-server/shared/app_ui/assets/fonts/Poppins-SemiBold.ttf b/extras/custom-server/shared/app_ui/assets/fonts/Poppins-SemiBold.ttf similarity index 100% rename from 03-custom-server/shared/app_ui/assets/fonts/Poppins-SemiBold.ttf rename to extras/custom-server/shared/app_ui/assets/fonts/Poppins-SemiBold.ttf diff --git a/03-custom-server/shared/app_ui/assets/images/copilotkit-logo.png b/extras/custom-server/shared/app_ui/assets/images/copilotkit-logo.png similarity index 100% rename from 03-custom-server/shared/app_ui/assets/images/copilotkit-logo.png rename to extras/custom-server/shared/app_ui/assets/images/copilotkit-logo.png diff --git a/03-custom-server/shared/app_ui/assets/images/unicorn-dark.svg b/extras/custom-server/shared/app_ui/assets/images/unicorn-dark.svg similarity index 100% rename from 03-custom-server/shared/app_ui/assets/images/unicorn-dark.svg rename to extras/custom-server/shared/app_ui/assets/images/unicorn-dark.svg diff --git a/03-custom-server/shared/app_ui/assets/images/unicorn.svg b/extras/custom-server/shared/app_ui/assets/images/unicorn.svg similarity index 100% rename from 03-custom-server/shared/app_ui/assets/images/unicorn.svg rename to extras/custom-server/shared/app_ui/assets/images/unicorn.svg diff --git a/03-custom-server/shared/app_ui/assets/images/vgv-lockup.svg b/extras/custom-server/shared/app_ui/assets/images/vgv-lockup.svg similarity index 100% rename from 03-custom-server/shared/app_ui/assets/images/vgv-lockup.svg rename to extras/custom-server/shared/app_ui/assets/images/vgv-lockup.svg diff --git a/03-custom-server/shared/app_ui/lib/app_ui.dart b/extras/custom-server/shared/app_ui/lib/app_ui.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/app_ui.dart rename to extras/custom-server/shared/app_ui/lib/app_ui.dart diff --git a/03-custom-server/shared/app_ui/lib/src/theme/app_palette.dart b/extras/custom-server/shared/app_ui/lib/src/theme/app_palette.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/theme/app_palette.dart rename to extras/custom-server/shared/app_ui/lib/src/theme/app_palette.dart diff --git a/03-custom-server/shared/app_ui/lib/src/theme/app_theme.dart b/extras/custom-server/shared/app_ui/lib/src/theme/app_theme.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/theme/app_theme.dart rename to extras/custom-server/shared/app_ui/lib/src/theme/app_theme.dart diff --git a/03-custom-server/shared/app_ui/lib/src/theme/theme.dart b/extras/custom-server/shared/app_ui/lib/src/theme/theme.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/theme/theme.dart rename to extras/custom-server/shared/app_ui/lib/src/theme/theme.dart diff --git a/03-custom-server/shared/app_ui/lib/src/tokens/app_colors.dart b/extras/custom-server/shared/app_ui/lib/src/tokens/app_colors.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/tokens/app_colors.dart rename to extras/custom-server/shared/app_ui/lib/src/tokens/app_colors.dart diff --git a/03-custom-server/shared/app_ui/lib/src/tokens/app_elevation.dart b/extras/custom-server/shared/app_ui/lib/src/tokens/app_elevation.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/tokens/app_elevation.dart rename to extras/custom-server/shared/app_ui/lib/src/tokens/app_elevation.dart diff --git a/03-custom-server/shared/app_ui/lib/src/tokens/app_motion.dart b/extras/custom-server/shared/app_ui/lib/src/tokens/app_motion.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/tokens/app_motion.dart rename to extras/custom-server/shared/app_ui/lib/src/tokens/app_motion.dart diff --git a/03-custom-server/shared/app_ui/lib/src/tokens/app_radii.dart b/extras/custom-server/shared/app_ui/lib/src/tokens/app_radii.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/tokens/app_radii.dart rename to extras/custom-server/shared/app_ui/lib/src/tokens/app_radii.dart diff --git a/03-custom-server/shared/app_ui/lib/src/tokens/app_sizes.dart b/extras/custom-server/shared/app_ui/lib/src/tokens/app_sizes.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/tokens/app_sizes.dart rename to extras/custom-server/shared/app_ui/lib/src/tokens/app_sizes.dart diff --git a/03-custom-server/shared/app_ui/lib/src/tokens/app_spacing.dart b/extras/custom-server/shared/app_ui/lib/src/tokens/app_spacing.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/tokens/app_spacing.dart rename to extras/custom-server/shared/app_ui/lib/src/tokens/app_spacing.dart diff --git a/03-custom-server/shared/app_ui/lib/src/tokens/app_typography.dart b/extras/custom-server/shared/app_ui/lib/src/tokens/app_typography.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/tokens/app_typography.dart rename to extras/custom-server/shared/app_ui/lib/src/tokens/app_typography.dart diff --git a/03-custom-server/shared/app_ui/lib/src/tokens/tokens.dart b/extras/custom-server/shared/app_ui/lib/src/tokens/tokens.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/tokens/tokens.dart rename to extras/custom-server/shared/app_ui/lib/src/tokens/tokens.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_brand.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_brand.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_brand.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_brand.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_button.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_button.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_button.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_button.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_card.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_card.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_card.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_card.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_chat.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_chat.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_chat.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_chat.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_chip.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_chip.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_chip.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_chip.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_decision.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_decision.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_decision.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_decision.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_dialog.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_dialog.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_dialog.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_dialog.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_icons.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_icons.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_icons.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_icons.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_order_row.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_order_row.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_order_row.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_order_row.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_person.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_person.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_person.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_person.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_pressable.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_pressable.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_pressable.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_pressable.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_progress.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_progress.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_progress.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_progress.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_segmented.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_segmented.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_segmented.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_segmented.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_skeleton.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_skeleton.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_skeleton.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_skeleton.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_stat.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_stat.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_stat.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_stat.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_toast.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_toast.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_toast.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_toast.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/app_tone.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/app_tone.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/app_tone.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/app_tone.dart diff --git a/03-custom-server/shared/app_ui/lib/src/widgets/widgets.dart b/extras/custom-server/shared/app_ui/lib/src/widgets/widgets.dart similarity index 100% rename from 03-custom-server/shared/app_ui/lib/src/widgets/widgets.dart rename to extras/custom-server/shared/app_ui/lib/src/widgets/widgets.dart diff --git a/03-custom-server/shared/app_ui/pubspec.yaml b/extras/custom-server/shared/app_ui/pubspec.yaml similarity index 100% rename from 03-custom-server/shared/app_ui/pubspec.yaml rename to extras/custom-server/shared/app_ui/pubspec.yaml diff --git a/03-custom-server/shared/app_ui/test/helpers/helpers.dart b/extras/custom-server/shared/app_ui/test/helpers/helpers.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/helpers/helpers.dart rename to extras/custom-server/shared/app_ui/test/helpers/helpers.dart diff --git a/03-custom-server/shared/app_ui/test/helpers/pump_app.dart b/extras/custom-server/shared/app_ui/test/helpers/pump_app.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/helpers/pump_app.dart rename to extras/custom-server/shared/app_ui/test/helpers/pump_app.dart diff --git a/03-custom-server/shared/app_ui/test/src/theme/app_theme_test.dart b/extras/custom-server/shared/app_ui/test/src/theme/app_theme_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/theme/app_theme_test.dart rename to extras/custom-server/shared/app_ui/test/src/theme/app_theme_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/tokens/tokens_test.dart b/extras/custom-server/shared/app_ui/test/src/tokens/tokens_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/tokens/tokens_test.dart rename to extras/custom-server/shared/app_ui/test/src/tokens/tokens_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_button_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_button_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_button_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_button_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_card_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_card_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_card_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_card_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_chat_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_chat_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_chat_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_chat_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_chip_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_chip_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_chip_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_chip_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_decision_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_decision_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_decision_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_decision_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_dialog_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_dialog_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_dialog_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_dialog_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_misc_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_misc_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_misc_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_misc_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_order_row_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_order_row_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_order_row_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_order_row_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_runtime_constructors_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_skeleton_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_skeleton_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_skeleton_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_skeleton_test.dart diff --git a/03-custom-server/shared/app_ui/test/src/widgets/app_stat_test.dart b/extras/custom-server/shared/app_ui/test/src/widgets/app_stat_test.dart similarity index 100% rename from 03-custom-server/shared/app_ui/test/src/widgets/app_stat_test.dart rename to extras/custom-server/shared/app_ui/test/src/widgets/app_stat_test.dart

AzPi!HK1CYdMasJ%868x!dF;`ny|>LRT>eY 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%0DElPF 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 W^&O&`J%u)z>gwo~gvKD8fBz35Y#oFE literal 0 HcmV?d00001 diff --git a/03-human-in-the-loop/shared/app_ui/assets/fonts/Poppins-Regular.ttf b/03-human-in-the-loop/shared/app_ui/assets/fonts/Poppins-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0bda228ade88b0bb5aac7da2c881d0c3f64d0817 GIT binary patch literal 160316 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