Skip to content

Commit 2260c14

Browse files
authored
Merge pull request #33 from flutter/update-skill-readme
Update READMEs
2 parents 7322ffb + 32dd443 commit 2260c14

File tree

6 files changed

+312
-85
lines changed

6 files changed

+312
-85
lines changed

README.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,57 @@
11
# Agent Skills for Flutter
22

3+
**NOTE: This repository is currently in development and is not yet ready for use.**
4+
35
This repository contains agent skills for Flutter.
46

7+
## Installation
8+
9+
To install the skills into your project, run the following command:
10+
11+
```bash
12+
npx skills add flutter/skills
13+
```
14+
15+
## Updating Skills
16+
17+
To update, run the following command:
18+
19+
```bash
20+
npx skills update flutter/skills
21+
```
22+
23+
## Available Skills
24+
25+
| Skill | Description |
26+
|---|---|
27+
| [flutter-accessibility](skills/flutter-accessibility/SKILL.md) | Configure your Flutter app to support assistive technologies like Screen Readers |
28+
| [flutter-animation](skills/flutter-animation/SKILL.md) | Add animated effects to your Flutter app |
29+
| [flutter-app-size](skills/flutter-app-size/SKILL.md) | Measure and reduce the size of the Flutter app bundle, APK, or IPA |
30+
| [flutter-architecture](skills/flutter-architecture/SKILL.md) | Build an app using the Flutter team's recommended app architecture |
31+
| [flutter-caching](skills/flutter-caching/SKILL.md) | Cache data in a Flutter app |
32+
| [flutter-concurrency](skills/flutter-concurrency/SKILL.md) | Execute long-running tasks in a background thread in Flutter |
33+
| [flutter-databases](skills/flutter-databases/SKILL.md) | Work with databases in a Flutter app |
34+
| [flutter-environment-setup-linux](skills/flutter-environment-setup-linux/SKILL.md) | Set up a Linux environment for Flutter development |
35+
| [flutter-environment-setup-macos](skills/flutter-environment-setup-macos/SKILL.md) | Set up a macOS environment for Flutter development |
36+
| [flutter-environment-setup-windows](skills/flutter-environment-setup-windows/SKILL.md) | Set up a Windows environment for Flutter development |
37+
| [flutter-http-and-json](skills/flutter-http-and-json/SKILL.md) | Make HTTP requests and encode / decode JSON in a Flutter app |
38+
| [flutter-layout](skills/flutter-layout/SKILL.md) | How to build your app's layout using Flutter's layout widgets and constraint system |
39+
| [flutter-localization](skills/flutter-localization/SKILL.md) | Configure your Flutter app to support different languages and regions |
40+
| [flutter-native-interop](skills/flutter-native-interop/SKILL.md) | Interoperate with native APIs in a Flutter app on Android, iOS, and the web |
41+
| [flutter-performance](skills/flutter-performance/SKILL.md) | Optimize the performance of your Flutter app |
42+
| [flutter-platform-views](skills/flutter-platform-views/SKILL.md) | Add a native view into your Flutter app |
43+
| [flutter-plugins](skills/flutter-plugins/SKILL.md) | Build a Flutter plugin that provides native interop for other Flutter apps to use |
44+
| [flutter-routing-and-navigation](skills/flutter-routing-and-navigation/SKILL.md) | Move between or deep link to different screens or routes within a Flutter application |
45+
| [flutter-state-management](skills/flutter-state-management/SKILL.md) | Manage state in your Flutter application |
46+
| [flutter-testing](skills/flutter-testing/SKILL.md) | Add Flutter unit tests, widget tests, or integration tests |
47+
| [flutter-theming](skills/flutter-theming/SKILL.md) | How to customize your app's theme using Flutter's theming system |
48+
549
## Contributing
650

51+
To contribute skills, see the instructions in [tool/README.md](tool/README.md).
52+
753
Please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
854

955
## Code of Conduct
1056

11-
Please see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for more information.
57+
Please see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for more information.

tool/README.md

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,47 +28,65 @@ dart run skills generate-skill [options] [config_file]
2828
* `--skill`: Filter to generate only the specified skill by name.
2929
* `--directory` (`-d`): The directory to output the generated skill folder. Defaults to `../skills/`.
3030

31-
### `validate-skill`
31+
**Example:**
32+
Generate all skills defined in resources/flutter_skills.yaml to the skills/ directory:
33+
34+
```bash
35+
dart run skills generate-skill
36+
```
37+
38+
Generate only the 'flutter-layout' skill to a custom directory:
3239

