fix(news-morning): drop hot section and WeChat stats row

Remove the trending/hot search lane and section, forbid stats summary in page spec, and stop injecting card/section counts into WeChat inline articles.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
John
2026-09-18 09:00:46 +08:00
parent af0282e963
commit 9ae35f38e1
5 changed files with 11 additions and 24 deletions
@@ -34,6 +34,7 @@ async function main() {
'asia_pacific / commodities / ai_chips / policy / community / science / culture / startup / crypto / geopolitics / local_life / official_feeds',
'以及 google / x / universities / global_markets。',
'全页去重:同一 URL 或同一核心事件只允许出现一次;主栏目优先,扩展栏目必须换角度或跳过。',
'禁止 id=hot 热搜栏目;禁止 .stats 或「X条资讯 · Y个栏目」统计行。',
'英文栏目标题可英文,每条必须有中文摘要与来源 URL;禁止整段纯英文正文。',
].join('\n'),
};
+5 -17
View File
@@ -52,7 +52,6 @@ const SECTION_LABELS = {
tech: 'TECH',
technews: 'TECH',
sports: 'SPORTS',
hot: 'TRENDING',
knowledge: 'INSIGHT',
};
@@ -495,7 +494,8 @@ function renderQuickLinks(html) {
if (!block) return '';
const labels = [...block.matchAll(/<a[^>]*>([\s\S]*?)<\/a>/gi)]
.map((item) => stripInlineText(item[1]))
.filter(Boolean);
.filter(Boolean)
.filter((label) => !/^(🔥|𝕏\s*)?热搜/u.test(label) && !/热门事件/u.test(label));
if (labels.length === 0) return '';
const pills = labels
.map((label) => `<span style="display:inline-block;padding:5px 12px;margin:0 6px 7px 0;border:1px solid ${BRAND.hair};border-radius:20px;font-size:12px;color:${BRAND.body}">${label}</span>`)
@@ -585,7 +585,6 @@ const DEFAULT_SECTION_CARD_LIMITS = {
tech: 4,
sports: 2,
technews: 2,
hot: 2,
knowledge: 3,
};
@@ -605,8 +604,8 @@ const CARD_LIMIT_TIERS = [
null,
DEFAULT_SECTION_CARD_LIMITS,
{ ...DEFAULT_SECTION_CARD_LIMITS, headlines: 6, world: 4, domestic: 4, finance: 4, tech: 4, knowledge: 3 },
{ headlines: 5, world: 3, domestic: 3, google: 2, finance: 3, tech: 3, sports: 2, technews: 1, hot: 2, knowledge: 3 },
{ headlines: 4, world: 3, domestic: 3, google: 1, finance: 2, tech: 2, sports: 2, technews: 1, hot: 1, knowledge: 2 },
{ headlines: 5, world: 3, domestic: 3, google: 2, finance: 3, tech: 3, sports: 2, technews: 1, knowledge: 3 },
{ headlines: 4, world: 3, domestic: 3, google: 1, finance: 2, tech: 2, sports: 2, technews: 1, knowledge: 2 },
];
/** 每档卡片摘要字数,标题信息已足够时优先压缩摘要来换取更多条目。 */
@@ -631,7 +630,6 @@ const SECTION_SHRINK_WEIGHTS = {
startup: 1.55,
science: 1.5,
sports: 1.45,
hot: 1.4,
x: 1.38,
google: 1.35,
official_feeds: 1.33,
@@ -687,6 +685,7 @@ function resolveSectionCardLimit(section, sectionCardLimits) {
function shouldSkipSection(section, trimProfile) {
if (!section) return true;
if (section.id === 'hot') return true;
if (section.id === 'history') return true;
if (section.id === 'knowledge' && trimProfile?.skipKnowledge === true) return true;
if (trimProfile?.skipSectionIds?.includes(section.id)) return true;
@@ -806,7 +805,6 @@ function buildWechatInlineContent(html, {
if (digest) bodyParts.push(digest);
const contentParts = [];
let weatherCityCount = 0;
let renderedSectionCount = 0;
for (const section of sections) {
@@ -819,9 +817,6 @@ function buildWechatInlineContent(html, {
if (rendered) {
contentParts.push(rendered);
renderedSectionCount += 1;
weatherCityCount = selectTouristWeatherCards(
extractClassDivBlocks(extractDivBlock(section.html, 'weather-grid'), 'weather-card'),
).length;
}
continue;
}
@@ -850,12 +845,6 @@ function buildWechatInlineContent(html, {
}
}
const newsCount = countInlineCards(contentParts.join(''));
bodyParts.push(renderBriefStats([
{ value: String(newsCount), label: '条资讯' },
{ value: String(renderedSectionCount), label: '个栏目' },
weatherCityCount > 0 ? { value: String(weatherCityCount), label: '地天气' } : null,
].filter(Boolean)));
if (!trimProfile.skipQuickLinks) {
bodyParts.push(renderQuickLinks(html));
}
@@ -937,7 +926,6 @@ function fitInlineContentToBudget(html, bodyBudget, {
global_markets: 1,
sports: 1,
technews: 1,
hot: 1,
knowledge: 0,
},
maxBodyChars: 80,
+4 -5
View File
@@ -33,21 +33,20 @@ const MAX_THUMB_BYTES = 64 * 1024;
export const NEWS_MORNING_TEMPLATE_REFERENCE_URL =
'https://m.tkmind.cn/MindSpace/a70ff537-8908-486e-9b6c-042e07cc25db/public/daily-news-0915.html';
export const NEWS_MORNING_TEMPLATE_VERSION = '2026-09-18-full';
export const NEWS_MORNING_TEMPLATE_VERSION = '2026-09-18-no-hot';
/** 生产 daily-news-0915 版式:div.section + 扩展全球栏目。 */
export const NEWS_MORNING_TEMPLATE_0915_SPEC = [
'生成「每日新闻早报」静态 HTML 页面(daily-news-MMDD),版式必须与生产参照页完全一致(仅 HTML/CSS 结构,禁止复制其正文):',
`参照页:${NEWS_MORNING_TEMPLATE_REFERENCE_URL}`,
'写页前可先 read_file 打开同目录最近 daily-news-*.html 或上述 URL 对应文件,对照 CSS 与 DOM 骨架;正文条目必须全部来自当日检索。',
'1. 外层:`.wrap` > `.hero``.hero-content` 内 h1「📰 每日新闻早报」、`.date-badge`、`.subtitle` 一句主编导语)> `.container`。',
'2. quick-links 固定顺序:📰 要闻|🌤️ 天气|🌍 国际|🇨🇳 国内|💰 财经|🤖 科技|🏆 体育|🔥 热搜|🔎 Google|𝕏 X|🌏 亚太|⛽ 能源|🧠 AI芯片|⚖️ 政策|🎓 高校|📈 全球股市|💬 社区|🔬 科学|🎬 文娱|🚀 创投|₿ 加密|🛡️ 地缘|🏙️ 城市|📡 权威快讯|📚 小知识|📅 历史(href 对应下方 id)。',
'1. 外层:`.wrap` > `.hero``.hero-content` 内 h1「📰 每日新闻早报」、`.date-badge`、`.subtitle` 一句主编导语)> `.container`;禁止 `.stats` 或「X条资讯 · Y个栏目」统计行。',
'2. quick-links 固定顺序:📰 要闻|🌤️ 天气|🌍 国际|🇨🇳 国内|💰 财经|🤖 科技|🏆 体育|🔎 Google|𝕏 X|🌏 亚太|⛽ 能源|🧠 AI芯片|⚖️ 政策|🎓 高校|📈 全球股市|💬 社区|🔬 科学|🎬 文娱|🚀 创投|₿ 加密|🛡️ 地缘|🏙️ 城市|📡 权威快讯|📚 小知识|📅 历史(href 对应下方 id);禁止 id=hot / 🔥 热搜。',
'3. 区块容器必须用 `<div class="section" id="...">`(禁止 `<section id>`);`.section-title` 含 `<span class="icon">` emoji。',
'4. 区块 id 与内容:',
' - id=headlines:「今日要闻 · {完整日期}」;至少 3 条 `.card.highlight-box`tag + h3 + p + source),标题 1528 字、前 10 字有钩子。',
' - id=weather:「今日天气 · {月日}」;`.weather-today` + `.weather-grid` 812 张 `.weather-card`;热门城市(北京、上海、广州、深圳、成都、杭州、西安、重庆、武汉、南京、厦门、三亚等),禁止用区域预报顶替城市卡。',
' - id=world / domestic / finance / tech / sports:各 34 条 card。',
' - id=hot:「今日热门事件与热搜 · {月日}」;2~3 条 highlight-box。',
' - id=google:「🔎 Google 热点 · Global Headlines」;2 条 card,标题可英文,p 用中文摘要。',
' - id=x:「𝕏 X 平台热点 · Trending」;2 条 cardX/Twitter 热议或媒体转述。',
' - id=asia_pacific:「🌏 亚太观察 · Asia-Pacific」;2 条 card,日韩台港/东盟视角。',
@@ -80,7 +79,7 @@ export const NEWS_MORNING_TEMPLATE_0910_SPEC = NEWS_MORNING_TEMPLATE_0915_SPEC;
export const NEWS_MORNING_FRESH_CONTENT_SPEC = [
'内容硬约束(必须遵守,优先于版式):',
'1. 检索必须双路:先 load_skill → web,再同一轮调用 tkmind_search(type=news) 与 web_search,合并去重后写页;禁止只靠 web_search。',
'2. 覆盖面至少包括:国内、国际、热搜、财经、科技、体育、天气,以及 Google/X/亚太/能源/AI芯片/政策/高校/全球股市/社区/科学/文娱/创投/加密(有则写)/地缘/城市/权威快讯等扩展栏目;不得凭记忆编造。',
'2. 覆盖面至少包括:国内、国际、财经、科技、体育、天气,以及 Google/X/亚太/能源/AI芯片/政策/高校/全球股市/社区/科学/文娱/创投/加密(有则写)/地缘/城市/权威快讯等扩展栏目;不得凭记忆编造;禁止单独「热搜/热门事件」栏目(原占位分给其它栏目)。',
'3. 若附有「专用联网搜索预取」,必须优先从中选题并写入对应栏目;预取有结果时禁止输出「未能获取」类空页。',
'4. 若 tkmind_search / web_search 暂时不可用,但预取 brief 已有条目:仍必须用预取结果写满各栏目,并在 source 标注预取来源 URL。',
'5. 仅当预取 brief 各路均为空且双路搜索均失败时,才允许写「检索暂不可用」说明页;禁止用历史 daily-news 正文充数。',
-1
View File
@@ -38,7 +38,6 @@ export function buildNewsMorningSearchQueries(dateLabel) {
{ id: 'finance', title: '财经', query: `${fresh} 财经 金融 A股 股市` },
{ id: 'tech', title: '科技', query: `${fresh} 科技 AI 创新 发布` },
{ id: 'sports', title: '体育', query: `${fresh} 体育 赛事 比赛 结果` },
{ id: 'hot', title: '热搜', query: `${fresh} 热搜 热门 话题 事件` },
{ id: 'weather', title: '天气', query: `${label} 全国 主要城市 天气预报` },
{ id: 'google', title: 'Google 热点', query: `${englishFresh} top news headlines site:reuters.com OR site:bbc.com OR site:apnews.com` },
{ id: 'x', title: 'X 平台热点', query: `${englishFresh} trending news site:x.com OR site:twitter.com` },
+1 -1
View File
@@ -16,7 +16,7 @@ test('buildNewsMorningSearchQueries covers core and extended channels', () => {
});
const ids = queries.map((item) => item.id);
assert.deepEqual(ids, [
'lead', 'domestic', 'world', 'finance', 'tech', 'sports', 'hot', 'weather',
'lead', 'domestic', 'world', 'finance', 'tech', 'sports', 'weather',
'google', 'x', 'universities', 'global_markets',
'asia_pacific', 'commodities', 'ai_chips', 'policy', 'community', 'science',
'culture', 'startup', 'crypto', 'geopolitics', 'local_life', 'official_feeds',