Skip to content

Commit 46248a8

Browse files
chore: add pre-commit hook with lint + format checks (#17)
* chore: add pre-commit hook configuration Adds .pre-commit-config.yaml for the pino monorepo. Hooks mirror what CI enforces: - trailing-whitespace, end-of-file-fixer, check-yaml, check-json, check-merge-conflict, check-added-large-files (general hygiene) - dart format --set-exit-if-changed (matches flutter-ci.yml) - flutter analyze --no-pub --fatal-infos (matches flutter-ci.yml) - pnpm typecheck (matches server-ci.yml) Generated build output (server/dist/) is excluded from all checks. Install locally: pip install pre-commit && pre-commit install Co-authored-by: Milan Le <leduckhc@users.noreply.github.com> * fix: apply trailing whitespace and end-of-file fixes Auto-fixed by pre-commit hooks (trailing-whitespace, end-of-file-fixer) on first repo-wide run. Establishes a clean baseline so future commits don't accumulate whitespace noise. Co-authored-by: Milan Le <leduckhc@users.noreply.github.com> * chore: simplify install comment (pre-commit already on PATH) Co-authored-by: Milan Le <leduckhc@users.noreply.github.com> * chore: switch hooks from pre-commit to pre-push stage Slow checks (flutter analyze, pnpm typecheck) are better suited to pre-push where they don't interrupt every local commit. Install: pre-commit install --hook-type pre-push Co-authored-by: Milan Le <leduckhc@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Milan Le <leduckhc@users.noreply.github.com>
1 parent 8873f63 commit 46248a8

22 files changed

Lines changed: 116 additions & 46 deletions

File tree

.agents/skills/dart-run-static-analysis/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void processData() {
9898
// Suppress for a specific line
9999
// ignore: invalid_assignment
100100
int x = '';
101-
101+
102102
const y = 10; // ignore: constant_identifier_names
103103
}
104104
```

.agents/skills/dart-setup-ffi-assets/SKILL.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,19 +281,19 @@ Future<File> downloadAsset(
281281
) async {
282282
final fileName = targetOS.dylibFileName('native_add_${targetOS.name}_${targetArchitecture.name}');
283283
final uri = downloadUri(fileName);
284-
284+
285285
final client = HttpClient()..findProxy = HttpClient.findProxyFromEnvironment;
286286
final request = await client.getUrl(uri);
287287
final response = await request.close();
288-
288+
289289
if (response.statusCode != 200) {
290290
throw ArgumentError('Download target $uri failed: Code ${response.statusCode}');
291291
}
292-
292+
293293
final targetFile = File.fromUri(outputDir.uri.resolve(fileName));
294294
await targetFile.create(recursive: true);
295295
await response.pipe(targetFile.openWrite());
296-
296+
297297
return targetFile;
298298
}
299299

.agents/skills/flutter-add-integration-test/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Use the Dart/Flutter MCP server tools to interactively explore and manipulate th
4141

4242
## Test Authoring Guidelines
4343

44-
Structure integration tests using the `flutter_test` API paradigm.
44+
Structure integration tests using the `flutter_test` API paradigm.
4545

4646
- Create a dedicated `integration_test/` directory at the project root.
4747
- Name all test files using the `<name>_test.dart` convention.
@@ -63,7 +63,7 @@ Execute tests using the `flutter drive` command. Require a host driver script lo
6363
`flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d chrome`
6464
- **If testing headless web:** Run with `-d web-server`.
6565
- **If testing on Android (Local):** Run `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart`.
66-
- **If testing on Firebase Test Lab (Android):**
66+
- **If testing on Firebase Test Lab (Android):**
6767
1. Build debug APK: `flutter build apk --debug`
6868
2. Build test APK: `./gradlew app:assembleAndroidTest`
6969
3. Upload both APKs to the Firebase Test Lab console.

.agents/skills/flutter-add-widget-preview/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ metadata:
1515

1616
## Preview Guidelines
1717

18-
Use the Flutter Widget Previewer to render widgets in real-time, isolated from the full application context.
18+
Use the Flutter Widget Previewer to render widgets in real-time, isolated from the full application context.
1919

2020
- **Target Elements:** Apply the `@Preview` annotation to top-level functions, static methods within a class, or public widget constructors/factories that have no required arguments and return a `Widget` or `WidgetBuilder`.
2121
- **Imports:** Always import `package:flutter/widget_previews.dart` to access the preview annotations.
@@ -98,7 +98,7 @@ final class TransformativePreview extends Preview {
9898
Preview transform() {
9999
final originalPreview = super.transform();
100100
final builder = originalPreview.toBuilder();
101-
101+
102102
builder
103103
..name = 'Transformed - ${originalPreview.name}'
104104
..theme = _themeBuilder;

.agents/skills/flutter-add-widget-test/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ Copy the following checklist to track progress when implementing a new widget te
5050
Apply the following conditional logic based on the type of interaction or state change being tested:
5151

5252
* **If testing static rendering:** Call `await tester.pumpWidget()` once, then immediately run `expect()` assertions.
53-
* **If testing standard state changes (e.g., button taps):**
53+
* **If testing standard state changes (e.g., button taps):**
5454
1. Call `await tester.tap(finder)`.
5555
2. Call `await tester.pump()` to trigger a single frame rebuild.
56-
* **If testing animations, transitions, or asynchronous UI updates:**
56+
* **If testing animations, transitions, or asynchronous UI updates:**
5757
1. Trigger the action (e.g., `await tester.drag(finder, Offset(500, 0))`).
5858
2. Call `await tester.pumpAndSettle()` to repeatedly pump frames until no more frames are scheduled (animation completes).
5959
* **If testing text input:** Call `await tester.enterText(textFieldFinder, 'Input string')`.

.agents/skills/flutter-apply-architecture-best-practices/SKILL.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ class ApiClient {
8383
// 2. Repository (Single source of truth, returns Domain Model)
8484
class UserRepository {
8585
UserRepository({required ApiClient apiClient}) : _apiClient = apiClient;
86-
86+
8787
final ApiClient _apiClient;
8888
User? _cachedUser;
8989
9090
Future<User> getUser(String id) async {
9191
if (_cachedUser != null) return _cachedUser!;
92-
92+
9393
final apiModel = await _apiClient.fetchUser(id);
9494
_cachedUser = User(id: apiModel.id, name: apiModel.fullName); // Transform to Domain Model
9595
return _cachedUser!;
@@ -102,7 +102,7 @@ class UserRepository {
102102
```dart
103103
// 3. ViewModel (State management and presentation logic)
104104
class ProfileViewModel extends ChangeNotifier {
105-
ProfileViewModel({required UserRepository userRepository})
105+
ProfileViewModel({required UserRepository userRepository})
106106
: _userRepository = userRepository;
107107
108108
final UserRepository _userRepository;
@@ -140,7 +140,7 @@ class ProfileView extends StatelessWidget {
140140
if (viewModel.isLoading) {
141141
return const Center(child: CircularProgressIndicator());
142142
}
143-
143+
144144
final user = viewModel.user;
145145
if (user == null) {
146146
return const Center(child: Text('User not found'));

.agents/skills/flutter-fix-layout-issues/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ metadata:
1414

1515
## Constraint Violation Diagnostics
1616

17-
Flutter layout operates on a strict rule: **Constraints go down. Sizes go up. Parent sets position.** Layout errors occur when this negotiation fails, typically due to unbounded constraints or unconstrained children.
17+
Flutter layout operates on a strict rule: **Constraints go down. Sizes go up. Parent sets position.** Layout errors occur when this negotiation fails, typically due to unbounded constraints or unconstrained children.
1818

1919
Diagnose layout failures using the following error signatures:
2020

@@ -85,7 +85,7 @@ Column(
8585
Row(
8686
children: [
8787
const Icon(Icons.search),
88-
TextField(),
88+
TextField(),
8989
],
9090
)
9191
```

.agents/skills/flutter-implement-json-serialization/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Use this conditional workflow when retrieving and parsing JSON from a network re
4848
- [ ] Decode and map the JSON to the model.
4949

5050
1. **Execute Request**: Use the `http` package to perform the network call.
51-
2. **Validate Response**:
51+
2. **Validate Response**:
5252
- If `response.statusCode == 200` (or 201 for POST), proceed to parsing.
5353
- If the status code indicates failure, throw an `Exception`.
5454
3. **Determine Parsing Strategy**:
@@ -81,7 +81,7 @@ class User {
8181
'id': int id,
8282
'name': String name,
8383
'email': String email,
84-
} =>
84+
} =>
8585
User(
8686
id: id,
8787
name: name,

.agents/skills/flutter-setup-declarative-routing/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ metadata:
1616

1717
## Core Concepts
1818

19-
Use the `go_router` package for declarative routing in Flutter. It provides a robust API for complex routing scenarios, deep linking, and nested navigation.
19+
Use the `go_router` package for declarative routing in Flutter. It provides a robust API for complex routing scenarios, deep linking, and nested navigation.
2020

2121
- **GoRouter**: The central configuration object defining the application's route tree.
2222
- **GoRoute**: A standard route mapping a URL path to a Flutter screen.
@@ -120,7 +120,7 @@ Configure the native platforms to intercept specific URLs and route them into th
120120
```
121121

122122
### If configuring for iOS:
123-
1. **Modify `Info.plist`**: Opt-in to Flutter's default deep link handler.
123+
1. **Modify `Info.plist`**: Opt-in to Flutter's default deep link handler.
124124
*Note: If using a third-party deep linking plugin (e.g., `app_links`), set this to `NO` to prevent conflicts.*
125125
```xml
126126
<key>FlutterDeepLinkingEnabled</key>

.agents/skills/flutter-setup-localization/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ class GreetingWidget extends StatelessWidget {
190190
final int notificationCount;
191191
192192
const GreetingWidget({
193-
super.key,
194-
required this.userName,
193+
super.key,
194+
required this.userName,
195195
required this.notificationCount,
196196
});
197197

0 commit comments

Comments
 (0)