fix: wait for worktree bootstrap before prompt dispatch; resolve session directory for send/fork (#2708)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import express from 'express';
|
||||
import { createOpencodeClient } from '@opencode-ai/sdk/v2';
|
||||
import { createWorktree } from '../git/index.js';
|
||||
import { createWorktree, getWorktreeBootstrapStatus } from '../git/index.js';
|
||||
import { expandSnippets } from '../opencode/snippets.js';
|
||||
import { expandCommandGoalObjective, parseScheduledCommandPrompt } from '../scheduled-tasks/runtime.js';
|
||||
import { buildGoalIntroText, createSessionGoal } from '../session-goal/create.js';
|
||||
@@ -275,6 +275,31 @@ const resolveRequestedDirectory = async ({ payload, readSettingsFromDiskMigrated
|
||||
const PROMPT_LANDED_TIMEOUT_MS = 5_000;
|
||||
const PROMPT_LANDED_POLL_MS = 150;
|
||||
|
||||
// createWorktree returns while the worktree is still being populated in the
|
||||
// background (git reset --hard after a --no-checkout add). Dispatching a
|
||||
// prompt into a half-populated directory makes opencode's run die with
|
||||
// UnknownError (agent and config files are not there yet), so wait until the
|
||||
// bootstrap reaches git-ready (population done) or fails before creating the
|
||||
// session and dispatching.
|
||||
const WORKTREE_BOOTSTRAP_TIMEOUT_MS = 60_000;
|
||||
const WORKTREE_BOOTSTRAP_POLL_MS = 150;
|
||||
|
||||
const waitForWorktreeBootstrapReady = async ({ directory }) => {
|
||||
const deadline = Date.now() + WORKTREE_BOOTSTRAP_TIMEOUT_MS;
|
||||
for (;;) {
|
||||
const status = await getWorktreeBootstrapStatus(directory);
|
||||
if (status?.status === 'failed') {
|
||||
throw new OpenChamberControlError(`Worktree bootstrap failed: ${status.error || 'unknown error'}`, 500);
|
||||
}
|
||||
const phase = status?.phase;
|
||||
if (status?.status === 'ready' || phase === 'git-ready' || phase === 'setup-ready') return;
|
||||
if (Date.now() >= deadline) {
|
||||
throw new OpenChamberControlError('Timed out waiting for the worktree bootstrap', 500);
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, WORKTREE_BOOTSTRAP_POLL_MS));
|
||||
}
|
||||
};
|
||||
|
||||
const latestUserMessageID = async ({ client, sessionID, directory }) => {
|
||||
let response;
|
||||
try {
|
||||
@@ -579,6 +604,7 @@ export const createOpenChamberSessionService = (dependencies) => {
|
||||
if (worktreeInput) {
|
||||
worktree = await createWorktree(resolvedDirectory.directory, worktreeInput);
|
||||
sessionDirectory = worktree.path;
|
||||
await waitForWorktreeBootstrapReady({ directory: sessionDirectory });
|
||||
}
|
||||
|
||||
const baseUrl = buildOpenCodeUrl('/', '').replace(/\/$/, '');
|
||||
|
||||
Reference in New Issue
Block a user