mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
improve: doctor migration checks no longer load every bundled plugin runtime (#120678)
* perf(plugins): declare doctor contract surfaces * perf(doctor): slim migration import closures * perf(plugins): narrow doctor declaration record surface and wire owner-test lane Registry records carry only the doctorContract declaration instead of the whole parsed manifest, and check:changed now selects the src/plugins-owned declaration honesty and closure-guard tests for extension module/manifest changes so cross-lane drift cannot pass PR classification. * fix(doctor): keep control-plane dist imports require-safe Keep doctor and channel control-plane chunks off exec-class dependencies, and enforce native require(esm) loading during postbuild. * chore(plugin-sdk): regenerate API baseline * chore(plugin-sdk): sync export ordering * fix(plugins): satisfy doctor contract CI boundaries * perf(doctor): make qqbot doctor closure dependency-light qqbot was the last plugin above 5s in doctor state-migration enumeration (~8s under tsx/jiti). The cost was not the state-key builder (already a leaf): its doctor closure value-imported the runtime-doctor SDK barrel, whose plugin-state-store/state-db re-exports pull kysely (~330 modules), plus security-runtime for one fileExists (~200 modules), all resolved per-module by jiti during enumeration. Split the migration-define helpers and light re-exports into a new private-local plugin-sdk/runtime-doctor-migrations subpath; runtime-doctor re-exports it so its public surface is byte-identical (API baseline hash unchanged). qqbot's doctor-contract and state-migrations now import only the light subpath, swapping fileExists for the equivalent async legacyStateFileExists already in the closure. qqbot enumeration: ~8.0s/531 modules -> ~0.25s/18 modules. * chore(plugin-sdk): drop private-local subpath from API baseline runtime-doctor-migrations is private-local-only; the baseline tracks public modules, and the earlier line was generated before the classification. * fix(plugins): register runtime-doctor-migrations boundary paths The private-local subpath list feeds the extension package boundary map; the shared paths config and xai's derived overrides must carry the same entry or the boundary contract test fails.
This commit is contained in:
committed by
GitHub
parent
bb23b6b5ca
commit
da4a656cdb
@@ -7,7 +7,9 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import type { PluginHealthErrorSummary } from "../../gateway/health/types.js";
|
||||
import { resolveGatewayProbeAuthSafeWithSecretInputs } from "../../gateway/probe-auth.js";
|
||||
import { probeGateway } from "../../gateway/probe.js";
|
||||
import { inspectPortUsage, LOOPBACK_PORT_PROBE_HOSTS, type PortUsage } from "../../infra/ports.js";
|
||||
import { inspectPortUsage } from "../../infra/ports-inspect.js";
|
||||
import { LOOPBACK_PORT_PROBE_HOSTS } from "../../infra/ports-probe.js";
|
||||
import type { PortUsage } from "../../infra/ports-types.js";
|
||||
import type { GatewayPortHealthSnapshot } from "./restart-health.types.js";
|
||||
import { allListenersOwnedByRuntimePid } from "./restart-port-ownership.js";
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { vi } from "vitest";
|
||||
import type { GatewayService } from "../../daemon/service.js";
|
||||
import type { GatewayLockIdentity } from "../../infra/gateway-lock.js";
|
||||
import type { PortUsage } from "../../infra/ports.js";
|
||||
import type { PortUsage } from "../../infra/ports-types.js";
|
||||
|
||||
type PortListenerKind = ReturnType<typeof import("../../infra/ports.js").classifyPortListener>;
|
||||
type PortListenerKind = ReturnType<
|
||||
typeof import("../../infra/ports-format.js").classifyPortListener
|
||||
>;
|
||||
|
||||
export const inspectPortUsage =
|
||||
vi.fn<(port: number, options?: { probeHosts?: readonly string[] }) => Promise<PortUsage>>();
|
||||
@@ -26,11 +28,17 @@ export const resolveGatewayServiceProbeHosts = vi.fn<
|
||||
(_params?: unknown) => Promise<readonly string[]>
|
||||
>(async () => ["127.0.0.1"]);
|
||||
|
||||
vi.mock("../../infra/ports.js", () => ({
|
||||
vi.mock("../../infra/ports-format.js", () => ({
|
||||
classifyPortListener: (listener: unknown, port: number) => classifyPortListener(listener, port),
|
||||
formatPortDiagnostics: vi.fn(() => []),
|
||||
}));
|
||||
|
||||
vi.mock("../../infra/ports-inspect.js", () => ({
|
||||
inspectPortUsage: (port: number, options?: { probeHosts?: readonly string[] }) =>
|
||||
inspectPortUsage(port, options),
|
||||
}));
|
||||
|
||||
vi.mock("../../infra/ports-probe.js", () => ({
|
||||
LOOPBACK_PORT_PROBE_HOSTS: ["127.0.0.1"],
|
||||
}));
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import { resolveGatewayServiceProbeHosts } from "../../daemon/gateway-service-pr
|
||||
import type { GatewayServiceRuntime } from "../../daemon/service-runtime.js";
|
||||
import type { GatewayService } from "../../daemon/service.js";
|
||||
import type { PluginHealthErrorSummary } from "../../gateway/health/types.js";
|
||||
import { classifyPortListener, inspectPortUsage, type PortUsage } from "../../infra/ports.js";
|
||||
import { classifyPortListener } from "../../infra/ports-format.js";
|
||||
import { inspectPortUsage } from "../../infra/ports-inspect.js";
|
||||
import type { PortUsage } from "../../infra/ports-types.js";
|
||||
import {
|
||||
hasActiveStartupMigrationLease,
|
||||
STARTUP_MIGRATION_LEASE_TTL_MS,
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { StaleOpenClawUpdateLaunchdJob } from "../../daemon/launchd.js";
|
||||
import { createMockGatewayService } from "../../daemon/service.test-helpers.js";
|
||||
import type { PortListener, PortUsageStatus } from "../../infra/ports.js";
|
||||
import type { PortListener, PortUsageStatus } from "../../infra/ports-types.js";
|
||||
import type { GatewayRestartHandoff } from "../../infra/restart-handoff.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { captureEnv, deleteTestEnvValue, setTestEnvValue } from "../../test-utils/env.js";
|
||||
@@ -15,7 +15,7 @@ import { gatherDaemonStatus } from "./status.gather.js";
|
||||
import { printDaemonStatus } from "./status.print.js";
|
||||
|
||||
type PortConnections = Awaited<
|
||||
ReturnType<typeof import("../../infra/ports.js").inspectPortConnections>
|
||||
ReturnType<typeof import("../../infra/ports-inspect.js").inspectPortConnections>
|
||||
>;
|
||||
|
||||
const callGatewayStatusProbe = vi.fn<
|
||||
@@ -270,7 +270,7 @@ vi.mock("../../gateway/probe-auth.js", async (importOriginal) => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../../infra/ports.js", () => ({
|
||||
vi.mock("../../infra/ports-inspect.js", () => ({
|
||||
inspectPortConnections: (port: number) => inspectPortConnections(port),
|
||||
inspectPortUsage: (port: number, options?: PortUsageInspectionOptions) =>
|
||||
inspectPortUsage(port, options),
|
||||
@@ -278,6 +278,9 @@ vi.mock("../../infra/ports.js", () => ({
|
||||
ports: readonly number[],
|
||||
options?: { probeHostsByPort?: ReadonlyMap<number, readonly string[]> },
|
||||
) => inspectPortUsages(ports, options),
|
||||
}));
|
||||
|
||||
vi.mock("../../infra/ports-format.js", () => ({
|
||||
formatPortDiagnostics: () => [],
|
||||
}));
|
||||
|
||||
|
||||
@@ -39,15 +39,13 @@ import {
|
||||
resolveBestEffortGatewayBindHostForDisplay,
|
||||
} from "../../infra/network-discovery-display.js";
|
||||
import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js";
|
||||
import { formatPortDiagnostics } from "../../infra/ports-format.js";
|
||||
import {
|
||||
formatPortDiagnostics,
|
||||
inspectPortConnections,
|
||||
inspectPortUsage,
|
||||
inspectPortUsages,
|
||||
type PortConnection,
|
||||
type PortListener,
|
||||
type PortUsageStatus,
|
||||
} from "../../infra/ports.js";
|
||||
} from "../../infra/ports-inspect.js";
|
||||
import type { PortConnection, PortListener, PortUsageStatus } from "../../infra/ports-types.js";
|
||||
import {
|
||||
readGatewayRestartHandoffSync,
|
||||
type GatewayRestartHandoff,
|
||||
|
||||
Reference in New Issue
Block a user