sdd-full 4.6.1 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/bin.js +1 -1
  2. package/package.json +1 -1
  3. package/skills/.agents/skills/flutter-add-integration-test/SKILL.md +165 -0
  4. package/skills/.agents/skills/flutter-add-widget-preview/SKILL.md +147 -0
  5. package/skills/.agents/skills/flutter-add-widget-test/SKILL.md +156 -0
  6. package/skills/.agents/skills/flutter-apply-architecture-best-practices/SKILL.md +164 -0
  7. package/skills/.agents/skills/flutter-build-responsive-layout/SKILL.md +141 -0
  8. package/skills/.agents/skills/flutter-fix-layout-issues/SKILL.md +132 -0
  9. package/skills/.agents/skills/flutter-implement-json-serialization/SKILL.md +155 -0
  10. package/skills/.agents/skills/flutter-setup-declarative-routing/SKILL.md +257 -0
  11. package/skills/.agents/skills/flutter-setup-localization/SKILL.md +212 -0
  12. package/skills/.agents/skills/flutter-use-http-package/SKILL.md +177 -0
  13. package/skills/VERSION.md +186 -62
  14. package/skills/design-planning/ai-coding-rules/SKILL.md +5 -13
  15. package/skills/design-planning/design-to-code/SKILL.md +5 -14
  16. package/skills/design-planning/enterprise-spec/SKILL.md +5 -13
  17. package/skills/design-planning/flutter-av/SKILL.md +5 -16
  18. package/skills/design-planning/flutter-map/SKILL.md +5 -14
  19. package/skills/design-planning/function-sdd/SKILL.md +5 -13
  20. package/skills/design-planning/global-overlay-stack-standard/SKILL.md +73 -0
  21. package/skills/design-planning/ui-motion-interaction-standard/SKILL.md +69 -0
  22. package/skills/design-planning/ui-sdd-specialized/SKILL.md +5 -14
  23. package/skills/development-execution/flutter-errors/SKILL.md +5 -15
  24. package/skills/flutter-skills/.github/dependabot.yaml +15 -0
  25. package/skills/flutter-skills/.github/workflows/dart_skills_lint_workflow.yaml +68 -0
  26. package/skills/flutter-skills/.github/workflows/skills_tool.yaml +51 -0
  27. package/skills/flutter-skills/CODE_OF_CONDUCT.md +3 -0
  28. package/skills/flutter-skills/CONTRIBUTING.md +36 -0
  29. package/skills/flutter-skills/LICENSE +26 -0
  30. package/skills/flutter-skills/README.md +50 -0
  31. package/skills/flutter-skills/pubspec.yaml +9 -0
  32. package/skills/flutter-skills/resources/flutter_skills.yaml +434 -0
  33. package/skills/flutter-skills/skills/flutter-add-integration-test/SKILL.md +163 -0
  34. package/skills/flutter-skills/skills/flutter-add-widget-preview/SKILL.md +145 -0
  35. package/skills/flutter-skills/skills/flutter-add-widget-test/SKILL.md +154 -0
  36. package/skills/flutter-skills/skills/flutter-apply-architecture-best-practices/SKILL.md +162 -0
  37. package/skills/flutter-skills/skills/flutter-build-responsive-layout/SKILL.md +139 -0
  38. package/skills/flutter-skills/skills/flutter-fix-layout-issues/SKILL.md +130 -0
  39. package/skills/flutter-skills/skills/flutter-implement-json-serialization/SKILL.md +153 -0
  40. package/skills/flutter-skills/skills/flutter-setup-declarative-routing/SKILL.md +255 -0
  41. package/skills/flutter-skills/skills/flutter-setup-localization/SKILL.md +210 -0
  42. package/skills/flutter-skills/skills/flutter-use-http-package/SKILL.md +175 -0
  43. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/add-dart-lint-validation-rule/SKILL.md +196 -0
  44. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-best-practices/SKILL.md +65 -0
  45. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-checks-migration/SKILL.md +158 -0
  46. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-cli-app-best-practices/SKILL.md +168 -0
  47. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-doc-validation/SKILL.md +87 -0
  48. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-long-lines/SKILL.md +101 -0
  49. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-matcher-best-practices/SKILL.md +136 -0
  50. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-modern-features/SKILL.md +266 -0
  51. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-package-maintenance/SKILL.md +92 -0
  52. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/SKILL.md +92 -0
  53. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/lib/src/calculator.dart +7 -0
  54. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/pubspec.yaml +8 -0
  55. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/test/calculator_test.dart +11 -0
  56. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/interpret_coverage.dart +95 -0
  57. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/pubspec.yaml +6 -0
  58. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/test/interpret_coverage_test.dart +93 -0
  59. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-fundamentals/SKILL.md +173 -0
  60. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/definition-of-done/SKILL.md +27 -0
  61. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/flutter_skills_ignore.json +3 -0
  62. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/grill-me/SKILL.md +10 -0
  63. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/ignore.json +3 -0
  64. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/SKILL.md +371 -0
  65. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/testing-anti-patterns.md +299 -0
  66. package/skills/flutter-skills/tool/dart_skills_lint/AUTHORS +7 -0
  67. package/skills/flutter-skills/tool/dart_skills_lint/CHANGELOG.md +12 -0
  68. package/skills/flutter-skills/tool/dart_skills_lint/CONTRIBUTING.md +51 -0
  69. package/skills/flutter-skills/tool/dart_skills_lint/LICENSE +27 -0
  70. package/skills/flutter-skills/tool/dart_skills_lint/README.md +203 -0
  71. package/skills/flutter-skills/tool/dart_skills_lint/analysis_options.yaml +296 -0
  72. package/skills/flutter-skills/tool/dart_skills_lint/bench/README.md +23 -0
  73. package/skills/flutter-skills/tool/dart_skills_lint/bench/baseline_throughput.dart +230 -0
  74. package/skills/flutter-skills/tool/dart_skills_lint/bin/cli.dart +10 -0
  75. package/skills/flutter-skills/tool/dart_skills_lint/dart_skills_lint.yaml +14 -0
  76. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/PRODUCTION_READYNESS.md +48 -0
  77. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/completion_migration_plan.md +99 -0
  78. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/legacy_patterns_report.md +110 -0
  79. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/pub_vs_skill_report.md +56 -0
  80. package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/SPECIFICATION.md +79 -0
  81. package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/architecture_overview.md +64 -0
  82. package/skills/flutter-skills/tool/dart_skills_lint/lib/dart_skills_lint.dart +11 -0
  83. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/config_parser.dart +156 -0
  84. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/entry_point.dart +354 -0
  85. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/fixable_rule.dart +20 -0
  86. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/analysis_severity.dart +15 -0
  87. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/check_type.dart +17 -0
  88. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.dart +34 -0
  89. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.g.dart +19 -0
  90. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_context.dart +27 -0
  91. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_rule.dart +27 -0
  92. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.dart +26 -0
  93. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.g.dart +24 -0
  94. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/validation_error.dart +31 -0
  95. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rule_registry.dart +79 -0
  96. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/absolute_paths_rule.dart +74 -0
  97. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/description_length_rule.dart +49 -0
  98. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/disallowed_field_rule.dart +61 -0
  99. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/name_format_rule.dart +167 -0
  100. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/relative_paths_rule.dart +72 -0
  101. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/trailing_whitespace_rule.dart +93 -0
  102. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/valid_yaml_metadata_rule.dart +74 -0
  103. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/skills_ignores_storage.dart +36 -0
  104. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validation_session.dart +559 -0
  105. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validator.dart +238 -0
  106. package/skills/flutter-skills/tool/dart_skills_lint/pubspec.yaml +28 -0
  107. package/skills/flutter-skills/tool/dart_skills_lint/skills/README.md +10 -0
  108. package/skills/flutter-skills/tool/dart_skills_lint/skills/dart-skills-lint-validation/SKILL.md +195 -0
  109. package/skills/flutter-skills/tool/dart_skills_lint/skills-lock.json +75 -0
  110. package/skills/flutter-skills/tool/dart_skills_lint/test/absolute_paths_test.dart +167 -0
  111. package/skills/flutter-skills/tool/dart_skills_lint/test/cli_integration_test.dart +683 -0
  112. package/skills/flutter-skills/tool/dart_skills_lint/test/config_file_test.dart +292 -0
  113. package/skills/flutter-skills/tool/dart_skills_lint/test/custom_rule_test.dart +122 -0
  114. package/skills/flutter-skills/tool/dart_skills_lint/test/directory_structure_test.dart +163 -0
  115. package/skills/flutter-skills/tool/dart_skills_lint/test/field_constraints_test.dart +178 -0
  116. package/skills/flutter-skills/tool/dart_skills_lint/test/fixer_test.dart +172 -0
  117. package/skills/flutter-skills/tool/dart_skills_lint/test/ignore_models_test.dart +63 -0
  118. package/skills/flutter-skills/tool/dart_skills_lint/test/metadata_validation_test.dart +116 -0
  119. package/skills/flutter-skills/tool/dart_skills_lint/test/relative_path_flag_test.dart +70 -0
  120. package/skills/flutter-skills/tool/dart_skills_lint/test/relative_paths_test.dart +172 -0
  121. package/skills/flutter-skills/tool/dart_skills_lint/test/resolve_rules_test.dart +82 -0
  122. package/skills/flutter-skills/tool/dart_skills_lint/test/rule_naming_test.dart +29 -0
  123. package/skills/flutter-skills/tool/dart_skills_lint/test/skills_ignores_storage_test.dart +89 -0
  124. package/skills/flutter-skills/tool/dart_skills_lint/test/test_utils.dart +19 -0
  125. package/skills/flutter-skills/tool/dart_skills_lint/test/trailing_whitespace_test.dart +152 -0
  126. package/skills/flutter-skills/tool/generator/README.md +150 -0
  127. package/skills/flutter-skills/tool/generator/analysis_options.yaml +143 -0
  128. package/skills/flutter-skills/tool/generator/bin/skills.dart +73 -0
  129. package/skills/flutter-skills/tool/generator/lib/src/commands/base_skill_command.dart +87 -0
  130. package/skills/flutter-skills/tool/generator/lib/src/commands/base_yaml_command.dart +83 -0
  131. package/skills/flutter-skills/tool/generator/lib/src/commands/generate_skill_command.dart +92 -0
  132. package/skills/flutter-skills/tool/generator/lib/src/commands/update_readme_command.dart +150 -0
  133. package/skills/flutter-skills/tool/generator/lib/src/commands/update_skill_command.dart +97 -0
  134. package/skills/flutter-skills/tool/generator/lib/src/commands/validate_skill_command.dart +284 -0
  135. package/skills/flutter-skills/tool/generator/lib/src/models/skill_params.dart +41 -0
  136. package/skills/flutter-skills/tool/generator/lib/src/services/gemini_service.dart +310 -0
  137. package/skills/flutter-skills/tool/generator/lib/src/services/markdown_converter.dart +226 -0
  138. package/skills/flutter-skills/tool/generator/lib/src/services/prompts.dart +72 -0
  139. package/skills/flutter-skills/tool/generator/lib/src/services/resource_fetcher_service.dart +84 -0
  140. package/skills/flutter-skills/tool/generator/lib/src/services/skill_instructions.dart +30 -0
  141. package/skills/flutter-skills/tool/generator/pubspec.yaml +32 -0
  142. package/skills/flutter-skills/tool/generator/test/commands/base_skill_command_test.dart +131 -0
  143. package/skills/flutter-skills/tool/generator/test/commands/validate_skills_input_test.dart +263 -0
  144. package/skills/flutter-skills/tool/generator/test/custom_skill_rules/last_modified_rule.dart +32 -0
  145. package/skills/flutter-skills/tool/generator/test/generate_skills_retry_test.dart +105 -0
  146. package/skills/flutter-skills/tool/generator/test/generate_skills_test.dart +519 -0
  147. package/skills/flutter-skills/tool/generator/test/lint_skills_test.dart +34 -0
  148. package/skills/flutter-skills/tool/generator/test/markdown_converter_test.dart +103 -0
  149. package/skills/flutter-skills/tool/generator/test/markdown_table_test.dart +131 -0
  150. package/skills/flutter-skills/tool/generator/test/models/skill_params_test.dart +37 -0
  151. package/skills/flutter-skills/tool/generator/test/services/gemini_service_test.dart +291 -0
  152. package/skills/flutter-skills/tool/generator/test/services/markdown_converter_test.dart +156 -0
  153. package/skills/flutter-skills/tool/generator/test/services/resource_fetcher_service_test.dart +188 -0
  154. package/skills/flutter-skills/tool/generator/test/update_skills_test.dart +241 -0
  155. package/skills/flutter-skills/tool/generator/test/validate_skills_test.dart +728 -0
  156. package/skills/quality-assurance/bdd-acceptance/SKILL.md +5 -14
  157. package/skills/quality-assurance/flutter-test/SKILL.md +5 -16
  158. package/skills/rules/project_rules.md +538 -127
  159. package/skills/special-tools/env-check/SKILL.md +5 -13
  160. package/skills/special-tools/ios-full-auto-debug/SKILL.md +5 -15
  161. package/skills/writing-skills/SKILL.md +654 -0
  162. package/skills/writing-skills/anthropic-best-practices.md +1149 -0
  163. package/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  164. package/skills/writing-skills/graphviz-conventions.dot +172 -0
  165. package/skills/writing-skills/persuasion-principles.md +187 -0
  166. package/skills/writing-skills/render-graphs.js +168 -0
  167. package/skills/writing-skills/testing-skills-with-subagents.md +384 -0
  168. package/skills/checklist.md +0 -154
  169. package/skills/rules/user_rules.md +0 -263
  170. package/skills//345/256/214/346/225/264/345/274/200/345/217/221/346/265/201/347/250/213/346/211/213/345/206/214.md +0 -454
  171. package/skills//346/212/200/350/203/275/344/275/223/347/263/273/345/256/214/345/226/204/345/273/272/350/256/256.md +0 -308
  172. package/skills//346/212/200/350/203/275/344/275/277/347/224/250/346/214/207/345/215/227.md +0 -309
  173. package/skills//346/212/200/350/203/275/345/206/263/347/255/226/346/240/221.md +0 -338
