
Ai Industry Brief
- 12 installs
- 13 repo stars
- Updated August 4, 2026
- mondaylab/ai-industry-brief
The AI Industry Brief is an agent skill that initializes a daily sourced AI industry brief project and drafts the first issue.
About
The AI Industry Brief is an agent skill from Monday Lab that helps solo builders and small editorial teams initialize a daily AI industry brief project and produce the first issue with sourcing discipline baked into the workflow. It exposes a clear agent interface—display name, short description, and a default prompt that tells Claude Code, Cursor, or similar agents to set up the brief structure and draft issue one in one pass. Use it when you are growing an audience through consistent news-style content about AI companies, models, and policy without hiring a full newsroom. The skill aligns with Prism's Grow journey: you are not validating product-market fit here; you are compounding distribution through a repeatable editorial product. Pair it with your own source list and fact-checking habits; the skill encodes the procedural kickoff for brief-shaped content rather than a single marketing page.
- Display name The AI Industry Brief with default prompt to initialize the project and produce the first issue
- Designed for daily, sourced industry briefs rather than generic blog drafts
- Interface metadata for agent UIs (display name, short description, default prompt)
- Fits operators publishing AI news/analysis under a repeatable brief format
- Initialization-plus-first-issue flow reduces blank-page friction for new brief products
Ai Industry Brief by the numbers
- 12 all-time installs (skills.sh)
- Ranked #1,510 of 1,879 Marketing & SEO skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mondaylab/ai-industry-brief --skill ai-industry-briefAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 12 |
|---|---|
| repo stars | ★ 13 |
| Last updated | August 4, 2026 |
| Repository | mondaylab/ai-industry-brief ↗ |
What it does
Stand up a sourced daily AI industry brief project and ship the first issue with consistent structure and publishing workflow.
Who is it for?
publishers, newsletter operators, and developer-founders who need a recurring AI news product with agent-assisted setup.
Skip if: Skip if you only need a one-time landing page or deep technical documentation with no editorial cadence.
When should I use this skill?
Use $ai-industry-brief to initialize a daily industry brief project and produce the first issue.
What you get
You leave initialization with a brief project scaffold and a first issue draft ready to edit, source-check, and publish on your chosen channel.
- Initialized brief project structure
- First issue draft ready for editorial review
Files
The AI Industry Brief
生成一份简洁、有来源依据的每日行业简报,并维护可发布的 HTML 归档站点。
安装触发
当用户要求从 GitHub 安装这个 Skill 时,优先使用标准 Skills 安装器:
npx skills add mondaylab/ai-industry-brief -y -g安装后,如果宿主环境需要重新发现 Skill,提醒用户重启或开启新会话。随后继续完成用户要求的初始化或第一期简报生成。
以下用户话术都应该触发本 Skill:
请帮我安装 mondaylab/ai-industry-brief 这个行业简报 Skill,并初始化一个行业简报项目。请用 ai-industry-brief Skill 生成第一期跨境电商简报。基于这个 Skill 搭一个出海印尼日报,不要让我手动配。
开始
1. 读取 references/brief-spec.md。 2. 如果用户要初始化非 AI 行业或全新的行业简报,同时读取 references/industry-starter.md。 3. 如果是在更新已有站点,先读取最新的 briefs/YYYY-MM-DD.html 和 index.html,保留已有布局和历史归档。 4. 如果是在新建站点,使用 assets/ 里的 HTML 基础模板,并替换所有示例内容、日期、颜色和链接。 5. 创建或更新 brief-data/YYYY-MM-DD.json。这个 JSON 是当天简报的唯一数据源,通常从 brief-data/_template.json 复制得到。
零配置初始化
当用户想做行业简报,但还没有配置项目时,替用户完成初始化,不要把配置清单丢回给用户。
1. 尽量从用户话术中提取行业名称。如果没有说明,只问行业名称和目标读者这两个最小问题。 2. 为该行业生成 4 个栏目、采集关键词、来源优先级和影响判断维度。常见行业默认值见 references/industry-starter.md。 3. 如果项目结构不存在,创建 brief-data/、briefs/、skills/ai-industry-brief/ 和 index.html。 4. 将 brief-data/_template.json 复制为 brief-data/YYYY-MM-DD.json,并替换栏目名称、首页手机预览栏目和示例副标题。 5. 先生成第一期简报,再让用户调整高级设置。 6. 只有在第一期已经生成之后,才继续询问是否接入 GitHub Pages 发布、飞书群推送或定时任务。
目标体验是“一句话到第一期”。除非外部账号、权限或部署选择阻塞流程,否则不要让用户自己照着清单操作。
调研
1. 使用当前网络搜索,优先选择官方发布、公司博客、开发者文章、产品文档或其他一手来源。 2. 围绕 4 个已配置栏目检索。默认 AI 简报使用:AI 工作台、AI 流水线、AI 大模型、AI 信息美学。 3. 每个栏目选择 3 条值得写入的动态,优先最近 7 天。 4. 如果某个栏目近 30 天内的主流候选源已经被历史简报用尽,不要继续用一两个月前的旧资料凑数;先向外围工具、相邻产品线和同一工作流的替代平台扩展搜索,再考虑更旧来源。 5. 只有在某条更旧资料对当天判断不可替代、且没有近 30 天外围替代源时,才允许使用 30 天前资料,并必须标注 最近官方参考。 6. 每条动态必须记录真实 URL 和发布日期。窗口外资料要标注 邻近窗口 或 最近官方参考,不要暗示它是今天的新消息。 7. 写 HTML 前先运行去重检查,并解决所有冲突:
node skills/ai-industry-brief/scripts/check-brief-dedup.js brief-data/YYYY-MM-DD.json
写作
1. 写一句明确判断式开场,控制在 50 个中文字符以内。 2. 12 条动态都使用 产品/工具名 | 核心动作短语 格式,动作短语控制在 15 个中文字符以内。 3. 每条描述先写事实,再写行业影响,长度约 60-80 个中文字符。 4. 写一段跨栏目洞察,控制在 150 个中文字符以内,必须有明确判断,避免模糊套话。
构建
1. 根据 brief-data/YYYY-MM-DD.json 生成 briefs/YYYY-MM-DD.html,使用规格文档中的星期色板和品牌规则。 2. 更新 index.html,包含最新一期、往期推荐列表和七天色板入口;保留历史简报链接。 3. 生成 share-images/YYYY-MM-DD.png 并随当日简报一起发布,作为飞书图片卡的稳定兜底素材。 4. 每期简报都必须保留可点击来源链接和来源日期标注。 5. 保留基础模板里的归档页/首页布局:
- 首页外层保持黑、白、灰的中性色,不要用当天主题色污染全局页面框架。
- 顶部导航使用中文标签,顺序为:
今日、色板、往期。 - Hero 按钮使用:
阅读最新一期、查看七天色板、查看往期;切换 Tab 的按钮不要强制页面滚回顶部。 - 使用手机形状预览来表达“一个手机里装着一份每日小报”。
- 首页七天色板使用色卡归档卡片,包含
MON-SUN、中文色调名和 HEX 色值,不使用普通胶囊条。 - 可见的归档/推荐区名称使用
往期,不要写成历史归档或精彩推荐。
6. 保留基础模板里的详情页双栏编辑版式:
- 桌面端页面更接近横版 A3 编辑页,不要做成长图海报。
- 默认 AI 简报的栏目顺序是:上排
01 AI 工作台、02 AI 信息美学;下排03 AI 流水线、04 AI 大模型。 - 保留低对比 route-map 图层、纸张网格和 waypoint 风格栏目卡片,形成国际化编辑地图报刊感。
- 栏目数字标记、阴影和引导线必须来自当天的
--primary和--primary-light色彩。 - 栏目内部条目标记使用非数字符号(
◆、◇、◈),不要使用01/02/03。 - 生成或编辑详情页时,保留桌面端动态行高对齐脚本。
检查与发布
1. 检查是否还有未替换占位符,并确认包含 4 个栏目、12 条内容和 12 个来源链接。 2. 发布前重新运行去重检查,确保与历史简报没有重复。 3. 在浏览器打开归档页和新详情页,确认卡片导航、头部、页脚、换行、小屏可读性、栏目横向顺序和莫兰迪主题色标记都正常。 4. 如果用户要求发布,或仓库已经配置发布流程,只提交相关站点和 Skill 文件,推送到配置好的 GitHub 仓库,并在部署后验证 GitHub Pages URL。 5. GitHub Pages 当前部署完全生效后,立即触发飞书图片推送,不要只等待 cron 巡逻。部署完成门槛是:归档首页已包含当天详情页链接、详情页日期/页脚正确、share-images/YYYY-MM-DD.png 已在公开站点返回 PNG:
MANUAL_TRIGGER_TOKEN=<token> npm --prefix workers/feishu-brief-push run post-publish-send -- --date YYYY-MM-DD- 该脚本会等待上述部署门槛通过后再触发 Worker,避免 Pages 仍为旧版本或 PNG 尚未生效时发送链接卡。
- 如果本地环境没有
MANUAL_TRIGGER_TOKEN或FEISHU_PUSH_TOKEN,但当前 Wrangler 已登录且能管理 Worker secrets,可以临时轮换MANUAL_TRIGGER_TOKEN,用新 token 调用/send-image-url?date=YYYY-MM-DD&image_url=<published_png_url>,成功后删除本地临时 token 文件,不要在输出或记忆中记录 token 明文。 - 如果无法取得或轮换触发 token,明确报告“站点已发布,但发布后飞书即时推送缺少 Worker 手动触发 token”,并说明定时 Worker 仍会按 cron 巡逻;此时因为
share-images/YYYY-MM-DD.png已发布,Worker 截图失败时也应优先发送该图片而不是链接卡。
6. 如果这个流程由定时任务驱动,保持品牌、页脚、归档页、Worker 解析逻辑和发布说明与本 Skill 同步。
资源
- 读取 references/brief-spec.md,获取内容规则、颜色、品牌、文件路径和发布检查要求。
- 初始化或改造成新行业简报时,读取 references/industry-starter.md。
- 使用 assets/brief-page-base.html 作为新详情页的视觉基础模板。
- 使用 assets/archive-page-base.html 作为新归档页的视觉基础模板。
- 使用
brief-data/_template.json创建每日配置,用scripts/check-brief-dedup.js防止重复。
interface:
display_name: "The AI Industry Brief"
short_description: "Initialize and publish sourced daily industry briefs"
default_prompt: "Use $ai-industry-brief to initialize a daily industry brief project and produce the first issue."
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The AI Industry Brief | 星期一研究室</title>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@700&family=Noto+Sans+SC:wght@400;500;600;700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--primary: #171717;
--primary-light: #F4F4F1;
--ink: #111111;
--muted: #6F6F6A;
--line: rgba(17, 17, 17, 0.12);
--paper: #FFFEFC;
--panel: rgba(255, 254, 252, 0.78);
--ground: #F1F0EC;
}
html { scroll-behavior: smooth; }
body {
min-height: 100vh;
background:
radial-gradient(circle at 12% 12%, rgba(17, 17, 17, 0.055), transparent 24%),
radial-gradient(circle at 82% 10%, rgba(17, 17, 17, 0.035), transparent 22%),
linear-gradient(135deg, #F7F6F2 0%, #ECEBE6 50%, #FAF9F4 100%);
color: var(--ink);
font-family: 'Noto Sans SC', 'Inter', sans-serif;
padding: 24px;
}
a { color: inherit; text-decoration: none; }
.page {
width: min(1240px, 100%);
margin: 0 auto;
}
.shell {
position: relative;
overflow: hidden;
min-height: calc(100vh - 48px);
border: 1px solid rgba(34, 28, 43, 0.12);
border-radius: 34px;
background:
linear-gradient(90deg, rgba(17, 17, 17, 0.04) 1px, transparent 1px),
linear-gradient(rgba(17, 17, 17, 0.035) 1px, transparent 1px),
rgba(255, 254, 252, 0.78);
background-size: 72px 72px;
box-shadow: 0 28px 80px rgba(17, 17, 17, 0.10);
backdrop-filter: blur(22px);
}
.topbar {
position: sticky;
top: 0;
z-index: 20;
display: flex;
justify-content: space-between;
align-items: center;
gap: 24px;
padding: 18px 22px;
border-bottom: 1px solid var(--line);
background: rgba(255, 254, 252, 0.78);
backdrop-filter: blur(18px);
}
.brand {
display: flex;
align-items: center;
gap: 12px;
font-family: 'Inter', sans-serif;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.brand-mark {
width: 34px;
height: 34px;
border: 1px solid var(--ink);
border-radius: 12px;
display: grid;
place-items: center;
background: var(--primary-light);
}
.brand-mark::before {
content: "";
width: 14px;
height: 14px;
border-radius: 50%;
background: var(--primary);
box-shadow: 9px 0 0 rgba(17, 17, 17, 0.18), 0 9px 0 rgba(17, 17, 17, 0.10);
}
.nav-tabs {
display: inline-flex;
padding: 5px;
gap: 4px;
border: 1px solid var(--line);
border-radius: 999px;
background: rgba(255, 255, 255, 0.62);
}
.tab-control { position: absolute; opacity: 0; pointer-events: none; }
.nav-tabs label {
cursor: pointer;
border-radius: 999px;
padding: 9px 15px;
color: var(--muted);
font-family: 'Inter', 'Noto Sans SC', sans-serif;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.03em;
transition: background 160ms ease, color 160ms ease, box-shadow 160ms ease;
}
#tab-today:checked ~ .shell label[for="tab-today"],
#tab-archive:checked ~ .shell label[for="tab-archive"],
#tab-palette:checked ~ .shell label[for="tab-palette"] {
color: #fff;
background: var(--ink);
box-shadow: 0 8px 22px rgba(17, 17, 17, 0.12);
}
.lab {
position: relative;
border: 0;
background: transparent;
color: var(--ink);
cursor: pointer;
font-family: inherit;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.08em;
white-space: nowrap;
}
.topbar-actions {
display: flex;
align-items: center;
gap: 12px;
margin-left: auto;
}
.github-link {
display: inline-grid;
place-items: center;
order: 2;
width: 18px;
height: 18px;
color: var(--ink);
cursor: pointer;
transition: opacity 160ms ease;
}
.github-link:hover,
.github-link:focus-visible {
opacity: 0.68;
}
.github-link svg {
width: 18px;
height: 18px;
fill: currentColor;
}
.lab-tooltip {
position: relative;
order: 1;
cursor: pointer;
}
.lab-tooltip-panel {
position: absolute;
top: calc(100% + 14px);
right: 0;
z-index: 40;
width: 178px;
padding: 12px;
border: 1px solid rgba(17, 17, 17, 0.14);
border-radius: 8px;
background: rgba(255, 254, 252, 0.96);
box-shadow: 0 18px 44px rgba(17, 17, 17, 0.16);
opacity: 0;
pointer-events: none;
transform: translateY(-4px);
transition: opacity 160ms ease, transform 160ms ease;
}
.lab-tooltip-panel::before {
content: "";
position: absolute;
top: -7px;
right: 28px;
width: 12px;
height: 12px;
border-top: 1px solid rgba(17, 17, 17, 0.14);
border-left: 1px solid rgba(17, 17, 17, 0.14);
background: rgba(255, 254, 252, 0.96);
transform: rotate(45deg);
}
.lab-tooltip:hover .lab-tooltip-panel,
.lab-tooltip:focus-within .lab-tooltip-panel {
opacity: 1;
pointer-events: auto;
transform: translateY(0);
}
.wechat-qr {
display: block;
width: 154px;
height: 154px;
object-fit: cover;
border-radius: 4px;
}
.hero {
position: relative;
display: grid;
grid-template-columns: minmax(0, 0.95fr) minmax(360px, 0.75fr);
gap: 44px;
align-items: center;
padding: clamp(34px, 6vw, 76px);
padding-bottom: 34px;
}
.hero-copy { position: relative; z-index: 2; }
.kicker {
display: inline-flex;
align-items: center;
gap: 10px;
color: var(--ink);
font-family: 'Inter', sans-serif;
font-size: 12px;
font-weight: 800;
letter-spacing: 0.15em;
text-transform: uppercase;
margin-bottom: 22px;
}
.kicker::before {
content: "";
width: 46px;
height: 1px;
background: currentColor;
}
h1 {
max-width: 760px;
font-family: 'Noto Serif SC', Georgia, serif;
font-size: clamp(52px, 8vw, 112px);
line-height: 0.92;
letter-spacing: -0.055em;
}
.lead {
max-width: 620px;
margin-top: 26px;
color: #4F4F4A;
font-size: clamp(16px, 2vw, 20px);
line-height: 1.8;
}
.hero-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 30px;
}
.button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 44px;
padding: 0 17px;
border-radius: 999px;
border: 1px solid var(--line);
background: rgba(255, 255, 255, 0.62);
color: var(--ink);
cursor: pointer;
font-size: 13px;
font-weight: 700;
transition: background 160ms ease, border-color 160ms ease, color 160ms ease, transform 160ms ease, box-shadow 160ms ease;
}
.button:hover {
border-color: rgba(17, 17, 17, 0.32);
background: rgba(255, 255, 255, 0.92);
transform: translateY(-1px);
box-shadow: 0 10px 24px rgba(17, 17, 17, 0.08);
}
.button.primary {
border-color: var(--ink);
background: var(--ink);
color: #fff;
}
.button.primary:hover {
background: #2A2A27;
color: #fff;
}
.signal-row {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
margin-top: 34px;
max-width: 690px;
}
.signal {
min-height: 112px;
padding: 16px;
border: 1px solid var(--line);
border-radius: 20px;
background: rgba(255, 254, 252, 0.58);
}
.signal strong {
display: block;
font-family: 'Inter', sans-serif;
font-size: 22px;
line-height: 1;
margin-bottom: 14px;
}
.signal span {
color: var(--muted);
font-size: 12px;
line-height: 1.55;
}
.phone-stage {
position: relative;
display: grid;
place-items: center;
min-height: 650px;
}
.route-lines {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0.7;
}
.route-lines path {
fill: none;
stroke: rgba(23, 19, 30, 0.16);
stroke-width: 1.2;
stroke-dasharray: 5 8;
}
.route-lines circle { fill: var(--ink); opacity: 0.42; }
.phone {
position: relative;
z-index: 2;
width: min(360px, 92vw);
min-height: 612px;
padding: 14px;
border: 1px solid rgba(23, 19, 30, 0.28);
border-radius: 44px;
background: linear-gradient(145deg, #111111, #3C3C38);
box-shadow: 0 28px 80px rgba(17, 17, 17, 0.22);
transform: rotate(2deg);
}
.phone::before {
content: "";
position: absolute;
top: 10px;
left: 50%;
width: 92px;
height: 22px;
border-radius: 999px;
background: #17131E;
transform: translateX(-50%);
z-index: 4;
}
.phone-screen {
overflow: hidden;
min-height: 584px;
border-radius: 33px;
background: #FFFEFC;
border: 1px solid rgba(255, 255, 255, 0.34);
}
.mobile-paper {
padding: 42px 22px 22px;
}
.mobile-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 18px;
padding-bottom: 18px;
border-bottom: 1.5px solid var(--ink);
}
.mobile-top strong {
font-family: 'Noto Serif SC', Georgia, serif;
font-size: 26px;
line-height: 0.95;
}
.mobile-date {
color: var(--ink);
font-family: 'Inter', sans-serif;
font-size: 11px;
font-weight: 800;
line-height: 1.35;
text-align: right;
}
.mobile-headline {
padding: 20px 0 18px;
border-bottom: 1px solid var(--line);
}
.mobile-headline h2 {
font-family: 'Noto Serif SC', Georgia, serif;
font-size: 28px;
line-height: 1.16;
letter-spacing: -0.04em;
}
.mobile-headline p {
margin-top: 12px;
color: var(--muted);
font-size: 13px;
line-height: 1.7;
}
.mobile-sections {
display: grid;
gap: 10px;
padding-top: 16px;
}
.mobile-section {
display: grid;
grid-template-columns: 42px 1fr;
gap: 10px;
align-items: stretch;
min-height: 72px;
}
.mobile-num {
border-radius: 16px;
background: var(--primary-light);
color: var(--ink);
display: grid;
place-items: center;
font-family: 'Inter', sans-serif;
font-weight: 800;
}
.mobile-section div:last-child {
border-bottom: 1px solid var(--line);
padding-bottom: 12px;
}
.mobile-section b {
display: block;
font-size: 14px;
margin-bottom: 6px;
}
.mobile-section span {
color: var(--muted);
font-size: 12px;
line-height: 1.55;
}
.orbit-note {
position: absolute;
right: 0;
bottom: 70px;
z-index: 3;
width: 168px;
padding: 14px;
border: 1px solid var(--line);
border-radius: 18px;
background: rgba(255, 254, 252, 0.84);
box-shadow: 0 14px 34px rgba(51, 40, 72, 0.12);
font-family: 'Inter', sans-serif;
font-size: 11px;
font-weight: 700;
line-height: 1.45;
text-transform: uppercase;
}
.orbit-note span { color: var(--ink); }
.content {
padding: 0 clamp(24px, 6vw, 76px) clamp(34px, 6vw, 76px);
}
.panel { display: none; }
#tab-today:checked ~ .shell .panel.today,
#tab-archive:checked ~ .shell .panel.archive,
#tab-palette:checked ~ .shell .panel.palette { display: block; }
.panel-head {
display: flex;
justify-content: space-between;
align-items: end;
gap: 24px;
padding-top: 26px;
border-top: 1px solid var(--line);
margin-bottom: 18px;
}
.eyebrow {
color: var(--ink);
font-family: 'Inter', sans-serif;
font-size: 12px;
font-weight: 800;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.panel-head h2 {
margin-top: 8px;
font-family: 'Noto Serif SC', Georgia, serif;
font-size: clamp(30px, 4vw, 48px);
line-height: 1;
}
.panel-head p {
max-width: 420px;
color: var(--muted);
font-size: 14px;
line-height: 1.75;
}
.brief-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 14px;
}
.brief-card {
display: flex;
flex-direction: column;
min-height: 230px;
padding: 20px;
border: 1px solid var(--line);
border-radius: 24px;
background: var(--panel);
transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease;
}
.brief-card:hover {
transform: translateY(-3px);
border-color: rgba(17, 17, 17, 0.28);
box-shadow: 0 18px 46px rgba(17, 17, 17, 0.10);
}
.brief-card.featured {
grid-column: span 2;
background:
linear-gradient(135deg, rgba(17, 17, 17, 0.055), transparent 42%),
rgba(255, 254, 252, 0.78);
}
.date {
color: var(--ink);
font-family: 'Inter', sans-serif;
font-size: 12px;
font-weight: 800;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.brief-card h3 {
margin-top: 24px;
font-family: 'Noto Serif SC', Georgia, serif;
font-size: 25px;
line-height: 1.28;
}
.brief-card p {
margin-top: 14px;
color: var(--muted);
font-size: 14px;
line-height: 1.72;
}
.read {
margin-top: auto;
padding-top: 20px;
color: var(--ink);
font-size: 13px;
font-weight: 800;
}
.archive-list {
border: 1px solid var(--line);
border-radius: 28px;
overflow: hidden;
background: rgba(255, 254, 252, 0.68);
}
.archive-item {
display: grid;
grid-template-columns: 130px 1fr auto;
gap: 22px;
align-items: center;
padding: 20px 22px;
border-bottom: 1px solid var(--line);
}
.archive-item:last-child { border-bottom: 0; }
.archive-item:hover { background: rgba(242, 238, 248, 0.55); }
.archive-title {
font-family: 'Noto Serif SC', Georgia, serif;
font-size: 23px;
line-height: 1.25;
}
.archive-desc {
margin-top: 6px;
color: var(--muted);
font-size: 13px;
line-height: 1.6;
}
.archive-arrow {
width: 34px;
height: 34px;
border: 1px solid var(--line);
border-radius: 50%;
display: grid;
place-items: center;
font-weight: 800;
}
.palette-board {
display: grid;
grid-template-columns: minmax(0, 1fr) 320px;
gap: 16px;
}
.palette-card {
min-height: 270px;
padding: 24px;
border: 1px solid var(--line);
border-radius: 28px;
background: rgba(255, 254, 252, 0.72);
}
.palette-atlas {
display: grid;
grid-template-columns: repeat(7, minmax(78px, 1fr));
gap: 10px;
margin-top: 26px;
}
.palette-swatch {
--swatch: #111;
position: relative;
overflow: hidden;
min-height: 156px;
padding: 12px;
border: 1px solid rgba(17, 17, 17, 0.12);
border-radius: 18px;
background: #FFFEFC;
}
.palette-swatch::before {
content: "";
position: absolute;
inset: 10px 10px auto;
height: 74px;
border: 1px solid rgba(17, 17, 17, 0.12);
border-radius: 14px;
background:
linear-gradient(135deg, rgba(255, 255, 255, 0.22), transparent 42%),
var(--swatch);
}
.palette-swatch::after {
content: "";
position: absolute;
right: -24px;
bottom: -28px;
width: 84px;
height: 84px;
border: 1px solid rgba(17, 17, 17, 0.1);
border-radius: 50%;
background: color-mix(in srgb, var(--swatch) 22%, transparent);
}
.palette-swatch b,
.palette-swatch span,
.palette-swatch code {
position: relative;
z-index: 1;
display: block;
}
.palette-swatch b {
margin-top: 88px;
color: var(--ink);
font-family: 'Inter', sans-serif;
font-size: 12px;
letter-spacing: 0.08em;
}
.palette-swatch span {
margin-top: 4px;
color: var(--muted);
font-size: 12px;
}
.palette-swatch code {
margin-top: 12px;
color: rgba(17, 17, 17, 0.46);
font-family: 'Inter', sans-serif;
font-size: 10px;
font-weight: 800;
}
.palette-swatch:nth-child(even) { transform: translateY(16px); }
.style-note {
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 270px;
padding: 22px;
border-radius: 28px;
background: var(--ink);
color: #fff;
}
.style-note p {
color: rgba(255, 255, 255, 0.72);
font-size: 14px;
line-height: 1.8;
}
.footnote {
display: flex;
justify-content: space-between;
gap: 18px;
margin-top: 34px;
color: rgba(23, 19, 30, 0.45);
font-family: 'Inter', 'Noto Sans SC', sans-serif;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.04em;
}
@media (max-width: 980px) {
body { padding: 14px; }
.shell { border-radius: 26px; }
.topbar { align-items: flex-start; flex-direction: column; }
.topbar-actions { width: 100%; justify-content: space-between; }
.lab-tooltip-panel { left: 0; right: auto; }
.lab-tooltip-panel::before { left: 32px; right: auto; }
.hero { grid-template-columns: 1fr; padding: 34px 22px; }
.phone-stage { min-height: 560px; }
.brief-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.palette-board { grid-template-columns: 1fr; }
.palette-atlas { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
.nav-tabs { width: 100%; overflow-x: auto; }
.nav-tabs label { flex: 1; text-align: center; white-space: nowrap; }
h1 { font-size: 48px; letter-spacing: -0.045em; }
.signal-row, .brief-grid { grid-template-columns: 1fr; }
.brief-card.featured { grid-column: span 1; }
.archive-item { grid-template-columns: 1fr; gap: 10px; }
.archive-arrow { display: none; }
.phone { width: min(330px, 94vw); transform: none; }
.orbit-note { right: 8px; bottom: 28px; }
.panel-head { display: block; }
.panel-head p { margin-top: 12px; }
.footnote { display: block; line-height: 1.9; }
.palette-atlas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.palette-swatch:nth-child(even) { transform: none; }
}
</style>
</head>
<body>
<main class="page">
<input class="tab-control" type="radio" name="home-tab" id="tab-today" checked>
<input class="tab-control" type="radio" name="home-tab" id="tab-archive">
<input class="tab-control" type="radio" name="home-tab" id="tab-palette">
<section class="shell" aria-label="The AI Industry Brief 首页">
<nav class="topbar" aria-label="首页导航">
<a class="brand" href="index.html" aria-label="返回首页">
<span class="brand-mark" aria-hidden="true"></span>
<span>每日 AI 行业简报</span>
</a>
<div class="nav-tabs" role="tablist" aria-label="内容切换">
<label for="tab-today" role="tab">今日</label>
<label for="tab-palette" role="tab">色板</label>
<label for="tab-archive" role="tab">往期</label>
</div>
<div class="topbar-actions">
<a class="github-link" href="https://github.com/mondaylab" target="_blank" rel="noopener noreferrer" aria-label="打开 GitHub 首页">
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M12 2C6.48 2 2 6.58 2 12.24c0 4.52 2.87 8.35 6.84 9.71.5.1.68-.22.68-.49 0-.24-.01-.88-.01-1.73-2.78.62-3.37-1.37-3.37-1.37-.45-1.19-1.11-1.51-1.11-1.51-.91-.64.07-.63.07-.63 1 .07 1.53 1.06 1.53 1.06.9 1.57 2.35 1.12 2.92.86.09-.66.35-1.12.63-1.37-2.22-.26-4.56-1.14-4.56-5.07 0-1.12.39-2.03 1.03-2.75-.1-.26-.45-1.3.1-2.71 0 0 .84-.28 2.75 1.05A9.35 9.35 0 0 1 12 6.95c.85 0 1.7.12 2.5.35 1.9-1.33 2.74-1.05 2.74-1.05.55 1.41.2 2.45.1 2.71.64.72 1.03 1.63 1.03 2.75 0 3.94-2.34 4.8-4.57 5.06.36.32.68.95.68 1.91 0 1.38-.01 2.49-.01 2.83 0 .27.18.59.69.49A10.13 10.13 0 0 0 22 12.24C22 6.58 17.52 2 12 2Z"/>
</svg>
</a>
<div class="lab-tooltip">
<button class="lab" type="button" aria-describedby="wechat-tooltip">星期一研究室</button>
<div class="lab-tooltip-panel" id="wechat-tooltip" role="tooltip">
<img class="wechat-qr" src="assets/wechat-qr.jpg" alt="星期一研究室公众号二维码">
</div>
</div>
</div>
</nav>
<section class="hero">
<div class="hero-copy">
<div class="kicker">Daily intelligence for AI builders</div>
<h1>The AI Industry Brief</h1>
<p class="lead">把一天的 AI 行业动态压缩进一份可读、可归档、可复用的报刊。用更轻的界面,追踪工作台、流水线、大模型与信息美学的结构性变化。</p>
<div class="hero-actions">
<a class="button primary" href="briefs/2026-05-29.html">阅读最新一期</a>
<label class="button" for="tab-palette" data-preserve-scroll>查看七天色板</label>
<label class="button" for="tab-archive" data-preserve-scroll>查看往期</label>
</div>
<div class="signal-row" aria-label="简报栏目">
<div class="signal"><strong>04</strong><span>固定栏目:AI 工作台、AI 信息美学、AI 流水线、AI 大模型。</span></div>
<div class="signal"><strong>03</strong><span>每个栏目筛选三条高信号动态,避免信息噪音。</span></div>
<div class="signal"><strong>07</strong><span>七天主色系统,保持日更节奏里的视觉识别。</span></div>
</div>
</div>
<div class="phone-stage" aria-hidden="true">
<svg class="route-lines" viewBox="0 0 520 650">
<path d="M40 116 C150 52, 302 62, 438 132 S490 336, 376 380 S152 366, 112 482 S252 618, 468 540" />
<path d="M70 520 C132 420, 236 446, 296 320 S370 126, 478 88" />
<circle cx="40" cy="116" r="5" />
<circle cx="376" cy="380" r="5" />
<circle cx="468" cy="540" r="5" />
</svg>
<div class="phone">
<div class="phone-screen">
<article class="mobile-paper">
<div class="mobile-top">
<strong>AI<br>Brief</strong>
<div class="mobile-date">05/29<br>FRIDAY</div>
</div>
<div class="mobile-headline">
<h2>编排层开始接管产品栈</h2>
<p>工作台、流水线、模型与创意接口同时朝闭环执行收束。</p>
</div>
<div class="mobile-sections">
<div class="mobile-section"><span class="mobile-num">01</span><div><b>AI 工作台</b><span>上下文、代理入口和任务界面重新组合。</span></div></div>
<div class="mobile-section"><span class="mobile-num">02</span><div><b>AI 信息美学</b><span>生成媒体从结果展示走向连续编辑。</span></div></div>
<div class="mobile-section"><span class="mobile-num">03</span><div><b>AI 流水线</b><span>CLI、MCP 与自动化成为新的执行骨架。</span></div></div>
<div class="mobile-section"><span class="mobile-num">04</span><div><b>AI 大模型</b><span>模型能力更贴近长任务和产品交付。</span></div></div>
</div>
</article>
</div>
</div>
<div class="orbit-note">One phone.<br><span>One daily paper.</span><br>Readable intelligence.</div>
</div>
</section>
<section class="content">
<section class="panel today">
<div class="panel-head">
<div>
<div class="eyebrow">Latest Edition</div>
<h2>今日简报</h2>
</div>
<p>首页保留足够留白,把最新一期作为入口,同时把值得回看的内容整理成往期推荐。</p>
</div>
<div class="brief-grid">
<a class="brief-card featured" href="briefs/2026-05-29.html">
<div class="date">05/29 · 星期五</div>
<h3>编排层开始接管产品栈</h3>
<p>工作台、流水线、模型与创意接口同时朝闭环执行收束。</p>
<span class="read">查看今日早报 →</span>
</a>
<a class="brief-card" href="briefs/2026-05-28.html">
<div class="date">05/28 · 星期四</div>
<h3>上下文接口成为新分界</h3>
<p>工作台、代理编排、长任务模型与创意 MCP 同步靠拢。</p>
<span class="read">查看前一期 →</span>
</a>
<a class="brief-card" href="color-palette-demo.html">
<div class="date">Style System</div>
<h3>Weekly Palette Demo</h3>
<p>查看周一到周日的紫、蓝、绿、粉色系在简报组件里的实际效果。</p>
<span class="read">查看色板 →</span>
</a>
</div>
</section>
<section class="panel archive">
<div class="panel-head">
<div>
<div class="eyebrow">Previous Issues</div>
<h2>往期</h2>
</div>
<p>从过往简报中挑出值得回看的行业信号,适合快速补齐 AI 产品栈、模型能力和创意工具的连续变化。</p>
</div>
<div class="archive-list">
<a class="archive-item" href="briefs/2026-05-29.html"><div class="date">05/29 · 星期五</div><div><div class="archive-title">编排层开始接管产品栈</div><div class="archive-desc">工作台、流水线、模型与创意接口同时朝闭环执行收束。</div></div><span class="archive-arrow">→</span></a>
<a class="archive-item" href="briefs/2026-05-28.html"><div class="date">05/28 · 星期四</div><div><div class="archive-title">上下文接口成为新分界</div><div class="archive-desc">工作台、代理编排、长任务模型与创意 MCP 同步靠拢。</div></div><span class="archive-arrow">→</span></a>
<a class="archive-item" href="briefs/2026-05-27.html"><div class="date">05/27 · 星期三</div><div><div class="archive-title">任务入口开始主动编排</div><div class="archive-desc">Daily Brief、Goal mode、Gemini 3.5 与 Aleph 2.0 指向持续执行链。</div></div><span class="archive-arrow">→</span></a>
<a class="archive-item" href="briefs/2026-05-26.html"><div class="date">05/26 · 星期二</div><div><div class="archive-title">入口之争转向工作现场</div><div class="archive-desc">Antigravity CLI、Managed Agents、Gemini Omni 与创意执行界面的演进。</div></div><span class="archive-arrow">→</span></a>
<a class="archive-item" href="briefs/2026-05-25.html"><div class="date">05/25 · 星期一</div><div><div class="archive-title">AI 正进入主动工作阶段</div><div class="archive-desc">Gemini 主动简报、Antigravity CLI、Gemini 3.5 与新的创意工作流。</div></div><span class="archive-arrow">→</span></a>
</div>
</section>
<section class="panel palette">
<div class="panel-head">
<div>
<div class="eyebrow">Visual System</div>
<h2>七天色板</h2>
</div>
<p>用紫、蓝、绿、粉色系建立轻量但稳定的日更识别,避免每期页面变成孤立视觉。</p>
</div>
<div class="palette-board">
<a class="palette-card" href="color-palette-demo.html">
<div class="date">Weekly Palette Demo</div>
<h3 class="archive-title">从周一到周日的主色预览</h3>
<div class="palette-atlas" aria-label="七天主色色票">
<div class="palette-swatch" style="--swatch:#927BBE"><b>MON</b><span>莫兰迪紫</span><code>#927BBE</code></div>
<div class="palette-swatch" style="--swatch:#6F97A8"><b>TUE</b><span>雾蓝</span><code>#6F97A8</code></div>
<div class="palette-swatch" style="--swatch:#7FA6C9"><b>WED</b><span>晴蓝</span><code>#7FA6C9</code></div>
<div class="palette-swatch" style="--swatch:#7FA68B"><b>THU</b><span>鼠尾草绿</span><code>#7FA68B</code></div>
<div class="palette-swatch" style="--swatch:#6F9F99"><b>FRI</b><span>青瓷绿</span><code>#6F9F99</code></div>
<div class="palette-swatch" style="--swatch:#8A93B7"><b>SAT</b><span>紫蓝</span><code>#8A93B7</code></div>
<div class="palette-swatch" style="--swatch:#EC9BC8"><b>SUN</b><span>柔粉</span><code>#EC9BC8</code></div>
</div>
</a>
<div class="style-note">
<div class="eyebrow">Design Note</div>
<p>首页保持黑白灰基调,把每日主色留给简报正文和色板样本,展示系统本身更克制。</p>
<a class="button" href="color-palette-demo.html">打开完整 Demo</a>
</div>
</div>
</section>
<footer class="footnote">
<span>星期一研究室出品</span>
<span>The AI Industry Brief · 每日行业简报 · 项目管理 · 信息美学</span>
</footer>
</section>
</section>
</main>
<script>
document.querySelectorAll('[data-preserve-scroll]').forEach((label) => {
label.addEventListener('click', (event) => {
const target = document.getElementById(label.getAttribute('for'));
if (!target) return;
event.preventDefault();
const x = window.scrollX;
const y = window.scrollY;
target.checked = true;
target.dispatchEvent(new Event('change', { bubbles: true }));
window.scrollTo(x, y);
});
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The AI Industry Brief | 05/26 · 星期二 | 星期一研究室</title>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700&family=Noto+Serif+SC:wght@400;500;700&family=Source+Serif+4:wght@400;600&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--primary: #6F97A8;
--primary-light: #F0F5F7;
--paper: #FCFBF9;
--ground: #EEECE8;
--text: #151515;
--body: #2E2E2E;
--rule: #D9D2CE;
--headline-rule: color-mix(in srgb, var(--primary) 78%, #151515);
--section-ink: var(--primary);
--section-ink-soft: var(--primary-light);
--section-guide: color-mix(in srgb, var(--primary) 42%, transparent);
}
body {
background:
radial-gradient(circle at 14% 18%, color-mix(in srgb, var(--primary) 18%, transparent), transparent 26%),
radial-gradient(circle at 88% 78%, rgba(127, 166, 201, 0.12), transparent 24%),
var(--ground);
display: flex;
justify-content: center;
padding: 36px clamp(32px, 4vw, 72px);
}
.card {
position: relative;
overflow: visible;
background: var(--paper);
max-width: 1480px;
width: 100%;
min-height: min(1046px, calc((100vw - 28px) / 1.414));
height: auto;
padding: 36px clamp(52px, 4.6vw, 72px);
border: 1px solid #D8D1CB;
box-shadow: 0 6px 30px rgba(17, 17, 17, 0.05);
font-family: 'Source Serif 4', 'Noto Serif SC', serif;
}
.card::before {
content: "";
position: absolute;
inset: 18px;
pointer-events: none;
border: 1px solid rgba(21, 21, 21, 0.08);
background-image:
linear-gradient(rgba(21, 21, 21, 0.035) 1px, transparent 1px),
linear-gradient(90deg, rgba(21, 21, 21, 0.035) 1px, transparent 1px);
background-size: 38px 38px;
mask-image: linear-gradient(to bottom, transparent, #000 16%, #000 82%, transparent);
}
.card::after {
content: "THE AI INDUSTRY BRIEF / GLOBAL SIGNALS";
position: absolute;
right: 28px;
top: 112px;
color: rgba(21, 21, 21, 0.18);
font-family: 'Inter', sans-serif;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.26em;
writing-mode: vertical-rl;
pointer-events: none;
}
.header {
position: relative;
z-index: 2;
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 26px;
border-bottom: 2px solid var(--text);
border-top: 6px solid var(--headline-rule);
padding-top: 24px;
margin-bottom: 34px;
}
.header-left .brand {
font-family: 'Playfair Display', 'Noto Serif SC', serif;
font-size: 42px;
font-weight: 700;
color: var(--text);
letter-spacing: 0;
line-height: 1;
}
.header-right { text-align: right; }
.header-right .lab {
font-size: 12px;
font-weight: 600;
color: #5A5A5A;
letter-spacing: 0.12em;
text-transform: uppercase;
margin-bottom: 4px;
}
.header-right .date { font-size: 11px; color: #777; letter-spacing: 0.08em; }
.quote-card {
position: relative;
z-index: 2;
background:
linear-gradient(90deg, color-mix(in srgb, var(--primary-light) 72%, transparent), transparent 42%),
#F8F6F2;
border-top: 1px solid rgba(21, 21, 21, 0.18);
border-bottom: 1px solid rgba(21, 21, 21, 0.18);
border-left: 0;
border-radius: 0;
padding: 18px 22px 18px 0;
margin-bottom: 46px;
font-size: 22px;
line-height: 1.42;
color: var(--body);
font-weight: 500;
min-height: 132px;
display: grid;
grid-template-columns: 74px minmax(0, 1fr) 230px;
gap: 28px;
align-items: center;
overflow: hidden;
}
.quote-card::before {
content: "LEAD";
align-self: stretch;
display: flex;
align-items: center;
justify-content: center;
border-right: 1px solid rgba(21, 21, 21, 0.18);
color: var(--section-ink);
font-family: 'Inter', sans-serif;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.24em;
writing-mode: vertical-rl;
text-orientation: mixed;
}
.quote-copy {
position: relative;
z-index: 1;
max-width: 760px;
}
.hero-illustration {
position: relative;
width: 230px;
height: 128px;
z-index: 1;
justify-self: end;
pointer-events: none;
opacity: 0.74;
}
.hero-line {
fill: none;
stroke: var(--section-ink);
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
.hero-soft {
fill: var(--section-ink-soft);
stroke: color-mix(in srgb, var(--section-ink) 28%, transparent);
stroke-width: 1;
}
.hero-ink {
fill: color-mix(in srgb, var(--section-ink) 72%, #151515);
}
.hero-label {
fill: rgba(21, 21, 21, 0.28);
font-family: 'Inter', sans-serif;
font-size: 8px;
font-weight: 700;
letter-spacing: 0.18em;
}
.quote-label {
font-family: 'Inter', sans-serif;
font-size: 10px;
font-weight: 600;
color: color-mix(in srgb, var(--section-ink) 64%, #151515);
letter-spacing: 0.18em;
text-transform: uppercase;
margin-bottom: 10px;
}
.insight-label {
font-size: 10px;
font-weight: 600;
color: #666;
letter-spacing: 0.14em;
text-transform: uppercase;
margin-bottom: 6px;
}
.section { padding: 14px 0 16px; border-bottom: 0; }
.sections-layout {
position: relative;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
column-gap: 46px;
row-gap: 78px;
align-items: stretch;
overflow: visible;
padding: 8px 10px 4px;
}
.sections-layout::before {
content: "AI INDUSTRY MAP";
position: absolute;
left: 50%;
top: -14px;
transform: translateX(-50%);
z-index: 1;
padding: 0 12px;
background: var(--paper);
color: rgba(21, 21, 21, 0.34);
font-family: 'Inter', sans-serif;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.22em;
white-space: nowrap;
}
.sections-layout > .section {
position: relative;
z-index: 2;
height: 100%;
display: flex;
flex-direction: column;
align-self: stretch;
padding: 18px 18px 14px;
background: color-mix(in srgb, var(--paper) 86%, var(--section-ink-soft));
border: 1px solid rgba(21, 21, 21, 0.08);
box-shadow: 14px 16px 0 color-mix(in srgb, var(--primary) 8%, transparent);
}
.sections-layout > .section::before {
content: "";
position: absolute;
top: -8px;
right: 18px;
width: 42px;
height: 14px;
background: var(--section-ink-soft);
border: 1px solid rgba(21, 21, 21, 0.09);
transform: skewX(-18deg);
}
.sections-layout > .section::after {
content: "SIGNAL NODE";
position: absolute;
right: 20px;
bottom: 12px;
color: rgba(21, 21, 21, 0.17);
font-family: 'Inter', sans-serif;
font-size: 9px;
font-weight: 700;
letter-spacing: 0.18em;
}
.sections-layout > .section:nth-of-type(odd) {
padding-right: 18px;
}
.sections-layout > .section:nth-of-type(even) {
padding-left: 18px;
}
.sections-layout > .section:nth-of-type(n + 3) {
padding-top: 18px;
}
.section-header {
position: relative;
margin-bottom: 12px;
min-height: 46px;
}
.section-tag {
position: relative;
z-index: 1;
display: inline-flex;
align-items: center;
gap: 12px;
background: transparent;
color: var(--text);
font-family: 'Inter', 'Noto Serif SC', serif;
font-size: 21px;
font-weight: 700;
padding: 0;
border-radius: 0;
letter-spacing: 0;
border-bottom: 0;
}
.section-tag::before {
content: attr(data-num);
display: inline-flex;
align-items: center;
justify-content: center;
width: 54px;
height: 36px;
background: var(--section-ink);
color: #fff;
font-size: 16px;
font-weight: 700;
font-family: 'Inter', sans-serif;
transform: skewX(-12deg);
box-shadow: 8px 8px 0 var(--section-ink-soft);
}
.section-tag::after {
content: "";
position: absolute;
left: 64px;
right: -96px;
top: 50%;
z-index: -1;
border-top: 1px dashed var(--section-guide);
transform: translateY(-50%) rotate(-3deg);
}
.section-tag svg { display: none; }
.section-sub {
font-size: 10px;
color: #787878;
margin-top: 4px;
margin-bottom: 14px;
margin-left: 66px;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.section-items {
display: flex;
flex-direction: column;
gap: 18px;
flex: 1 1 auto;
}
.item + .item {
margin-top: 0;
}
.item {
flex: 0 0 auto;
margin-bottom: 0;
background: rgba(252, 251, 249, 0.66);
border: 1px solid rgba(21, 21, 21, 0.07);
border-radius: 2px;
padding: 22px 30px 24px;
display: flex;
flex-direction: column;
}
.item-title {
font-size: 18px;
font-weight: 700;
color: var(--text);
margin-bottom: 14px;
line-height: 1.32;
display: flex;
align-items: flex-start;
gap: 12px;
}
.item-tool { color: #1C1C1C; font-weight: 700; }
.item-divider, .item-heading { color: var(--text); font-weight: 700; }
.item-copy { flex: 1; }
.item-num {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 26px;
height: 30px;
padding: 0 8px;
border-radius: 0;
background: transparent;
font-size: 0;
font-weight: 700;
font-family: 'Playfair Display', 'Noto Serif SC', serif;
color: var(--section-ink);
flex-shrink: 0;
line-height: 1;
}
.item-num::before {
content: attr(data-mark);
font-size: 17px;
color: var(--section-ink);
line-height: 1;
}
.item-desc {
font-size: 16px;
color: var(--body);
line-height: 1.72;
margin-bottom: 0;
font-weight: 400;
flex: 0 0 auto;
}
.item-source {
font-size: 13px;
color: #444;
text-decoration: none;
opacity: 0.9;
font-weight: 500;
margin-top: auto;
padding-top: 20px;
}
.item-source:hover { opacity: 1; text-decoration: underline; }
.source-date {
font-size: 11px;
color: #7C7C7C;
margin-left: 8px;
font-weight: 500;
}
.insight-card {
position: relative;
z-index: 2;
background: transparent;
border-top: 1px solid rgba(21, 21, 21, 0.2);
border-bottom: 1px solid rgba(21, 21, 21, 0.12);
border-left: 0;
border-radius: 0;
padding: 20px 4px 18px;
margin-top: 64px;
margin-bottom: 38px;
display: grid;
grid-template-columns: 188px minmax(0, 1fr);
column-gap: 18px;
align-items: center;
}
.insight-label {
position: relative;
justify-self: center;
width: max-content;
transform: translateY(12px);
margin-bottom: 0;
color: var(--section-ink);
font-family: 'Inter', sans-serif;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.insight-label::after {
content: "";
display: block;
width: 44px;
height: 44px;
margin-top: 22px;
margin-left: auto;
margin-right: auto;
border: 2px solid color-mix(in srgb, var(--section-ink) 72%, transparent);
border-radius: 50%;
background:
radial-gradient(circle at 50% 50%, var(--section-ink) 0 4px, transparent 5px),
linear-gradient(45deg, transparent 58%, color-mix(in srgb, var(--section-ink) 72%, transparent) 59% 64%, transparent 65%);
box-shadow: 14px 14px 0 var(--section-ink-soft);
opacity: 0.9;
}
.insight-text {
font-size: 18px;
color: #242424;
line-height: 1.72;
font-weight: 500;
}
.method-note {
grid-column: 2;
margin-top: 12px;
font-size: 11px;
color: #7A7A7A;
line-height: 1.6;
}
.footer {
position: relative;
z-index: 2;
border-top: 2px solid var(--text);
padding-top: 12px;
display: flex;
justify-content: space-between;
align-items: center;
}
.footer-lab { font-size: 12px; font-weight: 600; color: #303030; letter-spacing: 0.08em; text-transform: uppercase; }
.footer-sub { font-size: 11px; color: #666; letter-spacing: 0.03em; }
@media (max-width: 560px) {
body { padding: 0; }
.card { padding: 32px 22px; aspect-ratio: auto; }
.card::before, .card::after, .sections-layout::before { display: none; }
.header-left .brand { font-size: 34px; }
.header { align-items: flex-end; padding-top: 18px; padding-bottom: 18px; }
.sections-layout { grid-template-columns: 1fr; gap: 0; }
.quote-card { display: block; min-height: auto; padding: 18px 20px; font-size: 18px; }
.quote-card::before { display: none; }
.hero-illustration { display: none; }
.sections-layout > .section:nth-of-type(odd),
.sections-layout > .section:nth-of-type(even) {
border-left: 0;
padding-left: 0;
padding-right: 0;
background: transparent;
border: 0;
box-shadow: none;
}
.sections-layout > .section::before,
.sections-layout > .section::after { display: none; }
.sections-layout > .section:nth-of-type(n + 3) { padding-top: 14px; }
.section-header { min-height: 40px; }
.section-tag { font-size: 18px; gap: 10px; }
.section-tag::before { width: 46px; height: 32px; font-size: 14px; box-shadow: 6px 6px 0 var(--section-ink-soft); }
.section-tag::after { right: -48px; left: 56px; }
.section-sub { margin-left: 56px; }
.section-items { gap: 10px; }
.item { flex: 0 1 auto; min-height: auto; }
.item + .item { margin-top: 0; }
.section + .section { margin-top: 10px; padding-top: 14px; }
.item-num { min-width: 22px; padding: 0 6px; }
.item-title { font-size: 16px; gap: 8px; }
.item-desc { font-size: 15px; }
.insight-card { display: block; padding: 18px 0; }
.insight-label { margin-bottom: 10px; }
.insight-text { font-size: 16px; }
.method-note { margin-top: 12px; }
}
</style>
</head>
<body>
<main class="card">
<header class="header">
<div class="header-left"><div class="brand">The AI Industry Brief</div></div>
<div class="header-right">
<div class="lab">星期一研究室</div>
<div class="date">05/26 · 星期二</div>
</div>
</header>
<div class="quote-card">
<div class="quote-copy">
<div class="quote-label">今日一句话</div>
真正的 AI 入口之争,已从聊天框转向能接管任务的工作现场。
</div>
<svg class="hero-illustration" viewBox="0 0 230 154" aria-hidden="true" focusable="false">
<path class="hero-soft" d="M25 118 C44 82, 72 77, 94 98 S142 126, 174 91 C190 73, 207 72, 219 82 L219 142 L25 142 Z" />
<circle class="hero-soft" cx="175" cy="44" r="26" />
<path class="hero-line" d="M149 44H201 M175 18C165 31,165 57,175 70 M175 18C185 31,185 57,175 70 M153 35H197 M153 53H197" />
<path class="hero-line" d="M46 108 L66 72 L86 108 M55 92H77" />
<circle class="hero-ink" cx="70" cy="43" r="10" />
<path class="hero-soft" d="M47 132 C48 97, 56 63, 70 63 C84 63, 92 97, 93 132 Z" />
<path class="hero-line" d="M59 78 C42 83, 33 94, 27 109 M82 78 C100 83, 113 94, 121 109" />
<circle class="hero-line" cx="31" cy="102" r="10" />
<path class="hero-line" d="M38 109 L49 120" />
<path class="hero-line" d="M129 67 H147 M138 58 V76 M125 92 H154 M132 103 H149" />
<text class="hero-label" x="118" y="132">GLOBAL SIGNALS</text>
</svg>
</div>
<div class="sections-layout">
<section class="section">
<div class="section-header">
<span class="section-tag" data-num="01">
<svg width="13" height="13" viewBox="0 0 18 18" fill="none"><rect x="1" y="1" width="7" height="7" rx="1.5" fill="white"/><rect x="10" y="1" width="7" height="7" rx="1.5" fill="white"/><rect x="1" y="10" width="7" height="7" rx="1.5" fill="white"/><rect x="10" y="10" width="7" height="7" rx="1.5" fill="white"/></svg>
AI 工作台
</span>
</div>
<div class="section-sub">Gemini App · Notion · 飞书 aily</div>
<div class="section-items">
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◆" aria-label="01">01</span><span class="item-copy"><span class="item-tool">Gemini App</span><span class="item-divider"> | </span><span class="item-heading">主动简报连接日程</span></span></div>
<p class="item-desc">Google 为 Gemini App 引入结合许可数据生成的主动简报,可预先汇聚行程与行动事项。个人 AI 工作台由等候指令,转向每天自动组织注意力。</p>
<a class="item-source" href="https://blog.google/innovation-and-ai/products/gemini-app/next-evolution-gemini-app/" target="_blank" rel="noopener noreferrer">→ blog.google</a><span class="source-date">2026-05-19</span>
</article>
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◇" aria-label="02">02</span><span class="item-copy"><span class="item-tool">Notion</span><span class="item-divider"> | </span><span class="item-heading">开放 Agent 工作区</span></span></div>
<p class="item-desc">Notion Developer Platform 提供 Agent API、Workers、Webhooks 与命令行工具,让协作内容可触发自动执行。文档和数据库开始同时承担业务运行层角色。</p>
<a class="item-source" href="https://www.notion.com/releases/2026-05-13" target="_blank" rel="noopener noreferrer">→ notion.com</a><span class="source-date">2026-05-13 · 最近官方参考</span>
</article>
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◈" aria-label="03">03</span><span class="item-copy"><span class="item-tool">飞书 aily</span><span class="item-divider"> | </span><span class="item-heading">企业场景部署智能体</span></span></div>
<p class="item-desc">飞书 aily 面向企业提供知识、技能与系统接入的智能体开发能力。办公平台竞争不再止于助手体验,而在能否把 Agent 嵌回组织流程。</p>
<a class="item-source" href="https://www.feishu.cn/content/article/7597739180457806780" target="_blank" rel="noopener noreferrer">→ feishu.cn</a><span class="source-date">2026-01-21 · 最近官方参考</span>
</article>
</div>
</section>
<section class="section">
<div class="section-header">
<span class="section-tag" data-num="02">
<svg width="13" height="13" viewBox="0 0 18 18" fill="none"><path d="M9 2C5.13 2 2 5.13 2 9C2 12.87 5.13 16 9 16C9.83 16 10.5 15.33 10.5 14.5C10.5 14.11 10.35 13.76 10.1 13.5C9.86 13.25 9.72 12.91 9.72 12.5C9.72 11.67 10.39 11 11.22 11H13C14.66 11 16 9.66 16 8C16 4.69 12.87 2 9 2Z" stroke="white" stroke-width="1.3"/><circle cx="6" cy="6.5" r="1" fill="white"/><circle cx="9" cy="5" r="1" fill="white"/><circle cx="12" cy="6.5" r="1" fill="white"/><circle cx="6" cy="10" r="1" fill="white"/></svg>
AI 信息美学
</span>
</div>
<div class="section-sub">Google Pics · Gemini Omni · Adobe Firefly</div>
<div class="section-items">
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◆" aria-label="01">01</span><span class="item-copy"><span class="item-tool">Google Pics</span><span class="item-divider"> | </span><span class="item-heading">把生图带入编辑现场</span></span></div>
<p class="item-desc">Google 公布 Pics,将 Nano Banana 图像能力嵌入可组织、可修改的创意工作区。生成视觉从提示词的一次性输出,转向连续的构图与修订过程。</p>
<a class="item-source" href="https://blog.google/innovation-and-ai/sundar-pichai-io-2026/" target="_blank" rel="noopener noreferrer">→ blog.google</a><span class="source-date">2026-05-19 · 邻近窗口</span>
</article>
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◇" aria-label="02">02</span><span class="item-copy"><span class="item-tool">Gemini Omni</span><span class="item-divider"> | </span><span class="item-heading">跨媒体生成统一化</span></span></div>
<p class="item-desc">Gemini Omni 面向原生全模态理解与生成方向亮相,覆盖图像、音频和视频语境。视觉内容生产的入口将更自然地连接脚本、声音与动态画面。</p>
<a class="item-source" href="https://blog.google/innovation-and-ai/technology/developers-tools/google-io-2026-collection/" target="_blank" rel="noopener noreferrer">→ blog.google</a><span class="source-date">2026-05-20</span>
</article>
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◈" aria-label="03">03</span><span class="item-copy"><span class="item-tool">Adobe Firefly</span><span class="item-divider"> | </span><span class="item-heading">创意 Agent 贯通制作</span></span></div>
<p class="item-desc">Adobe 发布 Firefly AI Assistant 与创意 Agent 能力,以辅助生成、修改和品牌化制作。视觉工具的护城河正在转向工作流衔接和商用控制。</p>
<a class="item-source" href="https://news.adobe.com/news/2026/04/adobe-new-creative-agent" target="_blank" rel="noopener noreferrer">→ news.adobe.com</a><span class="source-date">2026-04-15 · 最近官方参考</span>
</article>
</div>
</section>
<section class="section">
<div class="section-header">
<span class="section-tag" data-num="03">
<svg width="13" height="13" viewBox="0 0 18 18" fill="none"><circle cx="2.5" cy="9" r="2" fill="white"/><line x1="4.5" y1="9" x2="7.5" y2="9" stroke="white" stroke-width="1.5" stroke-linecap="round"/><circle cx="9" cy="9" r="2" fill="white"/><line x1="11" y1="9" x2="13.5" y2="9" stroke="white" stroke-width="1.5" stroke-linecap="round"/><circle cx="15.5" cy="9" r="2" fill="white"/></svg>
AI 流水线
</span>
</div>
<div class="section-sub">Antigravity CLI · Claude Managed Agents · Codex</div>
<div class="section-items">
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◆" aria-label="01">01</span><span class="item-copy"><span class="item-tool">Antigravity CLI</span><span class="item-divider"> | </span><span class="item-heading">承接跨界面执行</span></span></div>
<p class="item-desc">Google 宣布 Gemini CLI 迁移为 Antigravity CLI,并将能力扩展至编辑器与浏览器中的智能体执行。开发入口正在围绕任务编排而非单轮请求重组。</p>
<a class="item-source" href="https://developers.googleblog.com/en/gemini-cli-is-now-antigravity-cli/" target="_blank" rel="noopener noreferrer">→ developers.googleblog.com</a><span class="source-date">2026-05-20</span>
</article>
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◇" aria-label="02">02</span><span class="item-copy"><span class="item-tool">Claude</span><span class="item-divider"> | </span><span class="item-heading">Managed Agents 接通 MCP</span></span></div>
<p class="item-desc">Anthropic 为 Claude Managed Agents 加入自托管沙箱与 MCP tunnels,使企业工具和受控执行环境可接入 Agent。企业落地重点转向权限与执行边界。</p>
<a class="item-source" href="https://claude.com/blog/claude-managed-agents-self-hosted-sandboxes-mcp-tunnels" target="_blank" rel="noopener noreferrer">→ claude.com</a><span class="source-date">2026-05-19 · 邻近窗口</span>
</article>
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◈" aria-label="03">03</span><span class="item-copy"><span class="item-tool">Codex</span><span class="item-divider"> | </span><span class="item-heading">移动端跟进长任务</span></span></div>
<p class="item-desc">OpenAI 发布可跨设备推进 Codex 任务的工作方式,使代码任务在离开桌面后仍可查看与继续。编程 Agent 的价值变成持续协作与成果回收。</p>
<a class="item-source" href="https://openai.com/index/work-with-codex-from-anywhere/" target="_blank" rel="noopener noreferrer">→ openai.com</a><span class="source-date">2026-05-14 · 最近官方参考</span>
</article>
</div>
</section>
<section class="section">
<div class="section-header">
<span class="section-tag" data-num="04">
<svg width="13" height="13" viewBox="0 0 18 18" fill="none"><path d="M10.5 2L4 10h5.5L7.5 16L14 8H8.5L10.5 2Z" fill="white"/></svg>
AI 大模型
</span>
</div>
<div class="section-sub">Gemini 3.5 · Gemini Omni · GPT-5.5</div>
<div class="section-items">
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◆" aria-label="01">01</span><span class="item-copy"><span class="item-tool">Gemini 3.5</span><span class="item-divider"> | </span><span class="item-heading">强化多步任务推理</span></span></div>
<p class="item-desc">Google 发布 Gemini 3.5,强调复杂推理、智能体使用与成本效率提升。头部模型的评判坐标已从回答漂亮,切换到多步骤任务是否跑得稳。</p>
<a class="item-source" href="https://blog.google/intl/en-africa/products/explore-get-answers/gemini-3-5/" target="_blank" rel="noopener noreferrer">→ blog.google</a><span class="source-date">2026-05-19 · 邻近窗口</span>
</article>
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◇" aria-label="02">02</span><span class="item-copy"><span class="item-tool">Gemini Omni</span><span class="item-divider"> | </span><span class="item-heading">统一理解与生成模态</span></span></div>
<p class="item-desc">Google 的 I/O 开发者合集披露 Gemini Omni 预览,将文本、图像、音频和视频能力纳入原生全模态方向。应用层的模型路由复杂度随之降低。</p>
<a class="item-source" href="https://blog.google/innovation-and-ai/technology/developers-tools/google-io-2026-collection/" target="_blank" rel="noopener noreferrer">→ blog.google</a><span class="source-date">2026-05-20</span>
</article>
<article class="item">
<div class="item-title"><span class="item-num" data-mark="◈" aria-label="03">03</span><span class="item-copy"><span class="item-tool">GPT-5.5</span><span class="item-divider"> | </span><span class="item-heading">聚焦复杂工作产出</span></span></div>
<p class="item-desc">OpenAI 将 GPT-5.5 定位为加强复杂工作与编码任务的模型,并服务于 Codex 工作流。模型升级正越来越直接地对应可交付的生产任务。</p>
<a class="item-source" href="https://openai.com/index/introducing-gpt-5-5/" target="_blank" rel="noopener noreferrer">→ openai.com</a><span class="source-date">2026-04-23 · 最近官方参考</span>
</article>
</div>
</section>
</div>
<aside class="insight-card">
<div class="insight-label">今日洞察</div>
<p class="insight-text">模型正在让位于“执行界面”:工作台抢上下文,CLI 抢动作入口,多模态编辑器抢最终产物。能管理权限、连接工具并持续推进任务的平台,将比单纯拥有更强模型的平台更快形成日常依赖。</p>
<p class="method-note">采集窗口以 2026-05-20 至 2026-05-26 为优先;窗口内官方新品不足以覆盖所有专栏时,补充项均标注为邻近窗口或最近官方参考。</p>
</aside>
<footer class="footer">
<div class="footer-lab">星期一研究室出品</div>
<div class="footer-sub">The AI Industry Brief · 每日行业简报 · 项目管理 · 信息美学</div>
</footer>
</main>
</body>
</html>
Brief Specification
Output
- Detail file:
briefs/YYYY-MM-DD.html - Archive file:
index.html - Data config file:
brief-data/YYYY-MM-DD.json - Share image file:
share-images/YYYY-MM-DD.png - Detail structure: opening line, 4 sections x 3 items, closing insight, sourcing note, footer
- Archive structure: latest card first; every existing brief remains clickable
Sections
Default AI brief sections:
| Section | Focus | Seed queries |
|---|---|---|
| AI 工作台 | Product updates, knowledge/workspace shifts | Notion AI, YouMind, 飞书 AI, Obsidian AI |
| AI 流水线 | CLI tools, agents, MCP, deployment | Claude Code, Gemini CLI, Codex CLI, MCP, Agent framework |
| AI 大模型 | Model launches, evaluations, benchmarks | Claude, GPT, Gemini, DeepSeek, Kimi model update |
| AI 信息美学 | Image/media generation and creator tools | GPT-Image, Gemini image, Flux, Ideogram, Adobe Firefly |
For non-AI industries, keep the same 4 sections x 3 items shape, but replace section names, seed queries, source priorities, and impact criteria before research. See industry-starter.md.
Archive Layout
- Archive/homepage uses a neutral black/white/gray shell even when the detail pages use weekday Morandi colors.
- Top visible brand text is Chinese-first:
每日 AI 行业简报; upper right remains星期一研究室. - Top navigation labels are Chinese and ordered:
今日,色板,往期. - The hero section keeps the English publication masthead
The AI Industry Brief, a phone-shaped daily-paper preview, and three action buttons: 阅读最新一期links to the latest detail page.查看七天色板switches to the palette panel without forcing scroll-to-top.查看往期switches to the previous-issues panel without forcing scroll-to-top.- The archive/recommendation panel is visibly named
往期; do not use历史归档or精彩推荐as the section heading. - Weekly palette on the homepage uses individual swatch archive cards with weekday shorthand, Chinese tone name, and hex code. Avoid plain oval/pill strips.
- Keep
color-palette-demo.htmlas a broader design-system preview page with comfortable left/right margins and a tabbed seven-day preview. - If homepage card markup changes, update the Feishu push worker archive parser so scheduled pushes can still locate the latest issue headline and summary.
Detail Layout
- Detail pages use a two-column editorial layout.
- Detail pages should feel like a landscape A3 editorial sheet, not a tall poster:
- use a wide page frame around
1480px - use the A3 landscape ratio as a minimum paper-height reference, not as a fixed crop box
- allow vertical overflow to scroll naturally; never crop lower sections, insight, or footer
- use generous left/right page margins and clear row spacing between section pairs
- keep generous vertical breathing room around the opening line and closing insight so major editorial blocks do not touch
- style the opening line as an international editorial pull quote: thin top/bottom rules, a non-numeric
LEADrail, strong serif text, and a right-side illustration panel; avoid rounded AI-card styling. - style the closing insight as an editorial note: top/bottom rules, a left label with a small theme-colored signal icon, and larger serif body text; avoid office-report card styling.
- The visual language should lean toward an international editorial atlas:
- use a faint paper grid inside the page frame
- place international editorial illustration inside the opening-line card as a right-side visual panel on desktop, not between section cards or near the footer
- prefer original inline SVG figures, globe grids, magnifiers, source-ledger tags, model-atlas marks, or archive labels
- avoid barely visible route paths and repeated paper-plane marks
- use English micro-labels that fit the publication theme, such as
AI INDUSTRY MAP,GLOBAL SIGNALS,SOURCE LEDGER, andMODEL ATLAS; avoid vague placeholder phrases. - keep section cards clean; decorative illustration should not cross over article text
- hide heavy illustration ornaments on mobile
- Section order is horizontal:
- top row:
01 AI 工作台,02 AI 信息美学 - bottom row:
03 AI 流水线,04 AI 大模型 - Each section header uses a skewed numbered marker and a subtle dashed guide line.
- Item markers inside each section use non-numeric symbols (
◆,◇,◈) so they do not compete with section numbers. - The section marker color must be derived from the day's
--primaryMorandi color: --section-ink: var(--primary)--section-ink-soft: var(--primary-light)--section-guide: color-mix(in srgb, var(--primary) 42%, transparent)- The top masthead rule should also derive from the day's
--primary, using a slightly darker mix for newspaper weight. - Do not hard-code an unrelated blue or accent color for section markers.
- Item rows should dynamically align left/right corresponding items by measured content height on desktop; mobile stays natural single-column.
Editorial Rules
- Prefer sources published in the seven days up to the brief date.
- Use official/primary URLs wherever available.
- Keep source freshness hierarchical:
- Tier 1: sources from the seven days up to the brief date.
- Tier 2: sources from the last 30 days, marked
邻近窗口when outside the seven-day window. - Tier 3: if the last 30 days of mainstream candidates are exhausted by historical dedup, expand outward to adjacent tools, competing platforms, infrastructure layers, creator utilities, governance/security tooling, or ecosystem releases that affect the same workflow.
- Tier 4: sources older than 30 days are exceptional background references only. Do not use them to fill quota when a relevant adjacent or peripheral source from the last 30 days exists.
- When a section lacks enough fresh primary items, broaden the search radius before broadening the time window. Examples: for
AI 工作台, also check browser/workspace/search/knowledge-base tools; forAI 流水线, check CI, sandbox, observability, MCP/security, deployment, and agent runtime tools; forAI 大模型, check model gateways, inference platforms, evals, safety releases, and open deployment ecosystems; forAI 信息美学, check video, image, design-system, asset-management, font/brand, and creator workflow tools. - If an item is older than 30 days, document why it is still necessary in the daily
methodNote, not only in the source date label. - Add visible dates to source links. Mark items outside the preferred window as
邻近窗口or最近官方参考. - Daily draft data must be prepared in
brief-data/YYYY-MM-DD.jsonbefore HTML generation. - New daily items must not duplicate historical entries by source URL or item title.
- Title form:
产品/工具名 | 核心动作短语; action phrase no longer than 15 Chinese characters. - Description form: fact, then meaning or impact; target 60-80 Chinese characters.
- Opening line: one judgment, maximum 50 Chinese characters.
- Closing insight: synthesize multiple sections, maximum 150 Chinese characters; avoid tentative filler.
Brand
- Public name:
The AI Industry Brief - Producer attribution in upper right:
星期一研究室 - Detail footer left:
星期一研究室出品 - Detail footer right:
The AI Industry Brief · 每日行业简报 · 项目管理 · 信息美学 - Archive title:
The AI Industry Brief
For a new industry, replace the public name and footer terms while preserving the template hierarchy. Suggested pattern: The <Industry> Brief plus a Chinese subtitle such as 每日跨境电商简报.
Palette
| Day | Primary | Tone |
|---|---|---|
| 星期一 | #927BBE | 莫兰迪紫 |
| 星期二 | #6F97A8 | 雾蓝 |
| 星期三 | #7FA6C9 | 晴蓝 |
| 星期四 | #7FA68B | 鼠尾草绿 |
| 星期五 | #6F9F99 | 青瓷绿 |
| 星期六 | #8A93B7 | 紫蓝 |
| 星期日 | #EC9BC8 | 柔粉 |
Use an approximately 10%-tinted pale background derived from the day's primary color for callouts and counters. Use the same day's primary color family for section number markers, marker shadows, and guide lines. Keep the weekly palette balanced around purple, blue, green, and pink families; do not use brown, orange, or honey-gold weekday accents.
Existing Site
- Repository:
mondaylab/ai-industry-brief - Public archive:
https://mondaylab.github.io/ai-industry-brief/ - Publish from
mainthrough GitHub Pages.
Release Gate
1. No template placeholders remain. 2. The new page contains exactly 4 section containers, 12 content items, and 12 source anchors. 3. Dedup check passes: node skills/ai-industry-brief/scripts/check-brief-dedup.js brief-data/YYYY-MM-DD.json. 4. The archive contains a clickable card for the new page and preserves earlier links. 5. Browser inspection shows clean header/footer, no obvious clipping, and functioning navigation. 6. The share image share-images/YYYY-MM-DD.png exists, is a PNG screenshot of the detail page, and is published with the same issue. 7. If the site is published, verify the deployed archive, current detail page, and current share image after Pages builds. Deployment is complete only when the archive contains briefs/YYYY-MM-DD.html, the detail page shows the correct date/footer, and share-images/YYYY-MM-DD.png returns image/png. 8. After Pages deployment verification succeeds, immediately trigger the Feishu image push with npm --prefix workers/feishu-brief-push run post-publish-send -- --date YYYY-MM-DD, or call /send-image-url with the published PNG when the Worker screenshot path is unavailable. Do not rely only on the scheduled patrol. Manual trigger commands require MANUAL_TRIGGER_TOKEN or FEISHU_PUSH_TOKEN.
Industry Starter
Use this reference when the user wants to adapt ai-industry-brief to a non-AI industry or asks for a zero-config first issue.
Minimal Questions
Ask at most two questions before generating the first issue:
1. What industry or niche should the brief cover? 2. Who is the target reader?
Infer everything else and state assumptions briefly. Do not ask about layout, data schema, color palette, or publishing until the first issue exists.
Initialization Output
Create or update:
brief-data/YYYY-MM-DD.jsonbriefs/YYYY-MM-DD.htmlindex.html
If the repo is missing templates, copy from assets/archive-page-base.html and assets/brief-page-base.html.
Common Industry Defaults
| Brief | Sections | Source priorities | Impact criteria |
|---|---|---|---|
| 出海印尼日报 | 政策监管, 电商平台, 消费趋势, 本地品牌与渠道 | 印尼政府与监管部门, Tokopedia/Shopee/TikTok Shop 官方公告, 本地商业媒体, 市场研究 | 准入门槛, 履约支付, 消费品类, 中国品牌机会 |
| 跨境电商简报 | Amazon, TikTok Shop, Shopee/Lazada, 物流支付与广告 | 平台公告, seller center, 物流商公告, 广告产品更新, 权威行业媒体 | 平台规则, 流量成本, 履约规则, 卖家自动化机会 |
| 外贸行业简报 | 汇率关税, 供应链与港口, 展会与客户, 品类价格与订单 | 海关/商务部门, 港口与航运公告, 展会官网, 行业协会, 大宗数据 | 成本变化, 交付风险, 客户需求, 市场窗口 |
| 教育行业简报 | 政策法规, 在线教育平台, AI 教学工具, 课程与考试趋势 | 教育主管部门, 平台公告, 学校/机构发布, AI 教育工具更新 | 合规风险, 获客变化, 教学效率, 内容供给 |
| 制造业简报 | 原材料价格, 工厂动态, 行业标准, 出口订单与设备 | 行业协会, 交易所/价格指数, 企业公告, 标准组织, 海关数据 | 采购成本, 产能变化, 认证质量, 订单交期 |
Section Rules
- Keep exactly 4 sections unless the user explicitly asks otherwise.
- Keep 3 items per section for a standard daily issue.
- Each item must have a source URL and source date label.
- The description must say why the item matters for that industry, not only summarize news.
Brand Adaptation
Use this pattern unless the user provides brand copy:
- Public title:
The <Industry> Brief - Chinese title:
每日<行业>简报 - Producer: keep
星期一研究室unless the user gives another publisher - Footer:
<Chinese title> · 行业动态 · 机会判断 · 来源可追溯
Prompt Examples
请用 ai-industry-brief Skill,初始化一个跨境电商简报项目,并生成第一期。请用 ai-industry-brief Skill 搭一个出海印尼日报。目标读者是中国出海品牌团队,先生成第一期,不要让我手动配置。请把这个项目改造成制造业简报,保留页面模板和去重脚本,替换栏目、来源和影响判断维度。#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
function fail(msg) {
console.error(`ERROR: ${msg}`);
process.exit(1);
}
function normalizeTitle(title) {
return String(title || "")
.toLowerCase()
.replace(/\s+/g, " ")
.trim();
}
function normalizeKeyFromTitle(title) {
const parts = String(title || "").split("|").map((s) => s.trim().toLowerCase());
if (parts.length >= 2) return `${parts[0]}|${parts.slice(1).join("|")}`;
return normalizeTitle(title);
}
function unescapeHtml(s) {
return String(s || "")
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, '"')
.replace(/'/g, "'");
}
function readJson(p) {
return JSON.parse(fs.readFileSync(p, "utf8"));
}
function collectFromDataJson(data) {
const out = [];
for (const section of data.sections || []) {
for (const item of section.items || []) {
out.push({
title: item.title || "",
titleNorm: normalizeTitle(item.title),
keyNorm: normalizeKeyFromTitle(item.title),
sourceUrl: item.sourceUrl || "",
});
}
}
return out;
}
function collectFromHtml(html) {
const out = [];
const articleBlocks = html.match(/<article class="item">[\s\S]*?<\/article>/g) || [];
for (const block of articleBlocks) {
const toolMatch = block.match(/<span class="item-tool">([\s\S]*?)<\/span>/);
const headingMatch = block.match(/<span class="item-heading">([\s\S]*?)<\/span>/);
const urlMatch = block.match(/<a class="item-source" href="([^"]+)"/);
const tool = unescapeHtml((toolMatch && toolMatch[1]) || "").trim();
const heading = unescapeHtml((headingMatch && headingMatch[1]) || "").trim();
const title = tool && heading ? `${tool} | ${heading}` : "";
out.push({
title,
titleNorm: normalizeTitle(title),
keyNorm: normalizeKeyFromTitle(title),
sourceUrl: (urlMatch && urlMatch[1]) || "",
});
}
return out;
}
function ensureCandidateShape(candidate) {
if (!candidate || !Array.isArray(candidate.sections)) {
fail("candidate JSON must include a `sections` array");
}
if (candidate.sections.length !== 4) {
fail(`candidate JSON must contain 4 sections, got ${candidate.sections.length}`);
}
let itemCount = 0;
for (const section of candidate.sections) {
if (!Array.isArray(section.items)) {
fail(`section "${section.name || "unknown"}" must include items array`);
}
if (section.items.length !== 3) {
fail(`section "${section.name || "unknown"}" must contain exactly 3 items`);
}
itemCount += section.items.length;
}
if (itemCount !== 12) {
fail(`candidate JSON must contain exactly 12 items, got ${itemCount}`);
}
}
function main() {
const candidateArg = process.argv[2];
if (!candidateArg) {
fail("usage: node skills/ai-industry-brief/scripts/check-brief-dedup.js brief-data/YYYY-MM-DD.json");
}
const root = process.cwd();
const candidatePath = path.resolve(root, candidateArg);
if (!fs.existsSync(candidatePath)) {
fail(`candidate file not found: ${candidatePath}`);
}
const candidate = readJson(candidatePath);
ensureCandidateShape(candidate);
const candidateDate = candidate.date ? String(candidate.date).trim() : "";
const candidateItems = collectFromDataJson(candidate);
const historical = [];
const dataDir = path.resolve(root, "brief-data");
if (fs.existsSync(dataDir)) {
for (const name of fs.readdirSync(dataDir)) {
if (!name.endsWith(".json") || name === "_template.json") continue;
const fp = path.join(dataDir, name);
if (path.resolve(fp) === candidatePath) continue;
const d = readJson(fp);
historical.push(...collectFromDataJson(d).map((x) => ({ ...x, from: `brief-data/${name}` })));
}
}
const briefsDir = path.resolve(root, "briefs");
if (fs.existsSync(briefsDir)) {
for (const name of fs.readdirSync(briefsDir)) {
if (!name.endsWith(".html")) continue;
if (candidateDate && name === `${candidateDate}.html`) continue;
const fp = path.join(briefsDir, name);
const html = fs.readFileSync(fp, "utf8");
historical.push(...collectFromHtml(html).map((x) => ({ ...x, from: `briefs/${name}` })));
}
}
const urlMap = new Map();
const titleMap = new Map();
const keyMap = new Map();
for (const h of historical) {
if (h.sourceUrl) urlMap.set(h.sourceUrl, h.from);
if (h.titleNorm) titleMap.set(h.titleNorm, h.from);
if (h.keyNorm) keyMap.set(h.keyNorm, h.from);
}
const issues = [];
for (const item of candidateItems) {
if (item.sourceUrl && urlMap.has(item.sourceUrl)) {
issues.push(`duplicate source URL: ${item.sourceUrl} (already in ${urlMap.get(item.sourceUrl)})`);
}
if (item.titleNorm && titleMap.has(item.titleNorm)) {
issues.push(`duplicate title: "${item.title}" (already in ${titleMap.get(item.titleNorm)})`);
}
if (item.keyNorm && keyMap.has(item.keyNorm)) {
issues.push(`duplicate normalized key: "${item.keyNorm}" (already in ${keyMap.get(item.keyNorm)})`);
}
}
if (issues.length > 0) {
console.error("Dedup check failed:");
for (const i of issues) console.error(`- ${i}`);
process.exit(2);
}
console.log(`Dedup check passed for ${candidateArg} (12 items, no historical overlap).`);
}
main();
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const ROOT = process.cwd();
const DATA_DIR = path.join(ROOT, "brief-data");
const BRIEFS_DIR = path.join(ROOT, "briefs");
const PALETTES = {
"星期一": { primary: "#927BBE", light: "#F4EFFA" },
"星期二": { primary: "#6F97A8", light: "#EEF4F7" },
"星期三": { primary: "#7FA6C9", light: "#EEF4FB" },
"星期四": { primary: "#7FA68B", light: "#EFF5F0" },
"星期五": { primary: "#6F9F99", light: "#EEF6F3" },
"星期六": { primary: "#8A93B7", light: "#F0F1F8" },
"星期日": { primary: "#EC9BC8", light: "#FDF0F7" },
};
const SECTION_ICONS = {
"AI 工作台": '<svg width="13" height="13" viewBox="0 0 18 18" fill="none"><rect x="1" y="1" width="7" height="7" rx="1.5" fill="white"/><rect x="10" y="1" width="7" height="7" rx="1.5" fill="white"/><rect x="1" y="10" width="7" height="7" rx="1.5" fill="white"/><rect x="10" y="10" width="7" height="7" rx="1.5" fill="white"/></svg>',
"AI 信息美学": '<svg width="13" height="13" viewBox="0 0 18 18" fill="none"><path d="M9 2C5.13 2 2 5.13 2 9C2 12.87 5.13 16 9 16C9.83 16 10.5 15.33 10.5 14.5C10.5 14.11 10.35 13.76 10.1 13.5C9.86 13.25 9.72 12.91 9.72 12.5C9.72 11.67 10.39 11 11.22 11H13C14.66 11 16 9.66 16 8C16 4.69 12.87 2 9 2Z" stroke="white" stroke-width="1.3"/><circle cx="6" cy="6.5" r="1" fill="white"/><circle cx="9" cy="5" r="1" fill="white"/><circle cx="12" cy="6.5" r="1" fill="white"/><circle cx="6" cy="10" r="1" fill="white"/></svg>',
"AI 流水线": '<svg width="13" height="13" viewBox="0 0 18 18" fill="none"><circle cx="2.5" cy="9" r="2" fill="white"/><line x1="4.5" y1="9" x2="7.5" y2="9" stroke="white" stroke-width="1.5" stroke-linecap="round"/><circle cx="9" cy="9" r="2" fill="white"/><line x1="11" y1="9" x2="13.5" y2="9" stroke="white" stroke-width="1.5" stroke-linecap="round"/><circle cx="15.5" cy="9" r="2" fill="white"/></svg>',
"AI 大模型": '<svg width="13" height="13" viewBox="0 0 18 18" fill="none"><path d="M10.5 2L4 10h5.5L7.5 16L14 8H8.5L10.5 2Z" fill="white"/></svg>',
};
const SECTION_NUMBERS = {
"AI 工作台": "01",
"AI 信息美学": "02",
"AI 流水线": "03",
"AI 大模型": "04",
};
const ITEM_MARKS = ["◆", "◇", "◈"];
function fail(message) {
console.error(message);
process.exit(1);
}
function readJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, "utf8"));
}
function escapeHtml(value) {
return String(value)
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function formatMd(date) {
return `${date.slice(5, 7)}/${date.slice(8, 10)}`;
}
function weekdayToEnglish(weekday) {
return {
"星期一": "MONDAY",
"星期二": "TUESDAY",
"星期三": "WEDNESDAY",
"星期四": "THURSDAY",
"星期五": "FRIDAY",
"星期六": "SATURDAY",
"星期日": "SUNDAY",
}[weekday] || "WEEKDAY";
}
function getTemplateBrief(targetDate) {
const files = fs.readdirSync(BRIEFS_DIR).filter((name) => /^\d{4}-\d{2}-\d{2}\.html$/.test(name) && name !== `${targetDate}.html`);
files.sort().reverse();
if (!files.length) fail("No existing brief template found.");
return fs.readFileSync(path.join(BRIEFS_DIR, files[0]), "utf8");
}
function replaceOne(html, pattern, value, label) {
if (!pattern.test(html)) fail(`Unable to replace ${label}`);
return html.replace(pattern, value);
}
function splitTitle(title) {
const parts = String(title).split("|");
return {
tool: (parts[0] || "").trim(),
heading: parts.slice(1).join("|").trim(),
};
}
function buildSectionsHtml(data) {
return data.sections
.map((section) => {
const num = SECTION_NUMBERS[section.name] || "00";
const icon = SECTION_ICONS[section.name] || "";
const items = section.items
.map((item, index) => {
const { tool, heading } = splitTitle(item.title);
return ` <article class="item">
<div class="item-title"><span class="item-num" data-mark="${ITEM_MARKS[index]}" aria-label="${String(index + 1).padStart(2, "0")}">${String(index + 1).padStart(2, "0")}</span><span class="item-copy"><span class="item-tool">${escapeHtml(tool)}</span><span class="item-divider"> | </span><span class="item-heading">${escapeHtml(heading)}</span></span></div>
<p class="item-desc">${escapeHtml(item.description)}</p>
<a class="item-source" href="${escapeHtml(item.sourceUrl)}" target="_blank" rel="noopener noreferrer">→ ${escapeHtml(item.sourceName)}</a><span class="source-date">${escapeHtml(item.sourceDateLabel)}</span>
</article>`;
})
.join("\n");
return ` <section class="section">
<div class="section-header">
<span class="section-tag" data-num="${num}">
${icon}
${escapeHtml(section.name)}
</span>
</div>
<div class="section-sub">${escapeHtml(section.subtitle)}</div>
<div class="section-items">
${items}
</div>
</section>`;
})
.join("\n\n");
}
function renderBriefPage(data) {
const palette = PALETTES[data.weekday];
if (!palette) fail(`Unknown weekday: ${data.weekday}`);
let html = getTemplateBrief(data.date);
const dateLabel = `${formatMd(data.date)} · ${data.weekday}`;
const title = `The AI Industry Brief | ${dateLabel} | 星期一研究室`;
const sectionsHtml = buildSectionsHtml(data);
html = replaceOne(html, /<title>[\s\S]*?<\/title>/, `<title>${title}</title>`, "detail title");
html = replaceOne(html, /--primary:\s*#[0-9A-Fa-f]{6};/, `--primary: ${palette.primary};`, "detail primary");
html = replaceOne(html, /--primary-light:\s*#[0-9A-Fa-f]{6};/, `--primary-light: ${palette.light};`, "detail primary light");
html = replaceOne(html, /<div class="lab">星期一研究室<\/div>/, '<div class="lab">星期一研究室</div>', "detail lab");
html = replaceOne(html, /<div class="date">[\s\S]*?<\/div>/, `<div class="date">${dateLabel}</div>`, "detail header date");
html = replaceOne(
html,
/<div class="quote-copy">[\s\S]*?<\/div>\s*<svg class="hero-illustration"/,
`<div class="quote-copy">
<div class="quote-label">今日一句话</div>
${escapeHtml(data.opening)}
</div>
<svg class="hero-illustration"`,
"detail opening"
);
html = replaceOne(
html,
/<div class="sections-layout">[\s\S]*?<\/div>\s*<aside class="insight-card">/,
`<div class="sections-layout">
${sectionsHtml}
</div>
<aside class="insight-card">`,
"detail sections"
);
html = replaceOne(html, /<p class="insight-text">[\s\S]*?<\/p>/, `<p class="insight-text">${escapeHtml(data.insight)}</p>`, "detail insight");
html = replaceOne(html, /<p class="method-note">[\s\S]*?<\/p>/, `<p class="method-note">${escapeHtml(data.methodNote)}</p>`, "detail method note");
html = replaceOne(html, /<div class="footer-lab">[\s\S]*?<\/div>/, '<div class="footer-lab">星期一研究室出品</div>', "detail footer left");
html = replaceOne(
html,
/<div class="footer-sub">[\s\S]*?<\/div>/,
'<div class="footer-sub">The AI Industry Brief · 每日行业简报 · 项目管理 · 信息美学</div>',
"detail footer right"
);
fs.writeFileSync(path.join(BRIEFS_DIR, `${data.date}.html`), html);
}
function buildArchiveCard(entry, featured = false, readLabel = "查看往期 →") {
const md = entry.dateLabel || `${formatMd(entry.date)} · ${entry.weekday}`;
const href = entry.href || `briefs/${entry.date}.html`;
const cls = featured ? "brief-card featured" : "brief-card";
return ` <a class="${cls}" href="${href}">
<div class="date">${escapeHtml(md)}</div>
<h3>${escapeHtml(entry.headline)}</h3>
<p>${escapeHtml(entry.summary)}</p>
<span class="read">${readLabel}</span>
</a>`;
}
function buildArchiveList(entries) {
return entries
.map((entry) => {
const md = entry.dateLabel || `${formatMd(entry.date)} · ${entry.weekday}`;
const href = entry.href || `briefs/${entry.date}.html`;
return ` <a class="archive-item" href="${href}"><div class="date">${escapeHtml(md)}</div><div><div class="archive-title">${escapeHtml(entry.headline)}</div><div class="archive-desc">${escapeHtml(entry.summary)}</div></div><span class="archive-arrow">→</span></a>`;
})
.join("\n");
}
function buildMobileSections(entry) {
const sections = entry.homepage.mobileSections || [];
return sections
.map((item, index) => ` <div class="mobile-section"><span class="mobile-num">${String(index + 1).padStart(2, "0")}</span><div><b>${escapeHtml(item.name)}</b><span>${escapeHtml(item.summary)}</span></div></div>`)
.join("\n");
}
function parseArchiveEntries(html) {
const matches = html.match(/<a class="archive-item" href="briefs\/\d{4}-\d{2}-\d{2}\.html">[\s\S]*?<\/a>/g) || [];
return matches
.map((block) => {
const href = block.match(/href="([^"]+)"/)?.[1];
const dateLabel = block.match(/<div class="date">([\s\S]*?)<\/div>/)?.[1]?.trim();
const headline = block.match(/<div class="archive-title">([\s\S]*?)<\/div>/)?.[1]?.trim();
const summary = block.match(/<div class="archive-desc">([\s\S]*?)<\/div>/)?.[1]?.trim();
const date = href?.match(/briefs\/(\d{4}-\d{2}-\d{2})\.html/)?.[1];
if (!href || !dateLabel || !headline || !summary || !date) return null;
return { href, dateLabel, headline, summary, date };
})
.filter(Boolean);
}
function renderIndexPage(latestData) {
let html = fs.readFileSync(path.join(ROOT, "index.html"), "utf8");
const oldEntries = parseArchiveEntries(html).filter((entry) => entry.date !== latestData.date);
const latest = {
date: latestData.date,
weekday: latestData.weekday,
href: `briefs/${latestData.date}.html`,
dateLabel: `${formatMd(latestData.date)} · ${latestData.weekday}`,
headline: latestData.homepage.headline,
summary: latestData.homepage.summary,
};
const previous = oldEntries[0];
if (!previous) fail("Unable to determine previous issue from index.html");
html = replaceOne(html, /href="briefs\/\d{4}-\d{2}-\d{2}\.html">阅读最新一期<\/a>/, `href="briefs/${latest.date}.html">阅读最新一期</a>`, "index latest button");
html = replaceOne(html, /<div class="mobile-date">[\s\S]*?<\/div>/, `<div class="mobile-date">${formatMd(latest.date)}<br>${weekdayToEnglish(latest.weekday)}</div>`, "index mobile date");
html = replaceOne(html, /<div class="mobile-headline">[\s\S]*?<\/div>\s*<div class="mobile-sections">/, `<div class="mobile-headline">
<h2>${escapeHtml(latest.headline)}</h2>
<p>${escapeHtml(latest.summary)}</p>
</div>
<div class="mobile-sections">`, "index mobile headline");
html = replaceOne(html, /<div class="mobile-sections">[\s\S]*?<\/div>\s*<\/article>/, `<div class="mobile-sections">
${buildMobileSections(latestData)}
</div>
</article>`, "index mobile sections");
html = replaceOne(
html,
/<div class="brief-grid">[\s\S]*?<\/div>\s*<\/section>\s*\n\n <section class="panel archive">/,
`<div class="brief-grid">
${buildArchiveCard(latest, true, "查看今日早报 →")}
${buildArchiveCard(previous, false, "查看前一期 →")}
<a class="brief-card" href="color-palette-demo.html">
<div class="date">Style System</div>
<h3>Weekly Palette Demo</h3>
<p>查看周一到周日的紫、蓝、绿、粉色系在简报组件里的实际效果。</p>
<span class="read">查看色板 →</span>
</a>
</div>
</section>
<section class="panel archive">`,
"index brief grid"
);
html = replaceOne(
html,
/<div class="archive-list">[\s\S]*?<\/div>\s*<\/section>\s*\n\n <section class="panel palette">/,
`<div class="archive-list">
${buildArchiveList([latest, ...oldEntries])}
</div>
</section>
<section class="panel palette">`,
"index archive list"
);
fs.writeFileSync(path.join(ROOT, "index.html"), html);
}
function main() {
const targetDate = process.argv[2];
if (!targetDate) fail("Usage: node skills/ai-industry-brief/scripts/render-brief.js YYYY-MM-DD");
const dataPath = path.join(DATA_DIR, `${targetDate}.json`);
if (!fs.existsSync(dataPath)) fail(`Missing data file: ${dataPath}`);
const data = readJson(dataPath);
renderBriefPage(data);
renderIndexPage(data);
console.log(`Rendered brief and index for ${targetDate}`);
}
main();
Related skills
How it compares
An editorial brief workflow skill, not a generic summarize-the-web shortcut without a publishing structure.
FAQ
Who is ai-industry-brief for?
Developers and small teams publishing AI industry news or analysis who want agent help initializing and drafting brief-style issues.
When should I use ai-industry-brief?
In Grow when launching a content cadence; in Launch when pairing distribution with a new AI-focused publication; in Idea when exploring whether a daily brief is your wedge before you commit to tooling.
Is ai-industry-brief safe to install?
Treat it like any third-party skill: review the Security Audits panel on this Prism page and validate outbound sourcing behavior in your environment.