@@ -2,8 +2,37 @@ import type { Envelope, EnvelopeItem, Event, SerializedSession } from '@sentry/c
22import { parseEnvelope } from '@sentry/core' ;
33import type { ChildProcess } from 'child_process' ;
44import { spawn } from 'child_process' ;
5+ import * as fs from 'fs' ;
6+ import * as path from 'path' ;
57import * as readline from 'readline' ;
68
9+ /**
10+ * Find the monorepo root by looking for a package.json with workspaces.
11+ * This works regardless of whether we're running from source or built output.
12+ */
13+ function findRepoRoot ( startDir : string ) : string {
14+ let dir = startDir ;
15+ while ( dir !== path . dirname ( dir ) ) {
16+ const pkgPath = path . join ( dir , 'package.json' ) ;
17+ if ( fs . existsSync ( pkgPath ) ) {
18+ try {
19+ const pkg = JSON . parse ( fs . readFileSync ( pkgPath , 'utf8' ) ) ;
20+ if ( pkg . workspaces ) {
21+ return dir ;
22+ }
23+ } catch {
24+ // Continue searching
25+ }
26+ }
27+ dir = path . dirname ( dir ) ;
28+ }
29+ throw new Error ( 'Could not find monorepo root' ) ;
30+ }
31+
32+ // Find spotlight binary in repo root's node_modules
33+ const REPO_ROOT = findRepoRoot ( __dirname ) ;
34+ const SPOTLIGHT_BIN = path . join ( REPO_ROOT , 'node_modules' , '.bin' , 'spotlight' ) ;
35+
736interface SpotlightOptions {
837 /** Port for the Spotlight sidecar. Use 0 for dynamic port assignment. */
938 port ?: number ;
@@ -48,9 +77,8 @@ export async function startSpotlight(options: SpotlightOptions = {}): Promise<Sp
4877 const { port = 0 , cwd = process . cwd ( ) , debug = false } = options ;
4978
5079 return new Promise ( ( resolve , reject ) => {
51- // Use npx to run Spotlight - works regardless of package manager
52- // and will use the installed version or download if needed
53- const args = [ '--yes' , '@spotlightjs/spotlight' , 'run' , '-f' , 'json' ] ;
80+ // Run Spotlight directly from repo root's node_modules
81+ const args = [ 'run' , '-f' , 'json' ] ;
5482
5583 if ( port !== 0 ) {
5684 args . push ( '-p' , String ( port ) ) ;
@@ -60,7 +88,7 @@ export async function startSpotlight(options: SpotlightOptions = {}): Promise<Sp
6088 args . push ( '-d' ) ;
6189 }
6290
63- const spotlightProcess = spawn ( 'npx' , args , {
91+ const spotlightProcess = spawn ( SPOTLIGHT_BIN , args , {
6492 cwd,
6593 stdio : [ 'ignore' , 'pipe' , 'pipe' ] ,
6694 } ) ;
@@ -81,21 +109,33 @@ export async function startSpotlight(options: SpotlightOptions = {}): Promise<Sp
81109 console . log ( '[spotlight stderr]' , line ) ;
82110 }
83111
84- // Look for port in various formats
85- const portMatch = line . match ( / l o c a l h o s t : ( \d + ) / i) || line . match ( / p o r t [: \s] + ( \d + ) / i) ;
112+ // Look for port in various formats:
113+ // - "Spotlight listening on 39143"
114+ // - "http://localhost:8969"
115+ // - "port: 8969"
116+ const portMatch =
117+ line . match ( / l i s t e n i n g o n ( \d + ) / i) ||
118+ line . match ( / l o c a l h o s t : ( \d + ) / i) ||
119+ line . match ( / p o r t [: \s] + ( \d + ) / i) ;
120+
86121 if ( portMatch ?. [ 1 ] && ! resolvedPort ) {
87122 resolvedPort = parseInt ( portMatch [ 1 ] , 10 ) ;
88- }
89-
90- // Also check for "Sidecar running" or similar ready messages
91- if ( ( line . includes ( 'listening' ) || line . includes ( 'running' ) || line . includes ( 'started' ) ) && resolvedPort ) {
92- if ( ! resolved ) {
123+ // Resolve immediately when we have the port from a "listening" message
124+ if ( ! resolved && line . includes ( 'listening' ) ) {
93125 resolved = true ;
94126 const instance = createSpotlightInstance ( spotlightProcess , resolvedPort , debug ) ;
95127 currentSpotlightInstance = instance ;
96128 resolve ( instance ) ;
97129 }
98130 }
131+
132+ // Fallback: check for other ready messages if we have a port
133+ if ( ! resolved && resolvedPort && ( line . includes ( 'running' ) || line . includes ( 'started' ) ) ) {
134+ resolved = true ;
135+ const instance = createSpotlightInstance ( spotlightProcess , resolvedPort , debug ) ;
136+ currentSpotlightInstance = instance ;
137+ resolve ( instance ) ;
138+ }
99139 } ) ;
100140
101141 // Parse stdout for JSON events
0 commit comments