sdd-full 4.8.0 → 4.8.1

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 (163) hide show
  1. package/bin.js +1 -1
  2. package/index.js +18 -12
  3. package/package.json +1 -1
  4. package/skills/VERSION.md +61 -175
  5. package/skills/design-planning/ai-coding-rules/SKILL.md +13 -5
  6. package/skills/design-planning/design-to-code/SKILL.md +14 -5
  7. package/skills/design-planning/enterprise-spec/SKILL.md +13 -5
  8. package/skills/design-planning/flutter-av/SKILL.md +16 -5
  9. package/skills/design-planning/flutter-map/SKILL.md +14 -5
  10. package/skills/design-planning/function-sdd/SKILL.md +13 -5
  11. package/skills/design-planning/global-overlay-stack-standard/SKILL.md +14 -4
  12. package/skills/design-planning/ui-motion-interaction-standard/SKILL.md +14 -4
  13. package/skills/design-planning/ui-sdd-specialized/SKILL.md +14 -5
  14. package/skills/development-execution/flutter-errors/SKILL.md +15 -5
  15. package/skills/quality-assurance/bdd-acceptance/SKILL.md +14 -5
  16. package/skills/quality-assurance/flutter-test/SKILL.md +16 -5
  17. package/skills/requirement-analysis/sdd/mock_sdd.md +156 -0
  18. package/skills/rules/project_rules.md +127 -538
  19. package/skills/rules/user_rules.md +263 -0
  20. package/skills/special-tools/env-check/SKILL.md +13 -5
  21. package/skills/special-tools/ios-full-auto-debug/SKILL.md +15 -5
  22. package/skills/flutter-skills/.github/dependabot.yaml +0 -15
  23. package/skills/flutter-skills/.github/workflows/dart_skills_lint_workflow.yaml +0 -68
  24. package/skills/flutter-skills/.github/workflows/skills_tool.yaml +0 -51
  25. package/skills/flutter-skills/CODE_OF_CONDUCT.md +0 -3
  26. package/skills/flutter-skills/CONTRIBUTING.md +0 -36
  27. package/skills/flutter-skills/LICENSE +0 -26
  28. package/skills/flutter-skills/README.md +0 -50
  29. package/skills/flutter-skills/pubspec.yaml +0 -9
  30. package/skills/flutter-skills/resources/flutter_skills.yaml +0 -434
  31. package/skills/flutter-skills/skills/flutter-add-integration-test/SKILL.md +0 -163
  32. package/skills/flutter-skills/skills/flutter-add-widget-preview/SKILL.md +0 -145
  33. package/skills/flutter-skills/skills/flutter-add-widget-test/SKILL.md +0 -154
  34. package/skills/flutter-skills/skills/flutter-apply-architecture-best-practices/SKILL.md +0 -162
  35. package/skills/flutter-skills/skills/flutter-build-responsive-layout/SKILL.md +0 -139
  36. package/skills/flutter-skills/skills/flutter-fix-layout-issues/SKILL.md +0 -130
  37. package/skills/flutter-skills/skills/flutter-implement-json-serialization/SKILL.md +0 -153
  38. package/skills/flutter-skills/skills/flutter-setup-declarative-routing/SKILL.md +0 -255
  39. package/skills/flutter-skills/skills/flutter-setup-localization/SKILL.md +0 -210
  40. package/skills/flutter-skills/skills/flutter-use-http-package/SKILL.md +0 -175
  41. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/add-dart-lint-validation-rule/SKILL.md +0 -196
  42. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-best-practices/SKILL.md +0 -65
  43. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-checks-migration/SKILL.md +0 -158
  44. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-cli-app-best-practices/SKILL.md +0 -168
  45. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-doc-validation/SKILL.md +0 -87
  46. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-long-lines/SKILL.md +0 -101
  47. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-matcher-best-practices/SKILL.md +0 -136
  48. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-modern-features/SKILL.md +0 -266
  49. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-package-maintenance/SKILL.md +0 -92
  50. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/SKILL.md +0 -92
  51. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/lib/src/calculator.dart +0 -7
  52. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/pubspec.yaml +0 -8
  53. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/test/calculator_test.dart +0 -11
  54. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/interpret_coverage.dart +0 -95
  55. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/pubspec.yaml +0 -6
  56. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/test/interpret_coverage_test.dart +0 -93
  57. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-fundamentals/SKILL.md +0 -173
  58. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/definition-of-done/SKILL.md +0 -27
  59. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/flutter_skills_ignore.json +0 -3
  60. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/grill-me/SKILL.md +0 -10
  61. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/ignore.json +0 -3
  62. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/SKILL.md +0 -371
  63. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/testing-anti-patterns.md +0 -299
  64. package/skills/flutter-skills/tool/dart_skills_lint/AUTHORS +0 -7
  65. package/skills/flutter-skills/tool/dart_skills_lint/CHANGELOG.md +0 -12
  66. package/skills/flutter-skills/tool/dart_skills_lint/CONTRIBUTING.md +0 -51
  67. package/skills/flutter-skills/tool/dart_skills_lint/LICENSE +0 -27
  68. package/skills/flutter-skills/tool/dart_skills_lint/README.md +0 -203
  69. package/skills/flutter-skills/tool/dart_skills_lint/analysis_options.yaml +0 -296
  70. package/skills/flutter-skills/tool/dart_skills_lint/bench/README.md +0 -23
  71. package/skills/flutter-skills/tool/dart_skills_lint/bench/baseline_throughput.dart +0 -230
  72. package/skills/flutter-skills/tool/dart_skills_lint/bin/cli.dart +0 -10
  73. package/skills/flutter-skills/tool/dart_skills_lint/dart_skills_lint.yaml +0 -14
  74. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/PRODUCTION_READYNESS.md +0 -48
  75. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/completion_migration_plan.md +0 -99
  76. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/legacy_patterns_report.md +0 -110
  77. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/pub_vs_skill_report.md +0 -56
  78. package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/SPECIFICATION.md +0 -79
  79. package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/architecture_overview.md +0 -64
  80. package/skills/flutter-skills/tool/dart_skills_lint/lib/dart_skills_lint.dart +0 -11
  81. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/config_parser.dart +0 -156
  82. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/entry_point.dart +0 -354
  83. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/fixable_rule.dart +0 -20
  84. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/analysis_severity.dart +0 -15
  85. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/check_type.dart +0 -17
  86. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.dart +0 -34
  87. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.g.dart +0 -19
  88. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_context.dart +0 -27
  89. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_rule.dart +0 -27
  90. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.dart +0 -26
  91. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.g.dart +0 -24
  92. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/validation_error.dart +0 -31
  93. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rule_registry.dart +0 -79
  94. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/absolute_paths_rule.dart +0 -74
  95. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/description_length_rule.dart +0 -49
  96. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/disallowed_field_rule.dart +0 -61
  97. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/name_format_rule.dart +0 -167
  98. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/relative_paths_rule.dart +0 -72
  99. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/trailing_whitespace_rule.dart +0 -93
  100. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/valid_yaml_metadata_rule.dart +0 -74
  101. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/skills_ignores_storage.dart +0 -36
  102. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validation_session.dart +0 -559
  103. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validator.dart +0 -238
  104. package/skills/flutter-skills/tool/dart_skills_lint/pubspec.yaml +0 -28
  105. package/skills/flutter-skills/tool/dart_skills_lint/skills/README.md +0 -10
  106. package/skills/flutter-skills/tool/dart_skills_lint/skills/dart-skills-lint-validation/SKILL.md +0 -195
  107. package/skills/flutter-skills/tool/dart_skills_lint/skills-lock.json +0 -75
  108. package/skills/flutter-skills/tool/dart_skills_lint/test/absolute_paths_test.dart +0 -167
  109. package/skills/flutter-skills/tool/dart_skills_lint/test/cli_integration_test.dart +0 -683
  110. package/skills/flutter-skills/tool/dart_skills_lint/test/config_file_test.dart +0 -292
  111. package/skills/flutter-skills/tool/dart_skills_lint/test/custom_rule_test.dart +0 -122
  112. package/skills/flutter-skills/tool/dart_skills_lint/test/directory_structure_test.dart +0 -163
  113. package/skills/flutter-skills/tool/dart_skills_lint/test/field_constraints_test.dart +0 -178
  114. package/skills/flutter-skills/tool/dart_skills_lint/test/fixer_test.dart +0 -172
  115. package/skills/flutter-skills/tool/dart_skills_lint/test/ignore_models_test.dart +0 -63
  116. package/skills/flutter-skills/tool/dart_skills_lint/test/metadata_validation_test.dart +0 -116
  117. package/skills/flutter-skills/tool/dart_skills_lint/test/relative_path_flag_test.dart +0 -70
  118. package/skills/flutter-skills/tool/dart_skills_lint/test/relative_paths_test.dart +0 -172
  119. package/skills/flutter-skills/tool/dart_skills_lint/test/resolve_rules_test.dart +0 -82
  120. package/skills/flutter-skills/tool/dart_skills_lint/test/rule_naming_test.dart +0 -29
  121. package/skills/flutter-skills/tool/dart_skills_lint/test/skills_ignores_storage_test.dart +0 -89
  122. package/skills/flutter-skills/tool/dart_skills_lint/test/test_utils.dart +0 -19
  123. package/skills/flutter-skills/tool/dart_skills_lint/test/trailing_whitespace_test.dart +0 -152
  124. package/skills/flutter-skills/tool/generator/README.md +0 -150
  125. package/skills/flutter-skills/tool/generator/analysis_options.yaml +0 -143
  126. package/skills/flutter-skills/tool/generator/bin/skills.dart +0 -73
  127. package/skills/flutter-skills/tool/generator/lib/src/commands/base_skill_command.dart +0 -87
  128. package/skills/flutter-skills/tool/generator/lib/src/commands/base_yaml_command.dart +0 -83
  129. package/skills/flutter-skills/tool/generator/lib/src/commands/generate_skill_command.dart +0 -92
  130. package/skills/flutter-skills/tool/generator/lib/src/commands/update_readme_command.dart +0 -150
  131. package/skills/flutter-skills/tool/generator/lib/src/commands/update_skill_command.dart +0 -97
  132. package/skills/flutter-skills/tool/generator/lib/src/commands/validate_skill_command.dart +0 -284
  133. package/skills/flutter-skills/tool/generator/lib/src/models/skill_params.dart +0 -41
  134. package/skills/flutter-skills/tool/generator/lib/src/services/gemini_service.dart +0 -310
  135. package/skills/flutter-skills/tool/generator/lib/src/services/markdown_converter.dart +0 -226
  136. package/skills/flutter-skills/tool/generator/lib/src/services/prompts.dart +0 -72
  137. package/skills/flutter-skills/tool/generator/lib/src/services/resource_fetcher_service.dart +0 -84
  138. package/skills/flutter-skills/tool/generator/lib/src/services/skill_instructions.dart +0 -30
  139. package/skills/flutter-skills/tool/generator/pubspec.yaml +0 -32
  140. package/skills/flutter-skills/tool/generator/test/commands/base_skill_command_test.dart +0 -131
  141. package/skills/flutter-skills/tool/generator/test/commands/validate_skills_input_test.dart +0 -263
  142. package/skills/flutter-skills/tool/generator/test/custom_skill_rules/last_modified_rule.dart +0 -32
  143. package/skills/flutter-skills/tool/generator/test/generate_skills_retry_test.dart +0 -105
  144. package/skills/flutter-skills/tool/generator/test/generate_skills_test.dart +0 -519
  145. package/skills/flutter-skills/tool/generator/test/lint_skills_test.dart +0 -34
  146. package/skills/flutter-skills/tool/generator/test/markdown_converter_test.dart +0 -103
  147. package/skills/flutter-skills/tool/generator/test/markdown_table_test.dart +0 -131
  148. package/skills/flutter-skills/tool/generator/test/models/skill_params_test.dart +0 -37
  149. package/skills/flutter-skills/tool/generator/test/services/gemini_service_test.dart +0 -291
  150. package/skills/flutter-skills/tool/generator/test/services/markdown_converter_test.dart +0 -156
  151. package/skills/flutter-skills/tool/generator/test/services/resource_fetcher_service_test.dart +0 -188
  152. package/skills/flutter-skills/tool/generator/test/update_skills_test.dart +0 -241
  153. package/skills/flutter-skills/tool/generator/test/validate_skills_test.dart +0 -728
  154. /package/skills/{.agents → flutter}/skills/flutter-add-integration-test/SKILL.md +0 -0
  155. /package/skills/{.agents → flutter}/skills/flutter-add-widget-preview/SKILL.md +0 -0
  156. /package/skills/{.agents → flutter}/skills/flutter-add-widget-test/SKILL.md +0 -0
  157. /package/skills/{.agents → flutter}/skills/flutter-apply-architecture-best-practices/SKILL.md +0 -0
  158. /package/skills/{.agents → flutter}/skills/flutter-build-responsive-layout/SKILL.md +0 -0
  159. /package/skills/{.agents → flutter}/skills/flutter-fix-layout-issues/SKILL.md +0 -0
  160. /package/skills/{.agents → flutter}/skills/flutter-implement-json-serialization/SKILL.md +0 -0
  161. /package/skills/{.agents → flutter}/skills/flutter-setup-declarative-routing/SKILL.md +0 -0
  162. /package/skills/{.agents → flutter}/skills/flutter-setup-localization/SKILL.md +0 -0
  163. /package/skills/{.agents → flutter}/skills/flutter-use-http-package/SKILL.md +0 -0
