refactor: simplify worktree script spawning
This commit is contained in:
@@ -7,7 +7,7 @@ import { scheduler } from "node:timers/promises";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { findFreePort, ScriptRouteStore } from "./script-proxy.js";
|
||||
import { ScriptHealthMonitor, type ScriptHealthEntry } from "./script-health-monitor.js";
|
||||
import { spawnWorktreeScripts } from "./worktree-bootstrap.js";
|
||||
import { spawnWorkspaceScript } from "./worktree-bootstrap.js";
|
||||
import { WorkspaceScriptRuntimeStore } from "./workspace-script-runtime-store.js";
|
||||
|
||||
type TcpServerHandle = {
|
||||
@@ -433,15 +433,19 @@ describe("ScriptHealthMonitor", () => {
|
||||
[];
|
||||
|
||||
try {
|
||||
await spawnWorktreeScripts({
|
||||
repoRoot: workspace.repoDir,
|
||||
workspaceId: workspace.repoDir,
|
||||
branchName: null,
|
||||
daemonPort: null,
|
||||
routeStore,
|
||||
runtimeStore,
|
||||
terminalManager: createStubTerminalManager(createTerminalCalls) as any,
|
||||
});
|
||||
for (const scriptName of ["typecheck", "api"]) {
|
||||
await spawnWorkspaceScript({
|
||||
repoRoot: workspace.repoDir,
|
||||
workspaceId: workspace.repoDir,
|
||||
projectSlug: "repo",
|
||||
branchName: null,
|
||||
scriptName,
|
||||
daemonPort: null,
|
||||
routeStore,
|
||||
runtimeStore,
|
||||
terminalManager: createStubTerminalManager(createTerminalCalls) as any,
|
||||
});
|
||||
}
|
||||
|
||||
expect(createTerminalCalls).toHaveLength(2);
|
||||
expect(routeStore.listRoutes()).toEqual([
|
||||
|
||||
@@ -5,11 +5,7 @@ import { join } from "path";
|
||||
import { tmpdir } from "os";
|
||||
|
||||
import type { AgentTimelineItem } from "./agent/agent-sdk-types.js";
|
||||
import {
|
||||
runAsyncWorktreeBootstrap,
|
||||
spawnWorkspaceScript,
|
||||
spawnWorktreeScripts,
|
||||
} from "./worktree-bootstrap.js";
|
||||
import { runAsyncWorktreeBootstrap, spawnWorkspaceScript } from "./worktree-bootstrap.js";
|
||||
import { ensureWorkspaceServicePortPlan } from "./workspace-service-port-registry.js";
|
||||
import { ScriptRouteStore } from "./script-proxy.js";
|
||||
import { createBranchChangeRouteHandler } from "./script-route-branch-handler.js";
|
||||
@@ -717,17 +713,19 @@ describe("runAsyncWorktreeBootstrap", () => {
|
||||
const createTerminalCalls: CreateTerminalCall[] = [];
|
||||
const terminalRecords: StubTerminalRecord[] = [];
|
||||
|
||||
const results = await spawnWorktreeScripts({
|
||||
const result = await spawnWorkspaceScript({
|
||||
repoRoot: repoDir,
|
||||
workspaceId: repoDir,
|
||||
projectSlug: "repo",
|
||||
branchName: "feature-socket-service",
|
||||
scriptName: "web",
|
||||
daemonPort: null,
|
||||
routeStore,
|
||||
runtimeStore,
|
||||
terminalManager: createStubTerminalManager(createTerminalCalls, terminalRecords),
|
||||
});
|
||||
|
||||
expect(results).toHaveLength(1);
|
||||
expect(result).toBeDefined();
|
||||
expect(routeStore.listRoutes()).toEqual([]);
|
||||
expect(createTerminalCalls).toHaveLength(1);
|
||||
expect(createTerminalCalls[0]?.cwd).toBe(repoDir);
|
||||
@@ -1344,15 +1342,19 @@ describe("runAsyncWorktreeBootstrap", () => {
|
||||
const terminalManager = createTerminalManager();
|
||||
realTerminalManagers.push(terminalManager);
|
||||
|
||||
await spawnWorktreeScripts({
|
||||
repoRoot: repoDir,
|
||||
workspaceId: repoDir,
|
||||
branchName: "feature-peer-env",
|
||||
daemonPort: 6767,
|
||||
routeStore,
|
||||
runtimeStore,
|
||||
terminalManager,
|
||||
});
|
||||
for (const scriptName of ["api", "web"]) {
|
||||
await spawnWorkspaceScript({
|
||||
repoRoot: repoDir,
|
||||
workspaceId: repoDir,
|
||||
projectSlug: "repo",
|
||||
branchName: "feature-peer-env",
|
||||
scriptName,
|
||||
daemonPort: 6767,
|
||||
routeStore,
|
||||
runtimeStore,
|
||||
terminalManager,
|
||||
});
|
||||
}
|
||||
|
||||
const apiEnvPath = join(repoDir, "api-env.json");
|
||||
const webEnvPath = join(repoDir, "web-env.json");
|
||||
@@ -1422,10 +1424,12 @@ describe("runAsyncWorktreeBootstrap", () => {
|
||||
const runtimeStore = new WorkspaceScriptRuntimeStore();
|
||||
const createTerminalCalls: CreateTerminalCall[] = [];
|
||||
|
||||
await spawnWorktreeScripts({
|
||||
await spawnWorkspaceScript({
|
||||
repoRoot: repoDir,
|
||||
workspaceId: repoDir,
|
||||
projectSlug: "repo",
|
||||
branchName: "feature-remote-service",
|
||||
scriptName: "web",
|
||||
daemonPort: 6767,
|
||||
daemonListenHost: "100.64.0.20",
|
||||
routeStore,
|
||||
|
||||
@@ -3,7 +3,6 @@ import type { Logger } from "pino";
|
||||
import type { TerminalManager } from "../terminal/terminal-manager.js";
|
||||
import type { TerminalSession } from "../terminal/terminal.js";
|
||||
import { buildScriptHostname } from "../utils/script-hostname.js";
|
||||
import { deriveProjectSlug } from "./workspace-git-metadata.js";
|
||||
import {
|
||||
getScriptConfigs,
|
||||
getWorktreeTerminalSpecs,
|
||||
@@ -922,39 +921,6 @@ export async function spawnWorkspaceScript(
|
||||
}
|
||||
}
|
||||
|
||||
export async function spawnWorktreeScripts(options: {
|
||||
repoRoot: string;
|
||||
workspaceId: string;
|
||||
branchName: string | null;
|
||||
daemonPort?: number | null;
|
||||
daemonListenHost?: string | null;
|
||||
routeStore: ScriptRouteStore;
|
||||
runtimeStore: WorkspaceScriptRuntimeStore;
|
||||
terminalManager: TerminalManager;
|
||||
logger?: Logger;
|
||||
onLifecycleChanged?: () => void;
|
||||
}): Promise<WorktreeScriptResult[]> {
|
||||
const { repoRoot } = options;
|
||||
const projectSlug = deriveProjectSlug(repoRoot);
|
||||
const scriptConfigs = getScriptConfigs(repoRoot);
|
||||
if (scriptConfigs.size === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const results: WorktreeScriptResult[] = [];
|
||||
for (const scriptName of scriptConfigs.keys()) {
|
||||
results.push(
|
||||
await spawnWorkspaceScript({
|
||||
...options,
|
||||
projectSlug,
|
||||
scriptName,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
export function teardownWorktreeScripts(options: {
|
||||
hostnames: string[];
|
||||
routeStore: ScriptRouteStore;
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
buildWorktreeSetupDetail,
|
||||
createWorktreeSetupProgressAccumulator,
|
||||
getWorktreeSetupProgressResults,
|
||||
spawnWorktreeScripts,
|
||||
} from "./worktree-bootstrap.js";
|
||||
import type { TerminalManager } from "../terminal/terminal-manager.js";
|
||||
import type { ScriptRouteStore } from "./script-proxy.js";
|
||||
@@ -738,28 +737,6 @@ export async function runWorktreeSetupInBackground(
|
||||
emitSetupProgress("completed", null);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
options.shouldBootstrap &&
|
||||
dependencies.terminalManager &&
|
||||
dependencies.scriptRouteStore &&
|
||||
dependencies.scriptRuntimeStore
|
||||
) {
|
||||
await spawnWorktreeScripts({
|
||||
repoRoot: worktree.worktreePath,
|
||||
workspaceId: options.workspaceId,
|
||||
branchName: worktree.branchName,
|
||||
daemonPort: dependencies.getDaemonTcpPort?.() ?? null,
|
||||
daemonListenHost: dependencies.getDaemonTcpHost?.() ?? null,
|
||||
routeStore: dependencies.scriptRouteStore,
|
||||
runtimeStore: dependencies.scriptRuntimeStore,
|
||||
terminalManager: dependencies.terminalManager,
|
||||
logger: dependencies.sessionLogger,
|
||||
onLifecycleChanged: () => {
|
||||
dependencies.onScriptsChanged?.(options.workspaceId, worktree.worktreePath);
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof WorktreeSetupError) {
|
||||
setupResults = error.results;
|
||||
|
||||
Reference in New Issue
Block a user