Add dart_skills_lint to devtools and configure it to run in the cli and in tests (#9770)

* add dart skills lint test and yaml config with instructions for how to use

* Add ignore file for valid links that are triggering false positives

* resolve readme to correct location

* Copyright added to new files and issue linked in pubspec

* Add link to yaml configuration feature

* presubmit feedback

* Update tool/test/validate_skills_test.dart

Co-authored-by: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com>

* Update pubspec.yaml

Co-authored-by: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com>

* Fix one relative path issues, update version of dart_skills_lint

* remove the root dependency on dart_skills_lint

* Change todo format

* Remove double trailing line

---------

Co-authored-by: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com>
diff --git a/.agents/skills/README.md b/.agents/skills/README.md
new file mode 100644
index 0000000..8555a78
--- /dev/null
+++ b/.agents/skills/README.md
@@ -0,0 +1,40 @@
+<!--
+Copyright 2026 The Flutter Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
+-->
+
+# Agent Skills
+
+This directory contains AI agent skills for this repository.
+
+## Validation
+
+To ensure skills meet the required specification, they are automatically validated in pre-submit checks.
+You should also validate your skills locally before submitting a review.
+
+### Running the Linter Locally
+
+To validate skills locally before review, run the linter from the `tool` directory:
+
+```bash
+cd tool && dart run dart_skills_lint:cli
+```
+
+This will use the configuration in `tool/dart_skills_lint.yaml` to validate all skills in the `.agents/skills` directory.
+
+Or for a single skill (also from the `tool` directory):
+
+```bash
+cd tool && dart run dart_skills_lint:cli --skill ../.agents/skills/my-skill
+```
+
+### Running via Dart Test
+
+Alternatively, you can run the validation as a test from the `tool` directory:
+
+```bash
+cd tool && dart test test/validate_skills_test.dart
+```
+
+This ensures that the validation logic is executed in the same way as in CI.
diff --git a/.agents/skills/adding-release-notes/SKILL.md b/.agents/skills/adding-release-notes/SKILL.md
index c47b3e6..59853bf 100644
--- a/.agents/skills/adding-release-notes/SKILL.md
+++ b/.agents/skills/adding-release-notes/SKILL.md
@@ -84,4 +84,4 @@
 **Constraint**: Use **dark mode** for screenshots.
 
 ## Resources
-- [README.md](../../packages/devtools_app/release_notes/README.md): Official project guidance.
+- [README.md](../../../packages/devtools_app/release_notes/README.md): Official project guidance.
diff --git a/.agents/skills/authoring-skills/SKILL.md b/.agents/skills/authoring-skills/SKILL.md
index ab87119..da0bdcf 100644
--- a/.agents/skills/authoring-skills/SKILL.md
+++ b/.agents/skills/authoring-skills/SKILL.md
@@ -17,6 +17,7 @@
 - **Naming**: Use the gerund form (**verb-ing-noun**) or **noun-phrase** (e.g., `authoring-skills`, `adding-release-notes`). Use only lowercase letters, numbers, and hyphens.
 - **Conciseness**: Prioritize brevity in `SKILL.md`. Agents are already highly capable; only provide context they don't already have.
 - **Automation**: Any utility scripts placed in the `scripts/` directory MUST be written in **Dart**.
+- **Validation**: Skills are automatically validated using `dart_skills_lint`. Ensure your skills pass the linter before submitting. See the `README.md` in `.agents/skills/` for instructions on how to run the linter locally.
 - **Progressive Disclosure**: Use the patterns below to organize instructions effectively:
   - [CHECKLIST.md](CHECKLIST.md): Template for tracking skill development progress.
   - [EXAMPLES.md](EXAMPLES.md): Local examples and anti-patterns.
diff --git a/.agents/skills/dart_skills_lint_ignore.json b/.agents/skills/dart_skills_lint_ignore.json
new file mode 100644
index 0000000..a35a789
--- /dev/null
+++ b/.agents/skills/dart_skills_lint_ignore.json
@@ -0,0 +1,10 @@
+{
+  "skills": {
+    "adding-release-notes": [
+      {
+        "rule_id": "check-relative-paths",
+        "file_name": "SKILL.md"
+      }
+    ]
+  }
+}
\ No newline at end of file
diff --git a/pubspec.lock b/pubspec.lock
index 0bd580b..a55f54d 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -209,6 +209,15 @@
       url: "https://pub.dev"
     source: hosted
     version: "0.0.3"
+  dart_skills_lint:
+    dependency: transitive
+    description:
+      path: "tool/dart_skills_lint"
+      ref: "2420128e11101002e2eac98eb90512103a388714"
+      resolved-ref: "2420128e11101002e2eac98eb90512103a388714"
+      url: "https://github.com/flutter/skills"
+    source: git
+    version: "0.2.0"
   dart_style:
     dependency: transitive
     description:
diff --git a/tool/dart_skills_lint.yaml b/tool/dart_skills_lint.yaml
new file mode 100644
index 0000000..150e390
--- /dev/null
+++ b/tool/dart_skills_lint.yaml
@@ -0,0 +1,10 @@
+# Copyright 2026 The Flutter Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
+dart_skills_lint:
+  rules:
+    check-relative-paths: error
+    check-absolute-paths: error
+    check-trailing-whitespace: error
+  directories:
+    - path: "../.agents/skills"
diff --git a/tool/pubspec.yaml b/tool/pubspec.yaml
index 90ccf11..68671b4 100644
--- a/tool/pubspec.yaml
+++ b/tool/pubspec.yaml
@@ -21,6 +21,13 @@
   meta: ^1.18.0
   path: ^1.9.0
   yaml: ^3.1.2
-  
+
 dev_dependencies:
+  # TODO(https://github.com/flutter/devtools/issues/9771): Update to published version
+  dart_skills_lint:
+    git:
+      url: https://github.com/flutter/skills
+      path: tool/dart_skills_lint
+      ref: 2420128e11101002e2eac98eb90512103a388714
+  logging: ^1.1.1
   test: ^1.25.8
diff --git a/tool/test/validate_skills_test.dart b/tool/test/validate_skills_test.dart
new file mode 100644
index 0000000..7c50d63
--- /dev/null
+++ b/tool/test/validate_skills_test.dart
@@ -0,0 +1,35 @@
+// Copyright 2026 The Flutter Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
+
+import 'dart:async';
+import 'package:dart_skills_lint/dart_skills_lint.dart';
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('Validate DevTools Skills', () async {
+    final Level oldLevel = Logger.root.level;
+    Logger.root.level = Level.ALL;
+    final StreamSubscription<LogRecord> subscription = Logger.root.onRecord.listen((record) {
+      print(record.message);
+    });
+
+    try {
+      // TODO(https://github.com/flutter/skills/issues/85): Update test 
+      // to use dart_skills_lint.yaml for config when available.
+      final bool isValid = await validateSkills(
+        skillDirPaths: ['../.agents/skills'],
+        resolvedRules: {
+          'check-relative-paths': AnalysisSeverity.error,
+          'check-absolute-paths': AnalysisSeverity.error,
+          'check-trailing-whitespace': AnalysisSeverity.error,
+        },
+      );
+      expect(isValid, isTrue, reason: 'Skills validation failed. See above for details.');
+    } finally {
+      Logger.root.level = oldLevel;
+      await subscription.cancel();
+    }
+  });
+}