Skip to content

Commit d3bed7c

Browse files
skills: drop pyyaml dep, hand-roll description parser
The previous fix added `pip install pyyaml` to the validate workflow, but the databricks-protected-runner can't reach pypi.org (SSL errors on every retry). Restoring a stdlib-only description parser sidesteps the network requirement entirely. The hand-rolled parser is the same shape as the pre-db9b2e5 version: handles plain, quoted, and block-scalar (>- / |-) values. db9b2e5 moved to yaml.safe_load to also unescape inner \" sequences, but no current SKILL.md description uses that escape, so the regression risk is nil. Re-introducing pyyaml is a one-line change if a future description ever needs it. Manifest regenerated; no content drift, only updated_at moved. Co-authored-by: Isaac
1 parent c595b45 commit d3bed7c

3 files changed

Lines changed: 29 additions & 10 deletions

File tree

.github/workflows/validate-manifest.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,5 @@ jobs:
2525
with:
2626
python-version: '3.11'
2727

28-
- name: Install Python deps
29-
run: pip install pyyaml
30-
3128
- name: Validate manifest is up to date
3229
run: python3 scripts/skills.py validate

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"version": "2",
3-
"updated_at": "2026-05-18T21:44:44Z",
3+
"updated_at": "2026-05-19T14:54:40Z",
44
"skills": {
55
"databricks-apps": {
66
"version": "0.1.1",

scripts/skills.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
from datetime import datetime, timezone
1010
from pathlib import Path
1111

12-
import yaml
13-
1412

1513
SHARED_ASSETS = [
1614
"assets/databricks.svg",
@@ -194,8 +192,17 @@ def check_assets_synced(repo_root: Path) -> list[str]:
194192
# Manifest generation
195193
# ---------------------------------------------------------------------------
196194

195+
_BLOCK_SCALAR_INDICATORS = {"|", "|-", "|+", ">", ">-", ">+"}
196+
197+
197198
def extract_description_from_skill(skill_path: Path) -> str:
198-
"""Best-effort extraction of `description:` from SKILL.md frontmatter."""
199+
"""Best-effort extraction of `description:` from SKILL.md frontmatter.
200+
201+
Handles plain (`description: foo`), quoted (`description: "foo"`), and
202+
block-scalar (`description: >-` followed by indented lines) values.
203+
Stdlib-only to keep the validate workflow on the protected runner
204+
self-contained — that runner can't reach pypi.org.
205+
"""
199206
skill_md = skill_path / "SKILL.md"
200207
if not skill_md.exists():
201208
return ""
@@ -205,9 +212,24 @@ def extract_description_from_skill(skill_path: Path) -> str:
205212
end_idx = content.find("---", 3)
206213
if end_idx == -1:
207214
return ""
208-
parsed = yaml.safe_load(content[3:end_idx]) or {}
209-
description = parsed.get("description", "")
210-
return description.strip() if isinstance(description, str) else ""
215+
lines = content[3:end_idx].splitlines()
216+
for i, line in enumerate(lines):
217+
m = re.match(r'^description:\s*(.*?)\s*$', line)
218+
if not m:
219+
continue
220+
value = m.group(1)
221+
if value in _BLOCK_SCALAR_INDICATORS:
222+
collected = []
223+
for cont in lines[i + 1:]:
224+
if cont and not cont[0].isspace():
225+
break
226+
stripped = cont.strip()
227+
if stripped:
228+
collected.append(stripped)
229+
joiner = " " if value.startswith(">") else "\n"
230+
return joiner.join(collected)
231+
return value.strip().strip('"').strip("'")
232+
return ""
211233

212234

213235
# Markers that separate the "what this skill does" lead-in from the

0 commit comments

Comments
 (0)