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.
- package/bin.js +1 -1
- package/package.json +1 -1
- package/skills/.agents/skills/flutter-add-integration-test/SKILL.md +165 -0
- package/skills/.agents/skills/flutter-add-widget-preview/SKILL.md +147 -0
- package/skills/.agents/skills/flutter-add-widget-test/SKILL.md +156 -0
- package/skills/.agents/skills/flutter-apply-architecture-best-practices/SKILL.md +164 -0
- package/skills/.agents/skills/flutter-build-responsive-layout/SKILL.md +141 -0
- package/skills/.agents/skills/flutter-fix-layout-issues/SKILL.md +132 -0
- package/skills/.agents/skills/flutter-implement-json-serialization/SKILL.md +155 -0
- package/skills/.agents/skills/flutter-setup-declarative-routing/SKILL.md +257 -0
- package/skills/.agents/skills/flutter-setup-localization/SKILL.md +212 -0
- package/skills/.agents/skills/flutter-use-http-package/SKILL.md +177 -0
- package/skills/VERSION.md +176 -62
- package/skills/design-planning/ai-coding-rules/SKILL.md +5 -13
- package/skills/design-planning/design-to-code/SKILL.md +5 -14
- package/skills/design-planning/enterprise-spec/SKILL.md +5 -13
- package/skills/design-planning/flutter-av/SKILL.md +5 -16
- package/skills/design-planning/flutter-map/SKILL.md +5 -14
- package/skills/design-planning/function-sdd/SKILL.md +5 -13
- package/skills/design-planning/global-overlay-stack-standard/SKILL.md +73 -0
- package/skills/design-planning/ui-motion-interaction-standard/SKILL.md +69 -0
- package/skills/design-planning/ui-sdd-specialized/SKILL.md +5 -14
- package/skills/development-execution/flutter-errors/SKILL.md +5 -15
- package/skills/flutter-skills/.github/dependabot.yaml +15 -0
- package/skills/flutter-skills/.github/workflows/dart_skills_lint_workflow.yaml +68 -0
- package/skills/flutter-skills/.github/workflows/skills_tool.yaml +51 -0
- package/skills/flutter-skills/CODE_OF_CONDUCT.md +3 -0
- package/skills/flutter-skills/CONTRIBUTING.md +36 -0
- package/skills/flutter-skills/LICENSE +26 -0
- package/skills/flutter-skills/README.md +50 -0
- package/skills/flutter-skills/pubspec.yaml +9 -0
- package/skills/flutter-skills/resources/flutter_skills.yaml +434 -0
- package/skills/flutter-skills/skills/flutter-add-integration-test/SKILL.md +163 -0
- package/skills/flutter-skills/skills/flutter-add-widget-preview/SKILL.md +145 -0
- package/skills/flutter-skills/skills/flutter-add-widget-test/SKILL.md +154 -0
- package/skills/flutter-skills/skills/flutter-apply-architecture-best-practices/SKILL.md +162 -0
- package/skills/flutter-skills/skills/flutter-build-responsive-layout/SKILL.md +139 -0
- package/skills/flutter-skills/skills/flutter-fix-layout-issues/SKILL.md +130 -0
- package/skills/flutter-skills/skills/flutter-implement-json-serialization/SKILL.md +153 -0
- package/skills/flutter-skills/skills/flutter-setup-declarative-routing/SKILL.md +255 -0
- package/skills/flutter-skills/skills/flutter-setup-localization/SKILL.md +210 -0
- package/skills/flutter-skills/skills/flutter-use-http-package/SKILL.md +175 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/add-dart-lint-validation-rule/SKILL.md +196 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-best-practices/SKILL.md +65 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-checks-migration/SKILL.md +158 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-cli-app-best-practices/SKILL.md +168 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-doc-validation/SKILL.md +87 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-long-lines/SKILL.md +101 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-matcher-best-practices/SKILL.md +136 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-modern-features/SKILL.md +266 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-package-maintenance/SKILL.md +92 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/SKILL.md +92 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/lib/src/calculator.dart +7 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/pubspec.yaml +8 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/test/calculator_test.dart +11 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/interpret_coverage.dart +95 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/pubspec.yaml +6 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/test/interpret_coverage_test.dart +93 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-fundamentals/SKILL.md +173 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/definition-of-done/SKILL.md +27 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/flutter_skills_ignore.json +3 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/grill-me/SKILL.md +10 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/ignore.json +3 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/SKILL.md +371 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/skills/flutter-skills/tool/dart_skills_lint/AUTHORS +7 -0
- package/skills/flutter-skills/tool/dart_skills_lint/CHANGELOG.md +12 -0
- package/skills/flutter-skills/tool/dart_skills_lint/CONTRIBUTING.md +51 -0
- package/skills/flutter-skills/tool/dart_skills_lint/LICENSE +27 -0
- package/skills/flutter-skills/tool/dart_skills_lint/README.md +203 -0
- package/skills/flutter-skills/tool/dart_skills_lint/analysis_options.yaml +296 -0
- package/skills/flutter-skills/tool/dart_skills_lint/bench/README.md +23 -0
- package/skills/flutter-skills/tool/dart_skills_lint/bench/baseline_throughput.dart +230 -0
- package/skills/flutter-skills/tool/dart_skills_lint/bin/cli.dart +10 -0
- package/skills/flutter-skills/tool/dart_skills_lint/dart_skills_lint.yaml +14 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/PRODUCTION_READYNESS.md +48 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/completion_migration_plan.md +99 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/legacy_patterns_report.md +110 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/pub_vs_skill_report.md +56 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/SPECIFICATION.md +79 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/architecture_overview.md +64 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/dart_skills_lint.dart +11 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/config_parser.dart +156 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/entry_point.dart +354 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/fixable_rule.dart +20 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/analysis_severity.dart +15 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/check_type.dart +17 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.dart +34 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.g.dart +19 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_context.dart +27 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_rule.dart +27 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.dart +26 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.g.dart +24 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/validation_error.dart +31 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rule_registry.dart +79 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/absolute_paths_rule.dart +74 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/description_length_rule.dart +49 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/disallowed_field_rule.dart +61 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/name_format_rule.dart +167 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/relative_paths_rule.dart +72 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/trailing_whitespace_rule.dart +93 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/valid_yaml_metadata_rule.dart +74 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/skills_ignores_storage.dart +36 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validation_session.dart +559 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validator.dart +238 -0
- package/skills/flutter-skills/tool/dart_skills_lint/pubspec.yaml +28 -0
- package/skills/flutter-skills/tool/dart_skills_lint/skills/README.md +10 -0
- package/skills/flutter-skills/tool/dart_skills_lint/skills/dart-skills-lint-validation/SKILL.md +195 -0
- package/skills/flutter-skills/tool/dart_skills_lint/skills-lock.json +75 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/absolute_paths_test.dart +167 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/cli_integration_test.dart +683 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/config_file_test.dart +292 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/custom_rule_test.dart +122 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/directory_structure_test.dart +163 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/field_constraints_test.dart +178 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/fixer_test.dart +172 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/ignore_models_test.dart +63 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/metadata_validation_test.dart +116 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/relative_path_flag_test.dart +70 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/relative_paths_test.dart +172 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/resolve_rules_test.dart +82 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/rule_naming_test.dart +29 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/skills_ignores_storage_test.dart +89 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/test_utils.dart +19 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/trailing_whitespace_test.dart +152 -0
- package/skills/flutter-skills/tool/generator/README.md +150 -0
- package/skills/flutter-skills/tool/generator/analysis_options.yaml +143 -0
- package/skills/flutter-skills/tool/generator/bin/skills.dart +73 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/base_skill_command.dart +87 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/base_yaml_command.dart +83 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/generate_skill_command.dart +92 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/update_readme_command.dart +150 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/update_skill_command.dart +97 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/validate_skill_command.dart +284 -0
- package/skills/flutter-skills/tool/generator/lib/src/models/skill_params.dart +41 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/gemini_service.dart +310 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/markdown_converter.dart +226 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/prompts.dart +72 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/resource_fetcher_service.dart +84 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/skill_instructions.dart +30 -0
- package/skills/flutter-skills/tool/generator/pubspec.yaml +32 -0
- package/skills/flutter-skills/tool/generator/test/commands/base_skill_command_test.dart +131 -0
- package/skills/flutter-skills/tool/generator/test/commands/validate_skills_input_test.dart +263 -0
- package/skills/flutter-skills/tool/generator/test/custom_skill_rules/last_modified_rule.dart +32 -0
- package/skills/flutter-skills/tool/generator/test/generate_skills_retry_test.dart +105 -0
- package/skills/flutter-skills/tool/generator/test/generate_skills_test.dart +519 -0
- package/skills/flutter-skills/tool/generator/test/lint_skills_test.dart +34 -0
- package/skills/flutter-skills/tool/generator/test/markdown_converter_test.dart +103 -0
- package/skills/flutter-skills/tool/generator/test/markdown_table_test.dart +131 -0
- package/skills/flutter-skills/tool/generator/test/models/skill_params_test.dart +37 -0
- package/skills/flutter-skills/tool/generator/test/services/gemini_service_test.dart +291 -0
- package/skills/flutter-skills/tool/generator/test/services/markdown_converter_test.dart +156 -0
- package/skills/flutter-skills/tool/generator/test/services/resource_fetcher_service_test.dart +188 -0
- package/skills/flutter-skills/tool/generator/test/update_skills_test.dart +241 -0
- package/skills/flutter-skills/tool/generator/test/validate_skills_test.dart +728 -0
- package/skills/quality-assurance/bdd-acceptance/SKILL.md +5 -14
- package/skills/quality-assurance/flutter-test/SKILL.md +5 -16
- package/skills/rules/project_rules.md +538 -127
- package/skills/special-tools/env-check/SKILL.md +5 -13
- package/skills/special-tools/ios-full-auto-debug/SKILL.md +5 -15
- package/skills/writing-skills/SKILL.md +654 -0
- package/skills/writing-skills/anthropic-best-practices.md +1149 -0
- package/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/writing-skills/persuasion-principles.md +187 -0
- package/skills/writing-skills/render-graphs.js +168 -0
- package/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/skills/checklist.md +0 -154
- package/skills/rules/user_rules.md +0 -263
- 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
- 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
- package/skills//346/212/200/350/203/275/344/275/277/347/224/250/346/214/207/345/215/227.md +0 -309
- package/skills//346/212/200/350/203/275/345/206/263/347/255/226/346/240/221.md +0 -338
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# Specify analysis options.
|
|
2
|
+
#
|
|
3
|
+
# For a list of lints, see: https://dart.dev/tools/linter-rules
|
|
4
|
+
# For guidelines on configuring static analysis, see:
|
|
5
|
+
# https://dart.dev/tools/analysis
|
|
6
|
+
#
|
|
7
|
+
# There are other similar analysis options files in the flutter repos,
|
|
8
|
+
# which should be kept in sync with this file:
|
|
9
|
+
#
|
|
10
|
+
# - analysis_options.yaml (this file)
|
|
11
|
+
# - https://github.com/flutter/packages/blob/main/analysis_options.yaml
|
|
12
|
+
|
|
13
|
+
analyzer:
|
|
14
|
+
language:
|
|
15
|
+
strict-casts: true
|
|
16
|
+
strict-inference: true
|
|
17
|
+
strict-raw-types: true
|
|
18
|
+
plugins:
|
|
19
|
+
- dart_code_linter
|
|
20
|
+
errors:
|
|
21
|
+
# allow deprecated members (we do this because otherwise we have to annotate
|
|
22
|
+
# every member in every test, assert, etc, when we or the Dart SDK deprecates
|
|
23
|
+
# something (https://github.com/flutter/flutter/issues/143312)
|
|
24
|
+
deprecated_member_use: ignore
|
|
25
|
+
deprecated_member_use_from_same_package: ignore
|
|
26
|
+
exclude:
|
|
27
|
+
- "bin/cache/**"
|
|
28
|
+
# Ignore protoc generated files
|
|
29
|
+
- "dev/conductor/lib/proto/*"
|
|
30
|
+
- "engine/**"
|
|
31
|
+
|
|
32
|
+
formatter:
|
|
33
|
+
page_width: 100
|
|
34
|
+
|
|
35
|
+
linter:
|
|
36
|
+
rules:
|
|
37
|
+
# This list is derived from the list of all available lints located at
|
|
38
|
+
# https://github.com/dart-lang/sdk/blob/main/pkg/linter/example/all.yaml
|
|
39
|
+
- always_declare_return_types
|
|
40
|
+
- always_put_control_body_on_new_line
|
|
41
|
+
# - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
|
|
42
|
+
# - always_specify_types # conflicts with omit_obvious_local_variable_types
|
|
43
|
+
# - always_use_package_imports # we do this commonly
|
|
44
|
+
- annotate_overrides
|
|
45
|
+
- annotate_redeclares
|
|
46
|
+
# - avoid_annotating_with_dynamic # conflicts with type_annotate_public_apis
|
|
47
|
+
- avoid_bool_literals_in_conditional_expressions
|
|
48
|
+
# - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023
|
|
49
|
+
# - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/4998
|
|
50
|
+
# - avoid_classes_with_only_static_members # we do this commonly for `abstract final class`es
|
|
51
|
+
- avoid_double_and_int_checks
|
|
52
|
+
- avoid_dynamic_calls
|
|
53
|
+
- avoid_empty_else
|
|
54
|
+
- avoid_equals_and_hash_code_on_mutable_classes
|
|
55
|
+
- avoid_escaping_inner_quotes
|
|
56
|
+
- avoid_field_initializers_in_const_classes
|
|
57
|
+
# - avoid_final_parameters # incompatible with prefer_final_parameters
|
|
58
|
+
- avoid_function_literals_in_foreach_calls
|
|
59
|
+
# - avoid_futureor_void # not yet tested
|
|
60
|
+
# - avoid_implementing_value_types # see https://github.com/dart-lang/linter/issues/4558
|
|
61
|
+
- avoid_init_to_null
|
|
62
|
+
- avoid_js_rounded_ints
|
|
63
|
+
# - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to
|
|
64
|
+
- avoid_null_checks_in_equality_operators
|
|
65
|
+
# - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it
|
|
66
|
+
- avoid_print
|
|
67
|
+
# - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356)
|
|
68
|
+
- avoid_redundant_argument_values
|
|
69
|
+
- avoid_relative_lib_imports
|
|
70
|
+
- avoid_renaming_method_parameters
|
|
71
|
+
- avoid_return_types_on_setters
|
|
72
|
+
- avoid_returning_null_for_void
|
|
73
|
+
# - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives
|
|
74
|
+
- avoid_setters_without_getters
|
|
75
|
+
- avoid_shadowing_type_parameters
|
|
76
|
+
- avoid_single_cascade_in_expression_statements
|
|
77
|
+
- avoid_slow_async_io
|
|
78
|
+
- avoid_type_to_string
|
|
79
|
+
- avoid_types_as_parameter_names
|
|
80
|
+
# - avoid_types_on_closure_parameters # not yet tested
|
|
81
|
+
- avoid_unnecessary_containers
|
|
82
|
+
- avoid_unused_constructor_parameters
|
|
83
|
+
- avoid_void_async
|
|
84
|
+
# - avoid_web_libraries_in_flutter # we use web libraries in web-specific code, and our tests prevent us from using them elsewhere
|
|
85
|
+
- await_only_futures
|
|
86
|
+
- camel_case_extensions
|
|
87
|
+
- camel_case_types
|
|
88
|
+
- cancel_subscriptions
|
|
89
|
+
# - cascade_invocations # doesn't match the typical style of this repo
|
|
90
|
+
- cast_nullable_to_non_nullable
|
|
91
|
+
# - close_sinks # not reliable enough
|
|
92
|
+
- collection_methods_unrelated_type
|
|
93
|
+
- combinators_ordering
|
|
94
|
+
# - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142
|
|
95
|
+
- conditional_uri_does_not_exist
|
|
96
|
+
# - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204
|
|
97
|
+
- control_flow_in_finally
|
|
98
|
+
- curly_braces_in_flow_control_structures
|
|
99
|
+
- dangling_library_doc_comments
|
|
100
|
+
- depend_on_referenced_packages
|
|
101
|
+
- deprecated_consistency
|
|
102
|
+
# - deprecated_member_use_from_same_package # we allow self-references to deprecated members
|
|
103
|
+
# - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib)
|
|
104
|
+
- directives_ordering
|
|
105
|
+
# - discarded_futures # too many false positives, similar to unawaited_futures
|
|
106
|
+
# - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic
|
|
107
|
+
# - document_ignores # not yet tested
|
|
108
|
+
- empty_catches
|
|
109
|
+
- empty_constructor_bodies
|
|
110
|
+
- empty_statements
|
|
111
|
+
- eol_at_end_of_file
|
|
112
|
+
- exhaustive_cases
|
|
113
|
+
- file_names
|
|
114
|
+
- flutter_style_todos
|
|
115
|
+
- hash_and_equals
|
|
116
|
+
- implementation_imports
|
|
117
|
+
- implicit_call_tearoffs
|
|
118
|
+
- implicit_reopen
|
|
119
|
+
- invalid_case_patterns
|
|
120
|
+
- invalid_runtime_check_with_js_interop_types
|
|
121
|
+
# - join_return_with_assignment # not required by flutter style
|
|
122
|
+
- leading_newlines_in_multiline_strings
|
|
123
|
+
- library_annotations
|
|
124
|
+
- library_names
|
|
125
|
+
- library_prefixes
|
|
126
|
+
- library_private_types_in_public_api
|
|
127
|
+
# - lines_longer_than_80_chars # not required by flutter style
|
|
128
|
+
- literal_only_boolean_expressions
|
|
129
|
+
# - matching_super_parameters # blocked on https://github.com/dart-lang/language/issues/2509
|
|
130
|
+
- missing_code_block_language_in_doc_comment
|
|
131
|
+
- missing_whitespace_between_adjacent_strings
|
|
132
|
+
- no_adjacent_strings_in_list
|
|
133
|
+
- no_default_cases
|
|
134
|
+
- no_duplicate_case_values
|
|
135
|
+
- no_leading_underscores_for_library_prefixes
|
|
136
|
+
- no_leading_underscores_for_local_identifiers
|
|
137
|
+
- no_literal_bool_comparisons
|
|
138
|
+
- no_logic_in_create_state
|
|
139
|
+
# - no_runtimeType_toString # ok in tests; we enable this only in packages/
|
|
140
|
+
- no_self_assignments
|
|
141
|
+
- no_wildcard_variable_uses
|
|
142
|
+
- non_constant_identifier_names
|
|
143
|
+
- noop_primitive_operations
|
|
144
|
+
- null_check_on_nullable_type_parameter
|
|
145
|
+
- null_closures
|
|
146
|
+
# - omit_local_variable_types # superset of omit_obvious_local_variable_types
|
|
147
|
+
- omit_obvious_local_variable_types # not yet tested
|
|
148
|
+
# - omit_obvious_property_types # conflicts with type_annotate_public_apis
|
|
149
|
+
# - one_member_abstracts # too many false positives
|
|
150
|
+
- only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al
|
|
151
|
+
- overridden_fields
|
|
152
|
+
- package_names
|
|
153
|
+
- package_prefixed_library_names
|
|
154
|
+
# - parameter_assignments # we do this commonly
|
|
155
|
+
- prefer_adjacent_string_concatenation
|
|
156
|
+
- prefer_asserts_in_initializer_lists
|
|
157
|
+
# - prefer_asserts_with_message # not required by flutter style
|
|
158
|
+
- prefer_collection_literals
|
|
159
|
+
- prefer_conditional_assignment
|
|
160
|
+
- prefer_const_constructors
|
|
161
|
+
- prefer_const_constructors_in_immutables
|
|
162
|
+
- prefer_const_declarations
|
|
163
|
+
- prefer_const_literals_to_create_immutables
|
|
164
|
+
# - prefer_constructors_over_static_methods # far too many false positives
|
|
165
|
+
- prefer_contains
|
|
166
|
+
# - prefer_double_quotes # opposite of prefer_single_quotes
|
|
167
|
+
# - prefer_expression_function_bodies # conflicts with ./docs/contributing/Style-guide-for-Flutter-repo.md#consider-using--for-short-functions-and-methods
|
|
168
|
+
- prefer_final_fields
|
|
169
|
+
- prefer_final_in_for_each
|
|
170
|
+
- prefer_final_locals
|
|
171
|
+
# - prefer_final_parameters # adds too much verbosity
|
|
172
|
+
- prefer_for_elements_to_map_fromIterable
|
|
173
|
+
- prefer_foreach
|
|
174
|
+
- prefer_function_declarations_over_variables
|
|
175
|
+
- prefer_generic_function_type_aliases
|
|
176
|
+
- prefer_if_elements_to_conditional_expressions
|
|
177
|
+
- prefer_if_null_operators
|
|
178
|
+
- prefer_initializing_formals
|
|
179
|
+
- prefer_inlined_adds
|
|
180
|
+
# - prefer_int_literals # conflicts with ./docs/contributing/Style-guide-for-Flutter-repo.md#use-double-literals-for-double-constants
|
|
181
|
+
- prefer_interpolation_to_compose_strings
|
|
182
|
+
- prefer_is_empty
|
|
183
|
+
- prefer_is_not_empty
|
|
184
|
+
- prefer_is_not_operator
|
|
185
|
+
- prefer_iterable_whereType
|
|
186
|
+
- prefer_mixin
|
|
187
|
+
# - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere
|
|
188
|
+
- prefer_null_aware_operators
|
|
189
|
+
- prefer_relative_imports
|
|
190
|
+
- prefer_single_quotes
|
|
191
|
+
- prefer_spread_collections
|
|
192
|
+
- prefer_typing_uninitialized_variables
|
|
193
|
+
- prefer_void_to_null
|
|
194
|
+
- provide_deprecation_message
|
|
195
|
+
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
|
|
196
|
+
- recursive_getters
|
|
197
|
+
# - require_trailing_commas # would be nice, but requires a lot of manual work: 10,000+ code locations would need to be reformatted by hand after bulk fix is applied
|
|
198
|
+
- secure_pubspec_urls
|
|
199
|
+
- sized_box_for_whitespace
|
|
200
|
+
- sized_box_shrink_expand
|
|
201
|
+
- slash_for_doc_comments
|
|
202
|
+
- sort_child_properties_last
|
|
203
|
+
- sort_constructors_first
|
|
204
|
+
# - sort_pub_dependencies # prevents separating pinned transitive dependencies
|
|
205
|
+
- sort_unnamed_constructors_first
|
|
206
|
+
- specify_nonobvious_local_variable_types
|
|
207
|
+
- specify_nonobvious_property_types
|
|
208
|
+
- strict_top_level_inference
|
|
209
|
+
- test_types_in_equals
|
|
210
|
+
- throw_in_finally
|
|
211
|
+
- tighten_type_of_initializing_formals
|
|
212
|
+
- type_annotate_public_apis
|
|
213
|
+
- type_init_formals
|
|
214
|
+
- type_literal_in_constant_pattern
|
|
215
|
+
# - unawaited_futures # too many false positives, especially with the way AnimationController works
|
|
216
|
+
# - unintended_html_in_doc_comment # blocked on https://github.com/dart-lang/linter/issues/5065
|
|
217
|
+
# - unnecessary_async # not yet tested
|
|
218
|
+
- unnecessary_await_in_return
|
|
219
|
+
- unnecessary_brace_in_string_interps
|
|
220
|
+
- unnecessary_breaks
|
|
221
|
+
- unnecessary_const
|
|
222
|
+
- unnecessary_constructor_name
|
|
223
|
+
# - unnecessary_final # conflicts with prefer_final_locals
|
|
224
|
+
- unnecessary_getters_setters
|
|
225
|
+
# - unnecessary_ignore # Disabled by default to simplify migrations; should be periodically enabled locally to clean up offenders
|
|
226
|
+
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
|
|
227
|
+
- unnecessary_late
|
|
228
|
+
- unnecessary_library_directive
|
|
229
|
+
# - unnecessary_library_name # blocked on https://github.com/dart-lang/dartdoc/issues/3882
|
|
230
|
+
- unnecessary_new
|
|
231
|
+
- unnecessary_null_aware_assignments
|
|
232
|
+
- unnecessary_null_aware_operator_on_extension_on_nullable
|
|
233
|
+
- unnecessary_null_checks
|
|
234
|
+
- unnecessary_null_in_if_null_operators
|
|
235
|
+
- unnecessary_nullable_for_final_variable_declarations
|
|
236
|
+
- unnecessary_overrides
|
|
237
|
+
- unnecessary_parenthesis
|
|
238
|
+
# - unnecessary_raw_strings # what's "necessary" is a matter of opinion; consistency across strings can help readability more than this lint
|
|
239
|
+
- unnecessary_statements
|
|
240
|
+
- unnecessary_string_escapes
|
|
241
|
+
- unnecessary_string_interpolations
|
|
242
|
+
- unnecessary_this
|
|
243
|
+
- unnecessary_to_list_in_spreads
|
|
244
|
+
- unnecessary_underscores
|
|
245
|
+
- unreachable_from_main
|
|
246
|
+
- unrelated_type_equality_checks
|
|
247
|
+
# - unsafe_variance # not yet tested
|
|
248
|
+
- use_build_context_synchronously
|
|
249
|
+
- use_colored_box
|
|
250
|
+
# - use_decorated_box # leads to bugs: DecoratedBox and Container are not equivalent (Container inserts extra padding)
|
|
251
|
+
- use_enums
|
|
252
|
+
- use_full_hex_values_for_flutter_colors
|
|
253
|
+
- use_function_type_syntax_for_parameters
|
|
254
|
+
- use_if_null_to_convert_nulls_to_bools
|
|
255
|
+
- use_is_even_rather_than_modulo
|
|
256
|
+
- use_key_in_widget_constructors
|
|
257
|
+
- use_late_for_private_fields_and_variables
|
|
258
|
+
- use_named_constants
|
|
259
|
+
- use_raw_strings
|
|
260
|
+
- use_rethrow_when_possible
|
|
261
|
+
- use_setters_to_change_properties
|
|
262
|
+
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
|
|
263
|
+
- use_string_in_part_of_directives
|
|
264
|
+
- use_super_parameters
|
|
265
|
+
- use_test_throws_matchers
|
|
266
|
+
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
|
|
267
|
+
- use_truncating_division
|
|
268
|
+
- valid_regexps
|
|
269
|
+
- void_checks
|
|
270
|
+
|
|
271
|
+
dart_code_linter:
|
|
272
|
+
metrics:
|
|
273
|
+
cyclomatic-complexity: 20
|
|
274
|
+
rules:
|
|
275
|
+
# Explicit typing
|
|
276
|
+
- avoid-dynamic
|
|
277
|
+
- avoid-unnecessary-type-assertions
|
|
278
|
+
- avoid-unnecessary-type-casts
|
|
279
|
+
- avoid-unrelated-type-assertions
|
|
280
|
+
- avoid-collection-methods-with-unrelated-types
|
|
281
|
+
|
|
282
|
+
# Predictable structure
|
|
283
|
+
- avoid-nested-conditional-expressions
|
|
284
|
+
- no-equal-then-else
|
|
285
|
+
- no-boolean-literal-compare
|
|
286
|
+
- no-empty-block
|
|
287
|
+
- avoid-redundant-async
|
|
288
|
+
- avoid-passing-async-when-sync-expected
|
|
289
|
+
- avoid-late-keyword
|
|
290
|
+
- prefer-named-record-fields
|
|
291
|
+
|
|
292
|
+
# Clean up
|
|
293
|
+
- avoid-unused-parameters
|
|
294
|
+
- prefer-moving-to-variable
|
|
295
|
+
- prefer-match-file-name
|
|
296
|
+
- always-remove-listener
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Performance benchmarks
|
|
2
|
+
|
|
3
|
+
When changing the validation loop, baseline I/O, or path-normalization code,
|
|
4
|
+
run the throughput benchmark to make sure you haven't regressed:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
dart run bench/baseline_throughput.dart
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
This generates synthetic skills at multiple sizes, runs them through
|
|
11
|
+
`validateSkills` with `--generate-baseline`, and prints a wall-clock table.
|
|
12
|
+
The benchmark is intentionally not run in CI — wall-clock on hosted runners
|
|
13
|
+
is too noisy to enforce. Use it locally and compare your branch's table
|
|
14
|
+
against `main` before submitting changes.
|
|
15
|
+
|
|
16
|
+
## Options
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
--sizes Comma-separated list of N values (default: 10,100,1000)
|
|
20
|
+
--errors-per-skill Baseline-recordable errors per synthetic skill, 1-3 (default: 1)
|
|
21
|
+
--runs Timed runs per cell (default: 3)
|
|
22
|
+
--warmup Untimed warmup runs (default: 1)
|
|
23
|
+
```
|
|
@@ -0,0 +1,230 @@
|
|
|
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
|
+
/// Baseline-generation throughput benchmark for `dart_skills_lint`.
|
|
6
|
+
///
|
|
7
|
+
/// Generates synthetic skill directories at multiple sizes, runs them through
|
|
8
|
+
/// `validateSkills` with `--generate-baseline`, and prints a wall-clock table.
|
|
9
|
+
/// Intentionally not run in CI — see `bench/README.md`.
|
|
10
|
+
library;
|
|
11
|
+
|
|
12
|
+
import 'dart:io';
|
|
13
|
+
|
|
14
|
+
import 'package:args/args.dart';
|
|
15
|
+
import 'package:dart_skills_lint/dart_skills_lint.dart';
|
|
16
|
+
import 'package:path/path.dart' as p;
|
|
17
|
+
|
|
18
|
+
const String _sizesFlag = 'sizes';
|
|
19
|
+
const String _errorsPerSkillFlag = 'errors-per-skill';
|
|
20
|
+
const String _runsFlag = 'runs';
|
|
21
|
+
const String _warmupFlag = 'warmup';
|
|
22
|
+
const String _helpFlag = 'help';
|
|
23
|
+
|
|
24
|
+
Future<void> main(List<String> args) async {
|
|
25
|
+
final parser = ArgParser()
|
|
26
|
+
..addOption(
|
|
27
|
+
_sizesFlag,
|
|
28
|
+
defaultsTo: '10,100,1000',
|
|
29
|
+
help: 'Comma-separated list of N values (number of synthetic skills) to benchmark.',
|
|
30
|
+
)
|
|
31
|
+
..addOption(
|
|
32
|
+
_errorsPerSkillFlag,
|
|
33
|
+
defaultsTo: '1',
|
|
34
|
+
help: 'Number of baseline-recordable errors each synthetic skill should produce (1-3).',
|
|
35
|
+
)
|
|
36
|
+
..addOption(_runsFlag, defaultsTo: '3', help: 'Number of timed runs per cell.')
|
|
37
|
+
..addOption(_warmupFlag, defaultsTo: '1', help: 'Number of untimed warmup runs before timing.')
|
|
38
|
+
..addFlag(_helpFlag, abbr: 'h', negatable: false, help: 'Show usage information.');
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
final ArgResults results = parser.parse(args);
|
|
42
|
+
|
|
43
|
+
if (results[_helpFlag] as bool) {
|
|
44
|
+
stdout.writeln('Usage: dart run bench/baseline_throughput.dart [options]');
|
|
45
|
+
stdout.writeln(parser.usage);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
final List<int> sizes = _parseSizes(results[_sizesFlag] as String);
|
|
50
|
+
final int errorsPerSkill = _clampErrorsPerSkill(
|
|
51
|
+
_parsePositiveInt(results[_errorsPerSkillFlag] as String, _errorsPerSkillFlag),
|
|
52
|
+
);
|
|
53
|
+
final int runs = _parsePositiveInt(results[_runsFlag] as String, _runsFlag);
|
|
54
|
+
final int warmup = _parseNonNegativeInt(results[_warmupFlag] as String, _warmupFlag);
|
|
55
|
+
|
|
56
|
+
final rows = <_BenchResult>[];
|
|
57
|
+
for (final n in sizes) {
|
|
58
|
+
final _BenchResult row = await _benchSize(
|
|
59
|
+
n: n,
|
|
60
|
+
errorsPerSkill: errorsPerSkill,
|
|
61
|
+
runs: runs,
|
|
62
|
+
warmup: warmup,
|
|
63
|
+
);
|
|
64
|
+
rows.add(row);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
_printTable(rows);
|
|
68
|
+
} on FormatException catch (e) {
|
|
69
|
+
stderr.writeln('Error: ${e.message}');
|
|
70
|
+
stderr.writeln(parser.usage);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
int _parsePositiveInt(String raw, String flag) {
|
|
75
|
+
final int value =
|
|
76
|
+
int.tryParse(raw) ?? (throw FormatException('--$flag must be an integer (got "$raw").'));
|
|
77
|
+
if (value < 1) {
|
|
78
|
+
throw FormatException('--$flag must be >= 1 (got $value).');
|
|
79
|
+
}
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
int _parseNonNegativeInt(String raw, String flag) {
|
|
84
|
+
final int value =
|
|
85
|
+
int.tryParse(raw) ?? (throw FormatException('--$flag must be an integer (got "$raw").'));
|
|
86
|
+
if (value < 0) {
|
|
87
|
+
throw FormatException('--$flag must be >= 0 (got $value).');
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
List<int> _parseSizes(String raw) {
|
|
93
|
+
final sizes = <int>[];
|
|
94
|
+
for (final String token in raw.split(',').map((String s) => s.trim())) {
|
|
95
|
+
if (token.isEmpty) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
final int? n = int.tryParse(token);
|
|
99
|
+
if (n == null || n < 1) {
|
|
100
|
+
throw FormatException('--$_sizesFlag entries must be positive integers (got "$token").');
|
|
101
|
+
}
|
|
102
|
+
sizes.add(n);
|
|
103
|
+
}
|
|
104
|
+
if (sizes.isEmpty) {
|
|
105
|
+
throw const FormatException('--sizes must contain at least one positive integer.');
|
|
106
|
+
}
|
|
107
|
+
return sizes;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
int _clampErrorsPerSkill(int requested) {
|
|
111
|
+
const maxSupported = 3;
|
|
112
|
+
if (requested < 1) {
|
|
113
|
+
stderr.writeln('errors-per-skill must be >= 1; using 1.');
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
if (requested > maxSupported) {
|
|
117
|
+
stderr.writeln(
|
|
118
|
+
'errors-per-skill > $maxSupported is not supported (only $maxSupported distinct '
|
|
119
|
+
'baseline-recordable rules trigger per skill); clamping to $maxSupported.',
|
|
120
|
+
);
|
|
121
|
+
return maxSupported;
|
|
122
|
+
}
|
|
123
|
+
return requested;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
Future<_BenchResult> _benchSize({
|
|
127
|
+
required int n,
|
|
128
|
+
required int errorsPerSkill,
|
|
129
|
+
required int runs,
|
|
130
|
+
required int warmup,
|
|
131
|
+
}) async {
|
|
132
|
+
final Directory tempDir = Directory.systemTemp.createTempSync('dskl_bench_');
|
|
133
|
+
try {
|
|
134
|
+
final skillsRoot = Directory(p.join(tempDir.path, 'skills'))..createSync();
|
|
135
|
+
for (var i = 0; i < n; i++) {
|
|
136
|
+
_writeSyntheticSkill(skillsRoot, i, errorsPerSkill);
|
|
137
|
+
}
|
|
138
|
+
final String ignorePath = p.join(tempDir.path, 'ignore.json');
|
|
139
|
+
|
|
140
|
+
for (var i = 0; i < warmup; i++) {
|
|
141
|
+
await _runOnce(skillsRoot.path, ignorePath);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
final samples = <int>[];
|
|
145
|
+
for (var i = 0; i < runs; i++) {
|
|
146
|
+
final int ms = await _runOnce(skillsRoot.path, ignorePath);
|
|
147
|
+
samples.add(ms);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
samples.sort();
|
|
151
|
+
final int min = samples.first;
|
|
152
|
+
final int max = samples.last;
|
|
153
|
+
final int median = samples[samples.length ~/ 2];
|
|
154
|
+
return (n: n, minMs: min, medianMs: median, maxMs: max, runs: runs);
|
|
155
|
+
} finally {
|
|
156
|
+
if (tempDir.existsSync()) {
|
|
157
|
+
tempDir.deleteSync(recursive: true);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
Future<int> _runOnce(String skillsRootPath, String ignorePath) async {
|
|
163
|
+
final ignoreFile = File(ignorePath);
|
|
164
|
+
if (ignoreFile.existsSync()) {
|
|
165
|
+
ignoreFile.deleteSync();
|
|
166
|
+
}
|
|
167
|
+
final sw = Stopwatch()..start();
|
|
168
|
+
await validateSkills(
|
|
169
|
+
skillDirPaths: <String>[skillsRootPath],
|
|
170
|
+
generateBaseline: true,
|
|
171
|
+
quiet: true,
|
|
172
|
+
ignoreFileOverride: ignorePath,
|
|
173
|
+
);
|
|
174
|
+
sw.stop();
|
|
175
|
+
return sw.elapsedMilliseconds;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
void _writeSyntheticSkill(Directory skillsRoot, int index, int errorsPerSkill) {
|
|
179
|
+
final dirName = 'skill-$index';
|
|
180
|
+
final skillDir = Directory(p.join(skillsRoot.path, dirName))..createSync();
|
|
181
|
+
|
|
182
|
+
// Error 1: name mismatch — `name:` does not match the directory name.
|
|
183
|
+
// This always triggers `invalid-skill-name`.
|
|
184
|
+
const name = 'wrong-name-on-purpose';
|
|
185
|
+
|
|
186
|
+
// Error 2 (when errorsPerSkill >= 2): description longer than 1024 chars
|
|
187
|
+
// triggers `description-too-long`.
|
|
188
|
+
final String description = errorsPerSkill >= 2
|
|
189
|
+
? 'x' * 1100
|
|
190
|
+
: 'Synthetic skill for benchmarking; '
|
|
191
|
+
'the yaml name does not match the directory name '
|
|
192
|
+
'so the linter records a name-format error.';
|
|
193
|
+
|
|
194
|
+
// Error 3 (when errorsPerSkill >= 3): an absolute-path link in the body
|
|
195
|
+
// triggers `check-absolute-paths` (warning, but baseline-recordable). Using
|
|
196
|
+
// `p.absolute(...)` guarantees the link is absolute on the host OS regardless
|
|
197
|
+
// of platform (POSIX or Windows).
|
|
198
|
+
final body = errorsPerSkill >= 3
|
|
199
|
+
? '# Test skill\n\n[abs](${p.absolute('synthetic-abs-path')})\n'
|
|
200
|
+
: '# Test skill\n';
|
|
201
|
+
|
|
202
|
+
final sb = StringBuffer()
|
|
203
|
+
..writeln('---')
|
|
204
|
+
..writeln('name: $name')
|
|
205
|
+
..writeln('description: $description')
|
|
206
|
+
..writeln('---')
|
|
207
|
+
..writeln()
|
|
208
|
+
..write(body);
|
|
209
|
+
|
|
210
|
+
File(p.join(skillDir.path, 'SKILL.md')).writeAsStringSync(sb.toString());
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
void _printTable(List<_BenchResult> rows) {
|
|
214
|
+
stdout.writeln('N | min | median | max | runs');
|
|
215
|
+
stdout.writeln('-------|-------|--------|-------|-----');
|
|
216
|
+
for (final row in rows) {
|
|
217
|
+
stdout.writeln(
|
|
218
|
+
'${_padRight(row.n.toString(), 6)} '
|
|
219
|
+
'| ${_padLeft('${row.minMs}ms', 5)} '
|
|
220
|
+
'| ${_padLeft('${row.medianMs}ms', 6)} '
|
|
221
|
+
'| ${_padLeft('${row.maxMs}ms', 5)} '
|
|
222
|
+
'| ${row.runs}',
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
String _padRight(String s, int width) => s.padRight(width);
|
|
228
|
+
String _padLeft(String s, int width) => s.padLeft(width);
|
|
229
|
+
|
|
230
|
+
typedef _BenchResult = ({int n, int minMs, int medianMs, int maxMs, int runs});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env dart
|
|
2
|
+
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
|
|
3
|
+
// for details. All rights reserved. Use of this source code is governed by a
|
|
4
|
+
// BSD-style license that can be found in the LICENSE file.
|
|
5
|
+
|
|
6
|
+
import 'package:dart_skills_lint/src/entry_point.dart';
|
|
7
|
+
|
|
8
|
+
Future<void> main(List<String> arguments) async {
|
|
9
|
+
await runApp(arguments);
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
dart_skills_lint:
|
|
2
|
+
rules:
|
|
3
|
+
check-relative-paths: error
|
|
4
|
+
check-absolute-paths: error
|
|
5
|
+
directories:
|
|
6
|
+
- path: ".agents/skills"
|
|
7
|
+
rules:
|
|
8
|
+
check-trailing-whitespace: error
|
|
9
|
+
ignore_file: ".agents/skills/ignore.json"
|
|
10
|
+
- path: "../../skills"
|
|
11
|
+
ignore_file: ".agents/skills/flutter_skills_ignore.json"
|
|
12
|
+
- path: "skills"
|
|
13
|
+
rules:
|
|
14
|
+
check-trailing-whitespace: error
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Production Readiness Evaluation: `dart-skills-lint`
|
|
2
|
+
|
|
3
|
+
## Executive Summary
|
|
4
|
+
`dart_skills_lint` is a well-structured Dart CLI tool designed to enforce the Agent Skills specification. It demonstrates solid engineering fundamentals, including a decoupled architecture, comprehensive testing, and adherence to Dart CLI best practices. However, while the core logic is robust, it lacks several critical "production-grade" features required for broad ecosystem adoption and enterprise-level CI/CD integration.
|
|
5
|
+
|
|
6
|
+
**Current Status:** **Beta / Tooling Candidate**
|
|
7
|
+
*Suitable for internal use by Dart-savvy teams, but not yet ready for a broad, multi-language developer audience.*
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Technical Evaluation
|
|
12
|
+
|
|
13
|
+
### 1. Strengths
|
|
14
|
+
- **Architecture:** The project correctly separates CLI concerns (`entry_point.dart`) from validation logic (`validator.dart`), making it highly testable.
|
|
15
|
+
- **Testing:** Excellent test coverage, including integration tests using `test_process` and granular unit tests for field constraints.
|
|
16
|
+
- **Best Practices:** Follows Dart idiomatic patterns (minimal `bin/` file, `exitCode` management, `logging` package usage).
|
|
17
|
+
- **Configuration:** Initial support for `dart_skills_lint.yaml` allows for some flexibility in rule enforcement (error vs. warning).
|
|
18
|
+
|
|
19
|
+
### 2. Required Features Missing (Gaps)
|
|
20
|
+
- **Distribution & Portability:**
|
|
21
|
+
- No pre-compiled binaries. Users are forced to have a Dart SDK installed, which is a barrier for non-Dart developers (e.g., Python or JS agent creators).
|
|
22
|
+
- Not yet published to `pub.dev`.
|
|
23
|
+
- **Machine-Readable Output:** The tool only outputs human-readable logs. Production CI/CD pipelines often require JSON, SARIF, or JUnit XML formats for automated reporting and dashboarding.
|
|
24
|
+
- **Granular Suppression (Ignore):** There is no way to ignore a specific violation on a specific line (e.g., `// ignore: broken-link`). This leads to "all or nothing" scenarios.
|
|
25
|
+
- **Global Discovery:** The "skills" directory mode is useful but rigid. A more flexible discovery mechanism (e.g., recursively finding all `SKILL.md` files) would better support diverse repo structures.
|
|
26
|
+
- **Rule Extensibility:** Rules are currently hardcoded in the `Validator` class. Adding new specification requirements requires a code change and a new release.
|
|
27
|
+
|
|
28
|
+
### 3. Production Risks
|
|
29
|
+
- **Windows Compatibility:** While the `path` package is used, there is an explicit lack of testing for Windows-specific paths (drive letters, backslashes) in absolute path checks.
|
|
30
|
+
- **Performance:** No benchmarks for extremely large skill repositories. Synchronous file reads in batch mode might become a bottleneck.
|
|
31
|
+
- **Standardization:** The specification itself (`documentation/knowledge/SPECIFICATION.md`) is internal to the project. For broad adoption, the spec should ideally be versioned and hosted independently.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Adoption Strategy (Increasing Likelihood)
|
|
36
|
+
|
|
37
|
+
To move from a "project-specific utility" to an "industry-standard linter," the author should:
|
|
38
|
+
|
|
39
|
+
1. **Zero-Install Path:** Provide a GitHub Action (e.g., `uses: dart-lang/skills-lint@v1`) that runs the linter in a container, hiding the Dart dependency.
|
|
40
|
+
2. **Binary Releases:** Use `dart compile exe` to provide standalone binaries for Linux, macOS, and Windows via GitHub Releases.
|
|
41
|
+
3. **IDE Integration:** A simple VS Code extension that highlights `SKILL.md` errors in real-time would significantly improve the developer experience.
|
|
42
|
+
4. **Auto-Fix Capabilities:** Implement a `--fix` flag that can automatically correct simple issues (e.g., matching the `name` field to the directory name).
|
|
43
|
+
5. **Interactive Init:** Add a `dart_skills_lint init` command to help users set up their configuration file correctly.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Conclusion
|
|
48
|
+
The codebase is a high-quality foundation. By shifting focus from "correctly validating Dart code" to "providing a seamless experience for all agent developers," the project can achieve broad adoption.
|