33-
Validates skills by re-generating and comparing with existing skills.
40+
```bash
41+
dart run skills generate-skill --skill flutter-layout --directory ../skills
42+
```
43+
44+
### `update-skill`
45+
46+
Updates an existing skill by combining its current content with fetched resources and new instructions.
3447

3548
**Usage:**
3649
```bash
37-
dart run skills validate-skill [options] [config_file]
50+
dart run skills update-skill [options] [config_file]
3851
```
3952

4053
**Arguments:**
4154
* `[config_file]`: Path to the YAML configuration file. Defaults to `resources/flutter_skills.yaml`.
4255

4356
**Options:**
44-
* `--skill`: Validate only the specified skill by name.
45-
* `--directory` (`-d`): The directory containing the generated skills. Defaults to the output directory or `../skills/`.
57+
* `--skill`: Filter to update only the specified skill by name.
58+
* `--directory` (`-d`): The directory to search for skills. Defaults to `../skills/`.
4659
* `--thinking-budget`: The token budget for the model to "think" before generating content. Defaults to 2048.
4760

4861
**Example:**
49-
Generate all skills defined in resources/flutter_skills.yaml to the skills/ directory:
62+
Update all skills defined in resources/flutter_skills.yaml:
5063

5164
```bash
52-
dart run skills generate-skill
65+
dart run skills update-skill
5366
```
5467

55-
Generate only the 'flutter-layout' skill to a custom directory:
68+
Update only the 'flutter-layout' skill:
5669

57-
```
58-
dart run skills generate-skill --skill flutter-layout --directory ../skills
70+
```bash
71+
dart run skills update-skill --skill flutter-layout
5972
```
6073

6174
### `validate-skill`
6275

63-
Validates generated skills by re-generating them using the same source and comparing the output. This is useful for testing prompts or verifying consistency.
76+
Validates skills by re-generating and comparing with existing skills. This is useful for testing prompts or verifying consistency.
6477

6578
**Usage:**
6679
```bash
67-
dart run skills validate-skill [options]
80+
dart run skills validate-skill [options] [config_file]
6881
```
6982

83+
**Arguments:**
84+
* `[config_file]`: Path to the YAML configuration file. Defaults to `resources/flutter_skills.yaml`.
85+
7086
**Options:**
71-
* `--directory` (`-d`): The directory containing the generated skills to validate. Defaults to `skills/`.
87+
* `--skill`: Validate only the specified skill by name.
88+
* `--directory` (`-d`): The directory containing the generated skills to validate. Defaults to `../skills/`.
89+
* `--thinking-budget`: The token budget for the model to "think" before generating content. Defaults to 2048.
7290

7391
**Example:**
7492
Validate skills in the default 'skills' directory:
@@ -78,10 +96,31 @@ dart run skills validate-skill
7896
```
7997

