配置收敛:
- 端口/DB名/产出根/榜单目录单源化到 mcn-work-shop/config.json,代码层统一经 load-config.js 读取
- 新增 get-port.js 供 start.bat 读端口(bat 内嵌 node -e 会被 cmd 截断,读到的是兜底值)
- start.bat 修复失效的 managed node 路径(原写死 22.22.2 已不存在),改为遍历 versions 自动探测
复盘诊断页(真 bug 修复):
- 问题清单严重度全部显示成绿色 + 修改建议不显示:模型输出 {sev:'high',fix} 与前端读取 {severity:'高',suggestion} 字段名与取值均不匹配
- 前端新增 normIssue 归一化,兼容 sev/severity/level 与中英取值,并回补所属维度显示
- 在 submit-review-tasks 与诊断/复盘 prompt 中固化 issues_json 字段契约,从源头防 schema 漂移
分镜提示词:
- 原创选题(video_id 为空)原本无生成入口(分镜按 video_id 查询)
- listStoryboards 支持按 rewrite_id 查询,前端放开入口、切版本重查,并补落库指令(此前入库靠模型自由发挥)
榜单展示:
- 期号改为显示区间「08/31 ~ 09/06」,避免被误读为单日(期号=该周周一)
- 后端新增 collectRanges,从落盘文件读真实 dateStart/dateEnd 随 API 返回(日榜 start=end 不显区间)
其他:
- 清理 dsh 环境废弃后的历史叙述类废话(16 文件约 18 处),文末变更记录区保留
- 新增 docs/工作台UI规范.md(设计 token / 布局 / 8 页面路由 / 12 类组件 / 9 条已知坑)
44 lines
1.6 KiB
JavaScript
44 lines
1.6 KiB
JavaScript
/* poll-review-tasks.cjs — 轮询 6 条复盘任务(/api/run/status,ACCEPTED 已归 done)*/
|
||
const TASKS = [
|
||
{ rw: 31, id: 'automation-1788251452496' },
|
||
{ rw: 30, id: 'automation-1788251455526' },
|
||
{ rw: 29, id: 'automation-1788251458549' },
|
||
{ rw: 28, id: 'automation-1788251461578' },
|
||
{ rw: 27, id: 'automation-1788251464600' },
|
||
{ rw: 26, id: 'automation-1788251467630' },
|
||
];
|
||
const { loadConfig } = require('./load-config');
|
||
const CFG = loadConfig();
|
||
const API = `http://localhost:${CFG.port}/api/run/status?id=`;
|
||
const state = {};
|
||
TASKS.forEach((t) => (state[t.rw] = 'pending'));
|
||
const status = async (id) => {
|
||
try {
|
||
const r = await fetch(API + encodeURIComponent(id));
|
||
const d = await r.json();
|
||
return d.state || 'unknown';
|
||
} catch { return 'unknown'; }
|
||
};
|
||
console.log('START polling 6 review tasks:', new Date().toLocaleTimeString('zh-CN'));
|
||
(async () => {
|
||
const started = Date.now();
|
||
while (Date.now() - started < 60 * 60 * 1000) {
|
||
let allDone = true;
|
||
for (const t of TASKS) {
|
||
const s = await status(t.id);
|
||
state[t.rw] = s;
|
||
if (s !== 'done' && s !== 'error') allDone = false;
|
||
}
|
||
console.log(new Date().toLocaleTimeString('zh-CN'), '|',
|
||
TASKS.map((t) => 'rw' + t.rw + ':' + state[t.rw]).join(' '));
|
||
if (allDone) {
|
||
const errs = TASKS.filter((t) => state[t.rw] === 'error');
|
||
console.log(errs.length ? 'ALL DONE (with errors): ' + errs.map((t) => 'rw' + t.rw).join(',') : 'ALL DONE ✓');
|
||
process.exit(0);
|
||
}
|
||
await new Promise((r) => setTimeout(r, 30000));
|
||
}
|
||
console.log('TIMEOUT after 60min, last states:', JSON.stringify(state));
|
||
process.exit(1);
|
||
})();
|