@@ -0,0 +1,150 @@
1
+ # Skills CLI
2
+
3
+ The Skills CLI simplifies the process of creating "Agent Skills" from external documentation. It allows you to crawl documentation websites to discover relevant pages and then uses Generative AI (Gemini) to convert those pages into structured `SKILL.md` files that agents can use.
4
+
5
+ ## Context
6
+
7
+ * [Agent Skills Best Practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices)
8
+
9
+ ## Prerequisite
10
+
11
+ This tool requires the `GEMINI_API_KEY` environment variable to be set.
12
+
13
+ ## Commands
14
+
15
+ > [!NOTE]
16
+ > To use the default configuration file path (`resources/flutter_skills.yaml`), commands should be run from the root of the repository as: `dart run tool/generator/bin/skills.dart <command>`.
17
+ > Alternatively, if running from this directory, specify the path to the configuration file explicitly (e.g., `../../resources/flutter_skills.yaml`).
18
+
19
+ ### `generate-skill`
20
+
21
+ Generates `SKILL.md` files from a YAML configuration file. Use the `--skill` option to generate a specific skill.
22
+
23
+ **Usage:**
24
+ ```bash
25
+ dart run skills generate-skill [options] [config_file]
26
+ ```
27
+
28
+ **Arguments:**
29
+ * `[config_file]`: Path to the YAML configuration file. Defaults to `resources/flutter_skills.yaml`.
30
+
31
+ **Options:**
32
+ * `--skill`: Filter to generate only the specified skill by name.
33
+ * `--directory` (`-d`): The directory to output the generated skill folder. Defaults to `../skills/`.
34
+ * `--dry-run`: Performs a dry run, showing what would be generated and token count without writing files.
35
+
36
+ **Example:**
37
+ Generate all skills defined in resources/flutter_skills.yaml to the skills/ directory:
38
+
39
+ ```bash
40
+ dart run skills generate-skill
41
+ ```
42
+
43
+ Generate only the 'flutter-layout' skill to a custom directory:
44
+
45
+ ```bash
46
+ dart run skills generate-skill --skill flutter-layout --directory ../skills
47
+ ```
48
+
49
+ ### `update-skill`
50
+
51
+ Updates an existing skill by combining its current content with fetched resources and new instructions.
52
+
53
+ **Usage:**
54
+ ```bash
55
+ dart run skills update-skill [options] [config_file]
56
+ ```
57
+
58
+ **Arguments:**
59
+ * `[config_file]`: Path to the YAML configuration file. Defaults to `resources/flutter_skills.yaml`.
60
+
61
+ **Options:**
62
+ * `--skill`: Filter to update only the specified skill by name.
63
+ * `--directory` (`-d`): The directory to search for skills. Defaults to `../skills/`.
64
+ * `--thinking-budget`: The token budget for the model to "think" before generating content. Defaults to 2048.
65
+
66
+ **Example:**
67
+ Update all skills defined in resources/flutter_skills.yaml:
68
+
69
+ ```bash
70
+ dart run skills update-skill
71
+ ```
72
+
73
+ Update only the 'flutter-layout' skill:
74
+
75
+ ```bash
76
+ dart run skills update-skill --skill flutter-layout
77
+ ```
78
+
79
+ ### `validate-skill`
80
+
81
+ Validates skills by re-generating and comparing with existing skills. This is useful for testing prompts or verifying consistency.
82
+
83
+ **Usage:**
84
+ ```bash
85
+ dart run skills validate-skill [options] [config_file]
86
+ ```
87
+
88
+ **Arguments:**
89
+ * `[config_file]`: Path to the YAML configuration file. Defaults to `resources/flutter_skills.yaml`.
90
+
91
+ **Options:**
92
+ * `--skill`: Validate only the specified skill by name.
93
+ * `--directory` (`-d`): The directory containing the generated skills to validate. Defaults to `../skills/`.
94
+ * `--thinking-budget`: The token budget for the model to "think" before generating content. Defaults to 2048.
95
+
96
+ **Example:**
97
+ Validate skills in the default 'skills' directory:
98
+
99
+ ```bash
100
+ dart run skills validate-skill
101
+ ```
102
+
103
+ Validate skills in a custom directory:
104
+
105
+ ```bash
106
+ dart run skills validate-skill --directory ../validation_results
107
+ ```
108
+
109
+ ### `update-readme`
110
+
111
+ Updates the `README.md` file with a table of available skills.
112
+
113
+ **Usage:**
114
+ ```bash
115
+ dart run skills update-readme [config_file] [readme_file]
116
+ ```
117
+
118
+ **Arguments:**
119
+ * `[config_file]`: Path to the YAML configuration file. Defaults to `resources/flutter_skills.yaml`.
120
+ * `[readme_file]`: Path to the README.md file to update. Defaults to `../README.md`.
121
+
122
+ **Example:**
123
+ Update the root README.md:
124
+
125
+ ```bash
126
+ dart run skills update-readme
127
+ ```
128
+
129
+ ## Configuration
130
+
131
+ The default configuration file is located at `resources/flutter_skills.yaml`. It contains a list of skill definitions:
132
+
133
+ ```yaml
134
+ - name: flutter-layout
135
+ description: "..."
136
+ resources:
137
+ - https://docs.flutter.dev/ui/widgets/layout
138
+ - https://docs.flutter.dev/ui/layout
139
+ - ../packages/flutter/lib/src/widgets/layout.md
140
+ ```
141
+
142
+ ## Development
143
+
144
+ To run analysis, formatting, and tests, navigate to this directory (`tool/generator`) and run:
145
+
146
+ ```bash
147
+ dart analyze
148
+ dart format .
149
+ dart test
150
+ ```
@@ -0,0 +1,143 @@
1
+ # This file configures the static analysis results for your project (errors,
2
+ # warnings, and lints).
3
+ #
4
+ # This enables the 'recommended' set of lints from `package:lints`.
5
+ # This set helps identify many issues that may lead to problems when running
6
+ # or consuming Dart code, and enforces writing Dart using a single, idiomatic
7
+ # style and format.
8
+ #
9
+ # If you want a smaller set of lints you can change this to specify
10
+ # 'package:lints/core.yaml'. These are just the most critical lints
11
+ # (the recommended set includes the core lints).
12
+ # The core lints are also what is used by pub.dev for scoring packages.
13
+
14
+ include: package:lints/recommended.yaml
15
+
16
+ linter:
17
+ # The lint rules applied to this project can be customized in the
18
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
19
+ # included above or to enable additional rules. A list of all available lints
20
+ # and their documentation is published at https://dart.dev/lints.
21
+ #
22
+ # Instead of disabling a lint rule for the entire project in the
23
+ # section below, it can also be suppressed for a single line of code
24
+ # or a specific dart file by using the `// ignore: name_of_lint` and
25
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
26
+ # producing the lint.
27
+ rules:
28
+ # Error Prevention
29
+ unnecessary_statements: true
30
+ no_self_assignments: true
31
+ avoid_catches_without_on_clauses: true
32
+ avoid_catching_errors: true
33
+ avoid_returning_this: true
34
+ avoid_void_async: true
35
+ await_only_futures: true
36
+ cancel_subscriptions: true
37
+ close_sinks: true
38
+ discarded_futures: true
39
+ literal_only_boolean_expressions: true
40
+ no_adjacent_strings_in_list: true
41
+ no_logic_in_create_state: true
42
+ only_throw_errors: true
43
+ prefer_is_empty: true
44
+ prefer_is_not_empty: true
45
+ test_types_in_equals: true
46
+ throw_in_finally: true
47
+ unawaited_futures: true
48
+ unnecessary_null_aware_assignments: true
49
+ unnecessary_null_in_if_null_operators: true
50
+ unnecessary_nullable_for_final_variable_declarations: true
51
+ use_build_context_synchronously: true
52
+ use_rethrow_when_possible: true
53
+
54
+ # Style & Formatting
55
+ always_declare_return_types: true
56
+ always_put_required_named_parameters_first: true
57
+ avoid_escaping_inner_quotes: true
58
+ avoid_function_literals_in_foreach_calls: true
59
+ avoid_init_to_null: true
60
+ avoid_multiple_declarations_per_line: true
61
+ avoid_positional_boolean_parameters: true
62
+ avoid_private_typedef_functions: true
63
+ avoid_redundant_argument_values: true
64
+ avoid_renaming_method_parameters: true
65
+ avoid_shadowing_type_parameters: true
66
+ avoid_types_on_closure_parameters: true
67
+ avoid_unused_constructor_parameters: true
68
+ camel_case_extensions: true
69
+ cascade_invocations: true
70
+ curly_braces_in_flow_control_structures: true
71
+ directives_ordering: true
72
+ eol_at_end_of_file: true
73
+ file_names: true
74
+ library_names: true
75
+ no_leading_underscores_for_library_prefixes: true
76
+ no_leading_underscores_for_local_identifiers: true
77
+ omit_local_variable_types: true
78
+ prefer_const_constructors: true
79
+ prefer_const_constructors_in_immutables: true
80
+ prefer_const_declarations: true
81
+ prefer_const_literals_to_create_immutables: true
82
+ prefer_final_fields: true
83
+ prefer_final_in_for_each: true
84
+ prefer_final_locals: true
85
+ prefer_if_elements_to_conditional_expressions: true
86
+ prefer_interpolation_to_compose_strings: true
87
+ prefer_mixin: true
88
+ prefer_relative_imports: true
89
+ prefer_single_quotes: true
90
+ require_trailing_commas: true
91
+ sized_box_for_whitespace: true
92
+ sort_child_properties_last: true
93
+ sort_constructors_first: true
94
+ sort_unnamed_constructors_first: true
95
+ type_init_formals: true
96
+ unnecessary_await_in_return: true
97
+ unnecessary_breaks: true
98
+ unnecessary_const: true
99
+ unnecessary_constructor_name: true
100
+ unnecessary_lambdas: true
101
+ unnecessary_late: true
102
+ unnecessary_new: true
103
+ unnecessary_parenthesis: true
104
+ unnecessary_raw_strings: true
105
+ unnecessary_string_escapes: true
106
+ unnecessary_string_interpolations: true
107
+ unnecessary_this: true
108
+ use_function_type_syntax_for_parameters: true
109
+ use_if_null_to_convert_nulls_to_bools: true
110
+ use_string_buffers: true
111
+ use_to_and_as_if_applicable: true
112
+
113
+ # Best Practices
114
+ annotate_redeclares: true
115
+ avoid_annotating_with_dynamic: true
116
+ avoid_bool_literals_in_conditional_expressions: true
117
+ avoid_classes_with_only_static_members: true
118
+ avoid_print: true
119
+ avoid_setters_without_getters: true
120
+ depend_on_referenced_packages: true
121
+ deprecated_consistency: true
122
+ library_private_types_in_public_api: true
123
+ prefer_asserts_in_initializer_lists: true
124
+ prefer_constructors_over_static_methods: true
125
+ secure_pubspec_urls: true
126
+ sort_pub_dependencies: true
127
+ unnecessary_to_list_in_spreads: true
128
+ use_super_parameters: true
129
+ annotate_overrides: true
130
+
131
+ # Documentation
132
+ dangling_library_doc_comments: true
133
+ library_annotations: true
134
+ public_member_api_docs: true
135
+
136
+ analyzer:
137
+ language:
138
+ strict-casts: true
139
+ strict-inference: true
140
+ strict-raw-types: true
141
+
142
+ # Additional information about this file can be found at
143
+ # https://dart.dev/guides/language/analysis-options
@@ -0,0 +1,73 @@
1
+ // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
2
+ // for details. All rights reserved. Use of this source code is governed by a
3
+ // BSD-style license that can be found in the LICENSE file.
4
+
5
+ import 'dart:io';
6
+
7
+ import 'package:args/command_runner.dart';
8
+ import 'package:http/http.dart' as http;
9
+ import 'package:logging/logging.dart';
10
+ import 'package:skills/src/commands/generate_skill_command.dart';
11
+ import 'package:skills/src/commands/update_readme_command.dart';
12
+ import 'package:skills/src/commands/update_skill_command.dart';
13
+ import 'package:skills/src/commands/validate_skill_command.dart';
14
+
15
+ const String version = '0.1.0';
16
+
17
+ void main(List<String> arguments) async {
18
+ final httpClient = http.Client();
19
+
20
+ final runner =
21
+ CommandRunner<void>('skills', 'A sample command-line application.')
22
+ ..addCommand(GenerateSkillCommand(httpClient: httpClient))
23
+ ..addCommand(UpdateSkillCommand(httpClient: httpClient))
24
+ ..addCommand(ValidateSkillCommand(httpClient: httpClient))
25
+ ..addCommand(UpdateReadmeCommand());
26
+
27
+ runner.argParser.addFlag(
28
+ 'version',
29
+ negatable: false,
30
+ help: 'Print the tool version.',
31
+ );
32
+ runner.argParser.addFlag(
33
+ 'verbose',
34
+ abbr: 'v',
35
+ negatable: false,
36
+ help: 'Show additional command output.',
37
+ );
38
+
39
+ try {
40
+ final results = runner.parse(arguments);
41
+ if (results.flag('version')) {
42
+ stdout.writeln('skills version: $version');
43
+ return;
44
+ }
45
+
46
+ _configureLogging(results.flag('verbose'));
47
+
48
+ if (results.flag('verbose')) {
49
+ Logger.root.fine('All arguments: ${results.arguments}');
50
+ }
51
+
52
+ await runner.run(arguments);
53
+ } on UsageException catch (e) {
54
+ stderr.writeln(e);
55
+ exit(64);
56
+ } on Exception catch (e) {
57
+ stderr.writeln('An error occurred: $e');
58
+ exit(1);
59
+ } finally {
60
+ httpClient.close();
61
+ }
62
+ }
63
+
64
+ void _configureLogging(bool verbose) {
65
+ Logger.root.level = verbose ? Level.ALL : Level.INFO;
66
+ Logger.root.onRecord.listen((record) {
67
+ if (record.level >= Level.SEVERE) {
68
+ stderr.writeln(record.message);
69
+ } else {
70
+ stdout.writeln(record.message);
71
+ }
72
+ });
73
+ }
@@ -0,0 +1,87 @@
1
+ // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
2
+ // for details. All rights reserved. Use of this source code is governed by a
3
+ // BSD-style license that can be found in the LICENSE file.
4
+
5
+ import 'dart:io';
6
+
7
+ import 'package:http/http.dart' as http;
8
+
9
+ import '../models/skill_params.dart';
10
+ import '../services/gemini_service.dart';
11
+ import 'base_yaml_command.dart';
12
+
13
+ /// Base command for skill operations requiring AI generation.
14
+ abstract class BaseSkillCommand extends BaseYamlCommand {
15
+ /// Creates a new [BaseSkillCommand].
16
+ BaseSkillCommand({
17
+ required this.httpClient,
18
+ required super.logger,
19
+ super.outputDir,
20
+ this.environment,
21
+ }) {
22
+ argParser
23
+ ..addOption(
24
+ 'thinking-budget',
25
+ help:
26
+ 'The token budget for the model to "think". Defaults to ${GeminiService.defaultThinkingBudget} (recommended for technical documentation).',
27
+ defaultsTo: GeminiService.defaultThinkingBudget.toString(),
28
+ )
29
+ ..addFlag(
30
+ 'dry-run',
31
+ abbr: 'n',
32
+ help:
33
+ 'Simulate the command without making API calls or modifying files.',
34
+ negatable: false,
35
+ );
36
+ }
37
+
38
+ /// The HTTP client used for fetching resources.
39
+ final http.Client httpClient;
40
+
41
+ /// Optional override for the environment variables, for testing.
42
+ final Map<String, String>? environment;
43
+
44
+ @override
45
+ Future<void> runWithSkills(
46
+ List<SkillParams> skills,
47
+ Directory outputDir, {
48
+ Directory? configDir,
49
+ }) async {
50
+ final apiKey = (environment ?? Platform.environment)['GEMINI_API_KEY'];
51
+ if (apiKey == null) {
52
+ logger.severe('GEMINI_API_KEY environment variable not set.');
53
+ return;
54
+ }
55
+
56
+ final gemini = GeminiService(apiKey: apiKey, httpClient: httpClient);
57
+
58
+ int thinkingBudget;
59
+ try {
60
+ thinkingBudget = int.parse(argResults!['thinking-budget'] as String);
61
+ } on FormatException {
62
+ logger.warning(
63
+ 'Invalid thinking-budget: ${argResults!['thinking-budget']}. Skipping.',
64
+ );
65
+ return;
66
+ }
67
+
68
+ for (final skill in skills) {
69
+ await runSkill(
70
+ skill,
71
+ gemini,
72
+ outputDir,
73
+ thinkingBudget,
74
+ configDir: configDir,
75
+ );
76
+ }
77
+ }
78
+
79
+ /// Executes the command for a specific skill.
80
+ Future<void> runSkill(
81
+ SkillParams skill,
82
+ GeminiService gemini,
83
+ Directory outputDir,
84
+ int thinkingBudget, {
85
+ Directory? configDir,
86
+ });
87
+ }
@@ -0,0 +1,83 @@
1
+ // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
2
+ // for details. All rights reserved. Use of this source code is governed by a
3
+ // BSD-style license that can be found in the LICENSE file.
4
+
5
+ import 'dart:convert';
6
+ import 'dart:io';
7
+
8
+ import 'package:args/command_runner.dart';
9
+ import 'package:logging/logging.dart';
10
+ import 'package:yaml/yaml.dart';
11
+
12
+ import '../models/skill_params.dart';
13
+
14
+ /// Base command for operations that read skills from a YAML file.
15
+ abstract class BaseYamlCommand extends Command<void> {
16
+ /// Creates a new [BaseYamlCommand].
17
+ BaseYamlCommand({required this.logger, this.outputDir}) {
18
+ argParser
19
+ ..addOption('skill', help: 'Process only the specified skill by name.')
20
+ ..addOption(
21
+ 'directory',
22
+ abbr: 'd',
23
+ help: 'The directory to search for skills.',
24
+ );
25
+ }
26
+
27
+ /// The logger for this command.
28
+ final Logger logger;
29
+
30
+ /// The directory to find generated skills.
31
+ final Directory? outputDir;
32
+
33
+ @override
34
+ Future<void> run() async {
35
+ final inputFile = argResults!.rest.isNotEmpty
36
+ ? argResults!.rest.first
37
+ : 'resources/flutter_skills.yaml';
38
+
39
+ final file = File(inputFile);
40
+ if (!file.existsSync()) {
41
+ logger.severe('Configuration file not found: $inputFile');
42
+ return;
43
+ }
44
+
45
+ final yamlContent = file.readAsStringSync();
46
+ final yamlList = loadYaml(yamlContent) as YamlList;
47
+ final skills = yamlList
48
+ .map(
49
+ (e) => SkillParams.fromJson(
50
+ jsonDecode(jsonEncode(e)) as Map<String, dynamic>,
51
+ ),
52
+ )
53
+ .toList();
54
+
55
+ final skillFilter = argResults?['skill'] as String?;
56
+ final targetSkills = skillFilter != null
57
+ ? skills.where((s) => s.name == skillFilter).toList()
58
+ : skills;
59
+
60
+ if (targetSkills.isEmpty) {
61
+ if (skillFilter != null) {
62
+ logger.warning('No skill found with name: $skillFilter');
63
+ } else {
64
+ logger.warning('No skills found in configuration file.');
65
+ }
66
+ return;
67
+ }
68
+
69
+ final directoryArg = argResults?['directory'] as String?;
70
+ final outDir = directoryArg != null
71
+ ? Directory(directoryArg)
72
+ : (outputDir ?? Directory('skills'));
73
+
74
+ await runWithSkills(targetSkills, outDir, configDir: file.parent);
75
+ }
76
+
77
+ /// Executes the command with the parsed and filtered list of skills.
78
+ Future<void> runWithSkills(
79
+ List<SkillParams> skills,
80
+ Directory outputDir, {
81
+ Directory? configDir,
82
+ });
83
+ }
@@ -0,0 +1,92 @@
1
+ // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
2
+ // for details. All rights reserved. Use of this source code is governed by a
3
+ // BSD-style license that can be found in the LICENSE file.
4
+
5
+ import 'dart:io';
6
+
7
+ import 'package:logging/logging.dart';
8
+ import 'package:path/path.dart' as p;
9
+
10
+ import '../models/skill_params.dart';
11
+ import '../services/gemini_service.dart';
12
+ import '../services/resource_fetcher_service.dart';
13
+ import 'base_skill_command.dart';
14
+
15
+ /// Command to generate skills from a configuration file.
16
+ class GenerateSkillCommand extends BaseSkillCommand {
17
+ /// Creates a new [GenerateSkillCommand].
18
+ GenerateSkillCommand({
19
+ required super.httpClient,
20
+ super.outputDir,
21
+ super.environment,
22
+ }) : super(logger: Logger('GenerateSkillCommand'));
23
+
24
+ @override
25
+ String get name => 'generate-skill';
26
+
27
+ @override
28
+ String get description => 'Generates skills from using yaml configuration.';
29
+
30
+ @override
31
+ Future<void> runSkill(
32
+ SkillParams skill,
33
+ GeminiService gemini,
34
+ Directory outputDir,
35
+ int thinkingBudget, {
36
+ Directory? configDir,
37
+ }) async {
38
+ logger.info('Generating skill: ${skill.name}...');
39
+
40
+ try {
41
+ final fetcher = ResourceFetcherService(
42
+ httpClient: httpClient,
43
+ logger: logger,
44
+ );
45
+ final combinedMarkdown = await fetcher.fetchAndConvertContent(
46
+ skill.resources,
47
+ configDir: configDir,
48
+ );
49
+
50
+ if (combinedMarkdown.isEmpty) {
51
+ logger.warning(' No content fetched for ${skill.name}. Skipping.');
52
+ return;
53
+ }
54
+
55
+ final dryRun = argResults?['dry-run'] as bool? ?? false;
56
+ if (dryRun) {
57
+ logger
58
+ ..info(' [DRY RUN] Would generate skill: ${skill.name}')
59
+ ..info(
60
+ ' [DRY RUN] Prompt size: ${combinedMarkdown.split(' ').length} tokens.',
61
+ );
62
+ return;
63
+ }
64
+
65
+ final generatedContent = await gemini.generateSkillContent(
66
+ combinedMarkdown,
67
+ skill.name,
68
+ skill.description,
69
+ instructions: skill.instructions,
70
+ thinkingBudget: thinkingBudget,
71
+ );
72
+
73
+ if (generatedContent != null && generatedContent.isNotEmpty) {
74
+ final skillDir = Directory(p.join(outputDir.path, skill.name));
75
+ if (!skillDir.existsSync()) {
76
+ skillDir.createSync(recursive: true);
77
+ }
78
+
79
+ File(
80
+ p.join(skillDir.path, 'SKILL.md'),
81
+ ).writeAsStringSync(generatedContent);
82
+ logger.info(
83
+ ' Generated ${p.join(outputDir.path, skill.name, 'SKILL.md')}',
84
+ );
85
+ } else {
86
+ logger.severe(' Failed to generate content for ${skill.name}');
87
+ }
88
+ } on Exception catch (e) {
89
+ logger.severe(' Error processing ${skill.name}: $e');
90
+ }
91
+ }
92
+ }