sdd-full 4.8.0 → 4.8.2

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 (164) hide show
  1. package/bin.js +2 -2
  2. package/index.js +18 -12
  3. package/package.json +1 -1
  4. package/skills/README.md +155 -47
  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/VERSION.md +0 -310
  23. package/skills/flutter-skills/.github/dependabot.yaml +0 -15
  24. package/skills/flutter-skills/.github/workflows/dart_skills_lint_workflow.yaml +0 -68
  25. package/skills/flutter-skills/.github/workflows/skills_tool.yaml +0 -51
  26. package/skills/flutter-skills/CODE_OF_CONDUCT.md +0 -3
  27. package/skills/flutter-skills/CONTRIBUTING.md +0 -36
  28. package/skills/flutter-skills/LICENSE +0 -26
  29. package/skills/flutter-skills/README.md +0 -50
  30. package/skills/flutter-skills/pubspec.yaml +0 -9
  31. package/skills/flutter-skills/resources/flutter_skills.yaml +0 -434
  32. package/skills/flutter-skills/skills/flutter-add-integration-test/SKILL.md +0 -163
  33. package/skills/flutter-skills/skills/flutter-add-widget-preview/SKILL.md +0 -145
  34. package/skills/flutter-skills/skills/flutter-add-widget-test/SKILL.md +0 -154
  35. package/skills/flutter-skills/skills/flutter-apply-architecture-best-practices/SKILL.md +0 -162
  36. package/skills/flutter-skills/skills/flutter-build-responsive-layout/SKILL.md +0 -139
  37. package/skills/flutter-skills/skills/flutter-fix-layout-issues/SKILL.md +0 -130
  38. package/skills/flutter-skills/skills/flutter-implement-json-serialization/SKILL.md +0 -153
  39. package/skills/flutter-skills/skills/flutter-setup-declarative-routing/SKILL.md +0 -255
  40. package/skills/flutter-skills/skills/flutter-setup-localization/SKILL.md +0 -210
  41. package/skills/flutter-skills/skills/flutter-use-http-package/SKILL.md +0 -175
  42. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/add-dart-lint-validation-rule/SKILL.md +0 -196
  43. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-best-practices/SKILL.md +0 -65
  44. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-checks-migration/SKILL.md +0 -158
  45. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-cli-app-best-practices/SKILL.md +0 -168
  46. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-doc-validation/SKILL.md +0 -87
  47. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-long-lines/SKILL.md +0 -101
  48. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-matcher-best-practices/SKILL.md +0 -136
  49. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-modern-features/SKILL.md +0 -266
  50. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-package-maintenance/SKILL.md +0 -92
  51. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/SKILL.md +0 -92
  52. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/lib/src/calculator.dart +0 -7
  53. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/pubspec.yaml +0 -8
  54. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/test/calculator_test.dart +0 -11
  55. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/interpret_coverage.dart +0 -95
  56. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/pubspec.yaml +0 -6
  57. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/test/interpret_coverage_test.dart +0 -93
  58. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-fundamentals/SKILL.md +0 -173
  59. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/definition-of-done/SKILL.md +0 -27
  60. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/flutter_skills_ignore.json +0 -3
  61. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/grill-me/SKILL.md +0 -10
  62. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/ignore.json +0 -3
  63. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/SKILL.md +0 -371
  64. package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/testing-anti-patterns.md +0 -299
  65. package/skills/flutter-skills/tool/dart_skills_lint/AUTHORS +0 -7
  66. package/skills/flutter-skills/tool/dart_skills_lint/CHANGELOG.md +0 -12
  67. package/skills/flutter-skills/tool/dart_skills_lint/CONTRIBUTING.md +0 -51
  68. package/skills/flutter-skills/tool/dart_skills_lint/LICENSE +0 -27
  69. package/skills/flutter-skills/tool/dart_skills_lint/README.md +0 -203
  70. package/skills/flutter-skills/tool/dart_skills_lint/analysis_options.yaml +0 -296
  71. package/skills/flutter-skills/tool/dart_skills_lint/bench/README.md +0 -23
  72. package/skills/flutter-skills/tool/dart_skills_lint/bench/baseline_throughput.dart +0 -230
  73. package/skills/flutter-skills/tool/dart_skills_lint/bin/cli.dart +0 -10
  74. package/skills/flutter-skills/tool/dart_skills_lint/dart_skills_lint.yaml +0 -14
  75. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/PRODUCTION_READYNESS.md +0 -48
  76. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/completion_migration_plan.md +0 -99
  77. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/legacy_patterns_report.md +0 -110
  78. package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/pub_vs_skill_report.md +0 -56
  79. package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/SPECIFICATION.md +0 -79
  80. package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/architecture_overview.md +0 -64
  81. package/skills/flutter-skills/tool/dart_skills_lint/lib/dart_skills_lint.dart +0 -11
  82. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/config_parser.dart +0 -156
  83. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/entry_point.dart +0 -354
  84. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/fixable_rule.dart +0 -20
  85. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/analysis_severity.dart +0 -15
  86. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/check_type.dart +0 -17
  87. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.dart +0 -34
  88. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.g.dart +0 -19
  89. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_context.dart +0 -27
  90. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_rule.dart +0 -27
  91. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.dart +0 -26
  92. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.g.dart +0 -24
  93. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/validation_error.dart +0 -31
  94. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rule_registry.dart +0 -79
  95. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/absolute_paths_rule.dart +0 -74
  96. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/description_length_rule.dart +0 -49
  97. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/disallowed_field_rule.dart +0 -61
  98. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/name_format_rule.dart +0 -167
  99. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/relative_paths_rule.dart +0 -72
  100. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/trailing_whitespace_rule.dart +0 -93
  101. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/valid_yaml_metadata_rule.dart +0 -74
  102. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/skills_ignores_storage.dart +0 -36
  103. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validation_session.dart +0 -559
  104. package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validator.dart +0 -238
  105. package/skills/flutter-skills/tool/dart_skills_lint/pubspec.yaml +0 -28
  106. package/skills/flutter-skills/tool/dart_skills_lint/skills/README.md +0 -10
  107. package/skills/flutter-skills/tool/dart_skills_lint/skills/dart-skills-lint-validation/SKILL.md +0 -195
  108. package/skills/flutter-skills/tool/dart_skills_lint/skills-lock.json +0 -75
  109. package/skills/flutter-skills/tool/dart_skills_lint/test/absolute_paths_test.dart +0 -167
  110. package/skills/flutter-skills/tool/dart_skills_lint/test/cli_integration_test.dart +0 -683
  111. package/skills/flutter-skills/tool/dart_skills_lint/test/config_file_test.dart +0 -292
  112. package/skills/flutter-skills/tool/dart_skills_lint/test/custom_rule_test.dart +0 -122
  113. package/skills/flutter-skills/tool/dart_skills_lint/test/directory_structure_test.dart +0 -163
  114. package/skills/flutter-skills/tool/dart_skills_lint/test/field_constraints_test.dart +0 -178
  115. package/skills/flutter-skills/tool/dart_skills_lint/test/fixer_test.dart +0 -172
  116. package/skills/flutter-skills/tool/dart_skills_lint/test/ignore_models_test.dart +0 -63
  117. package/skills/flutter-skills/tool/dart_skills_lint/test/metadata_validation_test.dart +0 -116
  118. package/skills/flutter-skills/tool/dart_skills_lint/test/relative_path_flag_test.dart +0 -70
  119. package/skills/flutter-skills/tool/dart_skills_lint/test/relative_paths_test.dart +0 -172
  120. package/skills/flutter-skills/tool/dart_skills_lint/test/resolve_rules_test.dart +0 -82
  121. package/skills/flutter-skills/tool/dart_skills_lint/test/rule_naming_test.dart +0 -29
  122. package/skills/flutter-skills/tool/dart_skills_lint/test/skills_ignores_storage_test.dart +0 -89
  123. package/skills/flutter-skills/tool/dart_skills_lint/test/test_utils.dart +0 -19
  124. package/skills/flutter-skills/tool/dart_skills_lint/test/trailing_whitespace_test.dart +0 -152
  125. package/skills/flutter-skills/tool/generator/README.md +0 -150
  126. package/skills/flutter-skills/tool/generator/analysis_options.yaml +0 -143
  127. package/skills/flutter-skills/tool/generator/bin/skills.dart +0 -73
  128. package/skills/flutter-skills/tool/generator/lib/src/commands/base_skill_command.dart +0 -87
  129. package/skills/flutter-skills/tool/generator/lib/src/commands/base_yaml_command.dart +0 -83
  130. package/skills/flutter-skills/tool/generator/lib/src/commands/generate_skill_command.dart +0 -92
  131. package/skills/flutter-skills/tool/generator/lib/src/commands/update_readme_command.dart +0 -150
  132. package/skills/flutter-skills/tool/generator/lib/src/commands/update_skill_command.dart +0 -97
  133. package/skills/flutter-skills/tool/generator/lib/src/commands/validate_skill_command.dart +0 -284
  134. package/skills/flutter-skills/tool/generator/lib/src/models/skill_params.dart +0 -41
  135. package/skills/flutter-skills/tool/generator/lib/src/services/gemini_service.dart +0 -310
  136. package/skills/flutter-skills/tool/generator/lib/src/services/markdown_converter.dart +0 -226
  137. package/skills/flutter-skills/tool/generator/lib/src/services/prompts.dart +0 -72
  138. package/skills/flutter-skills/tool/generator/lib/src/services/resource_fetcher_service.dart +0 -84
  139. package/skills/flutter-skills/tool/generator/lib/src/services/skill_instructions.dart +0 -30
  140. package/skills/flutter-skills/tool/generator/pubspec.yaml +0 -32
  141. package/skills/flutter-skills/tool/generator/test/commands/base_skill_command_test.dart +0 -131
  142. package/skills/flutter-skills/tool/generator/test/commands/validate_skills_input_test.dart +0 -263
  143. package/skills/flutter-skills/tool/generator/test/custom_skill_rules/last_modified_rule.dart +0 -32
  144. package/skills/flutter-skills/tool/generator/test/generate_skills_retry_test.dart +0 -105
  145. package/skills/flutter-skills/tool/generator/test/generate_skills_test.dart +0 -519
  146. package/skills/flutter-skills/tool/generator/test/lint_skills_test.dart +0 -34
  147. package/skills/flutter-skills/tool/generator/test/markdown_converter_test.dart +0 -103
  148. package/skills/flutter-skills/tool/generator/test/markdown_table_test.dart +0 -131
  149. package/skills/flutter-skills/tool/generator/test/models/skill_params_test.dart +0 -37
  150. package/skills/flutter-skills/tool/generator/test/services/gemini_service_test.dart +0 -291
  151. package/skills/flutter-skills/tool/generator/test/services/markdown_converter_test.dart +0 -156
  152. package/skills/flutter-skills/tool/generator/test/services/resource_fetcher_service_test.dart +0 -188
  153. package/skills/flutter-skills/tool/generator/test/update_skills_test.dart +0 -241
  154. package/skills/flutter-skills/tool/generator/test/validate_skills_test.dart +0 -728
  155. /package/skills/{.agents → flutter}/skills/flutter-add-integration-test/SKILL.md +0 -0
  156. /package/skills/{.agents → flutter}/skills/flutter-add-widget-preview/SKILL.md +0 -0
  157. /package/skills/{.agents → flutter}/skills/flutter-add-widget-test/SKILL.md +0 -0
  158. /package/skills/{.agents → flutter}/skills/flutter-apply-architecture-best-practices/SKILL.md +0 -0
  159. /package/skills/{.agents → flutter}/skills/flutter-build-responsive-layout/SKILL.md +0 -0
  160. /package/skills/{.agents → flutter}/skills/flutter-fix-layout-issues/SKILL.md +0 -0
  161. /package/skills/{.agents → flutter}/skills/flutter-implement-json-serialization/SKILL.md +0 -0
  162. /package/skills/{.agents → flutter}/skills/flutter-setup-declarative-routing/SKILL.md +0 -0
  163. /package/skills/{.agents → flutter}/skills/flutter-setup-localization/SKILL.md +0 -0
  164. /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
- }