@@ -20,7 +20,7 @@ function initGitRepo(projectPath: string): void {
2020 execSync ( "git init -b main" , { cwd : projectPath , stdio : "ignore" } ) ;
2121 execSync ( 'git config user.email "test@example.com"' , { cwd : projectPath , stdio : "ignore" } ) ;
2222 execSync ( 'git config user.name "test"' , { cwd : projectPath , stdio : "ignore" } ) ;
23- execSync ( ' bash -lc \ 'echo \"hello\" > README.md\'' , { cwd : projectPath , stdio : "ignore" } ) ;
23+ execSync ( " bash -lc 'echo \"hello\" > README.md'" , { cwd : projectPath , stdio : "ignore" } ) ;
2424 execSync ( "git add README.md" , { cwd : projectPath , stdio : "ignore" } ) ;
2525 execSync ( 'git commit -m "init"' , { cwd : projectPath , stdio : "ignore" } ) ;
2626}
@@ -45,17 +45,15 @@ describe("TaskService", () => {
4545 await fsPromises . rm ( rootDir , { recursive : true , force : true } ) ;
4646 } ) ;
4747
48- test (
49- "enforces maxTaskNestingDepth" ,
50- async ( ) => {
48+ test ( "enforces maxTaskNestingDepth" , async ( ) => {
5149 const config = new Config ( rootDir ) ;
5250 await fsPromises . mkdir ( config . srcDir , { recursive : true } ) ;
5351
5452 // Deterministic IDs for workspace names.
5553 const ids = [ "aaaaaaaaaa" , "bbbbbbbbbb" , "cccccccccc" ] ;
5654 let nextIdIndex = 0 ;
57- // eslint-disable-next-line @typescript-eslint/no-explicit-any
58- ( config as any ) . generateStableId = ( ) => ids [ nextIdIndex ++ ] ?? "dddddddddd" ;
55+ const configWithStableId = config as unknown as { generateStableId : ( ) => string } ;
56+ configWithStableId . generateStableId = ( ) => ids [ nextIdIndex ++ ] ?? "dddddddddd" ;
5957
6058 const projectPath = path . join ( rootDir , "repo" ) ;
6159 await fsPromises . mkdir ( projectPath , { recursive : true } ) ;
@@ -104,30 +102,27 @@ describe("TaskService", () => {
104102
105103 const aiService : AIService = {
106104 isStreaming : mock ( ( ) => false ) ,
107- getWorkspaceMetadata : mock ( async ( workspaceId : string ) : Promise < Result < WorkspaceMetadata > > => {
108- const all = await config . getAllWorkspaceMetadata ( ) ;
109- const found = all . find ( ( m ) => m . id === workspaceId ) ;
110- return found ? Ok ( found ) : Err ( "not found" ) ;
111- } ) ,
112- // eslint-disable-next-line @typescript-eslint/no-empty-function
113- on : mock ( ( ) => { } ) ,
114- // eslint-disable-next-line @typescript-eslint/no-empty-function
115- off : mock ( ( ) => { } ) ,
105+ getWorkspaceMetadata : mock (
106+ async ( workspaceId : string ) : Promise < Result < WorkspaceMetadata > > => {
107+ const all = await config . getAllWorkspaceMetadata ( ) ;
108+ const found = all . find ( ( m ) => m . id === workspaceId ) ;
109+ return found ? Ok ( found ) : Err ( "not found" ) ;
110+ }
111+ ) ,
112+ on : mock ( ( ) => undefined ) ,
113+ off : mock ( ( ) => undefined ) ,
116114 } as unknown as AIService ;
117115
118116 const workspaceService : WorkspaceService = {
119117 sendMessage : mock ( ( ) => Promise . resolve ( Ok ( undefined ) ) ) ,
120118 resumeStream : mock ( ( ) => Promise . resolve ( Ok ( undefined ) ) ) ,
121119 remove : mock ( ( ) => Promise . resolve ( Ok ( undefined ) ) ) ,
122- // eslint-disable-next-line @typescript-eslint/no-empty-function
123120 emit : mock ( ( ) => true ) ,
124121 } as unknown as WorkspaceService ;
125122
126123 const initStateManager : InitStateManager = {
127- // eslint-disable-next-line @typescript-eslint/no-empty-function
128- startInit : mock ( ( ) => { } ) ,
129- // eslint-disable-next-line @typescript-eslint/no-empty-function
130- appendOutput : mock ( ( ) => { } ) ,
124+ startInit : mock ( ( ) => undefined ) ,
125+ appendOutput : mock ( ( ) => undefined ) ,
131126 endInit : mock ( ( ) => Promise . resolve ( ) ) ,
132127 } as unknown as InitStateManager ;
133128
@@ -159,20 +154,16 @@ describe("TaskService", () => {
159154 if ( ! second . success ) {
160155 expect ( second . error ) . toContain ( "maxTaskNestingDepth" ) ;
161156 }
162- } ,
163- 20_000
164- ) ;
157+ } , 20_000 ) ;
165158
166- test (
167- "queues tasks when maxParallelAgentTasks is reached and starts them when a slot frees" ,
168- async ( ) => {
159+ test ( "queues tasks when maxParallelAgentTasks is reached and starts them when a slot frees" , async ( ) => {
169160 const config = new Config ( rootDir ) ;
170161 await fsPromises . mkdir ( config . srcDir , { recursive : true } ) ;
171162
172163 const ids = [ "aaaaaaaaaa" , "bbbbbbbbbb" , "cccccccccc" , "dddddddddd" ] ;
173164 let nextIdIndex = 0 ;
174- // eslint-disable-next-line @typescript-eslint/no-explicit-any
175- ( config as any ) . generateStableId = ( ) => ids [ nextIdIndex ++ ] ?? "eeeeeeeeee" ;
165+ const configWithStableId = config as unknown as { generateStableId : ( ) => string } ;
166+ configWithStableId . generateStableId = ( ) => ids [ nextIdIndex ++ ] ?? "eeeeeeeeee" ;
176167
177168 const projectPath = path . join ( rootDir , "repo" ) ;
178169 await fsPromises . mkdir ( projectPath , { recursive : true } ) ;
@@ -234,15 +225,15 @@ describe("TaskService", () => {
234225
235226 const aiService : AIService = {
236227 isStreaming : mock ( ( ) => false ) ,
237- getWorkspaceMetadata : mock ( async ( workspaceId : string ) : Promise < Result < WorkspaceMetadata > > => {
238- const all = await config . getAllWorkspaceMetadata ( ) ;
239- const found = all . find ( ( m ) => m . id === workspaceId ) ;
240- return found ? Ok ( found ) : Err ( "not found" ) ;
241- } ) ,
242- // eslint-disable-next-line @typescript-eslint/no-empty-function
243- on : mock ( ( ) => { } ) ,
244- // eslint-disable-next-line @typescript-eslint/no-empty-function
245- off : mock ( ( ) => { } ) ,
228+ getWorkspaceMetadata : mock (
229+ async ( workspaceId : string ) : Promise < Result < WorkspaceMetadata > > => {
230+ const all = await config . getAllWorkspaceMetadata ( ) ;
231+ const found = all . find ( ( m ) => m . id === workspaceId ) ;
232+ return found ? Ok ( found ) : Err ( "not found" ) ;
233+ }
234+ ) ,
235+ on : mock ( ( ) => undefined ) ,
236+ off : mock ( ( ) => undefined ) ,
246237 } as unknown as AIService ;
247238
248239 const resumeStream = mock ( ( ) => Promise . resolve ( Ok ( undefined ) ) ) ;
@@ -251,15 +242,12 @@ describe("TaskService", () => {
251242 sendMessage : mock ( ( ) => Promise . resolve ( Ok ( undefined ) ) ) ,
252243 resumeStream,
253244 remove : mock ( ( ) => Promise . resolve ( Ok ( undefined ) ) ) ,
254- // eslint-disable-next-line @typescript-eslint/no-empty-function
255245 emit : mock ( ( ) => true ) ,
256246 } as unknown as WorkspaceService ;
257247
258248 const initStateManager : InitStateManager = {
259- // eslint-disable-next-line @typescript-eslint/no-empty-function
260- startInit : mock ( ( ) => { } ) ,
261- // eslint-disable-next-line @typescript-eslint/no-empty-function
262- appendOutput : mock ( ( ) => { } ) ,
249+ startInit : mock ( ( ) => undefined ) ,
250+ appendOutput : mock ( ( ) => undefined ) ,
263251 endInit : mock ( ( ) => Promise . resolve ( ) ) ,
264252 } as unknown as InitStateManager ;
265253
@@ -311,9 +299,7 @@ describe("TaskService", () => {
311299 . flatMap ( ( p ) => p . workspaces )
312300 . find ( ( w ) => w . id === queued . data . taskId ) ;
313301 expect ( started ?. taskStatus ) . toBe ( "running" ) ;
314- } ,
315- 20_000
316- ) ;
302+ } , 20_000 ) ;
317303
318304 test ( "agent_report posts report to parent, finalizes pending task tool output, and triggers cleanup" , async ( ) => {
319305 const config = new Config ( rootDir ) ;
@@ -386,10 +372,8 @@ describe("TaskService", () => {
386372
387373 const aiService : AIService = {
388374 isStreaming : mock ( ( ) => false ) ,
389- // eslint-disable-next-line @typescript-eslint/no-empty-function
390- on : mock ( ( ) => { } ) ,
391- // eslint-disable-next-line @typescript-eslint/no-empty-function
392- off : mock ( ( ) => { } ) ,
375+ on : mock ( ( ) => undefined ) ,
376+ off : mock ( ( ) => undefined ) ,
393377 } as unknown as AIService ;
394378
395379 const sendMessage = mock ( ( ) => Promise . resolve ( Ok ( undefined ) ) ) ;
@@ -405,10 +389,8 @@ describe("TaskService", () => {
405389 } as unknown as WorkspaceService ;
406390
407391 const initStateManager : InitStateManager = {
408- // eslint-disable-next-line @typescript-eslint/no-empty-function
409- startInit : mock ( ( ) => { } ) ,
410- // eslint-disable-next-line @typescript-eslint/no-empty-function
411- appendOutput : mock ( ( ) => { } ) ,
392+ startInit : mock ( ( ) => undefined ) ,
393+ appendOutput : mock ( ( ) => undefined ) ,
412394 endInit : mock ( ( ) => Promise . resolve ( ) ) ,
413395 } as unknown as InitStateManager ;
414396
@@ -422,17 +404,33 @@ describe("TaskService", () => {
422404 ) ;
423405
424406 const internal = taskService as unknown as {
425- handleAgentReport : ( event : { type : "tool-call-end" ; workspaceId : string ; toolName : string } ) => Promise < void > ;
407+ handleAgentReport : ( event : {
408+ type : "tool-call-end" ;
409+ workspaceId : string ;
410+ toolName : string ;
411+ } ) => Promise < void > ;
426412 } ;
427- await internal . handleAgentReport ( { type : "tool-call-end" , workspaceId : childId , toolName : "agent_report" } ) ;
413+ await internal . handleAgentReport ( {
414+ type : "tool-call-end" ,
415+ workspaceId : childId ,
416+ toolName : "agent_report" ,
417+ } ) ;
428418
429419 const parentHistory = await historyService . getHistory ( parentId ) ;
430420 expect ( parentHistory . success ) . toBe ( true ) ;
431421 if ( parentHistory . success ) {
432422 const combined = parentHistory . data
433423 . filter ( ( m ) => m . role === "assistant" )
434424 . flatMap ( ( m ) => m . parts )
435- . map ( ( p ) => ( p && typeof p === "object" && "type" in p && ( p as { type ?: unknown } ) . type === "text" && "text" in p ? ( p as { text ?: unknown } ) . text : "" ) )
425+ . map ( ( p ) =>
426+ p &&
427+ typeof p === "object" &&
428+ "type" in p &&
429+ ( p as { type ?: unknown } ) . type === "text" &&
430+ "text" in p
431+ ? ( p as { text ?: unknown } ) . text
432+ : ""
433+ )
436434 . join ( "" ) ;
437435 expect ( combined ) . toContain ( "Hello from child" ) ;
438436 }
@@ -441,7 +439,11 @@ describe("TaskService", () => {
441439 expect ( updatedParentPartial ) . not . toBeNull ( ) ;
442440 if ( updatedParentPartial ) {
443441 const toolPart = updatedParentPartial . parts . find (
444- ( p ) => p && typeof p === "object" && "type" in p && ( p as { type ?: unknown } ) . type === "dynamic-tool"
442+ ( p ) =>
443+ p &&
444+ typeof p === "object" &&
445+ "type" in p &&
446+ ( p as { type ?: unknown } ) . type === "dynamic-tool"
445447 ) as unknown as
446448 | {
447449 toolName : string ;
@@ -529,10 +531,8 @@ describe("TaskService", () => {
529531
530532 const aiService : AIService = {
531533 isStreaming : mock ( ( ) => false ) ,
532- // eslint-disable-next-line @typescript-eslint/no-empty-function
533- on : mock ( ( ) => { } ) ,
534- // eslint-disable-next-line @typescript-eslint/no-empty-function
535- off : mock ( ( ) => { } ) ,
534+ on : mock ( ( ) => undefined ) ,
535+ off : mock ( ( ) => undefined ) ,
536536 } as unknown as AIService ;
537537
538538 const sendMessage = mock ( ( ) => Promise . resolve ( Ok ( undefined ) ) ) ;
@@ -548,10 +548,8 @@ describe("TaskService", () => {
548548 } as unknown as WorkspaceService ;
549549
550550 const initStateManager : InitStateManager = {
551- // eslint-disable-next-line @typescript-eslint/no-empty-function
552- startInit : mock ( ( ) => { } ) ,
553- // eslint-disable-next-line @typescript-eslint/no-empty-function
554- appendOutput : mock ( ( ) => { } ) ,
551+ startInit : mock ( ( ) => undefined ) ,
552+ appendOutput : mock ( ( ) => undefined ) ,
555553 endInit : mock ( ( ) => Promise . resolve ( ) ) ,
556554 } as unknown as InitStateManager ;
557555
@@ -585,7 +583,15 @@ describe("TaskService", () => {
585583 const combined = parentHistory . data
586584 . filter ( ( m ) => m . role === "assistant" )
587585 . flatMap ( ( m ) => m . parts )
588- . map ( ( p ) => ( p && typeof p === "object" && "type" in p && ( p as { type ?: unknown } ) . type === "text" && "text" in p ? ( p as { text ?: unknown } ) . text : "" ) )
586+ . map ( ( p ) =>
587+ p &&
588+ typeof p === "object" &&
589+ "type" in p &&
590+ ( p as { type ?: unknown } ) . type === "text" &&
591+ "text" in p
592+ ? ( p as { text ?: unknown } ) . text
593+ : ""
594+ )
589595 . join ( "" ) ;
590596 expect ( combined ) . toContain ( "Final output without agent_report" ) ;
591597 expect ( combined ) . toContain ( "fallback" ) ;
@@ -595,7 +601,11 @@ describe("TaskService", () => {
595601 expect ( updatedParentPartial ) . not . toBeNull ( ) ;
596602 if ( updatedParentPartial ) {
597603 const toolPart = updatedParentPartial . parts . find (
598- ( p ) => p && typeof p === "object" && "type" in p && ( p as { type ?: unknown } ) . type === "dynamic-tool"
604+ ( p ) =>
605+ p &&
606+ typeof p === "object" &&
607+ "type" in p &&
608+ ( p as { type ?: unknown } ) . type === "dynamic-tool"
599609 ) as unknown as
600610 | {
601611 toolName : string ;
0 commit comments