diff --git a/doc/汇报PPT.pptx b/doc/汇报PPT.pptx index 67582cd..51f12f3 100644 Binary files a/doc/汇报PPT.pptx and b/doc/汇报PPT.pptx differ diff --git a/scripts/fix-ppt.js b/scripts/fix-ppt.js new file mode 100644 index 0000000..887a5bb --- /dev/null +++ b/scripts/fix-ppt.js @@ -0,0 +1,13 @@ +const fs = require('fs'); +let c = fs.readFileSync('scripts/gen-ppt.js', 'utf8'); + +// Remove Windows CR chars +c = c.replace(/\r/g, ''); + +// Fix addNotes - replace literal newlines with \\n +c = c.replace(/addNotes\("([\s\S]*?)"\)/g, function(m, content) { + return 'addNotes("' + content.replace(/\n/g, '\\n') + '")'; +}); + +fs.writeFileSync('scripts/gen-ppt.js', c, 'utf8'); +console.log('fixed'); diff --git a/scripts/gen-ppt.js b/scripts/gen-ppt.js index 179b382..8490ca3 100644 --- a/scripts/gen-ppt.js +++ b/scripts/gen-ppt.js @@ -29,6 +29,10 @@ function iconCircle(slide, icon, x, y, color) { slide.addText(icon, { x, y, w: 0.5, h: 0.5, align: "center", valign: "middle", fontSize: 18, color: "FFFFFF" }); } +function demoBtn(slide, x, y) { + slide.addShape(pres.shapes.ROUNDED_RECTANGLE, { x, y, w: 1.6, h: 0.3, fill: { color: "F96167" }, line: { color: "F96167", width: 1 } }); + slide.addText("▶ 现场演示", { x, y, w: 1.6, h: 0.3, fontSize: 9, color: "FFFFFF", fontFace: "Arial", align: "center", valign: "middle" }); +} function card(slide, title, desc, x, y, w, h, icon, accent) { slide.addShape(pres.shapes.ROUNDED_RECTANGLE, { x, y, w, h, fill: { color: C.white }, @@ -58,6 +62,7 @@ let s2 = pres.addSlide(); s2.background = { fill: C.white }; s2.addText("目 录", { x: 0.8, y: 0.4, w: 5, h: 0.6, fontSize: 28, bold: true, color: C.navy, fontFace: "Arial" }); s2.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 1.0, w: 1.2, h: 0.04, fill: { color: C.teal } }); +s2.addNotes("目录页。\n我们将从项目背景开始,逐一介绍每个子任务的完成情况,\n最后进行现场演示和总结。"); const tocItems = [ ["01", "项目背景与目标", "CLI 能力扩展的背景与四大子任务概览"], ["02", "子任务一:CLI 能力扩展", "31 命令组 · 181+ 命令 · 20 测试 · 包管理"], @@ -79,6 +84,7 @@ let s3 = pres.addSlide(); s3.background = { fill: C.navy }; s3.addText("项目背景与目标", { x: 0.8, y: 0.4, w: 8, h: 0.6, fontSize: 28, bold: true, color: C.white, fontFace: "Arial" }); s3.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 1.0, w: 1.2, h: 0.04, fill: { color: C.accent } }); +s3.addNotes("gitlink-cli 是 GitLink 官方命令行工具,用 Go 语言开发。\n随着 AI 编程智能体的兴起,我们需要扩展 CLI 的能力,让它可以被 AI Agent 调用。\n四大子任务分别是:CLI 扩展、Skills 开发、工作流自动化以及科研辅助。"); s3.addText("gitlink-cli 是 GitLink 平台的官方命令行工具,采用 Go 语言开发。\n随着 AI 编程智能体的兴起,我们需要从\"手动操作\"转向\"Agent 驱动开发\"。", { x: 0.8, y: 1.3, w: 8.4, h: 0.8, fontSize: 13, color: C.lightBlue, fontFace: "Arial" }); // 4 cards const cards3 = [ @@ -114,6 +120,7 @@ stats.forEach((s, i) => { }); // Command groups showcase s4.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.4, y: 2.4, w: 9.2, h: 2.9, fill: { color: C.offWhite } }); +s4.addNotes("子任务一是 CLI 能力扩展,占总分的 50%。\n我们新增了 23 个 Shortcut 命令组、181 个子命令、20 个单元测试,覆盖了 4 个包管理平台。\n这里列出了所有命令组及其子命令数量。"); s4.addText("关键新增命令组", { x: 0.6, y: 2.5, w: 4, h: 0.35, fontSize: 13, bold: true, color: C.navy, fontFace: "Arial" }); const groups = ["repo(29)","issue(12)","pr(15)","user(24)","branch(9)","ci(12)","release(6)","webhook(8)","wiki(7)","snippet(4)","commit(5)","file(11)","milestone(6)","collaborator(6)","org(7)","search(2)","label(7)","tag(3)","dataset(4)","template(5)"]; groups.forEach((g, i) => { @@ -126,6 +133,7 @@ groups.forEach((g, i) => { // ===== Slide 5: 子任务一 - 架构 ===== let s5 = pres.addSlide(); s5.background = { fill: C.navy }; +s5.addNotes("CLI 采用经典的三层架构:\n第一层 Shortcuts 提供高频操作的快捷接口;\n第二层 API Commands 负责统一的认证和错误处理;\n第三层 Raw API 可以直接访问任意平台端点,灵活扩展。"); s5.addText("CLI 三层架构", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.white, fontFace: "Arial" }); s5.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.teal } }); const layers = [ @@ -146,6 +154,7 @@ layers.forEach((l, i) => { // ===== Slide 6: REPL & 输出优化 ===== let s6 = pres.addSlide(); s6.background = { fill: C.navy }; +s6.addNotes("我们还新增了 REPL 交互模式,支持命令面板、滚动视口,以及三种输出格式。\n表格渲染优化让嵌套数据可以直观展示。"); s6.addText("REPL 交互模式 & 输出优化", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.white, fontFace: "Arial" }); s6.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.accent } }); const replFeats = [ @@ -167,6 +176,7 @@ replFeats.forEach((f, i) => { // ===== Slide 7: 子任务二 - Skills ===== let s7 = pres.addSlide(); s7.background = { fill: C.white }; +s7.addNotes("子任务二是 AI Agent Skills,占总分的 20%。\n我们开发了 11 个 Claude Code Skills,覆盖了项目管理的各个场景。\n所有 Skill 都在 Claude Code 平台上做了端到端实测验证。\n这里展示了 6 个核心 Skill,每个 Skill 都包含完整的命令参考和工作流示例。"); s7.addText("子任务二:AI Agent Skills", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.navy, fontFace: "Arial" }); s7.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.purple } }); s7.addText("11 个 Claude Code Skills · 29 个官方 Skills · Claude Code 端到端验证", { x: 0.8, y: 1.0, w: 8, h: 0.3, fontSize: 11, color: C.gray, fontFace: "Arial" }); @@ -187,6 +197,7 @@ skills.forEach((sk, i) => { // ===== Slide 8: Skills 架构 ===== let s8 = pres.addSlide(); s8.background = { fill: C.navy }; +s8.addNotes("Skills 框架采用四层架构:\n共享层、领域层、智能层和编排层。\n这种分层设计让每个 Skill 职责清晰,同时可以灵活组合。"); s8.addText("Skills 框架分层架构", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.white, fontFace: "Arial" }); s8.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.green } }); const sLayers = [ @@ -207,6 +218,7 @@ sLayers.forEach((l, i) => { // ===== Slide 9: 子任务三 - 工作流 ===== let s9 = pres.addSlide(); s9.background = { fill: C.white }; +s9.addNotes("子任务三是端到端自动化工作流,占总分的 20%。\n我们实现了两个场景:\n场景 A 是社区运营自动化,从 Issue 分拣到周报生成再到 Release Notes 发布;\n场景 B 是代码质量看门人,从 PR 审查到 CI 检查再到自动合并决策。"); s9.addText("子任务三:端到端自动化工作流", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.navy, fontFace: "Arial" }); s7.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.orange } }); @@ -241,6 +253,7 @@ let s11 = pres.addSlide(); s11.background = { fill: C.navy }; s11.addText("工作流真实输出数据", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.white, fontFace: "Arial" }); s11.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.accent } }); +demoBtn(s11, 7.5, 0.9); s11.addText("以下数据通过对 z2_cc/gitlink-cli 仓库运行工作流脚本实际采集", { x: 0.8, y: 1.0, w: 8, h: 0.3, fontSize: 10, color: C.gray, fontFace: "Arial" }); const outputs = [ ["社区周报", "综合评分:3.5/10\nIssue 19 (关闭 4)\nPR 2 · 贡献者 1", C.teal], @@ -258,6 +271,7 @@ outputs.forEach((o, i) => { // ===== Slide 12: 子任务四 - 科研 ===== let s12 = pres.addSlide(); s12.background = { fill: C.white }; +s12.addNotes("子任务四是科研辅助,是加分项。\n模块 C 是科研项目洞悉,可以采集 8 维仓库数据,从成熟度、文档质量、贡献模式和社区健康度四个维度进行评分。\n模块 D 是热点追踪与知识图谱,支持多关键词搜索并自动构建交互式知识图谱。"); s12.addText("子任务四:科研辅助", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.navy, fontFace: "Arial" }); s12.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.green } }); @@ -286,6 +300,7 @@ let s14 = pres.addSlide(); s14.background = { fill: C.navy }; s14.addText("知识图谱可视化", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.white, fontFace: "Arial" }); s14.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.green } }); +demoBtn(s14, 7.5, 0.9); s14.addText("热点追踪 Skill 自动构建多关键词搜索结果的知识图谱", { x: 0.8, y: 1.0, w: 8, h: 0.3, fontSize: 10, color: C.gray, fontFace: "Arial" }); const kgNodes = [ ["研究项目", "4 个", C.blue, 0.5], @@ -307,6 +322,7 @@ s14.addText("✅ 滚轮缩放 ✅ 拖拽平移 ✅ 点击高亮 ✅ SVG 导 // ===== Slide 15: 演示展示 ===== let s15 = pres.addSlide(); s15.background = { fill: C.navy }; +s15.addNotes("现在是现场演示环节,我们将展示四个核心功能:\n1. 社区运营自动化(一键式三阶段流水线)\n2. 科研项目洞悉(8 维数据采集与 4 维评分)\n3. 热点追踪与知识图谱(交互式 HTML 可视化)\n4. 质量门禁(PR 审查与自动评分)\n\n演示脚本详见 doc/演示脚本.md,综合演示页详见 doc/demo.html"); s15.addText("演示展示", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 28, bold: true, color: C.white, fontFace: "Arial" }); s15.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.accent } }); // Terminals @@ -327,6 +343,7 @@ demos.forEach((d, i) => { // ===== Slide 16: 团队贡献 ===== let s16 = pres.addSlide(); s16.background = { fill: C.white }; +s16.addNotes("最后介绍一下团队贡献。\n刘焱负责 CLI 底层架构和大部分 Shortcut 实现;\n赵昌负责命令实现、Skills 开发、工作流编排和科研模块;\n曾蔚然作为组长负责 DevOps 流水线、代码审查和项目统筹。\n\n项目共交付 47 个文件、约 5,800 行代码,全部验证通过。\n感谢各位聆听,欢迎提问!"); s16.addText("团队贡献", { x: 0.8, y: 0.3, w: 8, h: 0.6, fontSize: 26, bold: true, color: C.navy, fontFace: "Arial" }); s16.addShape(pres.shapes.RECTANGLE, { x: 0.8, y: 0.85, w: 1.2, h: 0.04, fill: { color: C.teal } }); const members = [ @@ -355,6 +372,7 @@ let s17 = pres.addSlide(); s17.background = { fill: C.navy }; s17.addShape(pres.shapes.OVAL, { x: -2, y: -1, w: 6, h: 6, fill: { color: "24397A", transparency: 50 } }); s17.addShape(pres.shapes.OVAL, { x: 7, y: 3, w: 4, h: 4, fill: { color: "2B579A", transparency: 60 } }); +s17.addNotes("问答环节。\n可以准备以下问题的回答:\n1. CLI 如何保证向后兼容?——新增 Shortcut 不影响已有命令\n2. 工作流脚本安全吗?——默认 dry-run 模式,不会修改数据\n3. 科研模块数据来源?——全部通过 gitlink-cli 从 GitLink API 实时采集\n4. 知识图谱是如何构建的?——多关键词搜索 → 实体关系提取 → Mermaid 可视化"); s17.addText("Q & A", { x: 0, y: 1.5, w: 10, h: 1.2, fontSize: 48, bold: true, color: C.white, fontFace: "Arial", align: "center" }); s17.addText("感谢聆听 · 欢迎提问", { x: 0, y: 2.8, w: 10, h: 0.5, fontSize: 16, color: C.lightBlue, fontFace: "Arial", align: "center" });