Skip to content

Commit ca21e84

Browse files
committed
Merge branch 'main' of https://github.com/VeryGoodOpenSource/very_good_ai_flutter_plugin into feat/animations-skill
2 parents 82c2415 + 99d948f commit ca21e84

18 files changed

Lines changed: 293 additions & 77 deletions

File tree

.claude-plugin/plugin.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"testing",
5353
"theming",
5454
"very-good-cli",
55+
"ui-package",
5556
"wcag",
5657
"widget-testing",
5758
"sdk-upgrade",

.github/workflows/ci.yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ jobs:
1010
name: 📝 Markdown Quality
1111
runs-on: ubuntu-latest
1212
steps:
13-
- uses: actions/checkout@v4
13+
- uses: actions/checkout@v6
1414
- name: Lint Markdown
15-
uses: DavidAnson/markdownlint-cli2-action@v19
15+
uses: DavidAnson/markdownlint-cli2-action@v23
1616
with:
1717
globs: '**/*.md'
1818
config: 'config/custom.markdownlint.jsonc'
1919
spelling:
2020
name: ✍️ Spelling Check
2121
runs-on: ubuntu-latest
2222
steps:
23-
- uses: actions/checkout@v4
23+
- uses: actions/checkout@v6
2424
- name: Spell Check Code
25-
uses: streetsidesoftware/cspell-action@v6
25+
uses: streetsidesoftware/cspell-action@v8
2626
with:
2727
files: '**/*.md'
2828
config: 'config/cspell.json'
@@ -32,7 +32,7 @@ jobs:
3232
outputs:
3333
skills: ${{ steps.changed-skills.outputs.skills }}
3434
steps:
35-
- uses: actions/checkout@v4
35+
- uses: actions/checkout@v6
3636
with:
3737
fetch-depth: 0
3838
- name: Get changed skills
@@ -57,7 +57,7 @@ jobs:
5757
matrix:
5858
skill: ${{ fromJson(needs.detect-changed-skills.outputs.skills) }}
5959
steps:
60-
- uses: actions/checkout@v4
60+
- uses: actions/checkout@v6
6161
- name: Validate ${{ matrix.skill }}
6262
id: validate
6363
uses: Flash-Brew-Digital/validate-skill@v1
@@ -76,6 +76,6 @@ jobs:
7676
name: 📦 Manifest Validation
7777
runs-on: ubuntu-latest
7878
steps:
79-
- uses: actions/checkout@v4
79+
- uses: actions/checkout@v6
8080
- name: Validate Plugin Manifest
8181
run: bash ./scripts/validate_plugin_manifest.sh

