@@ -186,6 +186,7 @@ export async function run(
186186
187187 // Resume: 计算 skipStepIds + 兼容旧 output 变量名
188188 let skipStepIds : Set < string > | undefined ;
189+ let restoredStepMeta : Map < string , Partial < import ( './types.js' ) . StepResult > > | undefined ;
189190
190191 if ( resumeDir ) {
191192 // 兼容变量重命名:如果旧 metadata 的 output_var 和新 YAML 的 output 不同,
@@ -204,6 +205,14 @@ export async function run(
204205
205206 skipStepIds = computeResumeSkipIds ( dag , getCompletedStepIds ( resumeDir ) , fromStep ) ;
206207
208+ // 被复用步骤的展示字段(角色名/验收标准/核验结果)从旧档案带回新档案,
209+ // 否则续跑产生的 metadata 里这些步骤全是裸 id、验收记录凭空消失
210+ restoredStepMeta = new Map (
211+ ( metadata . steps as import ( './types.js' ) . StepResult [ ] )
212+ . filter ( s => s . status === 'completed' )
213+ . map ( s => [ s . id , { agentName : s . agentName , agentEmoji : s . agentEmoji , acceptance : s . acceptance , verification : s . verification } ] )
214+ ) ;
215+
207216 if ( ! options ?. quiet ) {
208217 console . log ( ` 恢复自: ${ resumeDir } ` ) ;
209218 console . log ( ` 跳过已完成步骤: ${ skipStepIds . size } 个` ) ;
@@ -272,6 +281,7 @@ export async function run(
272281 // 或终端 Ctrl-C 的 run 会无痕消失,历史里无法「继续运行」。
273282 const partialSteps : import ( './types.js' ) . StepResult [ ] = [ ] ;
274283 const runStartedAt = Date . now ( ) ;
284+ let flushHandler : ( ( signal : NodeJS . Signals ) => void ) | undefined ;
275285 if ( options ?. signalFlush ) {
276286 const flushAndExit = ( signal : NodeJS . Signals ) => {
277287 try {
@@ -309,7 +319,7 @@ export async function run(
309319 } catch { /* 落盘失败也必须退出 */ }
310320 process . exit ( signal === 'SIGINT' ? 130 : 143 ) ;
311321 } ;
312- // once:触发即自动移除;CLI 进程一次只跑一个工作流,正常结束后进程随即退出,无泄漏面
322+ flushHandler = flushAndExit ;
313323 process . once ( 'SIGTERM' , flushAndExit ) ;
314324 process . once ( 'SIGINT' , flushAndExit ) ;
315325 }
@@ -321,6 +331,7 @@ export async function run(
321331 concurrency : workflow . concurrency || 2 ,
322332 inputs : inputMap ,
323333 skipStepIds,
334+ restoredStepMeta,
324335 feedback : feedbackOption ,
325336 verify : options ?. verify ?? workflow . verify ?? true ,
326337 stepResultsSink : partialSteps ,
@@ -347,6 +358,13 @@ export async function run(
347358 } ,
348359 } satisfies ExecutorOptions ) ;
349360
361+ // 工作流跑完立即摘除信号监听:本次运行即将正常存档,此后(--materialize/--export
362+ // 等收尾期)的 Ctrl-C 不能再把已成功的运行二次存档成"被中断"的重复档案
363+ if ( flushHandler ) {
364+ process . removeListener ( 'SIGTERM' , flushHandler ) ;
365+ process . removeListener ( 'SIGINT' , flushHandler ) ;
366+ }
367+
350368 result . name = workflow . name ;
351369 // 源文件绝对路径随 metadata 存档——历史记录的"重跑/从某步续跑"靠它定位工作流
352370 result . file = resolve ( workflowPath ) ;
@@ -386,6 +404,10 @@ export async function compareWorkflowVsBaseline(
386404 genOverride ?: Partial < import ( './types.js' ) . LLMConfig > ;
387405 /** 评审模型(建议强模型);不传退回生成模型 */
388406 judgeLlm ?: import ( './types.js' ) . LLMConfig ;
407+ /** acceptance 自动核验开关,透传给内部 run()(CLI --verify/--no-verify 在 compare 模式同样生效) */
408+ verify ?: boolean ;
409+ /** SIGTERM/SIGINT 优雅存档,透传给内部 run()(仅 CLI 进程开;web in-process 调用勿开) */
410+ signalFlush ?: boolean ;
389411 } ,
390412) : Promise < {
391413 multiOutput : string ;
@@ -404,6 +426,8 @@ export async function compareWorkflowVsBaseline(
404426 quiet : options ?. quiet ?? true ,
405427 outputDir : options ?. outputDir ,
406428 llmOverride : options ?. genOverride ,
429+ verify : options ?. verify ,
430+ signalFlush : options ?. signalFlush ,
407431 } ) ;
408432 const multiOutput = finalOutput ( result ) ;
409433
0 commit comments