Docs/Skills and code/src/

src/analysis/priority-report-format.js

Code66 lines4.6 KBsrc/

function esc(value) { return String(value ?? "").replaceAll("|", "\\|").replace(/[\r\n]+/g, " "); }
function fmt(value) { return value == null ? "—" : Number(value).toFixed(1); }
function table(rows, fields) {
  if (!rows.length) return "_No candidates with sufficient evidence._\n";
  const header = `| ${fields.map(field => field.label).join(" | ")} |`;
  const separator = `| ${fields.map(() => "---").join(" | ")} |`;
  const body = rows.map(row => `| ${fields.map(field => esc(field.render ? field.render(row) : row[field.key])).join(" | ")} |`).join("\n");
  return `${header}\n${separator}\n${body}\n`;
}

export function buildPriorityMarkdown(report, overall, specialists, breakthroughs, novelty, niches) {
  const d = report.dataSummary;
  const overallRows = overall.map((row, index) => ({ rank: index + 1, ...row }));
  const commonFields = [
    { key: "rank", label: "#" }, { key: "channel_name", label: "Channel" },
    { key: "priority_score", label: "Priority", render: row => fmt(row.priority_score) },
    { key: "specialist_score", label: "Specialist", render: row => fmt(row.specialist_score) },
    { key: "breakthrough_score", label: "Breakthrough", render: row => fmt(row.breakthrough_score) },
    { key: "novelty_score", label: "Novelty", render: row => fmt(row.novelty_score) },
    { key: "evidence_quality_score", label: "Evidence", render: row => fmt(row.evidence_quality_score) },
    { key: "embedded_video_count", label: "Embedded titles" },
    { key: "dominant_niche_example", label: "Dominant niche example" }
  ];
  const simpleFields = metric => [
    { key: "channel_name", label: "Channel" }, { key: metric, label: "Score", render: row => fmt(row[metric]) },
    { key: "evidence_quality_score", label: "Evidence", render: row => fmt(row.evidence_quality_score) },
    { key: "performance_video_count", label: "Videos with views" },
    { key: "dominant_niche_example", label: "Niche example" }
  ];
  const lines = [
    "# Automatic channel prioritization", "",
    `- **Run:** ${report.runId}`,
    `- **Generated:** ${report.generatedAt}`,
    `- **Embedding model:** ${report.embeddingModel}`,
    `- **Scoring version:** ${report.scoringVersion}`,
    `- **Channels:** ${d.channels}; rankable: ${d.rankableChannels}`,
    `- **Videos embedded and clustered:** ${d.embeddedVideos}`,
    `- **Stable niche candidates:** ${d.stableNicheCandidates}`, "",
    "## How to read this", "",
    "This is a data-driven research queue, not a prediction of channel success. The scoring does not use human reference labels and does not include automation potential. Inspect the separate dimensions instead of treating the overall score as absolute truth.", "",
    "- **Specialist:** semantic coherence plus concentration into a small number of discovered clusters.",
    "- **Breakthrough:** within-channel performance outliers; available only with at least three performance observations.",
    "- **Novelty:** supported niche clusters that are relatively rare across channels.",
    "- **Exploration:** gives attention to channels with limited title coverage.",
    "- **Evidence:** coverage of embeddings, views and usable publication dates.", "",
    "## Overall research priority", "", table(overallRows, commonFields),
    "## Specialist channels", "", table(specialists, simpleFields("specialist_score")),
    "## Breakthrough candidates", "", table(breakthroughs, simpleFields("breakthrough_score")),
    "## Novel / underrepresented niches", "", table(novelty, simpleFields("novelty_score")),
    "## Candidate niches", "",
    "Clusters are generated by greedy cosine-to-centroid assignment with a seed-similarity guard. They are candidate groups for inspection, not an authoritative taxonomy.", ""
  ];
  for (const niche of niches.slice(0, 40)) {
    lines.push(`### Cluster ${niche.clusterNo}: ${esc(niche.representativeTitle)}`, "");
    lines.push(`- Videos: ${niche.memberCount}; channels: ${niche.channelCount}; mean similarity to centroid: ${fmt(niche.meanSimilarity)}`);
    lines.push(`- Leading channels: ${niche.topChannels.map(channel => `${esc(channel.channel)} (${channel.videos})`).join(", ") || "—"}`);
    lines.push("- Representative titles:");
    for (const example of niche.examples.slice(0, 5)) lines.push(`  - ${esc(example.title)} (similarity ${fmt(example.similarityToCentroid)})`);
    lines.push("");
  }
  lines.push("## Data and interpretation limits", "");
  for (const caveat of report.caveats) lines.push(`- ${caveat}`);
  lines.push("", "## Reproducibility", "", "Configuration:", "", "```json", JSON.stringify(report.configuration, null, 2), "```", "");
  return lines.join("\n");
}

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.