shared report widgets
This Site hosts the small ESM bundles loaded by pages published with
afspies-publish: the inline-threaded-annotation widget, and the
row-wise data inspector. The annotation Site also proxies requests to a
here.now Drive that stores the shared annotation JSON, with the token
injected server-side so it never reaches the browser.
Files
annotations.js— ESM annotation widget moduleannotations.css— annotation widget stylesinspector.js— ESM row-wise data inspector (compact table → drawer/split detail; sort/filter/resize/compare)inspector.css— inspector styles
Embedding
<link rel="stylesheet" href="/widget/annotations.css">
<script type="module">
import { autoInit } from '/widget/annotations.js';
autoInit({ articleSelector: 'main' }); // same-origin proxy via this Site's .herenow/proxy.json
</script>
Storage layout
Annotations are stored in a here.now Drive at path
annotations/<page-id>.json, where page-id
defaults to the first non-empty path segment of the URL (i.e. the
report label — saes for tmp.afspies.com/saes/).
On the root index Site it's index.
Inspector
Build inspector blocks from the Python side
(render_inspector / render-inspector.py in the
skill); the emitted fragment loads this bundle automatically. The bundle
upgrades the server-rendered <details> rows into a compact,
sortable, header-filterable table whose rows open a detail surface
(drawer in a report, persistent split in an
explorer, modal, or inline expand) carrying rich
detail blocks — chat transcript, judge meter, per-position token
heatmap, and server-side inline-SVG sparkline/mini-bars. Manual embed:
<link rel="stylesheet" href="/widget/inspector.css">
<script type="module">
import { autoInit } from '/widget/inspector.js';
autoInit(); // hydrates every [data-inspector] on the page, once each
</script>
See the skill's SKILL.md §"Row-wise data inspector"
for the column spec and worked examples.
Part of tmp.afspies.com.
Source lives in ~/.claude/skills/afspies-publish/widget/.