CLAUDE.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ hooks/
2020
check-vgv-cli.sh # Validates VGV CLI installed and >= 1.1.0
2121
format.sh # Runs dart format on modified .dart files
2222
vgv-cli-common.sh # Shared utilities for VGV CLI hook scripts
23+
warn-missing-mcp.sh # Warns at session start if VGV CLI is missing/outdated
2324
skills/
2425
accessibility/SKILL.md
2526
accessibility/reference.md
@@ -43,6 +44,7 @@ skills/
4344
static-security/reference.md
4445
testing/SKILL.md
4546
testing/reference.md
47+
ui-package/SKILL.md
4648
```
4749

4850
## Skill File Format
@@ -65,6 +67,7 @@ Every `SKILL.md` follows this structure:
6567
- Provide complete, copy-pasteable snippets, not fragments
6668
- Reference packages by full name (e.g., `package:mocktail`)
6769
- Include anti-patterns alongside correct patterns when helpful
70+
- Align pipe characters vertically in all markdown tables (enforced by markdownlint MD060)
6871

6972
## Adding a New Skill
7073

@@ -75,7 +78,13 @@ Every `SKILL.md` follows this structure:
7578

7679
## Hooks
7780

78-
The `hooks/` directory contains PreToolUse and PostToolUse hooks defined in `hooks.json`.
81+
The `hooks/` directory contains SessionStart, PreToolUse, and PostToolUse hooks defined in `hooks.json`.
82+
83+
### SessionStart Hooks
84+
85+
These run **when a session begins**:
86+
87+
- `warn-missing-mcp.sh` — checks if Very Good CLI is installed and >= 1.1.0; outputs a warning to Claude's context if missing or outdated (non-blocking)
7988

8089
### PreToolUse Hooks
8190

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ For more details, see the [Very Good Claude Marketplace][marketplace_link].
3838
| [**Bloc**](skills/bloc/SKILL.md) | State management with Bloc/Cubit — sealed events & states, `BlocProvider`/`BlocBuilder` widgets, event transformers, and testing with `blocTest()` & `mocktail` |
3939
| [**Layered Architecture**](skills/layered-architecture/SKILL.md) | VGV layered architecture — four-layer package structure (Data, Repository, Business Logic, Presentation), dependency rules, data flow, and bootstrap wiring |
4040
| [**Security**](skills/static-security/SKILL.md) | Flutter-specific static security review — secrets management, `flutter_secure_storage`, certificate pinning, `Random.secure()`, `formz` validation, dependency vulnerability scanning with `osv-scanner`, and OWASP Mobile Top 10 guidance |
41+
| [**UI Package**](skills/ui-package/SKILL.md) | Flutter UI package creation — custom widget libraries with `ThemeExtension`-based theming, design tokens, barrel file exports, widget tests, Widgetbook catalog, and consistent API conventions |
4142
| [**License Compliance**](skills/license-compliance/SKILL.md) | Dependency license auditing — categorizes licenses (permissive, weak/strong copyleft, unknown), flags non-compliant or missing licenses, and produces a structured compliance report using Very Good CLI |
4243
| [**Dart/Flutter SDK Upgrade**](skills/dart-flutter-sdk-upgrade/SKILL.md) | Bump Dart and Flutter SDK constraints across packages — CI workflow versions, pubspec.yaml environment constraints, and PR preparation for SDK upgrades |
4344

@@ -78,6 +79,7 @@ You can also invoke skills directly as slash commands:
7879
/vgv-navigation
7980
/vgv-static-security
8081
/vgv-testing
82+
/vgv-ui-package
8183
/vgv-license-compliance
8284
/vgv-dart-flutter-sdk-upgrade
8385
```

config/cspell.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"Bidirectionality",
55
"Bienvenido",
66
"bypassable",
7+
"dartdoc",
78
"CSPRNG",
89
"dismissable",
910
"elemento",
@@ -14,6 +15,7 @@
1415
"GHSA",
1516
"goldens",
1617
"hoverable",
18+
"lerp",
1719
"jailbroken",
1820
"LTRB",
1921
"mapbox",
@@ -27,6 +29,8 @@
2729
"serialization",
2830
"stdio",
2931
"WCAG",
32+
"widgetbook",
33+
"Widgetbook",
3034
"xxlg"
3135
],
3236
"flagWords": []

hooks/hooks.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
{
22
"description": "Very Good AI Flutter Plugin hooks for Dart and Flutter development",
33
"hooks": {
4+
"SessionStart": [
5+
{
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/warn-missing-mcp.sh",
10+
"timeout": 10
11+
}
12+
]
13+
}
14+
],
415
"PreToolUse": [
516
{
617
"matcher": "mcp__very-good-cli__.*",

hooks/scripts/warn-missing-mcp.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
# SessionStart hook: warn when Very Good CLI is missing or outdated.
3+
# Output is injected into Claude's context (not displayed in the terminal).
4+
# Non-blocking — always exits 0.
5+
6+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7+
source "$SCRIPT_DIR/vgv-cli-common.sh"
8+
9+
cli_status=$(check_vgv_cli)
10+
case "$cli_status" in
11+
not_installed)
12+
echo "⚠️ Very Good CLI is not installed. The Very Good CLI MCP server will not work without Very Good CLI >= ${MIN_VERSION}. Install with: dart pub global activate very_good_cli"
13+
;;
14+
outdated:*)
15+
version="${cli_status#outdated:}"
16+
echo "⚠️ Very Good CLI ${version} is too old. The Very Good CLI MCP server requires >= ${MIN_VERSION}. Update with: dart pub global activate very_good_cli"
17+
;;
18+
esac
19+
20+
exit 0

