diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 511e1010a37a..e80ee0d7e1a5 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -263,7 +263,6 @@ export namespace Config { "@opencode-ai/plugin": targetVersion, } await Bun.write(pkg, JSON.stringify(json, null, 2)) - await new Promise((resolve) => setTimeout(resolve, 3000)) const gitignore = path.join(dir, ".gitignore") const hasGitIgnore = await Bun.file(gitignore).exists() diff --git a/packages/opencode/src/tasks/pulse.ts b/packages/opencode/src/tasks/pulse.ts index 734e84aa3eca..9e9a8336b81b 100644 --- a/packages/opencode/src/tasks/pulse.ts +++ b/packages/opencode/src/tasks/pulse.ts @@ -541,8 +541,8 @@ async function processAdversarialVerdicts(jobId: string, projectId: string, pmSe continue } - if (verdict.verdict === "APPROVED") { - await commitTask(updatedTask, projectId, pmSessionId) + if (verdict.verdict === "APPROVED") { + await commitTask(updatedTask, jobId, projectId, pmSessionId) } else { const newAttempt = (updatedTask.pipeline.attempt || 0) + 1 if (newAttempt >= 3) { @@ -554,7 +554,7 @@ async function processAdversarialVerdicts(jobId: string, projectId: string, pmSe } } -async function commitTask(task: Task, projectId: string, pmSessionId: string): Promise { +async function commitTask(task: Task, jobId: string, projectId: string, pmSessionId: string): Promise { const parentSession = await Session.get(pmSessionId).catch(() => null) if (!parentSession?.directory) { log.error("PM session not found for commit", { taskId: task.id }) @@ -690,6 +690,11 @@ If there is an error, report the full error output.` }) log.info("task committed and closed", { taskId: task.id }) + + // Immediately reschedule after commit — don't wait for next Pulse tick + await scheduleReadyTasks(jobId, projectId, pmSessionId).catch((e) => + log.error("failed to reschedule after commit", { taskId: task.id, error: String(e) }), + ) } async function respawnDeveloper( diff --git a/packages/opencode/src/worktree/index.ts b/packages/opencode/src/worktree/index.ts index d85a0843fbaf..1deecbf892ed 100644 --- a/packages/opencode/src/worktree/index.ts +++ b/packages/opencode/src/worktree/index.ts @@ -342,7 +342,7 @@ export namespace Worktree { const base = input?.name ? slug(input.name) : "" const info = await candidate(root, base || undefined) - const created = await $`git worktree add --no-checkout -b ${info.branch} ${info.directory}` + const created = await $`git worktree add -b ${info.branch} ${info.directory}` .quiet() .nothrow() .cwd(Instance.worktree) diff --git a/packages/opencode/test/config/config.test.ts b/packages/opencode/test/config/config.test.ts index f9f0e11dec60..9078f417c194 100644 --- a/packages/opencode/test/config/config.test.ts +++ b/packages/opencode/test/config/config.test.ts @@ -618,6 +618,20 @@ test("does not try to install dependencies in read-only OPENCODE_CONFIG_DIR", as } }) +test("installDependencies completes without hardcoded delay", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + const cfg = path.join(dir, "configdir") + await fs.mkdir(cfg, { recursive: true }) + return cfg + }, + }) + + await Config.installDependencies(tmp.extra) + + expect(await Bun.file(path.join(tmp.extra, "package.json")).exists()).toBe(true) +}) + test("installs dependencies in writable OPENCODE_CONFIG_DIR", async () => { await using tmp = await tmpdir({ init: async (dir) => {