← Files Data Engineering CopilotARCHIVED FILE

scripts/validate_package.py

3.87 KB · Nov 3, 2026 · 00:12 UTC

↓ Download file

See the change to this file →

"""Offline structural checks. Does not prove runtime plugin behavior or host eligibility."""
from __future__ import annotations
import json
import re
import sys
from pathlib import Path
from urllib.parse import urlparse

ROOT=Path(__file__).resolve().parents[1]
checks=0

def verify(test:bool,message:str):
    global checks
    if not test: raise AssertionError(message)
    checks+=1

def main():
    p=json.loads((ROOT/'plugin.json').read_text(encoding='utf-8'))
    verify(p.get('name')=='production-data-engineering-copilot','Package ID must be preserved')
    verify(p.get('version')=='0.2.0','Unexpected version')
    verify(p.get('skills')=='./skills/','Expected skills path')
    i=p['extensions']['com.openai']['interface']
    verify(i.get('displayName')=='Data Engineering Copilot','Display name changed')
    verify(i.get('developerName')=='Tekris Labs','Developer mismatch')
    verify(len(i['shortDescription'])<=30,'Subtitle length')
    verify(len(i['defaultPrompt'])==3,'Exactly three prompts')
    for prompt in i['defaultPrompt']:verify(len(prompt)<=128,'Prompt length')
    verify(len(i['capabilities'])<=20,'Too many capabilities')
    for c in i['capabilities']:verify(len(c)<=120,'Capability too long')
    for field in ('websiteURL','supportURL','privacyPolicyURL','termsOfServiceURL'):
        parsed=urlparse(i[field]);verify(parsed.scheme=='https' and bool(parsed.netloc),f'URL invalid: {field}')
    for field in ('logo','composerIcon'):
        verify((ROOT/i[field].removeprefix('./')).is_file(),f'Icon missing: {field}')
    verify((ROOT/'docs/original-v0.1.0-skill.md').is_file(),'Original skill lost')
    old=list((ROOT/'references/original').glob('*.md'))
    verify(len(old)==7,f'Expected seven preserved technical references, found {len(old)}')
    skills=sorted((ROOT/'skills').glob('*/SKILL.md'))
    verify(len(skills)==18,f'Expected 18 focused skills; got {len(skills)}')
    seen=set()
    for skill in skills:
        text=skill.read_text(encoding='utf-8')
        m=re.match(r'^---\n(.*?)\n---\n\s*(.*)$',text,re.S)
        verify(bool(m),f'Frontmatter invalid: {skill}')
        fm,body=m.groups()
        n=re.search(r'^name:\s*(.+)$',fm,re.M)
        desc=re.search(r'^description:\s*(.+)$',fm,re.M)
        verify(bool(n and desc),f'Name/description missing: {skill}')
        name=n.group(1).strip();description=desc.group(1).strip()
        verify(name==skill.parent.name,f'Skill name/path mismatch: {skill}')
        verify(name not in seen,f'Duplicate skill: {name}');seen.add(name)
        verify(len(p['name']+':'+name)<=64,f'Skill identity too long: {name}')
        verify(0<len(description)<=1024,f'Skill description invalid: {name}')
        verify(len(body)>100,f'Skill body too short: {name}')
        for item in re.findall(r'`(\.\./\.\./(?:references|templates)/[^`]+)`',body):
            verify((skill.parent/item).resolve().is_file(),f'Broken reference {name}: {item}')
    verify(p['extensions']['com.openai']['onboardingSkill']=='./skills/data-engineering/SKILL.md','Invalid onboarding skill')
    legacy=json.loads((ROOT/'.codex-plugin/plugin.json').read_text(encoding='utf-8'))
    verify(legacy['name']==p['name'] and legacy['version']==p['version'],'Legacy identity mismatch')
    verify(legacy['interface']==i,'Legacy presentation disagrees with root manifest')
    bench=json.loads((ROOT/'benchmarks/scenarios.json').read_text(encoding='utf-8'))['cases']
    verify(len(bench)==24,'Expected 24 scenarios')
    verify(len({c['id'] for c in bench})==len(bench),'Duplicate scenario')
    for c in bench:
        verify(c['status']=='not_executed','Scenario claimed executed')
        verify(bool(c['expected']) and bool(c['prohibited']),'Scenario incomplete')
    verify(len(list((ROOT/'templates').iterdir()))>=6,'Missing templates')
    print(f'PASS: {checks} structural checks, {len(skills)} skills, {len(old)} originals, {len(bench)} benchmark scenarios')
if __name__=='__main__':
    main()

SHA-256: 62de9675ef11d3575ae7916aec9a7dfde77caa696e19546a8f63d1d2b936f3d8