@@ -5,7 +5,13 @@ import { createAppShell } from "./shell/index";
55import { withTestRenderer } from "./harness" ;
66import type { PendingAskWake } from "../subagent/fleet-report.js" ;
77import { classifySubmission , createSubmitHandler } from "./runner/submit.js" ;
8- import { routeQueuedDelivery } from "./queued-delivery.js" ;
8+ import {
9+ createDeliveryGeneration ,
10+ createLeftoverSend ,
11+ routeQueuedDelivery ,
12+ } from "./queued-delivery.js" ;
13+ import { createSessionOperationQueue } from "./session-operation-queue.js" ;
14+ import { ingestOperatorPrompt } from "./prompt-attachments.js" ;
915import {
1016 armFeedbackCapture ,
1117 cancelFeedbackCapture ,
@@ -482,4 +488,84 @@ describe("agent ask wake delivery", () => {
482488 { width : 80 , height : 24 } ,
483489 ) ;
484490 } ) ;
491+
492+ test ( "idle leftover wake keeps an @path in the question raw and consumes the echo" , async ( ) => {
493+ await withTestRenderer (
494+ async ( h ) => {
495+ const shell = createAppShell ( h . renderer , {
496+ terminal : { columns : 80 , rows : 24 } ,
497+ wireKeys : false ,
498+ run : "idle" ,
499+ } ) ;
500+ const sent : string [ ] = [ ] ;
501+ const attachments : number [ ] = [ ] ;
502+ const ingested : string [ ] = [ ] ;
503+ const queue = createSessionOperationQueue ( ) ;
504+ const leftoverSend = createLeftoverSend ( {
505+ enqueue : queue . enqueue ,
506+ ingest : async ( text , pending ) => {
507+ ingested . push ( text ) ;
508+ return ingestOperatorPrompt (
509+ text ,
510+ "/repo" ,
511+ async ( ) => {
512+ throw new Error ( "wake leftover must not load image paths" ) ;
513+ } ,
514+ pending ,
515+ ) ;
516+ } ,
517+ send : ( text , pending ) => {
518+ sent . push ( text ) ;
519+ attachments . push ( pending . length ) ;
520+ } ,
521+ captureGeneration : createDeliveryGeneration ( ) . capture ,
522+ onFailure : ( error ) => {
523+ throw error ;
524+ } ,
525+ } ) ;
526+ const send = ( text : string ) => {
527+ leftoverSend ( text ) ;
528+ } ;
529+ const bridge = attachSessionBridge (
530+ shell ,
531+ createLiveSessionPort ( {
532+ send,
533+ deliver : routeQueuedDelivery ( {
534+ send,
535+ deliverSteer : ( ) => {
536+ throw new Error ( "wake must not live-inject" ) ;
537+ } ,
538+ parentCycleLive : ( ) => bridge . parentCycleLive ,
539+ } ) ,
540+ interrupt : ( ) => { } ,
541+ } ) ,
542+ ) ;
543+ try {
544+ const ask = {
545+ ...wake ( "a1" , "q1" ) ,
546+ question : "Should I edit @src/foo.ts?" ,
547+ } ;
548+ bridge . handle ( { type : "agent-ask" , asks : [ ask ] } ) ;
549+ await queue . awaitTail ( ) ;
550+ expect ( sent ) . toHaveLength ( 1 ) ;
551+ const wakeText = sent [ 0 ] ;
552+ if ( wakeText === undefined ) throw new Error ( "expected wake text" ) ;
553+ expect ( wakeText ) . toContain ( "@src/foo.ts" ) ;
554+ expect ( wakeText ) . not . toContain ( "(not found)" ) ;
555+ expect ( attachments ) . toEqual ( [ 0 ] ) ;
556+ expect ( ingested ) . toEqual ( [ ] ) ;
557+ expect ( shell . streamLog . filter ( ( row ) => row . role === "user" ) ) . toHaveLength ( 1 ) ;
558+ bridge . handle ( {
559+ type : "message.received" ,
560+ data : { message : { content : wakeText } } ,
561+ } ) ;
562+ expect ( shell . streamLog . filter ( ( row ) => row . role === "user" ) ) . toHaveLength ( 1 ) ;
563+ } finally {
564+ bridge . dispose ( ) ;
565+ shell . dispose ( ) ;
566+ }
567+ } ,
568+ { width : 80 , height : 24 } ,
569+ ) ;
570+ } ) ;
485571} ) ;
0 commit comments