Skip to content

Commit 03c1d9c

Browse files
committed
Merge branch 'main' into gpt-5.2
2 parents da353f5 + a8cd5f2 commit 03c1d9c

File tree

5 files changed

+99
-49
lines changed

5 files changed

+99
-49
lines changed

.bin/bun

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
#!/usr/bin/env bash
22

33
# Bun wrapper that syncs secrets from Infisical to .env.local
4-
# Bun natively loads .env files in this order (highest precedence last):
5-
# 1. .env
6-
# 2. .env.development (or .env.production/.env.test based on NODE_ENV)
7-
# 3. .env.local
8-
# 4. .env.development.local - Worktree-specific overrides (ports, etc.)
94
#
10-
# .env.development.local has highest precedence, so worktree port overrides
11-
# correctly override values from Infisical-synced .env.local.
5+
# Why this wrapper exists:
6+
# Bun's automatic .env loading doesn't pass env vars to script subprocesses
7+
# (e.g., drizzle-kit, tsx, etc.). This wrapper explicitly passes --env-file
8+
# flags to ensure env vars are available everywhere.
129
#
13-
# This wrapper ensures .env.local is up-to-date from Infisical before running bun.
14-
# If Infisical is not set up, it falls back to using existing .env.local if present.
10+
# Env file precedence (later files override earlier ones):
11+
# 1. .env.local - Main secrets from Infisical
12+
# 2. .env.development.local - Worktree-specific overrides (ports, etc.)
13+
#
14+
# This wrapper:
15+
# 1. Syncs .env.local from Infisical (with caching)
16+
# 2. Creates symlinks in subdirectories for tools that need local .env files
17+
# 3. Passes --env-file flags to bun so subprocesses inherit env vars
1518

1619
# Common bun installation paths to check
1720
BUN_PATHS=(
@@ -202,11 +205,29 @@ check_env_setup() {
202205
echo "" >&2
203206
}
204207

208+
# Build env file arguments for bun
209+
# Bun's automatic .env loading doesn't pass vars to script subprocesses (like drizzle-kit),
210+
# so we explicitly pass --env-file flags to ensure env vars are available everywhere.
211+
build_env_file_args() {
212+
ENV_FILE_ARGS=""
213+
214+
# Add .env.local if it exists
215+
if [ -f "$ENV_LOCAL_FILE" ]; then
216+
ENV_FILE_ARGS="--env-file=$ENV_LOCAL_FILE"
217+
fi
218+
219+
# Add .env.development.local if it exists (higher precedence for worktree overrides)
220+
if [ -f "$ENV_DEVELOPMENT_LOCAL_FILE" ]; then
221+
ENV_FILE_ARGS="$ENV_FILE_ARGS --env-file=$ENV_DEVELOPMENT_LOCAL_FILE"
222+
fi
223+
}
224+
205225
run_bun() {
206226
create_env_symlinks
207227
check_env_setup
208-
# Bun natively loads .env files and gives them precedence over inherited shell vars
209-
exec "$REAL_BUN" "$@"
228+
build_env_file_args
229+
# Use --env-file to ensure env vars are passed to script subprocesses
230+
exec "$REAL_BUN" $ENV_FILE_ARGS "$@"
210231
}
211232

212233
# Main logic

cli/src/hooks/__tests__/use-usage-query.test.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
} from 'bun:test'
1212
import React from 'react'
1313

14+
import type { ClientEnv } from '@codebuff/common/types/contracts/env'
15+
1416
import { useChatStore } from '../../state/chat-store'
1517
import * as authModule from '../../utils/auth'
1618
import {
@@ -65,11 +67,12 @@ describe('fetchUsageData', () => {
6567
})
6668

6769
test('should throw error when app URL is not set', async () => {
68-
delete process.env.NEXT_PUBLIC_CODEBUFF_APP_URL
69-
70-
await expect(fetchUsageData({ authToken: 'test-token' })).rejects.toThrow(
71-
'NEXT_PUBLIC_CODEBUFF_APP_URL is not set',
72-
)
70+
await expect(
71+
fetchUsageData({
72+
authToken: 'test-token',
73+
clientEnv: { NEXT_PUBLIC_CODEBUFF_APP_URL: undefined } as unknown as ClientEnv,
74+
}),
75+
).rejects.toThrow('NEXT_PUBLIC_CODEBUFF_APP_URL is not set')
7376
})
7477
})
7578

packages/internal/knowledge.md

Lines changed: 0 additions & 24 deletions
This file was deleted.