skills/bloc/SKILL.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Apply these standards to ALL Bloc/Cubit work:
3030

3131
| Aspect | Cubit | Bloc |
3232
| ----------------- | ------------------------------ | --------------------------------------- |
33-
| API | Functions → `emit(state)` | Events → `on<Event>``emit(state)` |
33+
| API | Functions → `emit(state)` | Events → `on<Event>``emit(state)` |
3434
| Complexity | Low | Higher |
3535
| Traceability | Less (no event log) | Full (events + transitions) |
3636
| When to use | Simple state, UI-driven logic | Complex flows, event-driven, transforms |
@@ -76,13 +76,13 @@ class CounterBloc extends Bloc<CounterEvent, int> {
7676

7777
**Pattern:** `BlocSubject` + `Noun` + `VerbPastTense`
7878

79-
| Event class name | Meaning |
80-
| ----------------------------- | -------------------------------- |
81-
| `TodoListSubscriptionRequested` | Subscribing to todo list stream |
82-
| `TodoListTodoDeleted` | Deleting a specific todo |
83-
| `TodoListUndoDeletionRequested` | Undoing the last deletion |
84-
| `LoginFormSubmitted` | Submitting the login form |
85-
| `ProfilePageRefreshed` | Refreshing the profile page |
79+
| Event class name | Meaning |
80+
| ------------------------------- | -------------------------------- |
81+
| `TodoListSubscriptionRequested` | Subscribing to todo list stream |
82+
| `TodoListTodoDeleted` | Deleting a specific todo |
83+
| `TodoListUndoDeletionRequested` | Undoing the last deletion |
84+
| `LoginFormSubmitted` | Submitting the login form |
85+
| `ProfilePageRefreshed` | Refreshing the profile page |
8686

8787
```dart
8888
sealed class TodoListEvent extends Equatable {

skills/bloc/references/patterns.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class SearchBloc extends Bloc<SearchEvent, SearchState> {
6060
```
6161

6262
| Transformer | Behavior |
63-
| ------------------ | ---------------------------------------------------- |
63+
| ------------------| ----------------------------------------------------- |
6464
| `concurrent()` | Process all events concurrently (default) |
6565
| `sequential()` | Process events one at a time in order |
6666
| `droppable()` | Ignore new events while one is processing |

skills/bloc/references/testing.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
| Parameter | Type | Purpose |
66
| ---------- | --------------------------- | ---------------------------------------------- |
7-
| `build` | `() => Bloc/Cubit` | Creates the Bloc/Cubit under test |
8-
| `act` | `(bloc) => void` | Interacts with the Bloc/Cubit |
9-
| `expect` | `() => List<State>` | Expected states emitted (in order) |
10-
| `seed` | `() => State` | Initial state before `act` |
11-
| `setUp` | `() => void` | Runs before `build` |
12-
| `verify` | `(bloc) => void` | Additional verifications after `expect` |
13-
| `errors` | `() => List<Matcher>` | Expected errors thrown |
14-
| `wait` | `Duration` | Wait duration before asserting (for debounce) |
7+
| `build` | `() => Bloc/Cubit` | Creates the Bloc/Cubit under test |
8+
| `act` | `(bloc) => void` | Interacts with the Bloc/Cubit |
9+
| `expect` | `() => List<State>` | Expected states emitted (in order) |
10+
| `seed` | `() => State` | Initial state before `act` |
11+
| `setUp` | `() => void` | Runs before `build` |
12+
| `verify` | `(bloc) => void` | Additional verifications after `expect` |
13+
| `errors` | `() => List<Matcher>` | Expected errors thrown |
14+
| `wait` | `Duration` | Wait duration before asserting (for debounce) |
1515

1616
## Cubit Test Example
1717

0 commit comments

Comments
 (0)