@@ -1,131 +0,0 @@
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 'package:skills/src/services/markdown_converter.dart';
6
- import 'package:test/test.dart';
7
-
8
- void main() {
9
- group('MarkdownConverter Tables', () {
10
- late MarkdownConverter converter;
11
-
12
- setUp(() {
13
- converter = MarkdownConverter();
14
- });
15
-
16
- test('converts simple table', () {
17
- const html = '''
18
- <table>
19
- <thead>
20
- <tr>
21
- <th>Header 1</th>
22
- <th>Header 2</th>
23
- </tr>
24
- </thead>
25
- <tbody>
26
- <tr>
27
- <td>Cell 1</td>
28
- <td>Cell 2</td>
29
- </tr>
30
- </tbody>
31
- </table>
32
- ''';
33
- final markdown = converter.convert(html);
34
- expect(markdown, contains('| Header 1 | Header 2 |'));
35
- expect(markdown, contains('|---|---|'));
36
- expect(markdown, contains('| Cell 1 | Cell 2 |'));
37
- });
38
-
39
- test('converts table without thead', () {
40
- const html = '''
41
- <table>
42
- <tr>
43
- <td>Cell 1</td>
44
- <td>Cell 2</td>
45
- </tr>
46
- </table>
47
- ''';
48
- final markdown = converter.convert(html);
49
- // Fallback: treated as table with first row as header
50
- expect(markdown, contains('| Cell 1 | Cell 2 |'));
51
- expect(markdown, contains('|---|---|'));
52
- });
53
-
54
- test('converts definition lists', () {
55
- const html = '''
56
- <dl>
57
- <dt>Term 1</dt>
58
- <dd>Definition 1</dd>
59
- <dt>Term 2</dt>
60
- <dd>Definition 2</dd>
61
- </dl>
62
- ''';
63
- final markdown = converter.convert(html);
64
- expect(markdown, contains('**Term 1**'));
65
- expect(markdown, contains(': Definition 1'));
66
- expect(markdown, contains('**Term 2**'));
67
- expect(markdown, contains(': Definition 2'));
68
- });
69
-
70
- test('converts details/summary', () {
71
- const html = '''
72
- <details>
73
- <summary>Summary</summary>
74
- Details content
75
- </details>
76
- ''';
77
- // We'll preserve HTML for details as it's often supported in markdown rendering
78
- // OR we can just output the content.
79
- // Preserving HTML is usually safer for details.
80
- final markdown = converter.convert(html);
81
- expect(markdown, contains('<details>'));
82
- expect(markdown, contains('<summary>Summary</summary>'));
83
- expect(markdown, contains('Details content'));
84
- expect(markdown, contains('</details>'));
85
- });
86
- test('converts nested tables without flattening', () {
87
- const html = '''
88
- <table>
89
- <tr>
90
- <td>Outer 1</td>
91
- <td>
92
- <table>
93
- <tr><td>Inner 1</td></tr>
94
- </table>
95
- </td>
96
- </tr>
97
- </table>
98
- ''';
99
- final markdown = converter.convert(html);
100
- // Outer row should contain both outer text and inner table result.
101
- expect(markdown, contains('| Outer 1 |'));
102
- expect(markdown, contains('| Inner 1 |'));
103
- // The outer table should not have inner cells as separate columns of the outer structure.
104
- });
105
- test('handles empty table gracefully', () {
106
- const html = '<table></table>';
107
- final markdown = converter.convert(html);
108
- expect(markdown, isEmpty);
109
- });
110
-
111
- test('converts table with multiple tbodies', () {
112
- const html = '''
113
- <table>
114
- <thead>
115
- <tr><th>Header</th></tr>
116
- </thead>
117
- <tbody>
118
- <tr><td>Row 1</td></tr>
119
- </tbody>
120
- <tbody>
121
- <tr><td>Row 2</td></tr>
122
- </tbody>
123
- </table>
124
- ''';
125
- final markdown = converter.convert(html);
126
- expect(markdown, contains('| Header |'));
127
- expect(markdown, contains('| Row 1 |'));
128
- expect(markdown, contains('| Row 2 |'));
129
- });
130
- });
131
- }
@@ -1,37 +0,0 @@
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 'package:skills/src/models/skill_params.dart';
6
- import 'package:test/test.dart';
7
-
8
- void main() {
9
- group('SkillParams', () {
10
- test('fromJson parses correctly without instructions', () {
11
- final json = {
12
- 'name': 'test-skill',
13
- 'description': 'Test Description',
14
- 'resources': ['http://example.com'],
15
- };
16
- final skill = SkillParams.fromJson(json);
17
- expect(skill.name, 'test-skill');
18
- expect(skill.description, 'Test Description');
19
- expect(skill.resources, ['http://example.com']);
20
- expect(skill.instructions, isNull);
21
- });
22
-
23
- test('fromJson parses correctly with instructions', () {
24
- final json = {
25
- 'name': 'test-skill',
26
- 'description': 'Test Description',
27
- 'instructions': 'Do not hallucinate.',
28
- 'resources': ['http://example.com'],
29
- };
30
- final skill = SkillParams.fromJson(json);
31
- expect(skill.name, 'test-skill');
32
- expect(skill.description, 'Test Description');
33
- expect(skill.resources, ['http://example.com']);
34
- expect(skill.instructions, 'Do not hallucinate.');
35
- });
36
- });
37
- }
@@ -1,291 +0,0 @@
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
-
7
- import 'package:http/http.dart' as http;
8
- import 'package:http/testing.dart';
9
-
10
- import 'package:skills/src/services/gemini_service.dart';
11
- import 'package:test/test.dart';
12
-
13
- void main() {
14
- group('GeminiService', () {
15
- late GeminiService service;
16
-
17
- setUp(() {
18
- service = GeminiService(
19
- apiKey: 'test-api-key',
20
- httpClient: http.Client(),
21
- );
22
- });
23
-
24
- group('cleanContent', () {
25
- test('returns null for null content', () {
26
- expect(service.cleanContent(null), isNull);
27
- });
28
-
29
- test('removes markdown code blocks around content', () {
30
- const content = '''
31
- ```markdown
32
- # Title
33
- Some content
34
- ```
35
- ''';
36
- const expected = '''
37
- # Title
38
- Some content
39
- ''';
40
- expect(service.cleanContent(content), expected);
41
- });
42
-
43
- test('removes markdown code blocks with other languages', () {
44
- const content = '''
45
- ```text
46
- # Title
47
- Some content
48
- ```
49
- ''';
50
- const expected = '''
51
- # Title
52
- Some content
53
- ''';
54
- expect(service.cleanContent(content), expected);
55
- });
56
-
57
- test('ignores trailing markdown code block if no start block', () {
58
- const content = '''
59
- # Title
60
- Some content
61
- ```
62
- ''';
63
- const expected = '''
64
- # Title
65
- Some content
66
- ```
67
- ''';
68
- expect(service.cleanContent(content), expected);
69
- });
70
-
71
- test('strips possible frontmatter at start', () {
72
- const content = '''
73
- ---
74
- key: value
75
- ---
76
- # Title
77
- Some content
78
- ''';
79
- const expected = '''
80
- # Title
81
- Some content
82
- ''';
83
- expect(service.cleanContent(content), expected);
84
- });
85
-
86
- test('strips possible frontmatter after some noise', () {
87
- const content = '''
88
- Here is the content:
89
- ---
90
- key: value
91
- ---
92
- # Title
93
- Some content
94
- ''';
95
- const expected = '''
96
- # Title
97
- Some content
98
- ''';
99
- expect(service.cleanContent(content), expected);
100
- });
101
-
102
- test('preserves internal code blocks', () {
103
- const content = '''
104
- # Title
105
- Here is some code:
106
- ```dart
107
- void main() {}
108
- ```
109
- ''';
110
- const expected = '''
111
- # Title
112
- Here is some code:
113
- ```dart
114
- void main() {}
115
- ```
116
- ''';
117
- expect(service.cleanContent(content), expected);
118
- });
119
-
120
- test('ensures content ends with newline', () {
121
- const content = 'Some content';
122
- const expected = 'Some content\n';
123
- expect(service.cleanContent(content), expected);
124
- });
125
-
126
- test('handles complex nested structure', () {
127
- const content = '''
128
- ```markdown
129
- ---
130
- key: value
131
- ---
132
- # Title
133
- Content with code:
134
- ```dart
135
- print('hello');
136
- ```
137
- ```
138
- ''';
139
- const expected = '''
140
- # Title
141
- Content with code:
142
- ```dart
143
- print('hello');
144
- ```
145
- ''';
146
- expect(service.cleanContent(content), expected);
147
- });
148
- test('removes markdown code blocks with leading whitespace', () {
149
- const content = '''
150
- ```markdown
151
- # Title
152
- Some content
153
- ```
154
- ''';
155
- const expected = '''
156
- # Title
157
- Some content
158
- ''';
159
- expect(service.cleanContent(content), expected);
160
- });
161
-
162
- test(
163
- 'removes markdown code blocks with trailing whitespace on fence',
164
- () {
165
- const content = '''
166
- ```markdown
167
- # Title
168
- Some content
169
- ```
170
- ''';
171
- const expected = '''
172
- # Title
173
- Some content
174
- ''';
175
- expect(service.cleanContent(content), expected);
176
- },
177
- );
178
-
179
- test('removes markdown code blocks with uppercase language', () {
180
- const content = '''
181
- ```MARKDOWN
182
- # Title
183
- Some content
184
- ```
185
- ''';
186
- const expected = '''
187
- # Title
188
- Some content
189
- ''';
190
- expect(service.cleanContent(content), expected);
191
- });
192
- });
193
-
194
- group('generateSkillContent front matter', () {
195
- test('does not wrap metadata values with quotes', () async {
196
- final mockClient = MockClient((request) async {
197
- return http.Response(
198
- jsonEncode({
199
- 'candidates': [
200
- {
201
- 'content': {
202
- 'parts': [
203
- {'text': 'Markdown body'},
204
- ],
205
- },
206
- },
207
- ],
208
- }),
209
- 200,
210
- );
211
- });
212
-
213
- final serviceWithMock = GeminiService(
214
- apiKey: 'test-api-key',
215
- httpClient: mockClient,
216
- model: 'models/test-model',
217
- );
218
-
219
- final result = await serviceWithMock.generateSkillContent(
220
- 'Raw Content',
221
- 'test-skill',
222
- 'Test description without quotes',
223
- );
224
-
225
- expect(result, isNotNull);
226
- expect(result, contains('name: test-skill'));
227
- expect(
228
- result,
229
- contains('description: Test description without quotes'),
230
- );
231
- expect(result, contains('model: models/test-model'));
232
- // Make sure it doesn't contain double quotes for the fields
233
- expect(result, isNot(contains('name: "test-skill"')));
234
- expect(
235
- result,
236
- isNot(contains('description: "Test description without quotes"')),
237
- );
238
- expect(result, isNot(contains('model: "models/test-model"')));
239
- });
240
- });
241
-
242
- group('updateSkillContent front matter', () {
243
- test('does not wrap metadata values with quotes', () async {
244
- final mockClient = MockClient((request) async {
245
- return http.Response(
246
- jsonEncode({
247
- 'candidates': [
248
- {
249
- 'content': {
250
- 'parts': [
251
- {'text': 'Markdown body'},
252
- ],
253
- },
254
- },
255
- ],
256
- }),
257
- 200,
258
- );
259
- });
260
-
261
- final serviceWithMock = GeminiService(
262
- apiKey: 'test-api-key',
263
- httpClient: mockClient,
264
- model: 'models/test-model',
265
- );
266
-
267
- final result = await serviceWithMock.updateSkillContent(
268
- 'Existing Content',
269
- 'Raw Content',
270
- 'test-skill',
271
- 'Test description without quotes',
272
- );
273
-
274
- expect(result, isNotNull);
275
- expect(result, contains('name: test-skill'));
276
- expect(
277
- result,
278
- contains('description: Test description without quotes'),
279
- );
280
- expect(result, contains('model: models/test-model'));
281
- // Make sure it doesn't contain double quotes for the fields
282
- expect(result, isNot(contains('name: "test-skill"')));
283
- expect(
284
- result,
285
- isNot(contains('description: "Test description without quotes"')),
286
- );
287
- expect(result, isNot(contains('model: "models/test-model"')));
288
- });
289
- });
290
- });
291
- }
@@ -1,156 +0,0 @@
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 'package:skills/src/services/markdown_converter.dart';
6
- import 'package:test/test.dart';
7
-
8
- void main() {
9
- group('MarkdownConverter', () {
10
- late MarkdownConverter converter;
11
-
12
- setUp(() {
13
- converter = MarkdownConverter();
14
- });
15
-
16
- test('converts headers', () {
17
- expect(converter.convert('<h1>Title</h1>'), contains('# Title'));
18
- expect(converter.convert('<h2>Subtitle</h2>'), contains('## Subtitle'));
19
- expect(converter.convert('<h3>Section</h3>'), contains('### Section'));
20
- });
21
-
22
- test('converts paragraphs', () {
23
- expect(converter.convert('<p>Hello World</p>'), contains('Hello World'));
24
- });
25
-
26
- test('converts links', () {
27
- expect(
28
- converter.convert('<a href="https://example.com">Link</a>'),
29
- contains('[Link](https://example.com)'),
30
- );
31
- });
32
-
33
- test('converts bold and italic', () {
34
- expect(converter.convert('<b>Bold</b>'), contains('**Bold**'));
35
- expect(
36
- converter.convert('<strong>Strong</strong>'),
37
- contains('**Strong**'),
38
- );
39
- expect(converter.convert('<i>Italic</i>'), contains('*Italic*'));
40
- expect(
41
- converter.convert('<em>Emphasized</em>'),
42
- contains('*Emphasized*'),
43
- );
44
- });
45
-
46
- test('converts code', () {
47
- expect(
48
- converter.convert('<code>print("hello")</code>'),
49
- contains('`print("hello")`'),
50
- );
51
- expect(
52
- converter.convert('<pre>void main() {}</pre>'),
53
- allOf(contains('```'), contains('void main() {}')),
54
- );
55
- });
56
-
57
- test('converts lists', () {
58
- const html = '''
59
- <ul>
60
- <li>Item 1</li>
61
- <li>Item 2</li>
62
- </ul>
63
- ''';
64
- final md = converter.convert(html);
65
- expect(md, contains('- Item 1'));
66
- expect(md, contains('- Item 2'));
67
-
68
- const htmlOl = '''
69
- <ol>
70
- <li>First</li>
71
- <li>Second</li>
72
- </ol>
73
- ''';
74
- final mdOl = converter.convert(htmlOl);
75
- // Currently the converter uses simplified list handling (returning - for both)
76
- expect(mdOl, contains('- First'));
77
- expect(mdOl, contains('- Second'));
78
- });
79
-
80
- test('converts line breaks', () {
81
- expect(converter.convert('Line 1<br>Line 2'), contains('Line 1\nLine 2'));
82
- });
83
-
84
- test('converts structural elements', () {
85
- expect(
86
- converter.convert('<div>Div Content</div>'),
87
- contains('Div Content'),
88
- );
89
- expect(
90
- converter.convert('<section>Section Content</section>'),
91
- contains('Section Content'),
92
- );
93
- expect(
94
- converter.convert('<main>Main Content</main>'),
95
- contains('Main Content'),
96
- );
97
- expect(
98
- converter.convert('<article>Article Content</article>'),
99
- contains('Article Content'),
100
- );
101
- });
102
-
103
- test('handles empty body', () {
104
- expect(converter.convert(''), isEmpty);
105
- });
106
-
107
- test('converts table without thead or tbody', () {
108
- const html = '''
109
- <table>
110
- <tr><td>Data 1</td><td>Data 2</td></tr>
111
- <tr><td>Data 3</td><td>Data 4</td></tr>
112
- </table>
113
- ''';
114
- expect(converter.convert(html), contains('| Data 1 | Data 2 |'));
115
- expect(converter.convert(html), contains('| Data 3 | Data 4 |'));
116
- });
117
-
118
- test('converts video tag with nested source', () {
119
- expect(
120
- converter.convert(
121
- '<video><source src="https://example.com/video.mp4"></video>',
122
- ),
123
- contains('[Video](https://example.com/video.mp4)'),
124
- );
125
- });
126
-
127
- test('converts definition lists (dl, dt, dd)', () {
128
- const html = '''
129
- <dl>
130
- <dt>Term 1</dt>
131
- <dd>Definition 1</dd>
132
- </dl>
133
- ''';
134
- final md = converter.convert(html);
135
- expect(md, contains('**Term 1**'));
136
- expect(md, contains('Definition 1'));
137
- });
138
-
139
- test('converts iframes', () {
140
- expect(
141
- converter.convert('<iframe src="https://example.com/embed"></iframe>'),
142
- contains('[Iframe](https://example.com/embed)'),
143
- );
144
- });
145
- test('retains details and summary as HTML', () {
146
- const html = '''
147
- <details>
148
- <summary>Click to expand</summary>
149
- Hidden content
150
- </details>
151
- ''';
152
- final md = converter.convert(html);
153
- expect(md, contains('<details>'));
154
- });
155
- });
156
- }