8098
Validate skills in a custom directory:
81-
```
99+
100+
```bash
82101
dart run skills validate-skill --directory ../validation_results
83102
```
84103

104+
### `update-readme`
105+
106+
Updates the `README.md` file with a table of available skills.
107+
108+
**Usage:**
109+
```bash
110+
dart run skills update-readme [config_file] [readme_file]
111+
```
112+
113+
**Arguments:**
114+
* `[config_file]`: Path to the YAML configuration file. Defaults to `resources/flutter_skills.yaml`.
115+
* `[readme_file]`: Path to the README.md file to update. Defaults to `../README.md`.
116+
117+
**Example:**
118+
Update the root README.md:
119+
120+
```bash
121+
dart run skills update-readme
122+
```
123+
85124
## Configuration
86125

87126
The default configuration file is located at `tool/resources/flutter_skills.yaml`. It contains a list of skill definitions:

tool/bin/skills.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:args/command_runner.dart';
88
import 'package:http/http.dart' as http;
99
import 'package:logging/logging.dart';
1010
import 'package:skills/src/commands/generate_skill_command.dart';
11+
import 'package:skills/src/commands/update_readme_command.dart';
1112
import 'package:skills/src/commands/update_skill_command.dart';
1213
import 'package:skills/src/commands/validate_skill_command.dart';
1314

@@ -20,7 +21,8 @@ void main(List<String> arguments) async {
2021
CommandRunner<void>('skills', 'A sample command-line application.')
2122
..addCommand(GenerateSkillCommand(httpClient: httpClient))
2223
..addCommand(UpdateSkillCommand(httpClient: httpClient))
23-
..addCommand(ValidateSkillCommand(httpClient: httpClient));
24+
..addCommand(ValidateSkillCommand(httpClient: httpClient))
25+
..addCommand(UpdateReadmeCommand());
2426

2527
runner.argParser.addFlag(
2628
'version',

tool/lib/src/commands/base_skill_command.dart

Lines changed: 19 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,100 +2,50 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'dart:convert';
65
import 'dart:io';
76

8-
import 'package:args/command_runner.dart';
97
import 'package:http/http.dart' as http;
10-
import 'package:logging/logging.dart';
11-
import 'package:yaml/yaml.dart';
128

139
import '../models/skill_params.dart';
1410
import '../services/gemini_service.dart';
11+
import 'base_yaml_command.dart';
1512

16-
/// Base command for skill operations.
17-
abstract class BaseSkillCommand extends Command<void> {
13+
/// Base command for skill operations requiring AI generation.
14+
abstract class BaseSkillCommand extends BaseYamlCommand {
1815
/// Creates a new [BaseSkillCommand].
1916
BaseSkillCommand({
2017
required this.httpClient,
21-
required this.logger,
22-
this.outputDir,
18+
required super.logger,
19+
super.outputDir,
2320
this.environment,
2421
}) {
25-
argParser
26-
..addOption('skill', help: 'Process only the specified skill by name.')
27-
..addOption(
28-
'directory',
29-
abbr: 'd',
30-
help: 'The directory to output/search for skills.',
31-
)
32-
..addOption(
33-
'thinking-budget',
34-
help:
35-
'The token budget for the model to "think". Defaults to ${GeminiService.defaultThinkingBudget} (recommended for technical documentation).',
36-
defaultsTo: GeminiService.defaultThinkingBudget.toString(),
37-
);
22+
argParser.addOption(
23+
'thinking-budget',
24+
help:
25+
'The token budget for the model to "think". Defaults to ${GeminiService.defaultThinkingBudget} (recommended for technical documentation).',
26+
defaultsTo: GeminiService.defaultThinkingBudget.toString(),
27+
);
3828
}
3929

4030
/// The HTTP client used for fetching resources.
4131
final http.Client httpClient;
4232

43-
/// The directory to output or find generated skills.
44-
final Directory? outputDir;
45-
4633
/// Optional override for the environment variables, for testing.
4734
final Map<String, String>? environment;
4835

49-
/// The logger for this command.
50-
final Logger logger;
51-
5236
@override
53-
Future<void> run() async {
54-
final inputFile = argResults!.rest.isNotEmpty
55-
? argResults!.rest.first
56-
: 'resources/flutter_skills.yaml';
57-
58-
final file = File(inputFile);
59-
if (!file.existsSync()) {
60-
logger.severe('Configuration file not found: $inputFile');
61-
return;
62-
}
63-
64-
final yamlContent = file.readAsStringSync();
65-
final yamlList = loadYaml(yamlContent) as YamlList;
66-
final skills = yamlList
67-
.map(
68-
(e) => SkillParams.fromJson(
69-
jsonDecode(jsonEncode(e)) as Map<String, dynamic>,
70-
),
71-
)
72-
.toList();
73-
74-
final skillFilter = argResults?['skill'] as String?;
75-
final targetSkills = skillFilter != null
76-
? skills.where((s) => s.name == skillFilter).toList()
77-
: skills;
78-
79-
if (targetSkills.isEmpty) {
80-
if (skillFilter != null) {
81-
logger.warning('No skill found with name: $skillFilter');
82-
} else {
83-
logger.warning('No skills found in configuration file.');
84-
}
85-
return;
86-
}
87-
37+
Future<void> runWithSkills(
38+
List<SkillParams> skills,
39+
Directory outputDir, {
40+
Directory? configDir,
41+
}) async {
8842
final apiKey = (environment ?? Platform.environment)['GEMINI_API_KEY'];
8943
if (apiKey == null) {
9044
logger.severe('GEMINI_API_KEY environment variable not set.');
9145
return;
9246
}
9347

9448
final gemini = GeminiService(apiKey: apiKey, httpClient: httpClient);
95-
final directoryArg = argResults?['directory'] as String?;
96-
final outDir = directoryArg != null
97-
? Directory(directoryArg)
98-
: (outputDir ?? Directory('../skills'));
9949

10050
int thinkingBudget;
10151
try {
@@ -107,13 +57,13 @@ abstract class BaseSkillCommand extends Command<void> {
10757
return;
10858
}
10959

110-
for (final skill in targetSkills) {
60+
for (final skill in skills) {
11161
await runSkill(
11262
skill,
11363
gemini,
114-
outDir,
64+
outputDir,
11565
thinkingBudget,
116-
configDir: file.parent,
66+
configDir: configDir,
11767
);
11868
}
11969
}

0 commit comments

Comments
 (0)