2be0964d73
Teach pouch to optimize a named skill's loading layout: keep SKILL.md as a router, move mode-specific steps to references, and measure footprint with an audit script instead of dumping the whole skill into context.
77 lines
2.7 KiB
Python
77 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
SCRIPT = (
|
|
REPO_ROOT
|
|
/ "skills"
|
|
/ "pouch"
|
|
/ "scripts"
|
|
/ "audit_skill_structure.py"
|
|
)
|
|
|
|
|
|
class AuditSkillStructureTests(unittest.TestCase):
|
|
def _write_skill(self, root: Path, *, body: str, description: str = "short") -> Path:
|
|
skill = root / "demo"
|
|
skill.mkdir()
|
|
(skill / "SKILL.md").write_text(
|
|
"---\n"
|
|
"name: demo\n"
|
|
f"description: {description}\n"
|
|
"---\n\n"
|
|
f"{body}\n",
|
|
encoding="utf-8",
|
|
)
|
|
return skill
|
|
|
|
def _run(self, skill_dir: Path) -> subprocess.CompletedProcess[str]:
|
|
return subprocess.run(
|
|
[sys.executable, str(SCRIPT), str(skill_dir)],
|
|
check=False,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
|
|
def test_reports_within_budget_and_reference_size(self) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
skill = self._write_skill(
|
|
Path(tmp),
|
|
body="# Demo\n\n## 步骤\n\n1. 做一件事。\n",
|
|
)
|
|
(skill / "references").mkdir()
|
|
(skill / "references" / "guide.md").write_text(
|
|
"# Guide\n\n细节。\n", encoding="utf-8"
|
|
)
|
|
result = self._run(skill)
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
self.assertIn("status: within-budget", result.stdout)
|
|
self.assertIn("## 步骤", result.stdout)
|
|
self.assertIn("references/guide.md", result.stdout)
|
|
self.assertIn("notes:", result.stdout)
|
|
self.assertIn("reference 未被 SKILL.md 链接: guide.md", result.stdout)
|
|
|
|
def test_flags_hard_budget_and_vague_references(self) -> None:
|
|
padding = "这是一段占位说明,用来把正文撑过硬顶。" * 400
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
skill = self._write_skill(
|
|
Path(tmp),
|
|
body="# Demo\n\n详见 references/。\n\n" + padding,
|
|
)
|
|
result = self._run(skill)
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
self.assertIn("status: over-hard-budget", result.stdout)
|
|
self.assertIn("HARD SKILL.md", result.stdout)
|
|
self.assertIn("见 references/", result.stdout)
|
|
|
|
def test_missing_skill_exits_2(self) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
result = self._run(Path(tmp) / "missing")
|
|
self.assertEqual(result.returncode, 2)
|
|
self.assertIn("找不到 skill", result.stderr)
|