Skip to content

Commit 8c28567

Browse files
committed
poc: Implement the specs + sample + AI
1 parent 7ea62be commit 8c28567

191 files changed

Lines changed: 1562 additions & 6553 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/android_deploy_production.yml‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ jobs:
2525
uses: subosito/flutter-action@v2
2626
with:
2727
channel: 'stable'
28-
flutter-version: '3.10.5'
28+
flutter-version: '3.24.3'
2929

30-
- name: Generate new project
30+
- name: Set up project
3131
run: |
32-
dart pub global activate mason_cli
33-
mason get
34-
mason make template -c mason-config.json
32+
cp -r sample/* .
33+
cp -r sample/.* . 2>/dev/null || true
3534
3635
- name: Get Flutter dependencies
3736
run: flutter pub get

‎.github/workflows/android_deploy_production_to_playstore.yml‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ jobs:
2525
uses: subosito/flutter-action@v2
2626
with:
2727
channel: 'stable'
28-
flutter-version: '3.10.5'
28+
flutter-version: '3.24.3'
2929

30-
- name: Generate new project
30+
- name: Set up project
3131
run: |
32-
dart pub global activate mason_cli
33-
mason get
34-
mason make template -c mason-config.json
32+
cp -r sample/* .
33+
cp -r sample/.* . 2>/dev/null || true
3534
3635
- name: Get Flutter dependencies
3736
run: flutter pub get

‎.github/workflows/android_deploy_staging.yml‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ jobs:
2525
uses: subosito/flutter-action@v2
2626
with:
2727
channel: 'stable'
28-
flutter-version: '3.10.5'
28+
flutter-version: '3.24.3'
2929

30-
- name: Generate new project
30+
- name: Set up project
3131
run: |
32-
dart pub global activate mason_cli
33-
mason get
34-
mason make template -c mason-config.json
32+
cp -r sample/* .
33+
cp -r sample/.* . 2>/dev/null || true
3534
3635
- name: Get Flutter dependencies
3736
run: flutter pub get

‎.github/workflows/bump_version.yml‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,8 @@ jobs:
1818
uses: actions/checkout@v3
1919

2020
- name: Set new version
21-
uses: jossef/action-set-json-field@v2.1
22-
with:
23-
file: mason-config.json
24-
field: app_version
25-
value: ${{ github.event.inputs.newVersion }}
21+
run: |
22+
sed -i "s/^version: .*/version: ${{ github.event.inputs.newVersion }}/" sample/pubspec.yaml
2623
2724
- name: Create pull request
2825
uses: peter-evans/create-pull-request@v4

‎.github/workflows/ios_deploy_staging_to_firebase.yml‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,12 @@ jobs:
3535
uses: subosito/flutter-action@v1
3636
with:
3737
channel: 'stable'
38-
flutter-version: '3.10.5'
38+
flutter-version: '3.24.3'
3939

