- dsh-data: listCustomScripts/getCustomScript/saveScript(可写连接)/getRewriteStats - server: /api/dsh/custom-scripts|custom-script|script-save|rewrite-stats - data-pages: renderRewrites tab化重构(保留openRewriteCompare),徽标计数,账号级进入默认落有数据tab,chip清账号筛选,openCustomScriptView全文弹窗 - saveHintOf 追加全部UI创作prompt尾(参考选题带videoId/awemeId,自定义仅accountId) - 修复: note/accChip 顶层const不随tab更新→移入load()重算 - style: rw-tabs/rw-tab-badge/rw-chip/cw-modal; app.js +copy图标
72 KiB
72 KiB
2026-09-02 工作日志
工作台 UI 调整(09:53-10:15)
- 09:53 打开 MCN 工作台(服务重启,PID 32336,
?v=20260902-0953#/) - 账号详情页账号信息(data-pages.js:412-413):去掉「年龄」「地区」,重排两行——行1=抖音号/作品数/获取视频,行2=赛道/AI制作/粉丝/获赞;简介/账号定位/视频列表不变
- 视频详情字段间隔/对齐(style.css:383-385 + data-pages.js:552-556,多轮迭代定稿):
- 需求:字段横向间隔参考账号信息(flex+80px)→ 但「分享/收藏」与「时长/发布时间」要求跨行对齐
- 迭代教训:flex 内容宽度天然不跨行对齐;独立 .info-row 容器各自 grid 也不会对齐(跨容器不共享列轨道)
- 终版方案:8 字段(账号/视频ID/时长/发布时间 + 点赞/评论/分享/收藏)合并进同一个
.video-grid容器(2行×4列 grid,repeat(4, minmax(min-content, max-content))+ gap 10px 80px + justify-content:start),列轨道跨行共享→严格对齐,列宽贴合内容非均分;标签行 info-wide 占满整行 - 视频ID 限宽 220px(.vid-limited,省略号+hover title 全量)
- 服务未重启(纯静态资源,Cache-Control: no-store,重开页面即生效)
失误与规避:浏览器操作工具选择(10:15)
- 失误:验证页面时误用 agent-browser(system 技能列表可见),未遵守铁律「浏览器操作一律 browser-harness」(user 级技能)
- 检查:browser-harness 环境未安装——技能目录只有 SKILL.md,无 subskills/browser-harness/envs/(browser-harness.exe 不存在)
- 规避:需要浏览器自动化/截图时,先查
C:\Users\maidou\.workbuddy\skills\browser-harness\subskills\browser-harness\envs\browser-harness\Scripts\browser-harness.exe;未装则uv tool install --python 3.12 --upgrade --force browser-harness+ doctor 验三要素;不装 agent-browser
browser-harness 真实环境定位 + 对齐实测通过(10:20 纠正昨日误判)
- 纠正:browser-harness 并未"未安装"——真身在源技能
project/短视频脚本创作/V1.0/subskill/mcn-dou-analysis/subskills/browser-harness/(envs/browser-harness/python.exe 完整存在,已验证);另有C:/Users/maidou/.dsh/skills/browser-harness/src(无 envs)与D:/miniconda3/envs/browser-harness(08-28 用过)两处 - 昨天实测主流方式(非 python IPC):Node + WebSocket 直连 9223 CDP 脚本(mcn-work-shop/cdp-verify-.mjs、cdp-measure-.mjs 等 30+ 个),Runtime.evaluate 测量 DOM;browser-harness python 调用(BU_CDP_URL=9223 + PYTHONPATH=/src + env python -m browser_harness.run heredoc)今天实测 IPC 超时(daemon 0.1.8 vs client 0.1.10 版本不匹配)
- 9223 调试 Chrome:
chrome.exe --remote-debugging-port=9223 --user-data-dir=C:/Users/maidou/.workbuddy/tmp/bh-chrome-9223;新开 Tab 访问 localhost 会 chrome-error,必须复用现有 8900 标签页 - 对齐实测(新脚本 cdp-align-videoinfo.mjs):视频详情 .video-grid 8 字段逐列 left 完全一致(账号@41=点赞@41、视频ID@157=评论@157、时长@404=分享@404、发布时间@549=收藏@549,差 0)✅ 结构修复生效
browser-harness 移至主技能 subskill(16:00-16:25,用户要求收尾)
- 目录移动:
V1.0/subskill/mcn-dou-analysis/subskills/browser-harness/→V1.0/subskill/browser-harness/(envs/src 完整;mcn-dou-analysis/subskills 现仅剩 nuwa-skill-main) - 路径说明更新三处:① mcn-dou-analysis/SKILL.md「browser-harness 依赖(红线)」行——技能本体改为 主技能
短视频脚本创作/subskill/browser-harness/(不再挂 mcn-dou-analysis 下)+ dsh 环境~/.dsh/skills/browser-harness/;② references/浏览器搜索抖音账号操作规范.md 第159行环境说明 + 第175行技能本体,两处同步新位置;③ V1.0/SKILL.md 新增「外部技能依赖:浏览器工具(browser-harness)」小节登记 - 残留检查:全仓库 grep
mcn-dou-analysis/subskills/browser-harness与旧~/.dsh/skills/browser-harness无残留 ✅ - git:rename 识别完美(175 R + 3 文档修改,envs 被 .gitignore 忽略不进库),commit a255abd,push 8278865..a255abd 成功(fetch 无分叉)
- 注:M70h3o 轮询任务(S6 修复后重跑 6 创作任务)completed 通知已收到,但任务已不在存储中,验证结果无法追溯
趋势折线图收尾:数据管线实测 + push(16:23-16:35)
- 4 个 commit 统一 push:4473f15 /
dd15f12/d43578e/ cad3560,c314723..cad3560 main -> main(fetch 确认无分叉) - 真实 API 管线验证通过(关键:路由是
/api/dsh/account-videos?accountId=1629&pageSize=500,响应字段items非 list;/api/account-videos返回 Not Found):- 36 条全量视频、时间升序正确(2026/04/15 → 2026/08/17)
- numOf 解析 "3.5万"→35000 正确;点赞 2.6万
1838万 / 评论 45432万,双 grid 独立 y 轴量级适配良好 - tooltip 格式化、NaN 检查、语法检查全部通过
- 验证经验:Git Bash 下 /tmp 路径映射有问题(-o /tmp/x.json 落盘失败),临时文件用工作区内路径(.trend-check.json 用完即删)
- 浏览器实渲染未验证(9223 调试实例未开,遵守 Chrome 红线不主动开启),页面已带
?v=20260902-f#/account/1629重开供用户查看
趋势图「看不到」排查 + tab 直达修复(11:19-11:30)
- 根因:非代码 bug——图表只在「视频列表」tab 渲染,而重开 URL
#/account/1629默认停在「账号信息」tab(data-pages.jstab='info'),用户打开看不到图表 - 排查过程:① ECharts 资源完整(Node 拉取 1121883B/MIME 正确;curl 0B 是输出重定向假象)② 服务端 data-pages.js 含图表代码且语法 OK ③ 路由分发正常 ④ API 数据管线 36 条正常 ⑤ 9222 无 CDP 响应、9223 未开(遵守红线不主动开)
- 修复两处(data-pages.js):① hash 第三段支持直达 tab——
#/account/1629/persona→ 视频列表(含趋势图);② renderTrendChart 去掉静默 return——echarts 缺失显示「图表组件未加载」、数据不足显示「暂无足够视频数据」空态提示 - 重开
?v=20260902-tabfix#/account/1629/persona直达视频列表 tab - 经验:图表/交互元素「看不到」先查默认状态(tab/滚动/折叠)是否遮挡,再查资源与代码;Node vm 沙箱无法完整模拟 ECharts 6(缺浏览器 API,MozPerspective 报错属预期)
趋势图「白色横杠」根因 + 容器结构修复(11:27-11:32,P0 级 UI bug)
- 用户反馈:「只有一条白色横杠」→ 图表容器渲染了但高度失效
- 根因:data-pages.js 466 行
panel = '<div class="trend-chart" id="trendChart"></div>'——.trend-chart与#trendChart同挂一个 div,而 CSS 是后代选择器.trend-chart #trendChart { height: 240px },后代选择器匹配不到自身 → 容器高度只剩 padding(8+4=12px),ECharts 画布被压缩成一条细杠 - 修复:拆两层
<div class="trend-chart"><div id="trendChart"></div></div>,后代选择器命中,240px 高度生效 - 经验固化:HTML 结构
class+id同挂一个元素时,后代选择器(父 class 子 id)必然失效——class 是外壳、id 是内层必须拆两个元素;写 CSS 后代选择器前先核对 HTML 层级 - commit d9cbfd8;重开
?v=20260902-heightfix#/account/1629/persona
趋势图单图双 Y 轴彩色版(11:30,用户要求)
- 需求:「这两个折线可以放在一张图里,图要彩色的,Y轴数字单位用 w 万」
- 实现(data-pages.js renderTrendChart 重写):原双 grid 上下分区 → 单 grid 双 Y 轴(左=点赞红 #E54D42 / 右=评论蓝 #3B82F6),各带同色面积渐变;
wanTickformatter——≥1万显示「x万」(整万不带小数),<1万原值;tooltip marker 跟随序列色;X 轴 MM/DD - 量级设计:点赞 2.6万
1838万 vs 评论 45432万(60 倍差),双 Y 轴独立刻度是单图能看清两线的关键 - commit a0934c1;重开
?v=20260902-singlechart#/account/1629/persona
趋势图时间轴倒序(11:37,用户明确)
- 需求:「时间从左到右 新到旧,阅读习惯是从左到右 先看新的」
- 排序改为
new Date(b.t) - new Date(a.t)(倒序,左新右旧);此前我一度改过又按默认升序改回,用户明确后定稿 - commit f6ea791;重开
?v=20260902-desc#/account/1629/persona
趋势图半年时间窗口(11:39,用户要求)
- 需求:「图表展示 最新视频发布时间倒推半年的数据」
- 实现(renderTrendChart):排序后以最新发布(pts[0])为锚点
setMonth(-6)得 halfYearAgo,ptsWin = pts.filter(≥halfYearAgo),tooltip/xAxis/series 全部改用 ptsWin;不足 2 点显示「近半年暂无足够视频数据」 - 实测:账号 1629 最新 2026/08/17、锚点 2026-02-16,36 条全在窗口内(数据本身跨度 04/15~08/17 不足半年)
- commit 44fa126;重开
?v=20260902-halfyear#/account/1629/persona
参考skills 目录删除恢复(11:30,用户选择恢复)
- 工作区检测
script-writing-studio(38 文件)+seedance2.0-prompt-skill(77 文件)共 115 个删除(11:25 发生,非本会话操作) - 用户选择「恢复文件」→ git checkout 还原,工作区干净;SKILL.md 记载「参考skills 源文件已移除」与磁盘现状冲突,后续留意是否用户主动清理
Chrome 不主动关闭红线(10:29,用户明确)
- 用户原话:「没有用户要求 开启的chrome浏览器不要关掉」
- 固化三处:① 操作规范.md 新增 5.7 浏览器进程生命周期(红线)——已开启 Chrome(9223 调试实例/用户 Chrome/daemon 连接实例)一律不主动关闭,除非用户明确要求;只可自行回收本次任务自己启动的临时实例;② mcn-dou-analysis/SKILL.md 浏览器操作红线补第⑦条;③ V1.0/SKILL.md browser-harness 小节补进程生命周期红线
- 记忆:项目 MEMORY.md 工作方式约定新增「Chrome 不主动关闭(09-02)」;commit dc21faf(未 push,距上次 push 不足 2 小时)
主技能 subskill → subskills 更名(10:31,用户要求)
- 目录:
V1.0/subskill/→V1.0/subskills/(browser-harness/mcn-dou-analysis/mcn-script-review/mcn-video-prompt;git 识别 500+ R100 纯重命名保留历史) - 路径说明同步:V1.0/SKILL.md(96/105行)、Lite1.0/SKILL.md(66行)、mcn-dou-analysis/SKILL.md browser-harness 红线行、操作规范.md(159/175行)、mcn-work-shop app.js SKILL_HINT_ACCOUNT
- 重要发现:用户环境
~/.workbuddy/skills/短视频脚本创作/与源仓库project/短视频脚本创作/V1.0/同 inode(junction/链接)——改源仓库即自动同步用户环境,无需重复编辑(ls -i 验证 SKILL.md/app.js inode 相同) - 边界:mcn-dou-analysis 内部
subskills/nuwa-skill-main为正常结构不动;dsh 副本~/.dsh/skills/mcn-dou-analysis/单向只读未动 - 残留检查:project/ 下全类型 grep
subskill/(排除 subskills/)零命中;memory 历史日志为 append-only 不改写 - git:commit 11fe8d4(520 文件),push a255abd..11fe8d4 成功
账号详情页 tab 结构调整(16:25,用户要求)
- 需求原话:「账号详情 下面的视频列表 改为账号设定内容,视频列表放到现在账号设定tab下,改名为视频列表」
- 修改(data-pages.js renderAccountDetail):
- tab 定义:
persona标签「账号设定」→「视频列表」 - info tab(账号信息):移除视频列表表格,内联展示账号设定内容(空态/文字版/卡片+文字切换),小节标题「账号设定」
- persona tab:改为视频列表表格 + list-footer(批量/分页)
- 加载逻辑:persona 数据从「点击 persona tab 时才加载」改为「info tab 首屏即加载」(
if (tab==='info' && persona===null) await loadPersona(),与视频数据并行 dvP/await 拆分);tab 点击处理器去掉冗余 persona 加载
- tab 定义:
- 验证:bindPager/bindBatchBar 均用 querySelectorAll/空值守卫,容器缺元素不报错;data-rewrite(AI创作)点击时仍
if (!persona) await loadPersona()兜底;data-extract 绑定全局查找在 info tab 同样生效 - 服务未重启(纯静态资源),重开页面
?v=20260902#/account/1629(旧梦留声机)验证
账号信息精简(10:53,用户要求)
- 需求:「账号信息 不显示 简介,账号定位 改为收起时 显示4行」
- 修改:① data-pages.js info tab 删除「简介」info-row;② style.css
.clamp-textmax-height 240px→96px(=4行×15px×1.6),展开按钮阈值 length>200→>120(与 4 行匹配) - 重开
?v=20260902-b#/account/1629验证
视频列表标题/账号设定间距(10:55,用户要求)
- 需求:「视频列表 tab 下面的 视频列表标题可以去掉,账号设定 内容部分 左右减少20PX 间隔」
- 修改:① data-pages.js persona tab 删除
<h3>视频列表</h3>标题(info tab 的「账号设定」小节标题保留);② style.css.persona-wrappadding 0 20px→0(账号设定内容左右间隔去除) - 重开
?v=20260902-c#/account/1629验证
前3条重写请求 + 执行方式失误与固化(11:57-12:05)
- 用户需求:「前3条重新写,写完后6条一起诊断」——6 条 AI 创作任务(09-01 18:28 创建)中,前3条(automation-1788258518460→video309、1788258521485→video313、1788258524508→video315)用 18:33 优化前技能,后3条用优化后技能
- 失误(用户指出):我第一步在会话内直接写脚本草稿(tmp/new-309.md),未走工作台 AI 会话任务机制——违反技能边界(生成/改写必须走技能会话)+ 产出不入库/不在会话栏/不走技能 = 影子脚本
- 根因:执行方式没有固化成语义触发规则;重写任务没有先判定"要不要进工作台"再动手
- 固化(用户确认"固化就行不需要防呆,模型自己判断意图")三处:① SKILL.md 关键规则新增「〇执行方式判定(P0)」+ 原「〇方案与执行分离」顺延为「〇·1」;② SKILL.md 工作台章节新增第6条铁律(工作台任务必须 POST /api/run + skills 参数,重跑=复用原prompt,禁止会话内手写草稿),原6/7条顺延为7/8;③ 自动化任务调度机制.md 新增第八节「重新执行历史任务的标准姿势」(取prompt→提交→轮询→验证落库)
- 验证:用户技能目录
~/.workbuddy/skills/短视频脚本创作/与源仓库 V1.0 同 inode 软链接(stat 确认 2533274790401285 相同)→ 改源即改用户环境,AI 任务能读到新规则 - frontmatter updated_at 09-02;commit 47475d0(未 push)
- 下一步:确认后按标准姿势提交前3条重写任务(复用原 prompt + skills:['短视频脚本创作']),完成后 6 条一起按 mcn-script-review 诊断
前3条重写执行完成(12:05-12:13)
- submit-rewrite.cjs 提交 3 条重写任务(复用原 prompt + 附注"执行最新技能版本,务必落实 S6 场1 结构性符号承接检查,INSERT 新行保留旧版"):automation-1788321942675/2682/2686,skills:['短视频脚本创作']
- 轮询全部 ACCEPTED(12:05:59 并行启动,12:11-12:13 完成)
- 落库验证:309→rewrite_log#33《50块爸王餐》(5026字)、313→#32《妈妈"失声"第一天》(4704字)、315→#34《40块回血大餐》(4247字),旧版 id 28/27/26 保留;新脚本已导出 tmp/new-309/313/315.md,原6条导出 tmp/old-309/313/315/316/318/320.md
6条诊断执行方式二次失误 + 纠正(12:15-12:30,用户指出)
- 失误:拿到 6 条脚本后我又直接会话内人工诊断,未走 AI 会话任务——违反 2 小时前刚固化的「复盘必须走 AI 会话任务」;用户质疑「脚本诊断为什么 不创建AI会话任务执行呢,怎么多视频上下文混在一起 AI能识别清楚吗」
- 根因:执行惯性——把"诊断"当纯分析任务,没先过「〇执行方式判定」检查点;固化的规则在文件里但没成为动手前自查动作
- 纠正(按标准姿势):6 条诊断各建独立 AI 会话任务(submit-review.cjs,prompt 自包含脚本全文+俊希结构性符号+评分要求,skills:['脚本复盘']):automation-1788322765770/5778/5781/5784/5788/5792;8 分钟全部 ACCEPTED;落库 script_review id 4-9(type='ai',dims_json/total/verdict/issues_json/content 齐全)
- ★诊断结果(6条):309=89.5可交付 / 315=88.1可交付 / 316=87.6可交付;318=60需优化;313=40需大改;320=40需大改
- ★AI 独立会话抓出 5 个逻辑硬伤,其中 2 个我人工诊断漏掉:①313「妈妈小姨」称呼矛盾(旧版小姨陪同设定残留,全片小姨未出现)+35块账目不闭合(只记鱼13+梨3.5,虾仁/鸡蛋/面条/菌菇无报价);②318 排骨来源穿帮(场2-3 未买排骨场7 凭空炖排骨汤+40元账目超支);③320 四菜一汤数字不符(实做3菜1汤+长寿面,被我降级🟡实应🔴)+蛋糕来源穿帮(100块账目无蛋糕)
- 教训固化:①会话内混 6 条脚本人工诊断必然漏硬伤——独立会话任务是正确的执行方式(用户质疑实锤);②诊断禁止替脚本补信息(我人工用"市场价推算"补了 313 的账目=错误,AI 按脚本内数字判断才对);③AI 诊断间标准漂移:316 结尾承接"睡前点菜"判✅ vs 318 放学场景点菜判🟡中——S6 检查条款"场1承接 vs 全片承接"有歧义需留意
3条硬伤脚本修复完成(12:30-12:35,用户继续推进)
- 按诊断结论对 313/318/320 提交修复任务(submit-fix.cjs,prompt=脚本全文+script_review issues_json 问题清单+最小改动要求,skills:['短视频脚本创作']):automation-1788323400033/0050/0062,4分42秒全部 ACCEPTED
- 落库 INSERT 新行:313→rw#35(5003字)、318→rw#36(5076字)、320→rw#37(5975字),旧版全保留
- 修复验证(抽查 fix-313/318/320.md)全部落实:
- 313:「妈妈小姨」→「妈妈,睡前点菜!」;补面摊场景(面菌菇小葱4块),账本特写 13+3.5+11+3.5+4=35 闭合;写字板动作统一妈妈举板;「终于能开口」→「很快就能开口」时序修复;梨瓤「地板」→「台面」
- 318:场3 新增排骨摊(半斤6块)+报账口播「腊味18+鲈鱼13+排骨6+玉米2=39块剩1块」闭合;场1 俊希「说好的睡前点菜呢」+爸爸「晚上睡前视频」显式致敬睡前符号
- 320:补第4道菜「拍黄瓜」,场1/场2/场4 三处口径统一(四菜一汤=虾+鲈鱼+菜心+拍黄瓜,汤=排骨汤,面=主食);蛋糕=爸爸预订报尾号8023取件另出钱不入100块账;场1 爸爸画外「你妈昨晚睡前点菜」一镜承接三符号;记账本特写 虾28+排骨32+鲈鱼22+菜心5+黄瓜3+葱2=92余8;爸爸视频安全叮嘱
- 3 条修复版脚本导出 tmp/fix-313/318/320.md;提交脚本 tmp/submit-fix.cjs、轮询 tmp/poll-fix.cjs
3条修复版复检验收全部通过(12:45-13:00)
- 对 rw#35/36/37 三条修复版各提交独立复检任务(submit-recheck.cjs,skills:['脚本复盘']):automation-1788323767073(=313)/7089(=318)/7099(=320),4分02秒全部 ACCEPTED;落库 script_review id 10/11/12
- 验收结果:313=40→91.0可交付(2硬伤+4问题全清,账目 13+3.5+11+3.5+4=35 闭合,场1一镜承接三符号);318=60→86.9可交付(账目/认知链/符号承接/钩子全清,残留2中6低为表达细节);320=40→90.4可交付(7条诊断全清,账92+8闭合、蛋糕来源链闭合、四菜一汤口径三处一致、三符号场1承接)
- 修复-复检闭环验证:最小改动修复 → INSERT 新行保留旧版 → 独立会话复检 → 分数回升至可交付,流程成立
复盘技能对齐创作技能优化(13:12,用户提出)
- 用户问「优化创作技能后,复盘技能是不是也要对应优化」→ 核对结论:复盘对创作侧判定标准是只读路径引用(八类35项/故事成立性/11_检查诊断 3 文件均在、路径未变,自动同步);真正缺的是引用范围外创作侧新增硬规则 2 处
- 执行修改(源 SKILL.md v1.2→v1.3,09-02):
①「设定承接」维度补场1结构性符号承接检查(对齐创作技能
23edead09-01 规则:账号有结构性符号须场1一镜/一句话交代禁铺垫,缺失记高;无符号 N/A) ②新增「执行方式判定」节(P0):工作台复盘走 POST /api/run + skills:['脚本复盘'] 独立 AI 会话任务;对话内多条脚本复盘=每条一个独立上下文,禁止混审(一条脚本=一个独立上下文) - 同步:用户级副本与源同位置自动生效;dsh 副本
script-review逐处同步(保留其缺「MCN工作台」协作行环境差异) - 经验:复盘技能评价尺子=「引用文件自动同步 + 自身维度人工同步」双轨——创作侧改 references 内文件复盘不用动,改 SKILL.md/框架新增硬规则(references 外)复盘必须人工补
AI脚本诊断列表加分页(14:11)
- renderReviews 全量渲染 → 每页 20 条前端切片分页(PAGE_SIZE=20,slice((page-1)20, page20)),复用现有 pagerHtml/bindPager/list-footer;空态 colspan 13→动态
5+DIMS.length+1(原 13 为滞后值);openScriptDetail/openReviewDetail 仍用全量 items 查找不受分页影响 - 语法 node --check 通过;静态文件改动无需重启服务;已带 ?v= 重开 #/reviews
账号详情页抖音号可点击跳主页(14:15)
- renderAccountDetail info tab:抖音号值改为可点击链接 → 优先
https://www.douyin.com/user/{sec_uid}(account-videos 接口 account 已含 sec_uid,实测存在);无 sec_uid 兜底douyin.com/search/{抖音号}?type=user;复用 app.js 全局a[data-ext]委托(window.open+拦截兜底复制),无需新增绑定
AI脚本诊断列表操作列优化(14:18)
- 操作列表头
<th>→<th class="th-act">(居中,与数据列 .cell-act 对齐) - 已诊断行(reviewOf 非空:review_ai 或 review_compare done)按钮文案「复盘」→「更新」,未诊断仍「复盘」;运行中仍「复盘运行中」disabled
AI脚本诊断列表 生成方式列收拢两种取值(14:20)
- 原 GEN 映射死代码(rewrite/new/abc→爆款视频创作/账号列表创作/ABC融合创作,后端 listRewrites 从不返回 genMethod,恒显示爆款视频创作)
- 改为按
rewrite_log.video_id>0判定:有参考视频(视频/详情页 AI创作入口,prompt 参考视频选题)=「参考选题」;无 video_id(账号列表 confirmAiScript 入口,手输/AI生成选题)=「输入选题」;删 GEN 常量。当前库 26 行全有 video_id → 全显示参考选题(如实)
复盘按钮 prompt 按有无源脚本动态分支(14:24)
- 问题:复盘 prompt 固定要求「AI脚本/原视频脚本/对比分析三模式」,输入选题创作(video_id=0,无原视频脚本)或无源脚本视频会无对象可比 → AI 可能幻觉编造源脚本对比,污染 source/compare 数据
- 落地:点击复盘/更新按钮时 async 查
/api/dsh/video-script?videoId=N判 source 非空 → 有源=原三模式文案;无源(含 video_id=0)prompt/desc 改「仅 AI 脚本质量复盘评分(独立分析模式·10 维评分制),不做源脚本复盘与对比分析」+title 改「AI脚本复盘」;查询失败保守按有源(沿用原文案不误砍);dataset.lock 防 await 窗口期连点 - 检查发现遗留风险:按钮复盘 prompt 不含脚本全文/标识(executeTask 不透传行数据),AI 会话定位脚本依赖会话侧库访问——若点击复盘常跑偏,根因在此需另行注入
AI脚本诊断标题弹窗对齐「AI写脚本」查看弹窗(16:23)
- 需求:点击 AI脚本诊断列表脚本标题 → 弹窗布局参考 AI写脚本列表「查看脚本」弹窗(三段式),右侧「AI提示词」列改为「AI诊断」内容
- 实现(data-pages.js openScriptDetail 整体重写为 rw-stack 三列,对齐 openRewriteCompare 结构):
- 列1 源脚本(有 source 才渲染,默认
rw-sec-hidden收起,AI脚本列头data-src-toggle按钮展开,src-on高亮)|列2 AI脚本(md-body + 底部版本切换 foot:上一版/下一版 + 版本 N/M)|列3 AI诊断(评分条 11 维 + AI 总分 + compare 时「对比源脚本 N 分」+ 问题清单 + 综合评语 + 「查看完整复盘报告」链接 → openReviewDetail) - 评分口径与列表一致:review_ai done 优先,其次 review_compare 取 ai 侧 dims/total(dims_json.total 双对象结构)
- 诊断空态:
diag-empty「该版本 AI 脚本尚未诊断」+ 开始复盘按钮(走 startReview 动态分支 prompt);复盘运行中(review_running)显示运行中提示且禁用按钮(修复:原空态在 running 时误显示「开始复盘」——review_ai 最新行 running 未 done 导致 reviewOf 判空) - 数据源:
/api/dsh/video-script?videoId=的 rewrites(同表 rewrite_log.id,与列表 items.id 同体系)+ items 行聚合 review_ai/compare(find 不到时兜底 raw curRow → 显示空态) - CSS 补
.diag-empty(style.css,dim 灰 + padding)
- 列1 源脚本(有 source 才渲染,默认
- 语法 node --check 通过 ×2;服务未重启(纯静态,no-store);git commit afc45b7,与之前 6 个 commit 一起 push(d0cbd41..afc45b7 成功)
AI创作弹窗对话打磨 v2 定稿(15:50-16:00)
- 用户反馈:「跟 AI 打磨需求 和 载入需求单 交互很奇怪,而且不连贯」→ 要求改为「弹窗内 需求框 + 输入框 对话打磨」「AI 按钮去掉,全过程都用 AI」——彻底废弃旧分步向导 + 跨会话打磨 + 需求单 md 载入路径
- 方案:单弹窗 v2(
confirmAiScript完全重写,data-pages.js:199-326)= 顶部 10 行「创作需求」框(REQ_FIELDS空值灰显"待定·由 AI 按人设自决")+ 中部对话流(u/ai 气泡)+ 底部输入行(Enter 发,Shift+Enter 换行)+ 取消/提交创作;无 step/chip/AI 按钮/载入按钮/上下步 - 后端新增
POST /api/ai/clarify(server.js,紧跟/api/ai/topics之后)= 同步阻塞 Dify chat-messages(100s AbortController),request{ accountName, turn, reqMd, history },response{ answer };query 拼接=账号人设摘要+当前需求 md+最近 2 轮历史+用户本轮输入,强制输出"对话回复 + ==REQ== + 10 行需求" - 关键设计:每轮重发「当前完整需求 + 最近 2 轮历史」做无状态上下文;AI 可更新任意字段、用户可改写 AI 输出;AI 只澄清需求严禁生成脚本正文;最终 prompt
reqLines仅取非空字段,未填字段加 "由 AI 按人设自决" 提示 - 冒烟脚本
tmp/cdp-req-dialog-smoke.mjs(CDP 9224,4 步端到端)3 轮迭代定稿——首两轮 2 个脚本 bug:- ④ 提交点击
querySelector('[data-create]')命中背后列表按钮(弹窗内外按钮同名 data-create)→ 改为.req-modal [data-create]限定作用域;同时title改为.req-modal .modal-title-row span(原全局 querySelector 命中其他 modal 模板) Page.navigate同 URL 不真正 reload(旧弹窗残留叠加新弹窗,rows 30=3 个弹窗叠加)→ 改用?v=Date.now()强制 reload +waitFor('!document.querySelector(".req-modal")')等清场
- ④ 提交点击
- 最终全绿(53s):①结构 rows:10 / title="AI创作 · 旧梦留声机" ②第一轮 busy=true,AI 回复贴合人设("账号主打【隔辈亲情与温情催泪】...A. 角色换为笨拙爷"),filled 0→6 ③第二轮 filled 6→8 ④提交 label="创作指令"/skills=["短视频脚本创作"]/hasPersona=true(人设卡注入 prompt)/reqRows=8(8 条需求进 prompt)/modalClosed=true
- 截图产出
tmp/req-1-empty.png/req-2-after-turn1.png/req-3-after-turn2.png+ 报告tmp/req-dialog-report.json - 工作台页面 按"改完必重开"约定 present_files
?v=20260902-req#/accounts - 经验沉淀:①账号列表/弹窗内同名
data-create触发选择器歧义——统一加 modal 作用域或换名(如data-confirm-create)②CDP Page.navigate 同 URL 不可靠——浏览器/CDP 跨会话残留必须强制 reload + 显式等清空;冒烟脚本应假设首状态脏
AI创作弹窗 UI v3 升级(16:00-16:12,用户要求)
- 需求原话:①弹窗高度可以增加 ②需求展示部分 维度作为标题 内容在标题下面的展现形式 ③发送按钮改成图标 和输入框真正合在一个分块中(参考 WorkBuddy 输入框)④提交创作改为图标 放在输入框功能区域左边 ⑤不需要取消按钮(已经有关闭按钮了)
- 实现(data-pages.js confirmAiScript L219-251 HTML 重组 + style.css L209-272 整段重写 + app.js ICON_PATHS 加 'arrow-up'/'check'):
- 弹窗高度:
.req-modalwidth 720→760,height: min(840px, 92vh) + display:flex/flex-direction:column,gap:10px;title-row/head/sheet/bar 各自 flex none - 需求区:
.req-sheetgrid 2 列(gap 8×10px),每块.req-field=.rf-title标题(12px 灰小字加粗)在上 +.rf-val内容(14px)在下;卡片底 #f6f8fb 圆角 10 padding 7 11,empty 时浅 #fafbfd + rf-val 灰 #c6ccd6 - 输入条:
.req-barflex row[#reqCreate] [.req-input-box],input-box = 圆角 12 胶囊(border+focus-within 主色描边+halo),内嵌无边框 textarea(透明)+ 右侧 34×34 primary 蓝圆发送钮(svgarrow-up↑);busy 时钮 disabled 灰 + 中心 14×14 白色 spinner(@keyframes req-spin) - 提交创作:
#reqCreate44×44 描边圆角方块,蓝 ✓ 图标(svgcheck),hover 浅蓝底 - 关闭:右上
data-x× 保留;取消按钮整段删除(HTML data-cancel + 监听器 + .modal-actions 容器)
- 弹窗高度:
- 附带红利:弹窗提交按钮改 id 后,账号列表 [data-create] 与弹窗内提交同名选择器歧义自然消失(CDP 冒烟脚本④ selector 同步改
#reqCreate,旧.req-modal [data-create]写法作废) - 冒烟脚本
tmp/cdp-req-v3-smoke.mjs(CDP 9224 24s 一轮真打磨+提交捕获)全绿:①fields:10/empty:10/title="AI创作 · 旧梦留声机"/hasBar/createIsIcon/sendIsIcon/hasCancel:false/modalH:784/modalW:760 ②首轮 filled 0→6,首块"一句话创意与选题"=「离异母亲带娃整理房间,娃越帮越忙的搞笑反转日常」③提交 label=创作指令/skills=['短视频脚本创作']/hasPersona:true/reqRows:6/modalClosed:true - 截图
tmp/reqv3-1-empty.png/reqv3-2-after-turn1.png/reqv3-3-after-create.png+ 报告tmp/req-v3-report.json - 工作台重开
?v=20260902-v3#/accounts
AI创作弹窗 v3 补完:textarea auto-grow + 换行提示(16:13-16:16)
- 补完点:上一轮"参考 WorkBuddy 输入框"差两体验细节未落地——①textarea 无 auto-grow(多行输入会内部滚动而非长高)②placeholder 两行但 rows=1 只显示一行
- 实现(data-pages.js confirmAiScript):
- 新增
autoGrow()闭包:style.height = 'auto'; style.height = Math.min(scrollHeight, 100) + 'px'(与 CSS max-height 100px 一致) - input 事件绑定 autoGrow(多行自动增高到 cap 100)
- sendTurn 清空 + 错误恢复 input 后调 autoGrow 复位
- placeholder 单行化(去掉 "(Enter 发送,Shift+Enter 换行)"——rows=1 第二行被截断)
- req-head 末尾补 "Enter 直接发送,Shift+Enter 换行"——键盘说明从 placeholder 迁到头部更显眼
- 新增
- 验证
tmp/cdp-autogrow-check.mjs:5 行输入(scrollHeight 116)→ height 32→100(被 cap 到 max-height)✅;清空 → height 回 32 ✅ - git commit 1a8f445(1 文件 +10/-2)
AI创作弹窗 v4 上传需求附件(16:20-16:30,用户要求)
- 需求原话:「增加一个上传需求的功能,支持上传附件(doc txt pdf ),可根据附件内容 完善需求,确认后 将附件内容也当做创作AI脚本的上下文。」
- 实现(data-pages.js + style.css + server.js + 新 scripts/attachment-parser.js):
- 前端 confirmAiScript:
- HTML:req-dialog 与 req-bar 之间插入
<div class="req-attach-row" id="attachRow">(chip 行);req-input-box 内 textarea 前加 paperclip 按钮<button class="req-paper" id="reqPaper">;弹窗底部加<input type="file" id="attachInput" accept=".doc,.docx,.txt,.pdf" hidden> - 状态:
let attach = { name: '', text: '' }+let parsing = false(防重入) fileToBase64(f)= FileReader.readAsDataURL → split(',')[1]- attachInput change:校验扩展名+大小(>20MB 拒)→ 调
/api/req/parse-attachment→ 设置 attach +renderAttach()渲染 chip(paperclip+文件名+字数+×)+ 失败 toast sendTurn:空文本但 attach 非空时自动用引导语"(我已上传需求附件)请通读附件内容…";body 增加attach: attach.textreqCreate:buildCreatePrompt新增第 5 参 attachText
- HTML:req-dialog 与 req-bar 之间插入
- buildCreatePrompt:attachText 非空时在【创作需求】后拼【附件素材】段「达人上传的需求文档/资料原文,创作时须充分参考,其中的诉求与约束同【创作需求】一样必须满足」
- 后端 server.js:
require('./scripts/attachment-parser')一行/api/ai/clarify入参增attach,query 在「【账号定位】」后拼「【附件素材】(达人上传的需求文档/资料,打磨与最终创作都须充分参考…)」;attach 限 2 万字符- 新增
POST /api/req/parse-attachment:body 30MB 上限 →Buffer.from(data,'base64')→ 20MB 上限 →parseAttachment(name, buf)→ 返回{ text, chars, warn, sourceChars }(text 限 3 万字符)
- 零依赖解析器
scripts/attachment-parser.js(仅用 node:zlib):.txtutf8 直读+\uFFFD 警告 /.docxEOCD 0x06054b50+中央目录 0x02054b50 找 word/document.xml→inflateRawSync 抽 w:t/w:p/w:br/w:tab+xmlUnescape /.pdflatin1 流定位 stream/endstream+前文/Filter /FlateDecode→inflateSync+Tj/TJ/hex 文本抽取 /.doc400 报「请另存为 .docx/.txt」 - CSS style.css:新增
.req-attach-row/.req-chip/.chip-ic/.chip-name/.chip-meta/.chip-x/.req-paper(primary-soft 浅蓝胶囊 + paperclip 灰图标 + 28×32 灰圆角上传钮 + .loading 旋转);.req-input-boxpadding-left 13→2px 容纳回形针
- 前端 confirmAiScript:
- 测试样例
tmp/attach-tests/{req.txt,req.docx,old.doc}.b64(make_samples.py 零依赖生成):req.txt171 字 /req.docx100 字 /old.doc0xD0CF11E0 头 200B / 冒烟前已用真实账号名「俊希」作示例内容造成用户困惑,09-02 16:31 改为「亲子Vlog 方向(测试用样例)」中立内容(教训:冒烟附件样例必须中立,禁止带任何真实账号/达人名) - 端到端 API 验证(node fetch tmp/attach-tests/parse-check.mjs):txt 200/171字/warn:"" / docx 200/100字/warn:"" / doc 400「暂不支持 .doc 老格式…」/ 空参数 400「缺少文件参数」——全路径符合预期
- CDP 9224 冒烟脚本
tmp/cdp-req-v4-attach-smoke.mjs(3 轮迭代,2 轮失败根因):- 失败 1:
DOM.querySelector(rootId, sel)跨连接 root 失效(错误"Could not find node with given id")→ 改Runtime.evaluate+DOM.requestNode(objectId)拿稳定 nodeId - 失败 2:
DOM.setFileInputFiles仍抛"Could not find node with given id"(疑似目标 Chrome 多 client 句柄竞争,9224 同时被其他进程连接)→ 改纯 Runtime 方案:atob(b64)→Uint8Array→File+DataTransfer+input.files=dt.files+dispatchEvent('change'),change 处理器 FileReader→fetch 全在页面内异步完成 - 失败 3:每次 cdp() 调用新建 WebSocket 连接 = 不同 CDP session,objectId/nodeId 全部失效 → 改为单条持久 WebSocket(
_sock全局复用 + onopen 同步 + message listener 配对 id 移除)
- 最终全绿(含真实 Dify 一轮打磨 50s,总 90s):①结构 hasPaper/paperInBox/hasAttachInput/accept=".doc,.docx,.txt,.pdf"/attachRow/headHas ②txt chip "req.txt 162 字" ③移除成功+docx chip "req.docx 95 字" ④turn1 真实 Dify 回复明确读附件硬性要求:「俊希做煎蛋、妈妈手部指导镜头、爸爸烫到彩蛋以及牛奶口播植入已全部录入清单」+filled 0→5+msgs=2 ⑤提交创作弹窗关闭(executeTask 走通)
- 截图
tmp/reqv4-1-txt-chip.png/reqv4-2-docx-chip.png/tmp/reqv4-3-turn1-filled.png+ 报告tmp/req-v4-attach-report.json
- 失败 1:
- 测试残留清理(用户反馈「为什么旧梦留声机和俊希混在一起」后排查):
- 工作台 DB automations 表查到 2 条可疑任务:
automation-1788337499185创作指令(我 16:25 冒烟 ⑤ 触发,prompt 含 docx 俊希附件+旧梦留声机人设,scheduledAt 16:25:04,状态 IN_PROGRESS 跑中会污染脚本产物)/automation-1788334853018打磨需求(15:40:58 ACCEPTED,产物旧梦留声机/创作需求单.md实际是用户自己的「爷爷的旧收音机」默认 A 选题,无俊希字样——不动) - 处置:automation_update mode=update id=automation-1788337499185 status=PAUSED(scheduler 不再触发新轮次,但已 IN_PROGRESS thread 会自然跑完,产物落到
旧梦留声机/脚本创作/由用户决定清不清——不擅自清) - 根因:冒烟测试样例 req.docx 内容用了「俊希账号」真实账号名→ 弹窗标题「AI创作 · 旧梦留声机」+ 附件「俊希」=视觉上两账号混了;已改测试样例为中立(make_samples.py 改写后重生成 b64 验证仍 4 路径 OK)
- 工作台 DB automations 表查到 2 条可疑任务:
- ★经验沉淀(v4 设计层):
- 端到端附件功能实现要分 4 层:①解析器(零依赖纯文本提取)②上传 API(限大小/限字符/返回结构)③前端 chip 状态(attach 字符串而非 base64 缓存)④prompt 拼接(每轮 clarify + 最终 buildCreatePrompt 都带)
- AI 打磨 vs 创作上下文共享:clarify 时 attach 进 query 让 AI 把诉求吸收进需求清单;create 时 attach 原文进 prompt 让创作有完整参考——同一 attach 两个阶段都用,但作用不同(前者吸收诉求、后者保留原文)
- 「空输入但有附件」单独 UX:sendTurn 自动发引导语,避免用户必须输字才能让 AI 看附件;这是「上传需求」功能的核心交互
- CDP 冒烟注入文件的可靠方案:纯 Runtime + DataTransfer(绕开 DOM 域句柄),变更可靠 + 不依赖目标 Chrome session 状态
- git 改动未提交(按 2h 节奏):4 文件 M + 1 新增 attachment-parser.js(app.js 仅 ICON_PATHS 新加 paperclip 一行)
- ★工作台页面重开(按「改完必重开」约定):present_files 后面挂
http://localhost:8900/?v=20260902-v4#/accounts
AI创作弹窗 v5 输入框布局微调(16:32-16:38,用户参考 WorkBuddy 输入框截图)
- 需求原话:「输入框不是这样的 输入框分上下两部分,上面是文字输入区域,下面是功能区域,用一个边框包起来,参考下下workbuddy的[截图]」
- 实现(data-pages.js HTML 重排 + style.css 调整):
- HTML:
<div class="req-input-box">内部由「paperclip + textarea + send 横向」改为「textarea 在上 +<div class="req-input-toolbar">在下」结构;toolbar 内含 paperclip +<div class="req-spacer">弹性间距 + send - CSS:
.req-input-box:flex 方向 row→column、border-radius 12→14、padding 改为 0(让两块各自控 padding).req-input:flex:1→width:100% + box-sizing:border-box,padding 6/0/5→10/14/6(上输入区留白)- 新增
.req-input-toolbar:flex row + align center + gap 2px + padding 2/4/6 - 新增
.req-spacer:flex:1 推开 paperclip 与 send .req-send:34×34 圆角 9→32×32 圆角 50%(贴合 WorkBuddy 圆形按钮).req-paper:28×32→32×32(与 send 视觉对齐)
- req-create 仍保留在 .req-bar 左侧独立(44×44 ✓ 提交创作,对应 WorkBuddy 弹窗外功能)
- HTML:
- CDP 9224 验证
tmp/cdp-req-v5-layout-check.mjs(结构 + autoGrow 多行 + 截图):- 结构全绿:boxDisplay=flex / boxFlexDir=column / boxBorderRadius=14px / hasToolbar=true / taAboveTb=true / paperLeftOfSend=true / paperInToolbar=true / sendInToolbar=true / boxRounded=true
- autoGrow:6 行输入 → height 100px(被 max-height cap,scrollH 142 截断),toolbar 自然下移,外框圆角不变
- 截图
tmp/reqv5-1-input-layout.png(空态)/tmp/reqv5-2-input-multiline.png(多行+focus halo)
- 教训(冒烟脚本复用旧坑):CDP 测试用
el.value = 'A\\nB'字面 \n 被当 2 字符不换行——前次 v3 已踩,本次脚本复用相同模式,结构验证不受影响(autoGrow 实测 v3 cdp-autogrow-check.mjs 已覆盖真换行) - 设计要点:输入区(textarea)+ 功能区(toolbar)垂直堆叠 + 单一外框圆角描边 + focus-within 整体 halo —— 与 WorkBuddy 输入框视觉一致;保留 req-bar 左外侧 ✓ 提交(弹窗层级独立功能,不属输入框)
- git commit 待执行(按 2h 节奏不 push,本次仅 UI 微调,单 commit)
- ★工作台页面重开(按「改完必重开」约定):present_files 后面挂
http://localhost:8900/?v=20260902-v5#/accounts
AI创作弹窗 v6 确认按钮移入工具栏(16:38-16:50,用户要求)
- 需求原话:「把确认按钮 也改为图标 放到输入框功能区域中」
- 调整思路:确认按钮 ✓ 原本在 req-bar 内、req-input-box 外侧(左外 44×44 圆角方块独立按钮)→ 移入 req-input-toolbar(输入框底功能区),与 paperclip/send 同居;与 send 同尺寸同形状(32×32 圆形)形成「次主+主」配对
- DOM 重组(data-pages.js 行 230-240):
- req-bar 内独立
<button id="reqCreate">移除 - 在 req-input-toolbar 内追加
<button class="req-create" id="reqCreate">(svgcheck16px),位置在 spacer 后、send 前——构成右侧"动作簇":spacer → ✓ → ↑ - 文案同步:req-head 「点左侧的 ✓」改为「点输入框内的 ✓」
- req-bar 内独立
- CSS 调整(style.css):
.req-create:44×44 圆角 12px 描边方块 → 32×32 圆形(border-radius: 50%),主色描边 + 白底 + 主色图标;hover 时主色填实(与 send 实心配色形成"次主+主"配对)- 移动
display: flex→display: inline-flex(与其他 toolbar 按钮对齐)
- CDP 验证 v6(
tmp/cdp-req-v6-confirm-in-toolbar.mjs全绿):createInToolbar=true/sendInToolbar=true/paperInToolbar=true / createBeforeSend=true / createSize=sendSize=paperSize=32×32 / sameSizeAsSend=true / createBorderRadius=50% / createBorderColor=primary / sendBackground=primary / barHasCreateDirectly=false / barChildren=["req-input-box"](外置大按钮已彻底消失) - 截图
tmp/reqv6-1-confirm-in-toolbar.png(整体弹窗,外置✓消失)/tmp/reqv6-2-toolbar-zoom.png(工具栏 zoom)
AI创作弹窗 v6.1 ✓↔↑ 间距 10px(16:50,用户明确)
- 需求原话:「输入按钮 和 确认按钮 间隔10PX」
- 微调(style.css):
.req-createmargin-left: 4px + 新增 margin-right: 8px(toolbar gap 2px 保持)—— 总间距 = 2 + 8 = 10px ✓ - CDP 验证
tmp/cdp-req-v6_1-gap10-check.mjs:createRight=929/sendLeft=939/gap_px=10(精确) - 截图
tmp/reqv6-1-toolbar-zoom.png(更新版) - 工作台页面重开
?v=20260902-v6#/accounts(v6.1 同 v6 版本号足够,CSS no-store)
AI创作弹窗 v6.2 输入框默认两行空间(16:55,用户要求)
- 需求原话:「输入框的输入位高度扩大,默认有两行输入空间」
- 调整(style.css .req-input + data-pages.js HTML):
- CSS
.req-inputmin-height: 30px → 60px(行高 21px × 2 + padding 16 = 58px,取 60 留 2px 余量;box-sizing border-box 含 padding) - HTML
<textarea rows="1">→rows="2"(JS 加载前/极端情况也呈现两行)
- CSS
- autoGrow 行为复核:
- 初始空态:60px(CSS min-height 兜底 + rows=2)
- 多行输入(6 行):100px(max-height cap 到 100px,与 v5 一致)
- 清空复位:60px(autoGrow reset → min-height 兜底)
- CDP 验证 v6.2(
tmp/cdp-req-v6_2-twolines-check.mjs):rows=2/heightPx=60/lineHeight=21px/paddingTop=10/paddingBottom=6 ✓ - 截图
tmp/reqv6-2-twolines-empty.png(zoom 入参框:占位符一行 + 预留第二行 + 底部工具栏)/tmp/reqv6-2-full-modal.png(整体) - 工作台页面重开
?v=20260902-v62#/accounts(与 v6 不共存,最新版本号)
排查「创作指令」测试任务严重问题:根因=弹窗入口漏拼 SKILL_HINT_CREATE(17:09 定稿)
- 问题现象(用户贴续聊记录):16:25 测试 AI 会话任务「创作指令」产出脚本,用户追问发现 AI 承认「没按 S1-S11 逐步执行、直接一步到 S9」,S5-S8 脑内带过
- 根因定位(代码级):
data-pages.jsAI创作弹窗 reqCreate 提交(L386)只调buildCreatePrompt()拼 prompt,没拼 SKILL_HINT_CREATE("遵循 S1-S11 完整创作流程(选题→框架→大纲→情绪→结构→脚本)禁止跳步"那段);而详情页 rewrite 入口(L711/L920)在ef98395提交时都加了 SKILL_HINT_CREATE 前缀——弹窗是新入口(v2/v3/v4/v5/v6 系列迭代),漏加 - 证据链:① trace 19064 toolInput 提取任务实际收到 prompt 原文=只有「请为达人创作+人设卡+需求+附件」,无 SKILL_HINT_CREATE;② git
ef98395只在 L711/L920 两处加前缀,未覆盖弹窗路径;③ 任务执行时模型只读 S9 规范直出(工具调用序列:Skill→读memory→Glob俊希→ls outputs) - 次生问题:任务头部人设卡挂「旧梦留声机」(数据库账号ID 1629),但【创作需求】+【附件素材】=俊希亲子Vlog煎蛋(模板错配,任务创建时写死,AI 自纠按俊希卡创作)——用户确认非此问题
- 修复方向(待用户确认):弹窗 reqCreate 提交处 prompt 加
${SKILL_HINT_CREATE}\n前缀(对齐详情页入口)
修复执行与推送完成(17:20)
- 代码修复(data-pages.js,commit 35778e0):① L7
SKILL_HINT_CREATE追加自动模式语义——「⚡自动模式=严格按 S1-S11 顺序逐步走完整流程,后台静默=各步产物在上下文按序完整产出但不逐个展示,禁止跳过或合并中间步骤一步直出成品」;② L386 弹窗 reqCreate 提交处 prompt 改${SKILL_HINT_CREATE}\n${buildCreatePrompt(...)}(对齐详情页 L711/L920) - 验证:
node --check通过;curl localhost:8900/data-pages.js 含新标记;页面重开?v=20260902-auto#/accounts(present_files) - 记忆固化:MEMORY.md「AI 任务触发」行追加约束=所有创作类任务 prompt 必须带 SKILL_HINT_CREATE 前缀,新增入口时必须检查(commit 05f8127)
- 推送:fetch 无分叉 → push origin main afc45b7..05f8127(含弹窗 v4~v6.2 + 修复共 11 commits)
技能机制复盘:三入口补技能前缀(prompt 与技能边界分离,17:3x)
- 用户复盘链:①「选题→框架→大纲→情绪→结构→脚本」问创作流程是否有这两步 → 澄清 S5-S8 是静默中间产物(自动模式语义=上下文完整产出但不展示,最终展示只到 S9);②「是不是之前的 AI 创作功能也有这些问题,你要总结经验,技能该怎么用看明白再规划功能」→ 审计 8 个工作台 AI 操作入口,确认提炼账号设定/生成分镜/复盘三处 prompt 曾是裸文本或技能声明硬编码混入业务串;③「按方案修复,但注意 prompt 和技能边界的区分」→ 定版分层模式
- 分层模式(定稿):任务 prompt = 固定技能声明前缀(加载 Skill+模式+边界规则)+ 业务正文(为何任务/人设/选题);技能声明禁止混写进业务字符串、禁止彼此污染;UI 入口渲染时写死契约
- 代码修复(data-pages.js,commit d32492e,与 CREATE 同层管理):
- 新增
SKILL_HINT_EXTRACT(mcn-dou-analysis 功能三提炼账号设定:先判账号类型→基于库中已有 MCP 解析数据→人设卡 V2 12 段→边界:不生成/改写脚本、不含商业变现、不执行任何数据抓取流程——规避 server.js BROWSER_HINT 正则误注入) - 新增
SKILL_HINT_STORYBOARD(短视频分镜脚本 F4:时间戳分段/实体绑定/6 层结构,只输出分镜提示词不改写输入脚本) - 新增
SKILL_HINT_REVIEW(脚本复盘:独立会话一条脚本一上下文,只分析建议不改脚本不触发创作) - 三调用点改为
前缀+业务正文:提炼 confirmRun(L732)、分镜 confirmRun(L1007)、复盘 startReview(L1127/1129 按有无源脚本动态分支 desc/prompt,desc 只留用户可见摘要)
- 新增
- 验证:node --check 通过;构造与 server.js L516 精确一致的 BROWSER_HINT 正则逐一核对,四前缀均不命中;服务端 curl data-pages.js 四常量在位(CREATE×6/EXTRACT×2/STORYBOARD×2/REVIEW×3);静态资源 no-store 无需重启
- git:commit d32492e(本地,距上次 push 17:17 不足 2 小时不 push);c777732 为上一轮记忆日志 commit
- 经验:规划工作台功能必须先吃透技能契约(SKILL.md 加载方式/模式语义/边界)再定义入口,渲染入口写死契约;新增入口必须检查技能前缀与 BROWSER_HINT 命中词(「浏览器」「采集」「抓取」等);复盘页同时涉 mcn-script-review 与创作技能,边界需后续贯穿验证
同步时清 tmp 约定 + 首次执行(17:33-17:50,用户明确)
- 用户需求:「每次同步仓库的时间到了,执行同步的同时清除 tmp 文件夹」
- 范围确认(AskUserQuestion):工作台
mcn-work-shop/tmp(114M/85 文件:cdp-.mjs 验证脚本/png 截图/json 报告/attach-tests 样例/chrome-wztest Chrome user-data-dir)+ 仓库根tmp/(rosegold.py/证据 md);绝不清.workbuddy/tmp/(系统缓存 edge-cdp 21M) - 执行与坑(首次实操):①rm 批量删除被 safe-delete 回收站机制包裹,114M 大批量自动转后台 4m26s 才完成(耐心等待或分批);②chrome-wztest2 删除失败根因=冒烟残留 headless Chrome 9224 仍占用 143 文件(
--headless=new --remote-debugging-port=9224 --user-data-dir=...tmp/chrome-wztest2)——按 Chrome 红线回收自己启动的测试实例:netstat -ano | grep :9224找 PID →taskkill /PID 主进程 /T /F(8 子进程全清)→ 再删即成功;③Git Bash 下 taskkill 双斜杠//PID报「无效参数」,须单斜杠/PID - 结果:工作台 tmp 85→0(114M→16K 空目录)、根 tmp 2→0、.workbuddy/tmp 保留
- 固化:项目 MEMORY.md「git」行后新增「同步时清 tmp(09-02 用户明确)」条目(含 chrome-wztest 锁定坑与回收姿势)
- git:3+1 个 commit 全部 push 成功(c777732/d32492e/6853fa3/5e8670c,05f8127..5e8670c main->main,fetch 无分叉)
AI 任务入口技能契约机制固化(17:55,三入口修复收尾)
- 背景:三入口修复只解决已暴露问题,用户总结「技能该怎么用看明白再规划功能」——需机制化防「新增入口再缺约束」回归
- 代码核实:全 8 个 AI 会话入口参数逐一核实(data-pages.js 前缀常量 L7-16 + confirmRun 调用点 ~L397/720/732/929/1007/1130 + app.js SKILL_HINT_ACCOUNT L27/confirmSaveAccount/openImportAccounts)
- 改动(commit 6cd96c9,2 files 52+/25-):
V1.0/SKILL.md:工作台章节新增第7条「AI 任务入口技能契约(P0)」(prompt=技能前缀常量 SKILL_HINT_{CREATE,EXTRACT,STORYBOARD,REVIEW,ACCOUNT}+业务正文+skills 数组;新增/修改入口先读契约文档再动手;防裸 prompt 跳步/技能声明混入业务串/BROWSER_HINT 误注入);原第7/8条顺延为8/9;关键规则「〇执行方式判定」表后补契约引用行;frontmatter last_change 更新docs/AI会话任务输入输出对照.md全面升级:新增功能入口×技能调用契约总表(8 入口的按钮/label/skills/前缀常量/prompt 边界/代码位置)+ ★新增入口检查清单 7 项 + 复盘动态分支说明;prompt 模板统一为「前缀+正文」分层结构(原 09-01 版为裸 prompt 已过时)
- 验证:源技能与用户环境 junction 同 inode(2533274790401285)自动同步 ✅
- 未 push(距上次 push 17:50 不足 2h,按节奏攒到下次同步点;下次同步点=清 tmp+push 一起执行)
AI创作弹窗 v7:需求区单列 + 提交创作确认弹窗(18:00-18:03,用户要求)
- 需求原话:「输入框中 提交创作 按钮需要确认弹窗,需求部分 一个维度一行,不要左右卡片显示」
- CSS(style.css):
.req-sheetgrid 双列(1fr 1fr)→ 单列清单式(grid-template-columns: 1fr + gap 6px);.req-field改 flex(维度名=左标签 104px + 内容右侧同行),去 min-height;empty 态保留灰字「(待定 · 由 AI 按人设自决)」;max-height 290→340 - JS(data-pages.js reqCreate 提交处理器):点击 ✓ 不再直接 executeTask → 先
await loadPersona()再弹确认弹窗(modal-mask 内层 modal:标题「确认提交创作」+ 达人名 + 「S1-S11 全流程,自动模式」说明 + 已填需求清单reqLines(n/10)+ 人设已加载/暂无 + 附件有无 + 取消/确认提交创作);点确认后才close()+ executeTask - 语法 node --check 通过;纯静态资源 no-store,服务未重启;重开
?v=20260902-v7#/accounts - git commit 未做(与 6cd96c9/c40bc22 一起攒到下次同步点)
AI创作弹窗 v8:需求区默认折叠可点击展开(18:15-18:20,用户追加要求)
- 需求原话:「需求内容部分 默认折叠」
- HTML/JS(data-pages.js):req-sheet 外包
.req-sheet-box#reqSheetBox容器 → 顶部标题按钮#reqSheetToggle(「创作需求」+ 计数#reqFilledCountn/10 已填 + 右端箭头#reqCaret)+ 内容#reqSheet;renderSheet 每次重渲染更新 filled 计数、box 切换.has-filled装饰类(filled>0 标题前亮蓝点+计数徽标变主色);sheetToggle click 切 box.open、aria-expanded 同步;默认收起 - CSS(style.css,
.req-confirm-label前插入):.req-sheet-box白底描边圆角容器;.req-sheet-toggle整行可点击(hover 标题变主色);.rst-count灰底圆角徽标 /.has-filled变 primary-soft 底主色字;箭头.rst-caret svg收起态 rotate(180deg) 朝下(提示可展开)→ open 态转 0;折叠动画.req-sheet-box .req-sheet { max-height: 0; overflow: hidden; transition: max-height .2s }→.open恢复 max-height 340 + overflow auto - 折叠用 max-height 动画(非 display none),内容 10 行需展开后内部滚动
- 语法 node --check 通过;纯静态 no-store 未重启;commit de77425(2 files 43+/1-);重开
?v=20260902-2#/accounts
AI创作弹窗 v9:去重引导文案(18:25,用户问「两段引导是否重复可否留一」)
- 重复点:顶部常驻
.req-head(输入→整理到创作需求框→✓提交创作)≈ 对话空态.req-dialog-empty(输入初步想法→即时更新需求框) - 定案:保留空态引导(含维度清单、只在首屏出现不占常驻位)、删顶部常驻 req-head;快捷键与附件格式两处独有信息补进空态文案(「也可点回形针上传需求文档(doc / docx / txt / pdf)。Enter 发送,Shift+Enter 换行。」)
- 改动:data-pages.js 删 req-head div(模板)→ dialog-empty 扩文案;style.css 删 .req-head 规则(仅 1 处引用,grep 验证零残留)
- commit e4cede2(2 files 1+/3-);重开
?v=20260902-3#/accounts
AI创作弹窗 v10:需求框收窄为选题侧 6 字段(18:35,用户定「需求区重点是选题相关,账号设定不重复输入」)
- 定案:REQ_FIELDS 10→6——删 mood 情绪基调 / aud 受众 / sym 结构性符号 / ad 广告植入(账号级,人设卡+内容规则已自动带入创作);保留 idea 一句话创意与选题 / form 叙事形态 / dur 时长目标 / plot 核心情节 / end 结尾落点 / note 其他约束(兜底)
- data-pages.js:REQ_FIELDS 数组、w 初始对象、空态引导文案(维度清单改「创意/形态/时长/情节/结尾」+ 明示「账号级设定(情绪基调/受众/植入等)已由账号设定提供,无需重复填写」)、各处注释 10→6、空值文案改「按账号设定与选题自决」
- server.js(/api/ai/clarify):模板删 4 行 → 6 行;行为要求新增第 5 条——「需求框只收集选题相关信息;账号级设定(情绪基调/目标受众/结构性符号/广告植入等)已由账号设定自动带入创作,不要向达人重复询问;仅当达人主动提出与账号设定不同的要求时记入『其他约束』」;注释 10→6
- 两端 node --check 通过;server.js 改动 → 重启服务(taskkill PID 19936 → 后台重启 task CEiCmO),clarify 接口 curl 实测 200 返回正常
- commit 3be2ff1(2 files 14+/12-);重开
?v=20260902-4#/accounts
AI创作弹窗 v11:时长改功能选项下拉 + 字段改名(18:55,用户要求)
- 需求:①「一句话创意与选题」改名「一句话创意」②时长目标移出需求栏 → 需求栏下方「功能选项」下拉(30/60/120/240/自定义)
- data-pages.js:REQ_FIELDS 6→5(idea 标签改「一句话创意」、删 dur);reqLines 末尾追加时长行
- 时长目标:${dur}(创作 prompt/确认弹窗仍含时长,reqMdOf 模板不含→AI 不再管时长);HTML 在 req-sheet-box 与 req-dialog 之间插.req-opts(标签+select 30/60/120/240/自定义+自定义秒数输入);事件:选 custom 显示秒数输入(w.dur='45秒'),选固定值写 w.dur='60秒',默认「未指定(由 AI 定)」w.dur='';确认弹窗计数改「已填 x 项,含时长选项」(避免 lines>分母 6/5) - server.js clarify 模板 6 行 → 5 行(删时长目标、idea 标签同步);注释同步
- style.css:.req-opts 白底描边圆角条(复用 .input-select)
- 两端 node --check 通过;server.js 改动 → 重启服务(taskkill 26488 → 后台 task 1lDwFM,8900:200)
- commit 17acaf1(3 files 50+/11-);重开
?v=20260902-5#/accounts
AI创作弹窗 v12:需求字段卡片化(18:30-18:32,用户两轮澄清定稿)
- 需求:维度名=卡片内小标题置左上角,内容在标题下方,卡片边框 padding 10px(用户二次澄清「标题在卡片左上角、padding 卡片边框10px、内容在卡片内标题下方」)
- style.css:
.req-field由横向(rf-title 104px 左标签 + rf-val 同行)→ flex column(rf-title 顶部小标题 + rf-val 下方,gap 4px)+ padding 10px;rf-title 去掉 width/左浮(12px 600 #5b6472);折叠展开 max-height 340→400(卡片变高) - 纯 CSS,无需重启/改 JS;commit 504c92e(1 file 7+/7-);重开
?v=20260902-6后又?v=20260902-7(用户疑似看到旧缓存页,二次说明规格)
AI创作弹窗 v13:时长选项细节(18:33-18:35,用户要求)
- ①opts 标签「时长目标」→「时长」;②默认选项「未指定(由 AI 定)」→「自动」;③修复秒数输入框 bug——
.req-dur-customCSS display:inline-flex 覆盖 hidden 属性导致输入框一直显示,补.req-dur-custom[hidden]{display:none},现仅选中「自定义…」才出现可直接输入 - reqLines 需求行标签同步「- 时长目标:」→「- 时长:」(创作 prompt 侧)
- 语法通过;commit cc59c1c(2 files 4+/3-);重开
?v=20260902-8#/accounts
AI创作弹窗 v14:空值文案改「待完善」(18:35-18:37,用户要求)
- renderSheet 空字段占位「(待定 · 由 AI 按账号设定与选题自决)」→「待完善」;确认弹窗全空兜底「(未填写 · 由 AI 按人设自决)」→「(待完善)」;弹窗注释同步
- 语法通过;commit 8c5b66d(1 file 3+/3-);重开
?v=20260902-9#/accounts
AI创作弹窗 v15:时长下拉收窄(18:36,用户要求)
.req-dur-selwidth 168→110px(紧凑适配「自定义…」最长选项);commit 12ba43c(1 file 1+/1-);重开?v=20260902-10#/accounts
AI创作弹窗 v16:空态引导精简(18:39,用户要求)
- 空态文案后半段「账号级设定(情绪基调/受众/植入等)已由账号设定提供,无需重复填写。也可点回形针上传需求文档(doc/docx/txt/pdf)」→ 一句「支持上传附件」(附件格式由纸夹按钮 title 承载)
- 现文案:输入初步想法+AI引导补齐创意/形态/情节/结尾+即时更新需求框+支持上传附件+快捷键
- commit 84d4587(1 file 1+/1-);重开
?v=20260902-11#/accounts
AI创作弹窗 v17:需求框加入落点三字段 5→8 行可空(18:40-18:44,用户定稿)
- 需求:痛点/爽点、共鸣/共情、爆点是选题重要落点要素——创作流程需要但非必填,弹窗需求表单需体现;空着可留空、由 AI 按账号设定与选题补齐
- 判断定稿:需求表单是「输入层」,S5 选题方案是「方法论层」——S5/技能定义不改,仅弹窗承载可选输入,账号级设定不重复收集
- data-pages.js:REQ_FIELDS 5→8(idea/pain/relate/blow/form/plot/end/note);w 初值补 pain/relate/blow='';空态文案加「落点要素可留空,由 AI 按账号设定与选题补齐」;计数/渲染/reqMdOf 均自动适配 REQ_FIELDS.length 无硬编码
- server.js clarify 模板 5 行 → 8 行(顺序同 REQ_FIELDS:一句话创意/痛点爽点/共鸣共情/爆点/叙事形态/核心情节/结尾落点/其他约束),注释 5行→8行;行为规则第5条不动(账号级不问询仍成立)
- style.css:需求区展开 max-height 400→560px(8 张卡约 534px 全可见,超高内部滚动兜底),基础样式同步 560
- 两端 node --check 通过;server.js 改动 → 重启服务(taskkill 7928 → 后台 task mJ80F6,PID 40264);commit fd25045(4 files 61+/10-);重开
?v=20260902-12#/accounts
AI创作弹窗 v18:叙事形态→叙事结构 + 删情节/结尾 8→6 行(18:45-18:50,用户要求)
- 需求:①「叙事形态」改「叙事结构」②「核心情节」「结尾落点」两字段删掉(情节与结尾靠 AI 创作自决)
- data-pages.js:REQ_FIELDS 8→6(idea/pain/relate/blow/form(叙事结构)/note);w 初值删 plot/end;注释/空态同步(空态文案补「情节与结尾由 AI 创作」)
- server.js clarify 模板 8 行 → 6 行(同步删情节/结尾、形态改结构),提示补「情节/结尾/时长不由本清单承载,由创作阶段按人设与选题自决」;655 注释 v17 漏改「5行」→ 现改「6行」
- 红线确认:data-pages.js 42/787/996 行「结尾落点」为解析侧视频选题 9 维度描述(AI 写脚本/改写 prompt 引用视频解析内容),非需求字段,保留不动
- 踩坑:6 个 Edit 并行发同文件 → 读写竞态部分丢失(221 w 初值生效、REQ_FIELDS/注释未生效),改逐个串行重做后才全生效——同文件多 Edit 必须串行(下次先做数据改动再做注释类,全部串行)
- 语法通过;commit f45eb4a(2 files 9+/8-);重启(taskkill 40264 → task yKSlmD,PID 38732,HTTP 200);重开
?v=20260902-13#/accounts
AI创作弹窗 v19:爆点改名「创新 / 爆点」+ 移到一句话创意后(18:50-18:55,用户要求)
- 需求:①blow 字段标签「爆点」→「创新 / 爆点」②字段序调整:一句话创意 → 创新/爆点 → 痛点爽点 → 共鸣共情 → 叙事结构 → 其他约束
- data-pages.js:REQ_FIELDS 行序调整(blow 移至 idea 后、标签改名,key 仍 blow);顶部注释/空态文案同步新顺序与名称
- server.js clarify 模板同步(
- 创新 / 爆点:置于一句话创意后) - 标签含空格(「创新 / 爆点」)与「痛点/爽点」无空格风格并存——按用户字面执行,未擅自统一
- 语法通过;commit 6602b8d(2 files 5+/4-);重启(taskkill 38732 → task 35LCPh,PID 17016,HTTP 200);重开
?v=20260902-14#/accounts
AI创作弹窗 v20:删「共鸣/共情」字段 6→5 行,共鸣由 AI 依痛点爽点发挥(18:52-18:58,用户要求)
- 需求:共鸣/共情也从需求表单去掉——共鸣属创作发挥层,AI 根据痛点/爽点落点要素自然生成,无需用户单独填写
- data-pages.js:REQ_FIELDS 6→5(删 relate;idea→blow→pain→form→note);w 初值删 relate;空态/注释同步(「共鸣与情节结尾由 AI 依痛点爽点发挥」)
- server.js clarify 模板同步 5 行 + 707 提示补「共鸣/共情不收集,创作时由 AI 依痛点/爽点自然发挥」;655 注释 6行→5行
- 不动项:data-pages.js 1134/1232/1312 复盘评分维度「共鸣和共情」=mcn-script-review 复盘结构维度,非需求表单字段
- 语法通过;commit d31261e(2 files 9+/8-);重启(taskkill 17016 → task hAWaIV,PID 29820,HTTP 200);重开
?v=20260902-15#/accounts - 需求表单定稿轨迹:v11 5 字段 → v17 8 → v18 6 → v19 顺序调整 → v20 5 行(一句话创意/创新爆点/痛点爽点/叙事结构/其他约束)
MCN工作台 AI创作弹窗 v21:展开需求区挤出输入条修复(18:55-19:00,用户报 bug)
- 现象:点「创作需求」展开按钮后内容区过长,把底部输入框挤出弹窗
- 根因:v17 为 8 卡把
.req-sheet展开 max-height 提到 560px,v20 回 5 卡未回缩;窗口 92vh 较矮时 560+对话区 min130+输入条 超弹窗总高,输入条 flex:none 固定底 → 挤出;modal 无 overflow 约束 - 修复(style.css 4 处,纯 CSS 免重启):①展开上限 560→
min(44vh,400px)(5 空卡约 330 全显、超高内滚、矮窗口自动让位)②.req-dialogmin-height 130→60 腾弹性 ③.req-modal加overflow:hidden防残余溢出 - commit d5a83c4(1 file 4+/3-);重开
?v=20260902-16#/accounts
MCN工作台 v22:账号列表去地区列 + AI脚本列(数量跳转)(18:57-19:05,用户要求)
- 需求:①账号列表去掉「地区」列 ②操作列左侧加「AI脚本」列——展示该账号 AI 脚本数量,点击跳转 AI写脚本页并查看该账号下脚本
- dsh-data.js listAccounts:SELECT 加
rewrite_count子查询(口径同视频页:rewrite_log WHERE account_id=h.id AND status='done' AND script_text IS NOT NULL AND !='');实测:俊希 12/旧梦留声机 7/胡德禄 4/王微斯 3/张天琪等 0 - data-pages.js renderAccounts:删地区 td+th;操作列左加「AI脚本」td(>0 显示
<a href="#/rewrites/{encodeURIComponent(账号名)}">N</a>,0 显示 —);空行 colspan 13/12→12/11 - 跳转筛选链路:
#/rewrites/<账号名>→ parseHash param → app.jsrenderRewrites(view, param)→ state.search 初值=账号名(videos API search 已支持 account_name LIKE)+ toolbar-note 显示「正在查看账号「xx」…」上下文 - rewrites 页语义:本质=视频列表页(每视频行有 AI脚本 N 查看→对比弹窗),按账号预筛即列出该账号全部视频及其脚本入口
- 语法 4 文件通过;commit 5881610(3 files 10+/8-);重启(taskkill 29820 → task y70huy,PID 8528);接口实测 rewrite_count 正常;重开
?v=20260902-17#/accounts - v22-fix(自检发现):hash 路径段 param 未 decode——
#/rewrites/%E4%BF%8A...中文账号名编码串进搜索匹配不到;renderRewrites 开头补decodeURIComponent(initAccount)(try/catch 防坏 URI);纯前端 commit7cfe9c6免重启
MCN工作台 v23:账号列表 AI脚本列改按钮展示(用户要求)
- 需求:AI脚本列有数据时不要纯文本链接,改成按钮样式,方便点击
- data-pages.js renderAccounts 行 td:
<a class="link">N</a>→<a class="btn btn-sm btn-view">N 条</a>(复用 btn-view 白底主色描边、hover 主色软背景;btn-sm 与操作列「AI创作」同尺寸,视觉统一;文案带「条」明示可点数量) - 纯前端 commit
6fc4c1a免重启;语法通过;重开?v=20260902-18#/accounts(顺带人工验证 v22-fix:点俊希 12 条按钮应跳到 rewrites 且搜索预填「俊希」)
MCN工作台 v24:痛点标签加空格 + AI写脚本默认近三个月(用户要求)
- 需求:①「痛点/爽点」字段标签 → 「痛点 / 爽点」(斜杠两侧加空格)②AI写脚本 列表默认展示近三个月(原近一个月)
- 改动 3 处:data-pages.js REQ_FIELDS pain label
'痛点/爽点'→'痛点 / 爽点'(parseReqSheet/reqMdOf 均 label 驱动,自动一致);data-pages.js renderRewritesdays:'30'→'90'(下拉已有近三个月=90 选项,后端 listVideos 任意数值透传-${n} days);server.js clarify prompt 模板行 + 707 叙述句同步痛点 / 爽点 - 坑(Git Bash taskkill):
taskkill //PID 8528 //F在 Git Bash 报「无效参数/选项 - '//PID'」→ 旧进程没杀掉,新 node 发现 8900 被占退避 8901,8900 上仍是旧代码!改用 PowerShellStop-Process -Id X -Force双杀 8528+25320 后重启成功(新 PID 15148)。教训:Windows 杀 node 进程一律用 PowerShell Stop-Process,勿用 Git Bash taskkill // 语法 - 注释行 174/177(v17/v20 历史记录)保留旧写法不失真;commit 8443af1;重开
?v=20260902-19#/rewrites
MCN工作台 v25:AI写脚本页三 tab 脚本中心 + UI 创作写库闭环(用户方案「2 先执行」)
- 背景根因:UI 发起的 AI创作(账号列表弹窗/视频行)prompt 无写库指令 → 脚本只落会话/产出目录,从未进 rewrite_log(库内 26 条全为带写库提示的 batch 脚本);账号列表「AI脚本」N 条跳 rewrites 看不到自定义选题脚本(video_id 空行不被视频列表承载)
- 用户方案定稿:AI写脚本 列表页分三 tab——【参考选题创作】(有原视频 video_id>0)/【自定义选题创作】(无原视频 video_id 空,账号弹窗创作)/【ABC融合创作(功能待实现,占位)】
- 后端(已全量):dsh-data.js 新增 listCustomScripts(video 空+done+非空 text,search=title/account/topic,account 精确过滤)/ getCustomScript(id 拉全文,拒绝 video_id 行)/ saveScript(可写 DatabaseSync 独立连接,videoId>0→video_id 否则 NULL,datetime localtime)/ getRewriteStats(徽标计数:videoScripts vs customScripts,按 account 可选);server.js 路由 custom-scripts / custom-script / script-save(POST) / rewrite-stats;module.exports 全导出
- 前端(tab 化重构 renderRewrites,data-pages.js ~943 行整体 Python 拼接替换,保留嵌套 openRewriteCompare):state={tab,scope,ref:{search/parsed/days=90/page/batch},custom:{search/days/page},stats};tab 徽标=state.stats 计数(口径与账号列表 AI脚本 列一致);账号级进入(#/rewrites/账号名)时若 customScripts>0 → 默认落自定义 tab,否则参考 tab;自定义 tab 行=账号/标题/字数/创建时间/查看(openCustomScriptView 全文弹窗:GET custom-script?id,md 渲染+复制全文);chip×清除账号筛选回全局(scope/ref.search 清空→reloadAll 重算徽标);ABC tab=empty-state 占位;note/accChip 必须放 load() 内每次渲染重算(顶层 const 只在函数首次执行取值,tab 切换不更新——已修复)
- 写库闭环:saveHintOf(ctx)(data-pages.js 顶部常量)追加进所有 UI 创作 prompt 尾——参考选题=saveHintOf({videoId,awemeId,accountId})(rewrites ref 行 data-rewrite 补 aweme 字段);自定义=saveHintOf({accountId});指令=任务完成后 fetch POST /api/dsh/script-save JSON.stringify(明确不手拼 JSON、失败重试一次),agent 勿猜库路径
- 自检实录:POST save(accountId 1629 旧梦留声机)→ ok:true id=38 → custom-scripts?account=旧梦留声机 total=1 → custom-script?id=38 全文 ok → rewrite-stats 26/1 → node DatabaseSync DELETE id=38 清理 → 26/0。既有库中 26 条全部 video_id>0=有源(custom=0 符合「UI 从未入库」根因)
- commit 待执行;重启(PowerShell Stop-Process 杀 8900 → 后台 node server.js 新进程);前端静态文件改动免重启(no-store),重开页面必须带 ?v=20260902-2X 版本参数