Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions backend/src/development/developmentStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export interface DevelopmentStackConfig {
frontendPort: number;
gatewayTokenFile?: string;
gatewayUrl: string;
hotReload: boolean;
openClawClientHome: string;
openClawConfigSource?: string;
openClawHome: string;
Expand Down Expand Up @@ -269,6 +270,18 @@ function configuredStateOwner(value: string | undefined, fallback: string): stri
return owner;
}

function isEnvironmentFlagEnabled(
name: string,
value: string | undefined,
isEnabledByDefault: boolean
): boolean {
const configured = value?.trim();
if (!configured) return isEnabledByDefault;
if (configured === "1") return true;
if (configured === "0") return false;
throw new TypeError(`${name} must be 0 or 1`);
}

function absoluteNonRootPath(
name: string,
value: string | undefined,
Expand Down Expand Up @@ -425,6 +438,11 @@ export function resolveDevelopmentStackConfig(
frontendPort,
gatewayTokenFile,
gatewayUrl: gatewayUrl || DEFAULT_GATEWAY_URL,
hotReload: isEnvironmentFlagEnabled(
"MIRA_DASHBOARD_DEV_HOT_RELOAD",
environment.MIRA_DASHBOARD_DEV_HOT_RELOAD,
true
),
openClawClientHome: path.join(stateRoot, "openclaw-client"),
openClawConfigSource: absoluteNonRootPath(
"MIRA_DASHBOARD_DEV_OPENCLAW_CONFIG_SOURCE",
Expand Down Expand Up @@ -993,6 +1011,7 @@ function frontendEnvironment(config: DevelopmentStackConfig): Record<string, str
DASHBOARD_API_TARGET: config.apiTarget,
HOST: config.frontendHost,
MIRA_DASHBOARD_DEV_COOKIE_NAMESPACE: `mira_dashboard_dev_${config.frontendPort}`,
MIRA_DASHBOARD_DEV_HOT_RELOAD: config.hotReload ? "1" : "0",
MIRA_DASHBOARD_DEV_PUBLIC_ORIGIN: config.publicOrigin,
PORT: String(config.frontendPort),
};
Expand All @@ -1013,27 +1032,31 @@ function stopChild(child: DevelopmentChild): void {
}
}

/** Starts watched frontend/backend children and keeps their lifecycle coupled. */
/** Starts frontend/backend children and keeps their lifecycle coupled. */
export async function runDevelopmentStack(
config: DevelopmentStackConfig
): Promise<number> {
const state = prepareDevelopmentState(config);
prepareDevelopmentLog(config);
const bun = Bun.which("bun") || process.execPath;
const backend = Bun.spawn([bun, "--watch", "src/serverStart.ts"], {
const watchArguments = config.hotReload ? ["--watch"] : [];
const backend = Bun.spawn([bun, ...watchArguments, "src/serverStart.ts"], {
cwd: path.join(config.repositoryRoot, "backend"),
env: developmentBackendEnvironment(config),
stderr: "inherit",
stdin: "inherit",
stdout: "inherit",
});
const frontend = Bun.spawn([bun, "--watch", "scripts/developmentFrontend.ts"], {
cwd: config.repositoryRoot,
env: frontendEnvironment(config),
stderr: "inherit",
stdin: "inherit",
stdout: "inherit",
});
const frontend = Bun.spawn(
[bun, ...watchArguments, "scripts/developmentFrontend.ts"],
{
cwd: config.repositoryRoot,
env: frontendEnvironment(config),
stderr: "inherit",
stdin: "inherit",
stdout: "inherit",
}
);
let developmentLogFixtureIndex = 0;
const developmentLogFixtureTimer = setInterval(() => {
try {
Expand Down Expand Up @@ -1065,8 +1088,9 @@ export async function runDevelopmentStack(
console.log(
[
`Mira Dashboard development stack: ${config.publicOrigin}`,
`Frontend HMR: ${config.frontendHost}:${config.frontendPort}`,
`Backend HMR: ${config.backendHost}:${config.backendPort}`,
`Frontend${config.hotReload ? " HMR" : ""}: ${config.frontendHost}:${config.frontendPort}`,
`Backend${config.hotReload ? " restart-on-change" : ""}: ${config.backendHost}:${config.backendPort}`,
`Hot reload: ${config.hotReload ? "enabled" : "disabled"}.`,
`State: ${config.stateRoot} (database ${state.database}, workspace ${state.workspace}, releases ${state.releases})`,
`Gateway: ${config.gatewayUrl}`,
"Isolated scheduler/worker enabled.",
Expand Down
5 changes: 4 additions & 1 deletion backend/src/routes/pullRequestRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getPullRequestPreviewStatus,
prepareAndStartPullRequestPreview,
prepareAndStopPullRequestPreview,
reconcileClosedPullRequestPreview,
} from "../services/pullRequestPreviews.ts";
import {
getDashboardReleaseStatus,
Expand Down Expand Up @@ -43,7 +44,9 @@ export const pullRequestRoutes = {
"/api/pull-requests": {
GET: async () => {
try {
return json({ pullRequests: await listDashboardPullRequests() });
const pullRequests = await listDashboardPullRequests();
await reconcileClosedPullRequestPreview(pullRequests);
return json({ pullRequests });
} catch (error) {
return routeError(error);
}
Expand Down
Loading