feat: publish researched offline HTML presentation skill

This commit is contained in:
jarvis-at-skic committed 2026-10-21 20:27:50 +00:00
commit 50eab114ae
35 files changed
+1201

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
"""Build an offline, single-file deck with no package install or network."""
from pathlib import Path
import base64, hashlib, json, re
R=Path(__file__).resolve().parents[1]
def build():
vendor=R/'assets/vendor'; s=(R/'assets/starter.html').read_text()
manifest=R/'vendor-manifest.json'
if manifest.exists():
for entry in json.loads(manifest.read_text()):
assert hashlib.sha256((R/entry['path']).read_bytes()).hexdigest()==entry['sha256'], entry['path']
nodes=[]
labels=['People','Process','Platform','Quality','Cost','Risk']
details=['People: who owns the decision?','Process: how does work move?','Platform: what enables delivery?','Quality: what evidence proves fitness?','Cost: what constraint shapes the choice?','Risk: what could invalidate the plan?']
for i,(label,detail) in enumerate(zip(labels,details)):
x=[250,550,850][i%3];y=65 if i<3 else 305
nodes.append(f'<g role="button" tabindex="0" aria-label="{label}" aria-pressed="false" data-node="{i}" data-detail="{detail}"><rect x="{x-110}" y="{y-32}" width="220" height="64"/><text x="{x}" y="{y}">{label}</text></g>')
s=s.replace('<!-- NODES -->','\n'.join(nodes))
for marker,file in [('REVEAL_CSS','reveal.css'),('REVEAL_JS','reveal.js'),('ANIME_JS','anime.umd.min.js')]:
text=(vendor/file).read_text();text=re.sub(r'//# sourceMappingURL=.*','',text)
s=s.replace('/* '+marker+' */',text)
fonts=''
for file,weight in [('work-sans.woff2',400),('work-sans-bold.woff2',700)]:
fonts+=f"@font-face{{font-family:'Work Sans';font-weight:{weight};font-style:normal;font-display:block;src:url(data:font/woff2;base64,{base64.b64encode((vendor/file).read_bytes()).decode()}) format('woff2');}}"
s=s.replace('/* FONT_CSS */',fonts).replace('/* APP_JS */',(R/'assets/app.js').read_text())
licenses='\n'.join((vendor/f).read_text() for f in ['reveal-LICENSE','anime-LICENSE.md','work-sans-LICENSE'])
s=s.replace('<!-- LICENSES -->','<!-- THIRD-PARTY NOTICES\n'+licenses.replace('--','—')+'\n-->')
out=R/'dist';out.mkdir(exist_ok=True);p=out/'presentation-html-demo-0.1.0.html';p.write_text(s)
report={'file':p.name,'sha256':hashlib.sha256(p.read_bytes()).hexdigest(),'bytes':p.stat().st_size,'slides':6,'interactive_nodes':6,'reveal':'6.0.2','anime':'4.5.0'}
(out/'manifest.json').write_text(json.dumps(report,indent=2)+'\n');print(json.dumps(report))
if __name__=='__main__':build()