dsh-vibe-math 2.8.0 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2998,6 +2998,34 @@ try { ok = await wakeResident(r, await heartbeatPrompt(r), 'normal') } catch(e){
2998
2998
  return await writeText(norm,content)
2999
2999
  }
3000
3000
  function paperLog(line){ const ps=paperState; if(ps) ps.log.push(fmtTime()+'|'+String(line)) }
3001
+ /**
3002
+ * Compile-outcome note (docs/final-paper.md §D). The paper body is COMPOSED before compilation runs, so
3003
+ * the spec's two conditional bullets in §7 can only fire on a re-entry (where the persisted meta already
3004
+ * carries `compile`). State the outcome in the artifacts the user actually reads instead - ONCE and
3005
+ * idempotently, because finalize can be re-entered. The note text is the SAME string as those bullets, so
3006
+ * the bullet path and this path can never both add it.
3007
+ */
3008
+ async function paperAnnotateCompileOutcome(ps){
3009
+ const res=ps.compile&&ps.compile.result
3010
+ if(res!=='failed'&&res!=='not-detected') return
3011
+ const zh=ps.cfg.language!=='en'
3012
+ const note=res==='failed'
3013
+ ? (zh?'PDF 编译失败:已保留 paper.tex 与 paper.md 并上报':'PDF compilation failed: paper.tex and paper.md were kept and reported')
3014
+ : (zh?'本机未检测到 LaTeX 引擎:只产出 tex+md':'No LaTeX engine detected: tex+md only')
3015
+ if(ps.files.indexOf('paper.md')!==-1){
3016
+ const md=await readText(ps.dir+'/paper.md')
3017
+ if(typeof md==='string'&&md.indexOf(note)===-1) await paperWriteRel(ps.dir+'/paper.md',md.replace(/\s*$/,'')+'\n- '+note+'\n')
3018
+ }
3019
+ if(ps.files.indexOf('paper.tex')!==-1){
3020
+ const tex=await readText(ps.dir+'/paper.tex')
3021
+ if(typeof tex==='string'&&tex.indexOf(note)===-1){
3022
+ const line='% '+note
3023
+ await paperWriteRel(ps.dir+'/paper.tex',tex.indexOf('\\end{document}')!==-1
3024
+ ?tex.replace('\\end{document}',line+'\n\\end{document}')
3025
+ :tex.replace(/\s*$/,'')+'\n'+line+'\n')
3026
+ }
3027
+ }
3028
+ }
3001
3029
  function paperStepLimit(){ return Math.max(PAPER_WAIT_FLOOR_MS, recoverStallMs()*4) }
3002
3030
  function paperCfg(ov){
3003
3031
  const o=ov||{}
@@ -3543,6 +3571,8 @@ try { ok = await wakeResident(r, await heartbeatPrompt(r), 'normal') } catch(e){
3543
3571
  if(ps.cfg.format!=='md'){ if(await paperWriteRel(ps.dir+'/paper.tex',composed.tex)) ps.files.push('paper.tex') }
3544
3572
  ps.compile=await paperCompile(ps,composed,ev)
3545
3573
  if(ps.compile&&ps.compile.result==='ok') ps.files.push('paper.pdf')
3574
+ // The body was composed just above, BEFORE this compile ran, so the outcome is stated HERE (idempotent).
3575
+ await paperAnnotateCompileOutcome(ps)
3546
3576
  ps.finalizedAt=now(); ps.status='done'
3547
3577
  await paperWriteMeta(); await paperWriteLog()
3548
3578
  await paperWriteMeta(); await paperWriteLog()