sdd-full 4.6.2 → 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 +176 -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,99 @@
1
+ # Migration Plan: Adding Zsh Command Autocompletion (Approach A)
2
+
3
+ This document outlines the migration steps to add Zsh tab-autocompletion support to the `dart_skills_lint` CLI tool using Dart packages.
4
+
5
+ There are two main sub-approaches depending on whether we want to keep the current flat `ArgParser` structure or migrate to a more structured `CommandRunner` architecture.
6
+
7
+ ---
8
+
9
+ ## 🧭 Option A.1: Migrate to `CommandRunner` with `cli_completion` (Recommended)
10
+
11
+ If we plan to expand this CLI with subcommands in the future (e.g., `dart_skills_lint validate`, `dart_skills_lint init`, `dart_skills_lint check-ignore`), migrating to standard Dart `CommandRunner` is highly recommended.
12
+
13
+ ### 📜 Step-by-step
14
+ 1. **Add Dependency:**
15
+ ```bash
16
+ dart pub add cli_completion
17
+ ```
18
+ 2. **Refactor `entry_point.dart` to use `CompletionCommandRunner`:**
19
+ Create a custom runner and commands.
20
+ ```dart
21
+ import 'package:cli_completion/cli_completion.dart';
22
+
23
+ class SkillsLintRunner extends CompletionCommandRunner<int> {
24
+ SkillsLintRunner() : super('dart_skills_lint', 'Linter for Agent Skills');
25
+
26
+ @override
27
+ Future<int?> runCommand(ArgResults topLevelResults) async {
28
+ // Fast-track completions
29
+ if (topLevelResults.command?.name == 'completion') {
30
+ super.runCommand(topLevelResults);
31
+ return 0;
32
+ }
33
+ return super.runCommand(topLevelResults);
34
+ }
35
+ }
36
+ ```
37
+ 3. **Move existing flags into a `ValidateCommand`:**
38
+ Instead of top-level `ArgParser`, we encapsulate the validation logic inside a reusable Command class.
39
+ ```dart
40
+ class ValidateCommand extends Command<int> {
41
+ @override
42
+ String get name => 'validate';
43
+ @override
44
+ String get description => 'Validates agent skill directories.';
45
+
46
+ ValidateCommand() {
47
+ argParser..addFlag('quiet', negatable: false); // etc...
48
+ }
49
+
50
+ @override
51
+ Future<int> run() async {
52
+ // Run validation logic here
53
+ return 0;
54
+ }
55
+ }
56
+ ```
57
+ 4. **Update `bin/cli.dart`:**
58
+ Change `runApp(args)` to instantiate the new runner instead.
59
+
60
+ ---
61
+
62
+ ## ⚖️ Option A.2: Keep `ArgParser` and use `package:completion` (Simpler)
63
+
64
+ If we want to keep the tool's monolithic, single-command design without introducing sub-commands, we can use the lightweight `package:completion`.
65
+
66
+ ### 📜 Step-by-step
67
+ 1. **Add Dependency:**
68
+ ```bash
69
+ dart pub add completion
70
+ ```
71
+ 2. **Update `lib/src/entry_point.dart` parser runner:**
72
+ Instead of `parser.parse(args)`, intercept the call to let the completion package proposal take precedence.
73
+ ```dart
74
+ import 'package:completion/completion.dart' as completion;
75
+
76
+ Future<void> runApp(List<String> args) async {
77
+ final parser = ArgParser();
78
+ // ... add your flags ...
79
+
80
+ // Intercept for completions
81
+ completion.tryArgsCompletion(args, parser);
82
+
83
+ final results = parser.parse(args);
84
+ // ... rest of validation logic ...
85
+ }
86
+ ```
87
+
88
+ ---
89
+
90
+ ## 🧪 Verification Plan
91
+
92
+ Regardless of the option chosen:
93
+
94
+ ### Automated Tests
95
+ 1. **Completion proposal test:** Verify that running `dart_skills_lint completion zsh` exits success code 0 and outputs setup instructions.
96
+ 2. **Regression tests:** Run standard suite checks (`test/cli_integration_test.dart`) to ensure normal runs are not disrupted by interjections.
97
+
98
+ ### Manual Verification
99
+ 1. Install completion script locally using standard terminal evaluation and tap tab on `-d` to ensure directories are displayed.
@@ -0,0 +1,110 @@
1
+ # Feature Design Doc: Resolving Legacy Inconsistencies in Rule Resolution
2
+
3
+ This document analyzes patterns of code where legacy implementations create inconsistencies, specifically around rule resolution, configuration overrides, and global state management.
4
+
5
+ ## Identified Inconsistencies
6
+
7
+ ### 1. Mutable Global State in `CheckType`
8
+
9
+ The `CheckType` objects defined in `lib/src/rules.dart` behave as global singletons. While they are declared `final` as variables, their `severity` field itself is mutable.
10
+
11
+ - **Impact**: When `config_parser.dart` or `entry_point.dart` updates rule severities from a configuration file or CLI flags, they directly mutate these global objects.
12
+ - **Inconsistency**: This conflicts with the new Dependency Injection pattern in `Validator`, which is designed to receive an isolated set of rule configurations for a specific validation run. If we mutate global state, two independent `Validator` instances created in the same process would share the same rule severities.
13
+
14
+ ### 2. Side-Effects in Configuration Parsing
15
+
16
+ The `loadConfig` function in `lib/src/config_parser.dart` takes a `Set<CheckType> checkTypes` and mutates it as a side effect while parsing global rules.
17
+
18
+ - **Impact**: Code calling `loadConfig` gets its input modified without an explicit return value indicating the change.
19
+ - **Inconsistency**: It mixes "reading configuration" with "updating application state".
20
+
21
+ ### 3. Fragmentation in Directory Overrides
22
+
23
+ In `lib/src/entry_point.dart`, overrides for specific directories are resolved manually using hardcoded string keys (e.g., `'check-relative-paths'`), rather than leveraging the typed `CheckType` objects or a dynamic loop.
24
+
25
+ - **Impact**: When we added the explicit rule injection to `Validator`, we had to introduce local shadowing variables to bridge the gap between hardcoded config overrides and the `Validator` constructor.
26
+ - **Inconsistency**: Rule lookup logic is split across multiple styles (string-based maps vs typed `CheckType` instances).
27
+
28
+ ---
29
+
30
+ ## Proposed Solutions
31
+
32
+ ### Solution 1: Immutable `CheckType` with `copyWith`
33
+
34
+ Make `CheckType` fully immutable by marking all fields as `final`. Introduce a `copyWith` method to create modified instances safely.
35
+
36
+ ```dart
37
+ class CheckType {
38
+ final String name;
39
+ final AnalysisSeverity defaultSeverity;
40
+ final AnalysisSeverity severity; // Changed to final
41
+
42
+ CheckType({
43
+ required this.name,
44
+ required this.defaultSeverity,
45
+ AnalysisSeverity? severity,
46
+ }) : severity = severity ?? defaultSeverity;
47
+
48
+ CheckType copyWith({
49
+ String? name,
50
+ AnalysisSeverity? defaultSeverity,
51
+ AnalysisSeverity? severity,
52
+ }) {
53
+ return CheckType(
54
+ name: name ?? this.name,
55
+ defaultSeverity: defaultSeverity ?? this.defaultSeverity,
56
+ severity: severity ?? this.severity,
57
+ );
58
+ }
59
+ }
60
+ ```
61
+
62
+ This was also suggested in `FEATURE_REQUESTS.md`. By using immutable data types, we can pass configuration around without risking unintended side leaks.
63
+
64
+ ### Solution 2: Functional `loadConfig`
65
+
66
+ Refactor `loadConfig` to return a `Configuration` object that encapsulates *all* resolved rule overrides, rather than mutating its inputs.
67
+
68
+ ```dart
69
+ // Suggested loadConfig signature
70
+ Future<Configuration> loadConfig() async { ... }
71
+
72
+ class Configuration {
73
+ final Map<String, AnalysisSeverity> globalRuleOverrides;
74
+ final List<DirectoryConfig> directoryConfigs;
75
+ // ...
76
+ }
77
+ ```
78
+
79
+ ### Solution 3: Dynamic Rule Resolution in Entry Point
80
+
81
+ Instead of hardcoding rules in the directory loop, we can map directory config rules directly to creating a `Validator` instance.
82
+
83
+ ```dart
84
+ // Pre-resolve directory rules by name in entry_point.dart
85
+ final Map<String, AnalysisSeverity> resolvedLocalRules = {};
86
+
87
+ // Fallback to global rules
88
+ for (final rule in globalRules) {
89
+ resolvedLocalRules[rule.name] = rule.severity;
90
+ }
91
+
92
+ // Override with specific directory rules
93
+ for (final key in dirConfig.rules.keys) {
94
+ resolvedLocalRules[key] = dirConfig.rules[key]!;
95
+ }
96
+
97
+ // Create Validator with these local overrides
98
+ final localValidator = Validator(
99
+ rules: resolvedLocalRules.entries.map((e) => CheckType(name: e.key, defaultSeverity: e.value)).toSet(),
100
+ );
101
+ ```
102
+
103
+ This unifies rule resolution into a single dynamic pattern.
104
+
105
+ ---
106
+ ## Verification Plan
107
+
108
+ ### Automated Tests
109
+ 1. Add tests verify rule overriding works correctly without leak when `copyWith` is used in parallel validation runs.
110
+ 2. Verify that `loadConfig` works when called multiple times without affecting previous parsed states.
@@ -0,0 +1,56 @@
1
+ # Report: Conflict Analysis for Dual-Publishing as Pub Package and Agent Skill
2
+
3
+ This report investigates the compatibility of the `dart_skills_lint` codebase with two different distribution specifications: the [pub.dev package specification](https://dart.dev/tools/pub/pubspec) and the [Agent Skills specification](../knowledge/SPECIFICATION.md).
4
+
5
+ ## 1. Executive Summary
6
+
7
+ While it is technically possible to host both specifications in a single codebase, there are several **hard conflicts** regarding naming conventions and directory requirements. Most notably, a single identifier cannot satisfy both naming standards simultaneously if it contains separators.
8
+
9
+ ## 2. Identified Conflicts
10
+
11
+ ### 2.1 Naming Convention (Hard Conflict)
12
+ The most significant conflict lies in the allowed characters for project identifiers:
13
+
14
+ * **Pub Package Specification:** Package names must be valid Dart identifiers. They **must use underscores** (`_`) for separators and **cannot contain hyphens** (`-`).
15
+ * **Agent Skills Specification:** Skill names must be lowercase alphanumeric and **must use hyphens** (`-`) for separators. They **cannot contain underscores** (`_`).
16
+
17
+ **Result:** A project named `dart_skills_lint` (valid for pub) is invalid for Agent Skills. A project named `dart-skills-lint` (valid for skills) is invalid for pub. To publish as both, the project must use two different names (e.g., `dart_skills_lint` on pub and `dart-skills-lint` as a skill).
18
+
19
+ ### 2.2 Directory Name Match Rule (Structural Conflict)
20
+ * **Agent Skills Specification:** The `name` field in `SKILL.md` **must exactly match** the name of its parent directory.
21
+ * **Pub Package Specification:** While not strictly enforced for publishing, Dart conventions strongly prefer the directory name to match the package name in `pubspec.yaml`.
22
+
23
+ **Result:** To satisfy the Agent Skills specification, the project directory **must** be named `dart-skills-lint`. This forces a discrepancy between the directory name and the internal Dart package name (`dart_skills_lint`), which may cause minor confusion for Dart developers but does not prevent functionality.
24
+
25
+ ### 2.3 Directory Structure and "Clutter"
26
+ * **Agent Skills Specification:** Recommends a "flat and predictable structure" consisting of `SKILL.md`, `scripts/`, `references/`, and `assets/`.
27
+ * **Pub Package Specification:** Requires a specific structure with `pubspec.yaml`, `lib/`, `bin/`, and `test/`, along with ephemeral directories like `.dart_tool/`.
28
+
29
+ **Result:** While these can coexist, a Dart project is significantly more complex than the "flat" structure envisioned for Agent Skills. An AI agent scanning the skill directory will encounter numerous files (like `pubspec.lock`, `analysis_options.yaml`) that are irrelevant to its operation, potentially wasting context if not explicitly ignored.
30
+
31
+ ### 2.4 Executable Location
32
+ * **Agent Skills Specification:** Expects executable logic to reside in the `scripts/` directory.
33
+ * **Pub Package Specification:** Places CLI entry points in the `bin/` directory.
34
+
35
+ **Result:** To align with the Agent Skills specification, the `SKILL.md` instructions must either:
36
+ 1. Explicitly point the agent to `bin/cli.dart`.
37
+ 2. Provide a wrapper script in a `scripts/` directory (e.g., `scripts/run-linter.sh`) that executes the Dart code.
38
+
39
+ ### 2.5 Metadata Redundancy
40
+ Both specifications require overlapping metadata (description, license, version).
41
+ * **Pub:** Stored in `pubspec.yaml`.
42
+ * **Skills:** Stored in `SKILL.md` YAML frontmatter.
43
+
44
+ **Result:** There is no native mechanism to synchronize these. Developers must manually ensure that the description and version remain consistent across both files, increasing the risk of "metadata drift."
45
+
46
+ ## 3. Recommended Strategy for `dart_skills_lint`
47
+
48
+ To achieve dual-compatibility, the following configuration is recommended:
49
+
50
+ 1. **Directory Name:** Keep the directory named `dart-skills-lint`.
51
+ 2. **SKILL.md:**
52
+ - Set `name: dart-skills-lint`.
53
+ - Provide clear instructions to run `dart bin/cli.dart` or `dart run`.
54
+ 3. **pubspec.yaml:**
55
+ - Set `name: dart_skills_lint`.
56
+ 4. **Scripts Wrapper:** Consider adding a `scripts/lint.sh` that calls the Dart linter to satisfy the standard skill directory structure.
@@ -0,0 +1,79 @@
1
+ # Agent Skills Specification
2
+
3
+ This document defines the technical requirements and architectural priorities for implementing Agent Skills. It serves as a self-contained reference for engineers building or integrating skills into AI agent environments.
4
+
5
+ ## 1. Overview
6
+ An **Agent Skill** is a portable, self-contained directory that extends an AI agent's capabilities. It provides the agent with specific instructions, tools, and domain-specific knowledge required to perform a specialized task.
7
+
8
+ ## 2. Directory Structure
9
+ A skill directory must follow a flat and predictable structure. The only mandatory file is `SKILL.md` at the root.
10
+
11
+ ```text
12
+ skill-name/
13
+ ├── SKILL.md # Required: Metadata + Instructions
14
+ ├── scripts/ # Optional: Executable code (Python, Bash, JS, etc.)
15
+ ├── references/ # Optional: Deep-dive documentation and templates
16
+ └── assets/ # Optional: Static resources (images, schemas, etc.)
17
+ ```
18
+
19
+ ## 3. The `SKILL.md` File
20
+ The `SKILL.md` file uses YAML frontmatter for machine-readable metadata, followed by Markdown-formatted instructions for the agent.
21
+
22
+ ### 3.1 Metadata (YAML Frontmatter)
23
+ | Field | Required | Constraints |
24
+ | :--- | :--- | :--- |
25
+ | `name` | Yes | 1-64 chars; lowercase alphanumeric and hyphens (`-`) only; no leading/trailing/consecutive hyphens. **Must match the parent directory name.** |
26
+ | `description` | Yes | 1-1024 chars. A concise summary used by agents to determine when to activate the skill. |
27
+ | `license` | No | Short name (e.g., MIT, Apache-2.0) or reference to a bundled license file. |
28
+ | `compatibility` | No | 1-500 chars; specifies environment requirements (e.g., `Requires Python 3.10+`, `Node.js 18`). |
29
+ | `metadata` | No | Arbitrary key-value mapping for client-specific properties (e.g., `version`, `author`). |
30
+ | `allowed-tools` | No | (Experimental) Space-delimited list of pre-approved tools (e.g., `Bash(git:*)`). |
31
+
32
+ ### 3.2 Instructions (Markdown Body)
33
+ The body should contain the "expert knowledge" for the agent.
34
+ - **Referencing:** Use relative paths to files within the skill directory (e.g., `[See technical details](references/DETAILS.md)`).
35
+
36
+
37
+ ## 4. Implementation Requirements
38
+
39
+ ### 4.1 Validation
40
+ Validation ensures that a skill directory and its `SKILL.md` file adhere to the specification. A linter or validator must check the following rules:
41
+
42
+ #### 4.1.1 Directory and File Structure
43
+ - **Existence**: The target path must exist and be a directory.
44
+ - **Mandatory File**: The root directory must contain a `SKILL.md` file.
45
+
46
+ #### 4.1.2 Metadata (YAML Frontmatter)
47
+ - **YAML Integrity**: The frontmatter must be valid YAML.
48
+ - **Allowed Fields**: Only the following fields are allowed: `name`, `description`, `license`, `allowed-tools`, `metadata`, `compatibility`.
49
+ - **Required Fields**: `name` and `description` are mandatory.
50
+
51
+ #### 4.1.3 Field Specific Constraints
52
+ - **Skill Name (`name`)**:
53
+ - Must be lowercase.
54
+ - Length: Maximum 64 characters.
55
+ - Characters: Only lowercase letters, digits, and hyphens (`-`).
56
+ - No leading or trailing hyphens.
57
+ - No consecutive hyphens (`--`).
58
+ - **Directory Name Match**: The skill `name` must exactly match the name of its parent directory.
59
+ - **Description (`description`)**:
60
+ - Length: Maximum 1024 characters.
61
+ - **Compatibility (`compatibility`)**:
62
+ - Length: Maximum 500 characters.
63
+
64
+ #### 4.1.4 Content Constraints
65
+ - **Trailing Whitespace**: Lines in `SKILL.md` should not have trailing whitespace. Exactly 2 spaces at the end of a line are allowed to support Markdown hard line breaks, per the [CommonMark Spec](https://spec.commonmark.org/0.31.2/#hard-line-breaks).
66
+ - **Path Constraints**: **Inline** Markdown links must not use absolute paths to enforce portability. Can optionally be configured to check that relative paths point to valid, existing files (disabled by default). *Note: Validation only applies to inline Markdown links; HTML and reference-style links are not supported.*
67
+
68
+ ### 5.2 Scripts & Tools
69
+ - Scripts in the `scripts/` directory should be self-documenting and provide clear error messages.
70
+
71
+ ### 5.3 Versioning
72
+ - Use the `metadata` field in `SKILL.md` to track versions:
73
+ ```yaml
74
+ metadata:
75
+ version: "1.0.0"
76
+ ```
77
+
78
+ ## 6. Best Practices
79
+ - **Avoid Deep Nesting:** Keep the directory structure as flat as possible. References should ideally be only one level deep from the root.
@@ -0,0 +1,64 @@
1
+ # Architecture Overview: Agent Skills Linter (`dart_skills_lint`)
2
+
3
+ This document provides a high-level architectural overview of the `dart_skills_lint` codebase. It outlines the project's components, execution flow, and design patterns used to validate Agent Skill specifications.
4
+
5
+ ## 🧱 Key Components
6
+
7
+ The codebase is organized into standard Dart package layers, separating CLI handling, validation logic, and data models.
8
+
9
+ ### 🚗 1. CLI Entry Point (`lib/src/entry_point.dart`)
10
+ The `entry_point.dart` file serves as the command-line interface.
11
+ - **Argument Parsing:** Uses standard `package:args` to parse input flags (`--skills-directory`, `--generate-baseline`, rules toggles, etc.).
12
+ - **Workspace Discovery:** Resolves target folders by searching standard locations (e.g., `.agents/skills`, `.claude/skills`) or parsing user arguments.
13
+ - **Ignore System Integration:** Handlers for `dart_skills_lint_ignore.json` (baseline files) to filter out known failures without failing the build.
14
+ - **Log Management:** Consumes validation reports and standardizes format for terminal display (stouts vs stderr).
15
+
16
+ ### ⚙️ 2. Configuration Parser (`lib/src/config_parser.dart`)
17
+ - Loads user-defined custom settings from `dart_skills_lint.yaml` if it exists.
18
+ - Maps directory-specific rules overrides and toggles severity defaults.
19
+
20
+ ### 🛡️ 3. Validation Engine (`lib/src/validator.dart`)
21
+ The core motor of the package.
22
+ - Scans `SKILL.md` using regular expressions (`dotAll: true`) to extract Frontmatter.
23
+ - Delegates to sub-routines for checking:
24
+ - **Directory structure:** Correct place and flat tree constraints.
25
+ - **Field constraints:** Descriptions vs name match.
26
+ - **Relational properties:** Verifies relative links resolve correctly on disc.
27
+ - Outputs `ValidationResult` objects wrapping aggregates of `ValidationError`.
28
+
29
+ ### 📜 4. Predefined Rules templates (`lib/src/rules.dart`)
30
+ Contains global definitions for standard checks. Uses standard types (`CheckType`) allowing toggling and severity states.
31
+
32
+ ### 📦 5. Core Data Models (`lib/src/models/`)
33
+ - **`ValidationError`:** Complex error object recording rule IDs, messages, severity contexts, and ignore statuses.
34
+ - **`CheckType`:** A schema binding check descriptions to severity settings.
35
+ - **`IgnoreEntry`:** Structure for serializing/deserializing file suppressions to/from JSON.
36
+
37
+ ---
38
+
39
+ ## ⏳ Execution Lifecycle
40
+
41
+ A typical run of the linter follows this sequential graph:
42
+
43
+ ```mermaid
44
+ graph TD
45
+ Start([CLI - runApp]) --> ArgParse[Parse ARGs & Load config.yaml]
46
+ ArgParse --> Discover[Resolve Target Directories]
47
+ Discover --> ValidatorLoad[Instantiate Validator w/ Settings]
48
+ ValidatorLoad --> DirLoop[Iterate Directories]
49
+ DirLoop --> Validation[Run validator.validate]
50
+ Validation --> ParseFront[YAML Frontmatter Parsing]
51
+ ParseFront --> RuleChecks[Run Field + Path Checks]
52
+ RuleChecks --> ResultAggregate[Compile ValidationError List]
53
+ ResultAggregate --> IgnoreFilter[Apply dart_skills_lint_ignore.json filters]
54
+ IgnoreFilter --> LogOutput[Print to console & Set exitCode]
55
+ LogOutput --> Next{Next Dir?}
56
+ Next -- Yes --> DirLoop
57
+ Next -- No --> Finish([Exit Term])
58
+ ```
59
+
60
+ ## 🧠 Design Principles
61
+
62
+ - **Separation of Concerns:** CLI runners are isolated from pure validation units. The `Validator` takes objects and doesn't know about `ArgResults`.
63
+ - **Stateless Configuration vs Overrides:** When running against a workspace with specific subdirectory traits, the `Validator` instances are re-instantiated with isolated context bindings so properties do not leak.
64
+ - **Context Preservation:** Standardizing lint exceptions (Ignore Systems) as structural objects rather than ad-hoc string matches prevent brittle regressions.
@@ -0,0 +1,11 @@
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
+ export 'src/config_parser.dart';
6
+ export 'src/entry_point.dart';
7
+ export 'src/models/analysis_severity.dart';
8
+ export 'src/models/skill_context.dart';
9
+ export 'src/models/skill_rule.dart';
10
+ export 'src/models/validation_error.dart';
11
+ export 'src/validator.dart';
@@ -0,0 +1,156 @@
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
+ // ignore_for_file: specify_nonobvious_local_variable_types yaml parsing has dynamic types.
6
+
7
+ import 'dart:io';
8
+ import 'package:logging/logging.dart';
9
+ import 'package:yaml/yaml.dart';
10
+ import 'models/analysis_severity.dart';
11
+
12
+ final _log = Logger('dart_skills_lint');
13
+
14
+ class ConfigParser {
15
+ static const _dartSkillsLintKey = 'dart_skills_lint';
16
+ static const _rulesKey = 'rules';
17
+ static const _directoriesKey = 'directories';
18
+ static const _pathKey = 'path';
19
+ static const _ignoreFileKey = 'ignore_file';
20
+
21
+ static const Set<String> _allowedTopLevelKeys = {_rulesKey, _directoriesKey};
22
+ static const Set<String> _allowedDirectoryKeys = {_pathKey, _rulesKey, _ignoreFileKey};
23
+
24
+ static AnalysisSeverity _parseSeverity(String value) {
25
+ if (value == 'error') {
26
+ return AnalysisSeverity.error;
27
+ }
28
+ if (value == 'warning') {
29
+ return AnalysisSeverity.warning;
30
+ }
31
+ if (value == 'disabled') {
32
+ return AnalysisSeverity.disabled;
33
+ }
34
+ return AnalysisSeverity.disabled; // Default if unknown
35
+ }
36
+
37
+ /// Reads dart_skills_lint.yaml from the current directory and returns the configuration.
38
+ static Future<Configuration> loadConfig() async {
39
+ final configFile = File('dart_skills_lint.yaml');
40
+ if (!configFile.existsSync()) {
41
+ return Configuration();
42
+ }
43
+
44
+ try {
45
+ final String content = await configFile.readAsString();
46
+ final yaml = loadYaml(content);
47
+ if (yaml is YamlMap && yaml.containsKey(_dartSkillsLintKey)) {
48
+ final toolConfig = yaml[_dartSkillsLintKey];
49
+ if (toolConfig is YamlMap) {
50
+ final parsingErrors = <String>[];
51
+
52
+ _validateTopLevelKeys(toolConfig, parsingErrors);
53
+ final configuredRules = _parseRules(toolConfig);
54
+ final directoryConfigs = _parseDirectories(toolConfig, parsingErrors);
55
+ return Configuration(
56
+ directoryConfigs: directoryConfigs,
57
+ configuredRules: configuredRules,
58
+ parsingErrors: parsingErrors,
59
+ );
60
+ }
61
+ }
62
+ } catch (e) {
63
+ _log.warning('Failed to parse dart_skills_lint.yaml: $e');
64
+ }
65
+ return Configuration();
66
+ }
67
+
68
+ /// Validates that all keys at the top level of the `dart_skills_lint` configuration map are recognized.
69
+ /// Appends error messages to `parsingErrors` for any unrecognized keys.
70
+ static void _validateTopLevelKeys(YamlMap toolConfig, List<String> parsingErrors) {
71
+ for (final key in toolConfig.keys) {
72
+ if (!_allowedTopLevelKeys.contains(key.toString())) {
73
+ parsingErrors.add('Unrecognized top-level key "$key" in dart_skills_lint configuration.');
74
+ }
75
+ }
76
+ }
77
+
78
+ /// Parses the global rules configuration from the `dart_skills_lint` map.
79
+ /// Returns a map of rule names to their resolved `AnalysisSeverity`.
80
+ static Map<String, AnalysisSeverity> _parseRules(YamlMap toolConfig) {
81
+ final configuredRules = <String, AnalysisSeverity>{};
82
+ if (toolConfig.containsKey(_rulesKey)) {
83
+ final rules = toolConfig[_rulesKey];
84
+ if (rules is YamlMap) {
85
+ for (final key in rules.keys) {
86
+ configuredRules[key.toString()] = _parseSeverity(rules[key]?.toString() ?? '');
87
+ }
88
+ }
89
+ }
90
+ return configuredRules;
91
+ }
92
+
93
+ /// Parses the `directories` list from the configuration.
94
+ /// Validates keys for each directory entry and resolves path-specific rule overrides.
95
+ /// Appends any parsing errors to `parsingErrors`.
96
+ static List<DirectoryConfig> _parseDirectories(YamlMap toolConfig, List<String> parsingErrors) {
97
+ final directoryConfigs = <DirectoryConfig>[];
98
+ if (toolConfig.containsKey(_directoriesKey)) {
99
+ final dirs = toolConfig[_directoriesKey];
100
+ if (dirs is YamlList) {
101
+ for (final dir in dirs) {
102
+ if (dir is YamlMap && dir.containsKey(_pathKey)) {
103
+ final path = dir[_pathKey] as String;
104
+
105
+ for (final key in dir.keys) {
106
+ if (!_allowedDirectoryKeys.contains(key.toString())) {
107
+ parsingErrors.add('Unrecognized key "$key" in directory entry for "$path".');
108
+ }
109
+ }
110
+
111
+ final rules = <String, AnalysisSeverity>{};
112
+ if (dir.containsKey(_rulesKey)) {
113
+ final localRules = dir[_rulesKey];
114
+ if (localRules is YamlMap) {
115
+ for (final key in localRules.keys) {
116
+ rules[key.toString()] = _parseSeverity(localRules[key]?.toString() ?? '');
117
+ }
118
+ }
119
+ }
120
+ final ignoreFile = dir[_ignoreFileKey] as String?;
121
+ directoryConfigs.add(DirectoryConfig(path: path, rules: rules, ignoreFile: ignoreFile));
122
+ }
123
+ }
124
+ }
125
+ }
126
+ return directoryConfigs;
127
+ }
128
+ }
129
+
130
+ /// Configuration for a specific directory containing skills.
131
+ ///
132
+ /// Allows overriding rules and specifying a custom ignore file for skills
133
+ /// located within this directory.
134
+ class DirectoryConfig {
135
+ DirectoryConfig({required this.path, required this.rules, this.ignoreFile});
136
+
137
+ /// The path to the directory containing skills.
138
+ ///
139
+ /// Can be absolute or relative to the current working directory.
140
+ /// Supports tilde expansion (e.g., `~/...`).
141
+ final String path;
142
+ final Map<String, AnalysisSeverity> rules;
143
+ final String? ignoreFile;
144
+ }
145
+
146
+ /// Structured configuration for the linter.
147
+ class Configuration {
148
+ Configuration({
149
+ this.directoryConfigs = const [],
150
+ this.configuredRules = const {},
151
+ this.parsingErrors = const [],
152
+ });
153
+ final List<DirectoryConfig> directoryConfigs;
154
+ final Map<String, AnalysisSeverity> configuredRules;
155
+ final List<String> parsingErrors;
156
+ }