40-
- name: Generate new project
40+
- name: Set up project
4141
run: |
42-
dart pub global activate mason_cli
43-
mason get
44-
mason make template -c mason-config.json
42+
cp -r sample/* .
43+
cp -r sample/.* . 2>/dev/null || true
4544
4645
- name: Get Flutter dependencies
4746
run: flutter pub get

‎.github/workflows/ios_deploy_to_app_store.yml‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,12 @@ jobs:
3636
uses: subosito/flutter-action@v2
3737
with:
3838
channel: 'stable'
39-
flutter-version: '3.10.5'
39+
flutter-version: '3.24.3'
4040

41-
- name: Generate new project
41+
- name: Set up project
4242
run: |
43-
dart pub global activate mason_cli
44-
mason get
45-
mason make template -c mason-config.json
43+
cp -r sample/* .
44+
cp -r sample/.* . 2>/dev/null || true
4645
4746
- name: Get Flutter dependencies
4847
run: flutter pub get

‎.github/workflows/ios_deploy_to_testflight.yml‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,12 @@ jobs:
3636
uses: subosito/flutter-action@v2
3737
with:
3838
channel: 'stable'
39-
flutter-version: '3.10.5'
39+
flutter-version: '3.24.3'
4040

41-
- name: Generate new project
41+
- name: Set up project
4242
run: |
43-
dart pub global activate mason_cli
44-
mason get
45-
mason make template -c mason-config.json
43+
cp -r sample/* .
44+
cp -r sample/.* . 2>/dev/null || true
4645
4746
- name: Get Flutter dependencies
4847
run: flutter pub get

‎.github/workflows/test.yml‎

Lines changed: 25 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
name: CI
22
on:
3-
# Trigger the workflow on push or pull request,
4-
# but push action is only for the feature branch
53
pull_request:
64
types: [ opened, synchronize, reopened ]
75

86
jobs:
9-
test:
10-
name: Template initializing scripts test
7+
validate_sample:
8+
name: Validate sample project
119
runs-on: ubuntu-latest
1210
timeout-minutes: 30
1311
steps:
@@ -18,118 +16,36 @@ jobs:
1816
uses: subosito/flutter-action@v2
1917
with:
2018
channel: 'stable'
21-
flutter-version: '3.10.5'
19+
flutter-version: '3.24.3'
2220

23-
- name: Generate new project
21+
- name: Check for spec drift
2422
run: |
25-
dart pub global activate mason_cli
26-
mason get
27-
mason make template -c mason-config.json
23+
SAMPLE_CHANGED=$(git diff --name-only origin/develop...HEAD -- sample/ | wc -l)
24+
SPECS_CHANGED=$(git diff --name-only origin/develop...HEAD -- specs/ | wc -l)
25+
if [ "$SAMPLE_CHANGED" -gt 0 ] && [ "$SPECS_CHANGED" -eq 0 ]; then
26+
echo "::warning::sample/ changed but specs/ was not updated. Please review if specs need updating."
27+
fi
2828
29-
- name: Get Flutter dependencies
30-
run: flutter pub get
29+
- name: Layer 1 — Structural validation
30+
run: bash specs/validation/validate_structure.sh sample
3131

32-
- name: Run code generator
33-
run: flutter packages pub run build_runner build --delete-conflicting-outputs
32+
- name: Layer 2a — Get Flutter dependencies
33+
run: cd sample && flutter pub get
3434

35-
- name: Check for any formatting issues in the code
36-
run: dart format --set-exit-if-changed .
35+
- name: Layer 2b — Run code generator
36+
run: cd sample && flutter packages pub run build_runner build --delete-conflicting-outputs
3737

38-
- name: Statically analyze the Dart code for any errors
39-
run: flutter analyze .
38+
- name: Layer 2c — Check formatting
39+
run: cd sample && dart format --set-exit-if-changed .
4040

41-
- name: Run widget tests, unit tests
42-
run: flutter test --machine --coverage
41+
- name: Layer 2d — Static analysis
42+
run: cd sample && flutter analyze .
4343

44-
generate_mason_bundle:
45-
# The job generate_mason_bundle identify that the job test must complete successfully
46-
# before this generate_mason_bundle job will run
47-
needs: test
48-
name: Generate Mason bundle
49-
runs-on: ubuntu-latest
50-
steps:
51-
- name: Check out
52-
uses: actions/checkout@v3
53-
with:
54-
ref: ${{ github.head_ref }}
55-
56-
- name: Set up Flutter environment
57-
uses: subosito/flutter-action@v2
58-
with:
59-
channel: 'stable'
60-
flutter-version: '3.10.5'
61-
62-
- name: Install Mason CLI
63-
run: |
64-
dart pub global activate mason_cli
65-
mason get
66-
67-
- name: Generate Mason bundle
68-
run: |
69-
mason bundle bricks/permission_handler -t dart -o bricks/template/hooks/bundles
70-
71-
- id: changes
72-
name: Check for changes in the Mason bricks
73-
run: |
74-
count=$(git status bricks --porcelain | wc -l)
75-
echo "count=$count" >> $GITHUB_OUTPUT
76-
77-
- name: Commit & push the Mason bundle changes
78-
if: steps.changes.outputs.count > 0
79-
run: |
80-
git config user.name team-nimblehq
81-
git config user.email bot@nimblehq.co
82-
git add bricks
83-
git commit -m "[Chore] Generate Mason bundle"
84-
git push
85-
86-
generate_sample_project:
87-
# The job generate_sample_project identify that the job generate_mason_bundle must complete successfully
88-
# before this generate_sample_project job will run
89-
needs: generate_mason_bundle
90-
name: Generate the sample project
91-
runs-on: ubuntu-latest
92-
timeout-minutes: 30
93-
steps:
94-
- name: Check out
95-
uses: actions/checkout@v3
96-
with:
97-
ref: ${{ github.head_ref }}
98-
99-
- name: Set up Flutter environment
100-
uses: subosito/flutter-action@v2
101-
with:
102-
channel: 'stable'
103-
flutter-version: '3.10.5'
104-
105-
- name: Remove the old sample project
44+
- name: Layer 3 — Architecture invariants
10645
run: |
107-
rm -rf sample
46+
cp specs/validation/invariant_architecture_test.dart sample/test/
47+
cd sample && flutter test test/invariant_architecture_test.dart
48+
rm -f test/invariant_architecture_test.dart
10849
109-
- name: Set the project name "sample"
110-
uses: jossef/action-set-json-field@v2.1
111-
with:
112-
file: mason-config.json
113-
field: project_name
114-
value: sample
115-
116-
- name: Generate the new "sample" project
117-
run: |
118-
dart pub global activate mason_cli
119-
mason get
120-
mason make template -c mason-config.json -o sample
121-
122-
- id: changes
123-
name: Check for changes in the sample project
124-
run: |
125-
count=$(git status sample --porcelain | wc -l)
126-
echo "count=$count" >> $GITHUB_OUTPUT
127-
128-
- name: Commit & push the sample project changes
129-
if: steps.changes.outputs.count > 0
130-
run: |
131-
git config user.name team-nimblehq
132-
git config user.email bot@nimblehq.co
133-
git add sample
134-
git commit -m "[Chore] Generate & update sample project"
135-
git push
50+
- name: Layer 3b — Run tests
51+
run: cd sample && flutter test --coverage

‎.gitignore‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
*.iml
99
.idea/*
1010

11-
# Mason
12-
mason-lock.json
13-
.mason/
11+
# Generated projects (created by AI generation, not source of truth)
12+
*_project/
13+
*_app/
14+
15+
# Build artifacts
16+
coverage/
17+
build/
18+
.dart_tool/
19+
20+
# Flutter/Dart generated files (in case they leak to root)
21+
*.g.dart
22+
*.freezed.dart
23+
*.mocks.dart

‎AGENTS.md‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# AGENTS.md
2+
3+
## Project
4+
5+
Flutter project template using **spec-driven AI generation**. A golden reference project (`sample/`) + markdown specs + a validation pipeline replace traditional Mason/Mustache templates.
6+
7+
## Repo structure
8+
9+
```
10+
sample/ # Golden reference project (source of truth, CI-validated)
11+
specs/ # Generation prompt + architecture rules + validation scripts
12+
```
13+
14+
## Generating a new project
15+
16+
1. Fill in the 7 parameters in `specs/generation-prompt.md`
17+
2. Feed the prompt + `sample/` source code to an AI model
18+
3. AI generates the project into a fresh directory
19+
4. Run `bash specs/validation/validate.sh <project-path>`
20+
5. If validation fails, feed errors back to the AI and re-validate
21+
22+
## Modifying the template
23+
24+
1. Make the change in `sample/` first (real, runnable code)
25+
2. Run `bash specs/validation/validate.sh sample` — must pass
26+
3. If the change involves a non-obvious constraint, update `specs/architecture-rules.md`
27+
4. If the change affects generation parameters or checklist, update `specs/generation-prompt.md`
28+
5. Run validation again to confirm
29+
6. Never commit if validation fails
30+
31+
## Validation
32+
33+
```bash
34+
bash specs/validation/validate.sh sample
35+
```
36+
37+
4 layers: structure, static analysis (`flutter analyze` + `dart format`), architecture invariants, unit tests.
38+
39+
## Key rules
40+
41+
- `sample/` is the sole source of truth for all code patterns — specs only document non-obvious constraints
42+
- Never generate `*.g.dart`, `*.freezed.dart`, `*.config.dart`, `*.mocks.dart`, or `lib/gen/` — these come from `build_runner` / `flutter_gen`
43+
- Domain layer must not import from data or app layers; data must not import from app
44+
- All Dart imports use `package:` format, never relative imports

0 commit comments

Comments
 (0)