@volter/supercode-terminal 0.2.54 → 0.2.55

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.
Files changed (2) hide show
  1. package/index.mjs +13 -8
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -1793,10 +1793,15 @@ function composerMatches(value, wanted) {
1793
1793
 
1794
1794
  /** Busy evidence must come from the live UI bottom, not a fleet label or a
1795
1795
  * quoted phrase in the transcript. */
1796
- function composerBusy(screen) {
1797
- const bottom=String(screen??'').split('\n').map(line=>styledCells(line).map(cell=>cell.char).join('')).filter(line=>line.trim()).slice(-8).join('\n');
1798
- return /\b(?:esc to (?:interrupt|cancel)|tab to queue (?:a )?message)\b/iu.test(bottom);
1796
+ function composerBusyEvidence(screen) {
1797
+ const bottom=String(screen??'').split('\n').map(line=>styledCells(line).map(cell=>cell.char).join('')).filter(line=>line.trim()).slice(-8);
1798
+ for (const row of bottom) {
1799
+ const match=/\b(?:esc to (?:interrupt|cancel)|tab to queue (?:a )?message)\b/iu.exec(row);
1800
+ if (match) return { indicator: match[0], row: row.trim().slice(0, 240) };
1801
+ }
1802
+ return null;
1799
1803
  }
1804
+ function composerBusy(screen) { return composerBusyEvidence(screen) !== null; }
1800
1805
 
1801
1806
  /** Undo only text this input wrote, including when a turn started meanwhile.
1802
1807
  * Never Enter, Escape, or Ctrl-C: restoration must not submit or stop work. */
@@ -1831,18 +1836,18 @@ export async function deliverComposerInput(host, sessionId, kind, text, { deadli
1831
1836
  const read=async()=>composerText(kind,await capture(),{allowBusy:true});
1832
1837
  const expired=()=>signal?.aborted||Date.now()>=deadlineMs;
1833
1838
  let touched=false;
1834
- const failed=async reason=>{
1835
- if(!touched)return {delivered:false,reason};
1839
+ const failed=async (reason, evidence={})=>{
1840
+ if(!touched)return {delivered:false,reason,...evidence};
1836
1841
  let restored;
1837
1842
  try{restored=await restoreComposerInput(host,sessionId,kind,text);}catch(error){restored={restored:false,reason:error.message};}
1838
- return {delivered:false,reason,restored:restored.restored,cleanup_required:!restored.restored,cleanup_reason:restored.reason,cleanup_remaining:restored.remaining};
1843
+ return {delivered:false,reason,...evidence,restored:restored.restored,cleanup_required:!restored.restored,cleanup_reason:restored.reason,cleanup_remaining:restored.remaining};
1839
1844
  };
1840
1845
  if(expired())return failed('deadline');
1841
1846
  const wanted=String(text).trim();
1842
1847
  if(!wanted||/[\x00-\x08\x0b-\x1f\x7f]/u.test(text))return failed('unsupported-text');
1843
1848
  for(let check=0;check<2;check++) {
1844
1849
  const screen=await capture(),before=composerText(kind,screen);
1845
- if(composerBusy(screen))return failed('busy-composer');
1850
+ if(composerBusy(screen))return failed('busy-composer',{phase:'before-paste',busy:composerBusyEvidence(screen)});
1846
1851
  if(before!=='')return failed(before===null?'no-composer':'draft');
1847
1852
  if(check===0)await sleep(200);
1848
1853
  }
@@ -1859,7 +1864,7 @@ export async function deliverComposerInput(host, sessionId, kind, text, { deadli
1859
1864
  for(let attempt=0;attempt<3;attempt++) {
1860
1865
  if(expired())return failed('deadline');
1861
1866
  const screen=await capture();
1862
- if(composerBusy(screen))return failed('busy-composer');
1867
+ if(composerBusy(screen))return failed('busy-composer',{phase:'before-submit',busy:composerBusyEvidence(screen)});
1863
1868
  if(!composerMatches(composerText(kind,screen),wanted))return failed('composer-changed');
1864
1869
  if(expired())return failed('deadline');
1865
1870
  await host.sendInput(sessionId,'\r',{submitMode:'single',deadlineMs});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-terminal",
3
- "version": "0.2.54",
3
+ "version": "0.2.55",
4
4
  "type": "module",
5
5
  "description": "Optional leak-safe terminal and tmux host adapter for Volter Harness frontends",
6
6
  "exports": {