← Files Technical Interview CopilotARCHIVED FILE
scripts/validate_package.py
2.64 KB · Nov 6, 2026 · 18:22 UTC
"""Offline structural checks for the skills-only plugin. No LLM/runtime claim."""
from pathlib import Path
import re, json, sys
ROOT=Path(__file__).resolve().parents[1]
count=0
def must(ok,reason):
global count
count+=1
if not ok: raise AssertionError(reason)
p=json.loads((ROOT/'plugin.json').read_text())
legacy=json.loads((ROOT/'.codex-plugin/plugin.json').read_text())
interface=p['extensions']['com.openai']['interface']
must(p['name']=='technical-interview-copilot','name changed')
must(p['version']=='0.2.0','wrong version')
must('mcpServers' not in p and not (ROOT/'mcp.json').exists(),'unexpected MCP')
must(interface['displayName']=='Technical Interview Copilot','display name changed')
must(interface['developerName']=='Tekris Labs','publisher wrong')
must(legacy['interface']['developerName']=='Tekris Labs','legacy developer mismatch')
must(len(interface['defaultPrompt'])==3,'exactly three starter prompts')
must(len(interface['shortDescription'])<30,'subtitle must be less than 30')
for key in ('websiteURL','supportURL','privacyPolicyURL','termsOfServiceURL'):
must(interface[key].startswith('https://tekrislabs.com/'),f'missing {key}')
for key in ('logo','composerIcon'):
target=(ROOT/interface[key]).resolve()
must(target.is_file() and target.is_relative_to(ROOT.resolve()),'asset invalid '+key)
skills=list((ROOT/'skills').glob('*/SKILL.md'))
must(len(skills)==18,'expected 18 focused skills')
for f in skills:
s=f.read_text();must(s.startswith('---\n'),'missing frontmatter '+str(f))
m=re.search(r'^name: ([a-z0-9-]+)\s*$',s,re.M)
must(bool(m) and m.group(1)==f.parent.name,'skill name mismatch '+str(f))
must(bool(re.search(r'^description: .{20,}$',s,re.M)),'description missing '+str(f))
must(len(s)>400,'skill too short '+str(f))
for ref in re.findall(r'`(\.\./\.\./(?:references|templates)/[^`]+)`',s):
must((f.parent/ref).resolve().is_file(),f'broken ref {f}: {ref}')
for folder in ('references','templates','benchmarks'):
must((ROOT/folder).is_dir(),'missing '+folder)
for f in (ROOT/'references'/'original-v0.1.0').rglob('*.md'):
must(f.stat().st_size>0,'empty original '+str(f))
cases=json.loads((ROOT/'benchmarks/cases.json').read_text())['cases']
must(len(cases)==24,'benchmark count')
must(len([x for x in cases if x['kind']=='positive'])==16,'positive count')
must(len([x for x in cases if x['kind']=='negative'])==8,'negative count')
for c in cases:
must(c['skill'] in {f.parent.name for f in skills},'unknown benchmark skill')
must(bool(c['prompt']) and bool(c['expected']),'empty benchmark')
print(f'PASS {count} structural checks; {len(skills)} skills; {len(cases)} benchmark specifications')
SHA-256: f9382d35cbbf9880a15bb45702010ccf2c460698b7c422820f27ba34222a8f5f