agents: Add skill for reading LE audio profiles specifications

Change-Id: I0eb7ee7b3b04dea6ebfd38844790bde31e64ec5e
Reviewed-on: https://bluetooth-review.googlesource.com/c/bluetooth/+/2901
diff --git a/.agents/skills/le_profiles_specifications/SKILL.md b/.agents/skills/le_profiles_specifications/SKILL.md
new file mode 100644
index 0000000..03ac327
--- /dev/null
+++ b/.agents/skills/le_profiles_specifications/SKILL.md
@@ -0,0 +1,18 @@
+---
+name: LE Audio Profiles Specifications
+description: Caches and provides access to LE Audio profile specifications.
+---
+
+# LE Audio Profiles Specifications
+
+This resource maintains a local cache of specifications related to LE Audio profiles and services.
+
+## Structure
+
+The specifications are stored in the `specifications/` directory in this skill folder.
+You can search them directly using `grep_search` or read them with `view_file`.
+
+## Management
+
+To refresh or download the specifications, run:
+`python3 .agents/skills/le_profiles_specifications/scripts/downloader.py`
diff --git a/.agents/skills/le_profiles_specifications/scripts/downloader.py b/.agents/skills/le_profiles_specifications/scripts/downloader.py
new file mode 100644
index 0000000..a50acec
--- /dev/null
+++ b/.agents/skills/le_profiles_specifications/scripts/downloader.py
@@ -0,0 +1,111 @@
+import os
+from urllib.request import urlopen, Request
+from urllib.error import URLError
+from bs4 import BeautifulSoup
+
+SPEC_DIR = os.path.join(
+    os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
+    "specifications",
+)
+
+# List of specifications to download
+SPECS = [
+    {
+        "name": "BAP_v1.0.2",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/BAP_v1.0.2/out/en/index-en.html",
+    },
+    {
+        "name": "CAP_v1.0.1",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/CAP_v1.0.1/out/en/index-en.html",
+    },
+    {
+        "name": "TMAP_v1.0.1",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/TMAP_v1.0.1/out/en/index-en.html",
+    },
+    {
+        "name": "HAP_v1.0.1",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/HAP_v1.0.1/out/en/index-en.html",
+    },
+    {
+        "name": "PBP_v1.0.1",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/PBP_v1.0.1/out/en/index-en.html",
+    },
+    {
+        "name": "MCP_v1.0",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/28982-MCP-html5/out/en/index-en.html",
+    },
+    {
+        "name": "CCP_v1.0",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/26587-CCP-html5/out/en/index-en.html",
+    },
+    {
+        "name": "MICP_v1.0",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/21264-MICP-html5/out/en/index-en.html",
+    },
+    {
+        "name": "VCP_v1.0",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/76878-VCP-html5/out/en/index-en.html",
+    },
+    {
+        "name": "ASCS_v1.0.1",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/ASCS_v1.0.1/out/en/index-en.html",
+    },
+    {
+        "name": "PACS_v1.0.2",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/PACS_v1.0.2/out/en/index-en.html",
+    },
+    {
+        "name": "CSIS_v1.0",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/28085-CSIS-html5/out/en/index-en.html",
+    },
+    {
+        "name": "CSIP_v1.0",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/27407-CSIP-html5/out/en/index-en.html",
+    },
+    {
+        "name": "BASS_v1.0.1",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/BASS_v1.0.1/out/en/index-en.html",
+    },
+    {
+        "name": "AICS_v1.0.1",
+        "url": "https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/AICS_v1.0.1/out/en/index-en.html",
+    },
+]
+
+def download_spec(name, url):
+    print(f"Downloading {name} from {url}...")
+    headers = {'User-Agent': 'Mozilla/5.0'}
+    try:
+        req = Request(url, headers=headers)
+        with urlopen(req, timeout=30) as response:
+            html_content = response.read()
+
+            # Create spec dir if not exists
+            os.makedirs(SPEC_DIR, exist_ok=True)
+
+            # Save HTML
+            html_path = os.path.join(SPEC_DIR, f"{name}.html")
+            with open(html_path, 'wb') as f:
+                f.write(html_content)
+            print(f"Saved HTML to {html_path}")
+
+            # Save Text/Markdown for searching
+            soup = BeautifulSoup(html_content, 'html.parser')
+            text_content = soup.get_text(separator='\n', strip=True)
+
+            md_path = os.path.join(SPEC_DIR, f"{name}.md")
+            with open(md_path, 'w', encoding='utf-8') as f:
+                f.write(text_content)
+            print(f"Saved Markdown to {md_path}")
+
+    except URLError as e:
+        print(f"Error downloading {name}: {e}")
+    except Exception as e:
+        print(f"An error occurred: {e}")
+
+def main():
+    for spec in SPECS:
+        download_spec(spec["name"], spec["url"])
+
+if __name__ == "__main__":
+    main()
diff --git a/.gitignore b/.gitignore
index b45d8bf..b4147a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,4 @@
 infra/packages
 
 # Specification files.
-.agents/skills/core_specification/specifications
+.agents/skills/*/specifications