1- import { createHmac , randomUUID } from 'node:crypto'
1+ import { createHmac } from 'node:crypto'
22import {
33 createServer ,
44 request as httpRequest ,
99} from 'node:http'
1010import { connect , type Socket } from 'node:net'
1111import type { Duplex } from 'node:stream'
12+ import { generateId , generateShortId } from '@sim/utils/id'
13+ import { toArray } from '@sim/utils/object'
1214import postgres from 'postgres'
1315
1416/**
@@ -47,7 +49,7 @@ export function liveSimConfig(): LiveSimConfig | string {
4749 ] . filter ( ( name ) => ! env [ name ] )
4850 if ( missing . length > 0 ) return `Needs a local Sim app: set ${ missing . join ( ', ' ) } `
4951 const databaseUrl = env . SIM_DESKTOP_E2E_DATABASE_URL ?? ''
50- if ( ! / t e s t / i. test ( new URL ( databaseUrl ) . pathname ) )
52+ if ( ! / (?: ^ | [ _ - ] ) t e s t $ / i. test ( new URL ( databaseUrl ) . pathname . slice ( 1 ) ) )
5153 return 'SIM_DESKTOP_E2E_DATABASE_URL must name a dedicated test database'
5254 return {
5355 upstream : env . SIM_DESKTOP_E2E_SIM_URL ?? '' ,
@@ -330,7 +332,7 @@ class AgentTurn {
330332
331333 /** Issues a client-executed tool call and returns its id. */
332334 toolCall ( call : ScriptedToolCall ) : string {
333- const toolCallId = `toolu_${ randomUUID ( ) . replaceAll ( '-' , '' ) } `
335+ const toolCallId = `toolu_${ generateShortId ( ) } `
334336 this . toolCallIds . push ( toolCallId )
335337 this . emit ( 'tool' , {
336338 phase : 'call' ,
@@ -349,9 +351,9 @@ class AgentTurn {
349351 pause ( ) : void {
350352 this . emit ( 'run' , {
351353 kind : 'checkpoint_pause' ,
352- checkpointId : randomUUID ( ) ,
353- executionId : randomUUID ( ) ,
354- runId : randomUUID ( ) ,
354+ checkpointId : generateId ( ) ,
355+ executionId : generateId ( ) ,
356+ runId : generateId ( ) ,
355357 pendingToolCallIds : [ ...this . toolCallIds ] ,
356358 } )
357359 this . finish ( )
@@ -452,7 +454,7 @@ export class ScriptedAgent {
452454 const body : Record < string , unknown > = raw ? JSON . parse ( raw ) : { }
453455 if ( path === '/api/mothership' || path === '/api/copilot' ) {
454456 const message = typeof body . message === 'string' ? body . message : ''
455- const streamId = typeof body . messageId === 'string' ? body . messageId : randomUUID ( )
457+ const streamId = typeof body . messageId === 'string' ? body . messageId : generateId ( )
456458 const turn = new AgentTurn ( body , streamId , response )
457459 this . turns . push ( turn )
458460 const entry = [ ...this . scripts ] . find ( ( [ marker ] ) => message . includes ( marker ) )
@@ -465,7 +467,7 @@ export class ScriptedAgent {
465467 }
466468 if ( path === '/api/tools/resume' ) {
467469 const streamId = typeof body . streamId === 'string' ? body . streamId : ''
468- const results = Array . isArray ( body . results ) ? ( body . results as ResumedResult [ ] ) : [ ]
470+ const results = toArray < ResumedResult > ( body . results )
469471 const resume : Resume = { at : Date . now ( ) , streamId, results }
470472 this . resumes . push ( resume )
471473 for ( const wake of this . waiters . splice ( 0 ) ) wake ( )
@@ -518,25 +520,25 @@ export class SimDatabase {
518520
519521 /** A user with a workspace, a session as the desktop sign-in creates, and one chat per title. */
520522 async seedUser ( chatTitles : string [ ] ) : Promise < SeededUser > {
521- const userId = randomUUID ( )
522- const workspaceId = randomUUID ( )
523- const sessionId = randomUUID ( )
524- const token = randomUUID ( ) . replaceAll ( '-' , '' )
523+ const userId = generateId ( )
524+ const workspaceId = generateId ( )
525+ const sessionId = generateId ( )
526+ const token = generateShortId ( )
525527 const name = `Desktop E2E ${ userId . slice ( 0 , 6 ) } `
526528 const email = `${ userId } @desktop-tools-e2e.test`
527529 const chats : Record < string , string > = { }
528530 await this . sql . begin ( async ( tx ) => {
529531 await tx `insert into "user" (id, name, email, normalized_email, email_verified, created_at, updated_at)
530532 values (${ userId } , ${ name } , ${ email } , ${ email } , true, now(), now())`
531- await tx `insert into user_stats (id, user_id) values (${ randomUUID ( ) } , ${ userId } )`
533+ await tx `insert into user_stats (id, user_id) values (${ generateId ( ) } , ${ userId } )`
532534 await tx `insert into workspace (id, name, owner_id, billed_account_user_id)
533535 values (${ workspaceId } , 'Desktop tools E2E', ${ userId } , ${ userId } )`
534536 await tx `insert into permissions (id, user_id, entity_type, entity_id, permission_type)
535- values (${ randomUUID ( ) } , ${ userId } , 'workspace', ${ workspaceId } , 'admin')`
537+ values (${ generateId ( ) } , ${ userId } , 'workspace', ${ workspaceId } , 'admin')`
536538 await tx `insert into session (id, token, user_id, user_agent, expires_at, created_at, updated_at)
537539 values (${ sessionId } , ${ token } , ${ userId } , 'Sim Desktop', now() + interval '1 day', now(), now())`
538540 for ( const title of chatTitles ) {
539- const chatId = randomUUID ( )
541+ const chatId = generateId ( )
540542 chats [ title ] = chatId
541543 await tx `insert into copilot_chats (id, user_id, workspace_id, type, title)
542544 values (${ chatId } , ${ userId } , ${ workspaceId } , 'mothership', ${ title } )`
@@ -626,15 +628,27 @@ export class RedisMonitor {
626628 socket . once ( 'connect' , resolve )
627629 socket . once ( 'error' , reject )
628630 } )
631+ // Each command sent before MONITOR answers `+OK`; MONITOR's own `+OK` means it is recording.
632+ let pendingAcks = target . password ? 2 : 1
629633 let buffer = ''
630- socket . on ( 'data' , ( chunk ) => {
631- buffer += chunk . toString ( 'utf8' )
632- const lines = buffer . split ( '\r\n' )
633- buffer = lines . pop ( ) ?? ''
634- this . lines . push ( ...lines . filter ( ( line ) => line . startsWith ( '+' ) && line !== '+OK' ) )
634+ const acknowledged = new Promise < void > ( ( resolve , reject ) => {
635+ socket . on ( 'data' , ( chunk ) => {
636+ buffer += chunk . toString ( 'utf8' )
637+ const lines = buffer . split ( '\r\n' )
638+ buffer = lines . pop ( ) ?? ''
639+ for ( const line of lines ) {
640+ if ( pendingAcks > 0 ) {
641+ if ( line . startsWith ( '-' ) ) reject ( new Error ( `Redis refused MONITOR: ${ line } ` ) )
642+ else if ( line === '+OK' && -- pendingAcks === 0 ) resolve ( )
643+ continue
644+ }
645+ if ( line . startsWith ( '+' ) ) this . lines . push ( line )
646+ }
647+ } )
635648 } )
636649 if ( target . password ) socket . write ( `AUTH ${ decodeURIComponent ( target . password ) } \r\n` )
637650 socket . write ( 'MONITOR\r\n' )
651+ await acknowledged
638652 }
639653
640654 /** Commands seen that publish to a channel whose name contains `channel`. */
0 commit comments