@@ -6,6 +6,10 @@ import Module from 'module'
66import { delimiter , join } from 'path'
77
88import { generateDtsBundle } from 'dts-bundle-generator'
9+ import { exec as execCb } from 'child_process'
10+ import { promisify } from 'util'
11+
12+ const exec = promisify ( execCb )
913
1014const workspaceNodeModules = join ( import . meta. dir , '..' , 'node_modules' )
1115const existingNodePath = process . env . NODE_PATH ?? ''
@@ -92,7 +96,11 @@ async function build() {
9296
9397 console . log ( '📝 Generating and bundling TypeScript declarations...' )
9498 let dtsBundlingFailed = false
99+ let cleanupCommonDts : ( ) => Promise < void > = async ( ) => { }
95100 try {
101+ // Emit declarations for @codebuff /common so the SDK bundle can resolve its types
102+ cleanupCommonDts = await emitCommonDeclarations ( )
103+
96104 const [ bundle ] = generateDtsBundle (
97105 [
98106 {
@@ -113,6 +121,10 @@ async function build() {
113121 } catch ( error ) {
114122 dtsBundlingFailed = true
115123 console . error ( '❌ TypeScript declaration bundling failed:' , error . message )
124+ } finally {
125+ await cleanupCommonDts ( ) . catch ( ( err ) =>
126+ console . warn ( '⚠ Failed to clean generated common declarations:' , err ) ,
127+ )
116128 }
117129
118130 console . log ( '📂 Copying WASM files for tree-sitter...' )
@@ -131,6 +143,62 @@ async function build() {
131143 }
132144}
133145
146+ async function emitCommonDeclarations ( ) : Promise < ( ) => Promise < void > > {
147+ const repoRoot = join ( import . meta. dir , '..' , '..' )
148+ const commonSrcDir = join ( repoRoot , 'node_modules' , '@codebuff' , 'common' , 'src' )
149+
150+ // Gather all common source files excluding tests to avoid noisy type errors
151+ const { stdout : fileList } = await exec (
152+ `cd ${ repoRoot } && find common/src -name '*.ts' ! -path '*__tests__*'` ,
153+ )
154+ const files = fileList
155+ . split ( '\n' )
156+ . map ( ( s ) => s . trim ( ) )
157+ . filter ( Boolean )
158+ . join ( ' ' )
159+
160+ const cmd = [
161+ 'bun x tsc' ,
162+ '--emitDeclarationOnly' ,
163+ '--declaration' ,
164+ '--noEmit false' ,
165+ '--moduleResolution bundler' ,
166+ '--module ESNext' ,
167+ '--target ES2023' ,
168+ "--lib 'ES2023,DOM'" ,
169+ '--types bun,node' ,
170+ '--allowImportingTsExtensions true' ,
171+ '--skipLibCheck' ,
172+ '--strict' ,
173+ `--rootDir common/src` ,
174+ `--declarationDir ${ commonSrcDir } ` ,
175+ files ,
176+ ] . join ( ' ' )
177+
178+ const { stdout, stderr } = await exec ( cmd , { cwd : repoRoot } )
179+ if ( stdout ) console . log ( stdout . trim ( ) )
180+ if ( stderr ) console . error ( stderr . trim ( ) )
181+
182+ return async ( ) => {
183+ const { stdout } = await exec (
184+ `cd ${ repoRoot } && git ls-files --others --exclude-standard common/src` ,
185+ )
186+ const files = stdout
187+ . split ( '\n' )
188+ . map ( ( s ) => s . trim ( ) )
189+ . filter ( ( s ) => s . endsWith ( '.d.ts' ) )
190+
191+ if ( files . length === 0 ) return
192+
193+ const chunkSize = 50
194+ for ( let i = 0 ; i < files . length ; i += chunkSize ) {
195+ const chunk = files . slice ( i , i + chunkSize )
196+ const quoted = chunk . map ( ( f ) => `"${ f } "` ) . join ( ' ' )
197+ await exec ( `cd ${ repoRoot } && rm -f ${ quoted } ` )
198+ }
199+ }
200+ }
201+
134202/**
135203 * Fix duplicate imports in the generated index.d.ts file
136204 */
0 commit comments