Docs/Skills and code/src/
src/series-viewer/public/app.js
What the file says about itself
Series analysis viewer client. Routes: / | /s/:series[?tab=videos|channels&channel=..] | /s/:series/v/:videoId
// Series analysis viewer client. Routes: / | /s/:series[?tab=videos|channels&channel=..] | /s/:series/v/:videoId
const app = document.getElementById("app");
const crumbs = document.getElementById("crumbs");
function h(tag, attrs, ...kids) {
const el = document.createElement(tag);
for (const [k, v] of Object.entries(attrs ?? {})) {
if (v == null || v === false) continue;
if (k === "class") el.className = v;
else if (k.startsWith("on")) el.addEventListener(k.slice(2), v);
else if (k === "checked" || k === "value" || k === "disabled") el[k] = v;
else el.setAttribute(k, v);
}
for (const kid of kids.flat()) if (kid != null && kid !== false) el.append(kid.nodeType ? kid : document.createTextNode(String(kid)));
return el;
}
const api = async (url, opts) => {
const r = await fetch(url, opts);
if (!r.ok) throw new Error((await r.json().catch(() => ({}))).error ?? `${r.status} ${r.statusText}`);
return r.json();
};
const compact = x => (x == null ? "–" : new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 }).format(x));
const int = x => (x == null ? "–" : Number(x).toLocaleString("en-US"));
const fixed = (x, d = 2) => (x == null ? "–" : Number(x).toFixed(d));
const dur = s => (s == null ? "–" : `${Math.floor(s / 60)}:${String(s % 60).padStart(2, "0")}`);
const ageText = r => {
if (r.age_days != null) return r.age_days >= 365 ? `${(r.age_days / 365).toFixed(1)} y` : `${Math.round(r.age_days)} d`;
if (r.published_at) { const d = (Date.now() - Date.parse(r.published_at)) / 864e5; return d >= 365 ? `${(d / 365).toFixed(1)} y` : `${Math.round(d)} d`; }
return r.search_published_text ?? "–";
};
const thumb = (id, big) => `https://i.ytimg.com/vi/${id}/${big ? "maxresdefault" : "mqdefault"}.jpg`;
const link = (href, ...kids) => h("a", { href, onclick: e => { if (e.metaKey || e.ctrlKey) return; e.preventDefault(); go(href); } }, ...kids);
function go(href) { history.pushState({}, "", href); route(); }
window.addEventListener("popstate", route);
const setCrumbs = parts => { crumbs.replaceChildren(...parts.map(([label, href]) => (href ? link(href, label) : h("span", {}, label)))); };
async function route() {
const url = new URL(location.href);
const parts = url.pathname.split("/").filter(Boolean);
app.replaceChildren(h("p", { class: "muted" }, "Loading…"));
try {
if (!parts.length) return await homePage();
if (parts[0] === "s" && parts[2] === "v") return await videoPage(decodeURIComponent(parts[1]), parts[3]);
if (parts[0] === "s") return await seriesPage(decodeURIComponent(parts[1]), url.searchParams);
app.replaceChildren(h("p", {}, "Not found."));
} catch (e) {
app.replaceChildren(h("div", { class: "status err" }, `Could not load this page: ${e.message}`));
}
}
// ------------------------------------------------------------------ home
async function homePage() {
setCrumbs([]);
document.title = "Series analysis viewer";
const list = await api("/api/series");
app.replaceChildren(h("h1", {}, "Series"), h("p", { class: "muted" }, "Each series is a packaging idea we searched YouTube for."),
h("div", { class: "cards" }, list.map(s => h("div", { class: "card" },
h("h3", {}, link(`/s/${s.id}`, s.name)),
h("p", { class: "muted small" }, s.premise),
h("p", {}, `${int(s.videos)} videos · ${int(s.channels)} channels`),
h("p", { class: "small muted" }, `${s.transcripts} transcripts · ${s.teardowns} teardowns`)))));
}
// ------------------------------------------------------------------ series page (videos + channels)
async function seriesPage(S, q) {
const [seriesList, videos, channels] = await Promise.all([api("/api/series"), api(`/api/series/${S}/videos`), api(`/api/series/${S}/channels`)]);
const meta = seriesList.find(s => s.id === S);
document.title = `${meta?.name ?? S} · Series analysis`;
setCrumbs([[meta?.name ?? S, null]]);
const state = { tab: q.get("tab") === "channels" ? "channels" : "videos", search: q.get("q") ?? "", channel: q.get("channel") ?? "",
learn: q.get("learn") === "1", teardown: q.get("teardown") === "1", transcript: q.get("transcript") === "1", enriched: false, sort: q.get("sort") ?? "default", limit: 100 };
const body = h("div");
const sync = () => {
const p = new URLSearchParams();
if (state.tab !== "videos") p.set("tab", state.tab);
if (state.search) p.set("q", state.search);
if (state.channel) p.set("channel", state.channel);
if (state.learn) p.set("learn", "1");
if (state.teardown) p.set("teardown", "1");
if (state.transcript) p.set("transcript", "1");
if (state.sort !== "default") p.set("sort", state.sort);
history.replaceState({}, "", `${location.pathname}${p.size ? "?" + p : ""}`);
};
const channelName = new Map(channels.map(c => [c.channel_key, c.name]));
const sorters = {
default: (a, b) => (b.selected ?? 0) - (a.selected ?? 0) || (a.rank ?? 1e9) - (b.rank ?? 1e9) || (b.views ?? 0) - (a.views ?? 0),
views: (a, b) => (b.views ?? 0) - (a.views ?? 0),
outlier: (a, b) => (b.outlier_ratio ?? -1) - (a.outlier_ratio ?? -1),
score: (a, b) => (b.learn_score ?? -1) - (a.learn_score ?? -1),
newest: (a, b) => (Date.parse(b.published_at) || 0) - (Date.parse(a.published_at) || 0),
};
function render() {
sync();
const tabs = h("div", { class: "tabs" }, ["videos", "channels"].map(t => h("button", { class: state.tab === t ? "on" : "", onclick: () => { state.tab = t; render(); } },
t === "videos" ? `Videos (${videos.length})` : `Channels (${channels.length})`)));
body.replaceChildren(tabs, state.tab === "videos" ? videosView() : channelsView());
}
function videosView() {
const needle = state.search.toLowerCase();
const rows = videos.filter(v => (!needle || `${v.title} ${v.channel_name} ${v.subject ?? ""}`.toLowerCase().includes(needle))
&& (!state.channel || v.channel_key === state.channel) && (!state.learn || v.selected) && (!state.teardown || v.has_teardown) && (!state.transcript || v.has_transcript))
.sort(sorters[state.sort]);
const toggle = (key, label) => h("label", {}, h("input", { type: "checkbox", checked: state[key], onchange: e => { state[key] = e.target.checked; state.limit = 100; render(); } }), label);
const bar = h("div", { class: "bar" },
h("input", { type: "search", placeholder: "Search title, channel, subject", value: state.search, oninput: e => { state.search = e.target.value; state.limit = 100; renderTable(); sync(); } }),
h("select", { onchange: e => { state.sort = e.target.value; render(); } },
[["default", "Learn-from first"], ["views", "Most views"], ["outlier", "Biggest outlier"], ["score", "Learn score"], ["newest", "Newest"]].map(([v, l]) => h("option", { value: v, ...(state.sort === v ? { selected: "" } : {}) }, l))),
toggle("learn", "Learn-from set"), toggle("teardown", "Has teardown"), toggle("transcript", "Has transcript"),
state.channel ? h("button", { class: "btn ghost", onclick: () => { state.channel = ""; render(); } }, `Channel: ${channelName.get(state.channel) ?? state.channel} ✕`) : null);
const holder = h("div");
function renderTable() {
const needle2 = state.search.toLowerCase();
const shown = videos.filter(v => (!needle2 || `${v.title} ${v.channel_name} ${v.subject ?? ""}`.toLowerCase().includes(needle2))
&& (!state.channel || v.channel_key === state.channel) && (!state.learn || v.selected) && (!state.teardown || v.has_teardown) && (!state.transcript || v.has_transcript))
.sort(sorters[state.sort]);
holder.replaceChildren(h("p", { class: "muted small" }, `${shown.length} videos`),
h("table", {}, h("thead", {}, h("tr", {}, ["Video", "Channel", "Views", "Outlier", "Age", "Length", "Learn score", "Status"].map((c, i) => h("th", { class: i >= 2 && i <= 6 ? "num" : "" }, c)))),
h("tbody", {}, shown.slice(0, state.limit).map(v => h("tr", {},
h("td", {}, h("div", { class: "vrow" }, h("img", { src: thumb(v.video_id), loading: "lazy", alt: "" }),
h("div", {}, h("div", { class: "t" }, link(`/s/${S}/v/${v.video_id}`, v.title)), v.subject ? h("div", { class: "small muted" }, v.subject) : null))),
h("td", {}, link(`/s/${S}?channel=${encodeURIComponent(v.channel_key)}`, v.channel_name ?? "–"), v.subscribers ? h("div", { class: "small muted" }, `${compact(v.subscribers)} subs`) : null),
h("td", { class: "num" }, compact(v.views)),
h("td", { class: "num" }, v.outlier_ratio != null ? `${fixed(v.outlier_ratio, 1)}x` : "–"),
h("td", { class: "num" }, ageText(v)),
h("td", { class: "num" }, dur(v.duration_seconds)),
h("td", { class: "num" }, v.learn_score != null ? fixed(v.learn_score, 2) : "–", v.rank ? h("div", { class: "small muted" }, `#${v.rank}`) : null),
h("td", {}, v.selected ? h("span", { class: "chip good" }, "learn-from") : null, v.has_transcript ? h("span", { class: "chip" }, "transcript") : null,
v.has_teardown ? h("span", { class: "chip good" }, "teardown") : v.job === "running" ? h("span", { class: "chip warn" }, "generating") : null,
v.excluded ? h("span", { class: "chip warn", title: v.excluded }, "excluded") : null))))),
shown.length > state.limit ? h("p", {}, h("button", { class: "btn ghost", onclick: () => { state.limit += 200; renderTable(); } }, `Show more (${shown.length - state.limit} left)`)) : null);
}
renderTable();
return h("div", {}, bar, holder);
}
function channelsView() {
const rows = [...channels].sort((a, b) => (b.selected ?? 0) - (a.selected ?? 0) || (b.subscribers ?? 0) - (a.subscribers ?? 0) || b.videos - a.videos);
return h("table", {}, h("thead", {}, h("tr", {}, ["Channel", "Subscribers", "Typical views", "Found", "Learn-from", "Teardowns", "Best video"].map((c, i) => h("th", { class: i >= 1 && i <= 6 ? "num" : "" }, c)))),
h("tbody", {}, rows.map(c => h("tr", {},
h("td", {}, h("div", { class: "t" }, c.channel_url ? h("a", { href: c.channel_url, target: "_blank", rel: "noopener" }, c.name ?? "–") : c.name ?? "–"),
h("div", { class: "small muted" }, [c.handle, c.country, c.joined ? `since ${String(c.joined).slice(0, 4)}` : null].filter(Boolean).join(" · ")),
c.description ? h("div", { class: "small muted" }, c.description.slice(0, 140) + (c.description.length > 140 ? "…" : "")) : null),
h("td", { class: "num" }, compact(c.subscribers)),
h("td", { class: "num" }, compact(c.baseline_median_views)),
h("td", { class: "num" }, link(`/s/${S}?channel=${encodeURIComponent(c.channel_key)}`, c.videos)),
h("td", { class: "num" }, c.selected || 0), h("td", { class: "num" }, c.teardowns || 0), h("td", { class: "num" }, compact(c.best_views))))));
}
app.replaceChildren(h("h1", {}, meta?.name ?? S), h("p", { class: "muted" }, meta?.premise ?? ""), body);
render();
}
// ------------------------------------------------------------------ video page
async function videoPage(S, id) {
const [data, seriesList] = await Promise.all([api(`/api/series/${S}/videos/${id}`), api("/api/series")]);
const { video: v, ranking, channel, queries, llm, transcript } = data;
const meta = seriesList.find(s => s.id === S);
document.title = `${v.title} · Series analysis`;
setCrumbs([[meta?.name ?? S, `/s/${S}`], [v.title.length > 50 ? v.title.slice(0, 50) + "…" : v.title, null]]);
const d = ranking?.detail ?? {};
const views = v.views ?? v.search_views;
const fact = (label, value) => h("div", { class: "fact" }, h("b", {}, value), h("span", {}, label));
const teardownHolder = h("div");
const img = h("img", { src: thumb(id, true), alt: v.title, onerror: e => { e.target.onerror = null; e.target.src = thumb(id, false); } });
app.replaceChildren(
h("div", { class: "hero" }, img,
h("div", {}, h("h1", {}, v.title),
h("div", {}, v.channel_url ? link(`/s/${S}?channel=${encodeURIComponent(v.channel_id ?? v.channel_url ?? v.channel_name)}`, v.channel_name) : v.channel_name,
" · ", h("a", { href: `https://www.youtube.com/watch?v=${id}`, target: "_blank", rel: "noopener" }, "Open on YouTube")),
h("div", { class: "facts" },
fact("views", int(views)), fact("likes", int(v.likes)), fact("length", dur(v.duration_seconds ?? v.search_duration_seconds)),
fact("published", v.published_at ? v.published_at.slice(0, 10) : v.search_published_text ?? "–"),
fact("subscribers", channel ? compact(channel.subscriber_count) : compact(d.subscribers)),
fact("vs channel typical", d.outlier_ratio != null ? `${fixed(d.outlier_ratio, 1)}x` : "–"),
fact("learn score", ranking?.learn_score != null ? fixed(ranking.learn_score, 2) : "–"),
fact("learn-from rank", ranking?.rank ? `#${ranking.rank}` : "–")),
ranking?.excluded ? h("p", {}, h("span", { class: "chip warn" }, `Excluded from ranking: ${ranking.excluded}`)) : null,
d.subject ? h("p", { class: "small muted" }, `Subject: ${d.subject}${d.failure_terms?.length ? " · failure terms: " + d.failure_terms.join(", ") : ""}${d.structures?.length ? " · structure: " + d.structures.join(", ") : ""}`) : null,
llm?.note ? h("p", { class: "small muted" }, `LLM fit note: ${llm.note}`) : null,
queries.length ? h("p", { class: "small muted" }, "Found by: ", queries.slice(0, 4).map(x => h("span", { class: "chip" }, `${x.query} (#${x.position})`))) : null)),
h("h2", {}, "Teardown"), teardownHolder,
h("h2", {}, "Description"), h("div", { class: "desc" }, v.description || "No description fetched for this video (it has not been enriched yet)."),
h("h2", {}, "Transcript", transcript ? h("span", { class: "muted small" }, ` ${transcript.language ?? ""}${transcript.info ? " · " + transcript.info : ""}`) : null),
transcript ? h("div", { class: "transcript" }, transcript.paragraphs.map(p => h("p", {}, h("span", { class: "ts" }, p.ts), h("span", {}, p.text))))
: h("p", { class: "muted" }, "No transcript saved yet. Generating a teardown fetches it first."));
renderTeardown(S, id, v, data.teardown, data.job, teardownHolder);
}
let pollTimer = null;
function renderTeardown(S, id, v, teardown, job, holder) {
clearTimeout(pollTimer);
if (teardown) {
holder.replaceChildren(...teardownView(teardown, job?.status === "running"));
return;
}
const running = job?.status === "running";
const start = async () => {
try { job = await api(`/api/series/${S}/videos/${id}/teardown`, { method: "POST" }); } catch (e) { job = { status: "error", error: e.message }; }
renderTeardown(S, id, v, null, job, holder);
};
holder.replaceChildren(
running ? h("div", { class: "status" }, h("span", { class: "spin" }), job.step ?? "Working") : null,
job?.status === "error" ? h("div", { class: "status err" }, `Teardown failed: ${job.error}`) : null,
!running ? h("div", { class: "card" }, h("p", {}, "No teardown for this video yet."),
h("p", { class: "small muted" }, "A Sonnet analyst reads the full transcript and looks at the thumbnail, then explains what the video does well and how, with quoted moments checked against the transcript. It takes a few minutes and uses your Claude Code subscription."),
h("button", { class: "btn", onclick: start }, job?.status === "error" ? "Try again" : "Generate teardown")) : null);
if (running) {
pollTimer = setTimeout(async () => {
if (!document.body.contains(holder)) return;
try { const r = await api(`/api/series/${S}/videos/${id}/teardown`); renderTeardown(S, id, v, r.teardown, r.job, holder); }
catch { renderTeardown(S, id, v, null, job, holder); }
}, 4000);
}
}
const ev = list => (list ?? []).slice(0, 3).map(e => h("div", { class: "quote" }, h("span", { class: "ts" }, `[${e.ts}]`), `“${e.quote}”`, e.gloss ? h("div", { class: "small muted" }, e.gloss) : null));
function teardownView(a, regenerating) {
const p = a.packaging ?? {}, s = a.script ?? {};
const title = p.title ?? {}, th = p.thumbnail, pd = p.promise_delivery ?? {};
const delivered = String(pd.delivered ?? "");
return [
h("div", { class: "lead" }, h("b", {}, "Why it works. "), a.one_line),
h("div", { class: "td-section" },
h("h3", {}, "Packaging"),
h("ul", { class: "tight" },
h("li", {}, h("b", {}, "Promise: "), `${title.promise ?? "–"}${title.specificity ? ` (specificity: ${title.specificity})` : ""}`),
h("li", {}, h("b", {}, "Gap it opens: "), `${title.info_gap?.type ?? "n/a"}${title.info_gap?.what_is_withheld ? ": " + title.info_gap.what_is_withheld : ""}`),
title.formula ? h("li", {}, h("b", {}, "Formula: "), title.formula) : null,
...(title.mechanisms ?? []).map(m => h("li", {}, h("span", { class: "chip" }, m.id), m.how)),
th?.seen ? h("li", {}, h("b", {}, "Thumbnail: "), th.description, " ", ...(th.mechanisms ?? []).map(m => [h("span", { class: "chip" }, m.id), m.how, " "]).flat(),
th.division_of_labour ? h("div", { class: "small muted" }, `Division of labour: ${th.division_of_labour}`) : null) : h("li", {}, h("b", {}, "Thumbnail: "), "not analysed")),
h("p", {}, h("b", {}, "Does it earn the promise? "), h("span", { class: `chip ${/^yes|full/i.test(delivered) ? "good" : "warn"}` }, delivered || "–"),
pd.delivered_at ? ` at ${pd.delivered_at}. ` : ". ", pd.clickbait_risk ? h("span", { class: `chip ${/low|none/i.test(pd.clickbait_risk) ? "good" : "warn"}` }, `clickbait risk: ${pd.clickbait_risk}`) : null, " ", pd.why)),
h("div", { class: "td-section" }, h("h3", {}, "What it does well, and how"),
(a.doing_well ?? []).map((m, i) => h("div", { class: "move" }, h("div", { class: "m" }, `${i + 1}. ${m.move}`), h("div", {}, m.how), ev(m.evidence)))),
h("div", { class: "td-section" }, h("h3", {}, "Hook (first minute)"), h("p", {}, s.hook?.summary), s.hook?.time_to_promise_sec != null ? h("p", { class: "small muted" }, `Time to the promise: ${s.hook.time_to_promise_sec} s`) : null,
h("h3", {}, "Structure"), h("ul", { class: "tight" }, (s.structure ?? []).map(x => h("li", {}, h("span", { class: "chip" }, `${x.from} – ${x.to}`), x.function, x.note ? h("span", { class: "muted" }, ` (${x.note})`) : null))),
h("h3", {}, "Open loops"), (s.loops ?? []).length ? h("ul", { class: "tight" }, s.loops.map(l => h("li", {}, h("span", { class: "chip" }, `${l.opened_at} → ${l.closed_at ?? "never closed"}`), l.question, l.how_kept_alive ? h("span", { class: "muted" }, ` (kept alive by: ${l.how_kept_alive})`) : null))) : h("p", { class: "muted" }, "None."),
h("h3", {}, "Voice and pacing"), h("p", {}, s.voice), h("ul", { class: "tight" }, (s.pacing_devices ?? []).map(x => h("li", {}, x))),
s.ending ? h("p", {}, h("b", {}, "Ending: "), `${s.ending.type}: ${s.ending.what_it_does}`) : null),
h("div", { class: "td-section" }, h("h3", {}, "Weak points"),
(a.weak_points ?? []).length ? h("ul", { class: "tight" }, a.weak_points.map(w => h("li", {}, h("b", {}, `${w.where}: `), w.what, w.risk ? h("span", { class: "muted" }, ` (${w.risk})`) : null))) : h("p", { class: "muted" }, "None found."),
h("h3", {}, "Moves to copy"), h("ul", { class: "tight" }, (a.transferable_moves ?? []).map(m => h("li", {}, m)))),
h("p", { class: "small muted" }, `Analyst confidence: ${a.confidence ?? "–"}. ${a.transcript_quality_notes ?? ""} One analyst's reading; quotes are machine-checked against the transcript.`),
];
}
route();
Shown as it is in the repository at build time (2026-11-03); the home directory appears as <home>. If this page and the file differ, the file is right. Back to the catalogue.