Skip to content

Commit 0e80993

Browse files
fix: prevent database locked errors and suppress git stderr noise
Add PRAGMA busy_timeout=5000 to the readonly forge.db connections in tui-loop-store and dashboard launch so reads wait for WAL checkpoints instead of failing immediately. The dashboard's long-lived reader made the previously latent lock collision likely to surface. Suppress git stderr in worktree-cleanup execSync calls and sandbox manager git probes so handled non-zero exits no longer leak 'fatal: not a git repository' to the terminal. Bump version to 0.4.14.
1 parent 2591739 commit 0e80993

5 files changed

Lines changed: 7 additions & 3 deletions

File tree

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "opencode-forge",
3-
"version": "0.4.13",
3+
"version": "0.4.14",
44
"type": "module",
55
"oc-plugin": [
66
"server",

‎src/dashboard/launch.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export function startDashboardServer(options: StartDashboardOptions = {}): Dashb
4949
const basePort = options.port ?? DEFAULT_PORT
5050
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS
5151
const db = new Database(dbPath, { readonly: true })
52+
db.run('PRAGMA busy_timeout=5000')
5253
const handler = createRequestHandler(db)
5354

5455
for (let attempt = 0; attempt < maxAttempts; attempt++) {

‎src/sandbox/manager.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@ export function createSandboxManager(
4444
const gitDirResult = spawnSync('git', ['rev-parse', '--git-dir'], {
4545
cwd: projectDir,
4646
encoding: 'utf-8',
47+
stdio: ['ignore', 'pipe', 'ignore'],
4748
})
4849
const commonDirResult = spawnSync('git', ['rev-parse', '--git-common-dir'], {
4950
cwd: projectDir,
5051
encoding: 'utf-8',
52+
stdio: ['ignore', 'pipe', 'ignore'],
5153
})
5254
if (gitDirResult.status !== 0 || commonDirResult.status !== 0 || !gitDirResult.stdout || !commonDirResult.stdout) return []
5355

‎src/utils/tui-loop-store.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export function fetchLoopsList(projectId: string, dbPathOverride?: string): Loop
7373
let db: Database | null = null
7474
try {
7575
db = new Database(dbPath, { readonly: true })
76+
db.run('PRAGMA busy_timeout=5000')
7677
const loopsRepo = createLoopsRepo(db)
7778
const sectionPlansRepo = createSectionPlansRepo(db)
7879

‎src/utils/worktree-cleanup.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export async function cleanupLoopWorktree(
2626
result.removed = true
2727
input.logger.log(`${input.logPrefix}: worktree directory already removed ${input.worktreeDir}`)
2828
try {
29-
const gitCommonDir = execSync('git rev-parse --git-common-dir', { cwd: input.worktreeDir, encoding: 'utf-8' }).trim()
29+
const gitCommonDir = execSync('git rev-parse --git-common-dir', { cwd: input.worktreeDir, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim()
3030
const gitRoot = resolve(input.worktreeDir, gitCommonDir, '..')
3131
spawnSync('git', ['worktree', 'prune'], { cwd: gitRoot, encoding: 'utf-8' })
3232
} catch {
@@ -44,7 +44,7 @@ export async function cleanupLoopWorktree(
4444

4545
let gitCommonDir: string
4646
try {
47-
gitCommonDir = execSync('git rev-parse --git-common-dir', { cwd: input.worktreeDir, encoding: 'utf-8' }).trim()
47+
gitCommonDir = execSync('git rev-parse --git-common-dir', { cwd: input.worktreeDir, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim()
4848
} catch (err) {
4949
if (isNotGitRepositoryError(err)) {
5050
rmSync(input.worktreeDir, { recursive: true, force: true })

0 commit comments

Comments
 (0)