packages/internal/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@
3838
"scripts": {
3939
"typecheck": "tsc --noEmit -p .",
4040
"test": "bun test",
41-
"db:generate": "bunx --bun drizzle-kit generate --config=./src/db/drizzle.config.ts",
42-
"db:migrate": "bunx --bun drizzle-kit push --config=./src/db/drizzle.config.ts",
41+
"db:generate": "drizzle-kit generate --config=./src/db/drizzle.config.ts",
42+
"db:migrate": "drizzle-kit push --config=./src/db/drizzle.config.ts",
4343
"db:start": "docker compose -f ./src/db/docker-compose.yml up --wait && bun run db:generate && (timeout 1 || sleep 1) && bun run db:migrate",
44-
"db:studio": "bunx --bun drizzle-kit studio --config=./src/db/drizzle.config.ts"
44+
"db:studio": "drizzle-kit studio --config=./src/db/drizzle.config.ts"
4545
},
4646
"sideEffects": false,
4747
"engines": {

scripts/init-worktree.ts

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,15 @@ async function checkGitBranchExists(branchName: string): Promise<boolean> {
206206
}
207207
}
208208

209+
async function getCurrentBranch(): Promise<string> {
210+
const proc = Bun.spawn(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], {
211+
stdout: 'pipe',
212+
stderr: 'pipe',
213+
})
214+
const output = await new Response(proc.stdout).text()
215+
return output.trim() || 'main'
216+
}
217+
209218
function createEnvDevelopmentLocalFile(
210219
worktreePath: string,
211220
args: WorktreeArgs,
@@ -334,11 +343,32 @@ async function runDirenvAllow(worktreePath: string): Promise<void> {
334343
const envrcPath = join(worktreePath, '.envrc')
335344
if (existsSync(envrcPath)) {
336345
console.log('Running direnv allow...')
337-
try {
338-
await runCommand('direnv', ['allow'], worktreePath)
339-
} catch (error) {
340-
console.warn('Failed to run direnv allow:', error)
341-
}
346+
return new Promise((resolve) => {
347+
// Use bash -c with explicit cd to ensure direnv sees the correct directory context
348+
// Just using cwd option doesn't work reliably with direnv
349+
const proc = spawn('bash', ['-c', `cd '${worktreePath}' && direnv allow`], {
350+
stdio: 'inherit',
351+
shell: false,
352+
})
353+
354+
proc.on('close', (code) => {
355+
if (code === 0) {
356+
console.log('direnv allow completed successfully')
357+
} else {
358+
console.warn(`direnv allow exited with code ${code}`)
359+
}
360+
resolve()
361+
})
362+
363+
proc.on('error', (error) => {
364+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
365+
console.warn('bash not found, skipping direnv allow')
366+
} else {
367+
console.warn('Failed to run direnv allow:', error.message)
368+
}
369+
resolve()
370+
})
371+
})
342372
} else {
343373
console.log('No .envrc found, skipping direnv allow')
344374
}
@@ -387,14 +417,33 @@ async function main(): Promise<void> {
387417
console.log(`Location: ${worktreePath}`)
388418

389419
// Create the git worktree (with or without creating new branch)
420+
// Explicitly use HEAD to ensure worktree has latest tooling (.bin/bun, etc.)
421+
const baseBranch = await getCurrentBranch()
390422
const worktreeAddArgs = ['worktree', 'add', worktreePath]
391423
if (branchExists) {
424+
// Branch exists - check it out
392425
worktreeAddArgs.push(args.name)
393426
} else {
394-
worktreeAddArgs.push('-b', args.name)
427+
// New branch - explicitly create from HEAD to get latest tooling
428+
worktreeAddArgs.push('-b', args.name, 'HEAD')
395429
}
396430
await runCommand('git', worktreeAddArgs)
397431

432+
// If branch already existed, merge in the base branch to get latest tooling
433+
if (branchExists) {
434+
console.log(`Merging ${baseBranch} into ${args.name} to get latest tooling...`)
435+
const mergeResult = await runCommand(
436+
'git',
437+
['merge', baseBranch, '--no-edit', '-m', `Merge ${baseBranch} to get latest tooling`],
438+
worktreePath,
439+
)
440+
if (mergeResult.exitCode !== 0) {
441+
console.warn(
442+
`Warning: Merge had conflicts. Please resolve them manually in the worktree.`,
443+
)
444+
}
445+
}
446+
398447
console.log('Setting up worktree environment...')
399448
console.log(`Backend port: ${args.backendPort}`)
400449
console.log(`Web port: ${args.webPort}`)
@@ -416,6 +465,7 @@ async function main(): Promise<void> {
416465

417466
console.log(`✅ Worktree '${args.name}' created and set up successfully!`)
418467
console.log(`📁 Location: ${worktreePath}`)
468+
console.log(`🌿 Based on: ${baseBranch} (HEAD)`)
419469
console.log(`🚀 You can now cd into the worktree and start working:`)
420470
console.log(` cd ${worktreePath}`)
421471
console.log(``)

0 commit comments

Comments
 (0)