From cb2965dddecec2f449fdf5d990653112dcca8bc2 Mon Sep 17 00:00:00 2001 From: qingminlong Date: Tue, 4 Aug 2026 23:11:12 +0800 Subject: [PATCH] fix(scripts): use direct-run helper for Windows guards (#110877) * fix(scripts): normalize Windows direct-run guards * test(scripts): cover direct-run routing --------- Co-authored-by: Vincent Koc --- package.json | 2 +- scripts/android-app-i18n.ts | 3 +- scripts/android-pin-version.ts | 3 +- scripts/ci-changed-scope.mjs | 4 +- scripts/ci-run-timings.mjs | 3 +- scripts/e2e/lib/package-compat.mjs | 4 +- ...enerate-bundled-channel-config-metadata.ts | 3 +- scripts/plan-release-workflow-matrix.mjs | 4 +- scripts/run-additional-boundary-checks.mjs | 3 +- scripts/verify-docker-attestations.mjs | 3 +- test/package-scripts.test.ts | 6 + test/scripts/direct-run-entrypoints.test.ts | 105 ++++++++++++++++++ test/scripts/test-projects.test.ts | 11 +- 13 files changed, 141 insertions(+), 13 deletions(-) create mode 100644 test/scripts/direct-run-entrypoints.test.ts diff --git a/package.json b/package.json index f63ea7030f84..a2b8404ea0eb 100644 --- a/package.json +++ b/package.json @@ -1898,7 +1898,7 @@ "test:unit:fast:audit": "node scripts/test-unit-fast-audit.mjs", "test:voicecall:closedloop": "node scripts/test-voicecall-closedloop.mjs", "test:watch": "node scripts/test-projects.mjs --watch", - "test:windows:ci": "node scripts/test-projects.mjs src/shared/runtime-import.test.ts src/infra/sqlite-snapshot.test.ts src/infra/ssh-client.windows.test.ts src/infra/update-managed-service-handoff.test.ts src/infra/exec-allowlist-pattern.test.ts src/infra/fs-safe-remove.test.ts src/snapshot/local-repository.windows.test.ts src/state/openclaw-database-paths.windows.test.ts src/commands/backup-verify.test.ts src/infra/state-migrations.legacy-session-store.test.ts src/test-utils/openclaw-test-state.test.ts src/agents/sessions/windows-git-bash-path.test.ts src/agents/bash-tools.exec.script-preflight.test.ts src/process/exec.windows.test.ts src/process/exec.windows.integration.test.ts src/process/windows-command.test.ts src/infra/windows-install-roots.test.ts src/node-host/invoke-system-run-allowlist.test.ts src/daemon/schtasks.startup-fallback.test.ts extensions/lobster/src/lobster-runner.test.ts extensions/mxc/test/mxc-backend.test.ts extensions/mxc/test/sandbox-policy-loader.test.ts test/e2e/qa-lab/runtime/package-openclaw-for-docker.e2e.test.ts test/scripts/format-generated-module.test.ts test/scripts/npm-runner.test.ts test/scripts/openclaw-cross-os-installer.windows.test.ts test/scripts/openclaw-cross-os-release-workflow.test.ts test/scripts/pnpm-runner.test.ts test/scripts/run-with-env.test.ts test/scripts/ts-topology.test.ts test/scripts/ui.test.ts test/scripts/vitest-process-group.test.ts", + "test:windows:ci": "node scripts/test-projects.mjs src/shared/runtime-import.test.ts src/infra/sqlite-snapshot.test.ts src/infra/ssh-client.windows.test.ts src/infra/update-managed-service-handoff.test.ts src/infra/exec-allowlist-pattern.test.ts src/infra/fs-safe-remove.test.ts src/snapshot/local-repository.windows.test.ts src/state/openclaw-database-paths.windows.test.ts src/commands/backup-verify.test.ts src/infra/state-migrations.legacy-session-store.test.ts src/test-utils/openclaw-test-state.test.ts src/agents/sessions/windows-git-bash-path.test.ts src/agents/bash-tools.exec.script-preflight.test.ts src/process/exec.windows.test.ts src/process/exec.windows.integration.test.ts src/process/windows-command.test.ts src/infra/windows-install-roots.test.ts src/node-host/invoke-system-run-allowlist.test.ts src/daemon/schtasks.startup-fallback.test.ts extensions/lobster/src/lobster-runner.test.ts extensions/mxc/test/mxc-backend.test.ts extensions/mxc/test/sandbox-policy-loader.test.ts test/e2e/qa-lab/runtime/package-openclaw-for-docker.e2e.test.ts test/scripts/direct-run-entrypoints.test.ts test/scripts/format-generated-module.test.ts test/scripts/npm-runner.test.ts test/scripts/openclaw-cross-os-installer.windows.test.ts test/scripts/openclaw-cross-os-release-workflow.test.ts test/scripts/pnpm-runner.test.ts test/scripts/run-with-env.test.ts test/scripts/ts-topology.test.ts test/scripts/ui.test.ts test/scripts/vitest-process-group.test.ts", "test:windows:schtasks:integration": "node scripts/run-with-env.mjs CI_WINDOWS_SCHTASKS_INTEGRATION=1 OPENCLAW_E2E_VERBOSE=1 OPENCLAW_VITEST_MAX_WORKERS=1 -- node scripts/run-vitest.mjs src/daemon/schtasks.integration.e2e.test.ts", "tool-display:check": "node --import tsx scripts/tool-display.ts --check", "tool-display:write": "node --import tsx scripts/tool-display.ts --write", diff --git a/scripts/android-app-i18n.ts b/scripts/android-app-i18n.ts index 06ffe2cbf7f0..07f8fdaf7421 100644 --- a/scripts/android-app-i18n.ts +++ b/scripts/android-app-i18n.ts @@ -3,6 +3,7 @@ import { mkdir, readdir, readFile, writeFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { expectDefined } from "../packages/normalization-core/src/expect.js"; +import { isDirectRunUrl } from "./lib/direct-run.mjs"; import { NATIVE_I18N_LOCALES } from "./native-i18n-locales.ts"; const HERE = path.dirname(fileURLToPath(import.meta.url)); @@ -1612,7 +1613,7 @@ export async function checkAndroidAppI18n(options: { tolerateManagedPending?: bo ); } -if (process.argv[1] && import.meta.url === `file://${path.resolve(process.argv[1])}`) { +if (isDirectRunUrl(process.argv[1], import.meta.url)) { const [command] = process.argv.slice(2); if (command === "sync") { await syncAndroidAppI18n(); diff --git a/scripts/android-pin-version.ts b/scripts/android-pin-version.ts index 05b113edf818..918fa641d932 100644 --- a/scripts/android-pin-version.ts +++ b/scripts/android-pin-version.ts @@ -9,6 +9,7 @@ import { syncAndroidVersioning, writeAndroidVersionManifest, } from "./lib/android-version.ts"; +import { isDirectRunUrl } from "./lib/direct-run.mjs"; type CliOptions = { explicitVersion: string | null; @@ -194,7 +195,7 @@ export async function main(argv: string[]): Promise { } } -if (import.meta.url === `file://${process.argv[1]}`) { +if (isDirectRunUrl(process.argv[1], import.meta.url)) { const exitCode = await main(process.argv.slice(2)); if (exitCode !== 0) { process.exit(exitCode); diff --git a/scripts/ci-changed-scope.mjs b/scripts/ci-changed-scope.mjs index 084580422a14..f0eb9207fd02 100644 --- a/scripts/ci-changed-scope.mjs +++ b/scripts/ci-changed-scope.mjs @@ -50,9 +50,9 @@ const NODE_SCOPE_RE = /^(src\/|test\/|extensions\/|packages\/|scripts\/|ui\/|\.github\/|openclaw\.mjs$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|tsconfig.*\.json$|vitest.*\.ts$|tsdown\.config\.ts$|\.oxlintrc\.json$|\.oxfmtrc\.jsonc$)/; const WINDOWS_SQLITE_SCOPE_RE = /^src\/(?:state\/|.*sqlite.*\.ts$)/; const WINDOWS_SCOPE_RE = - /^(extensions\/mxc\/|src\/agents\/(?:bash-tools\.exec-script-(?:preflight|target)|bash-tools\.exec\.script-preflight\.test)\.ts$|src\/config\/sessions\/(?:session-accessor\.sqlite-archive|store\.session-lifecycle-mutation\.test)\.ts$|src\/process\/|src\/infra\/(?:(?:exec-allowlist-pattern|fs-safe-remove)(?:\.test)?|ssh-client(?:\.windows\.test)?|update-managed-service-handoff(?:\.test)?|windows-install-roots)\.ts$|src\/shared\/(?:import-specifier|runtime-import)(?:\.test)?\.ts$|src\/test-utils\/openclaw-test-state(?:\.test)?\.ts$|scripts\/(?:install\.ps1|openclaw-cross-os-release-checks\.ts|github\/run-openclaw-cross-os-release-checks\.sh|(?:npm-runner|pnpm-runner|ui|vitest-process-group)\.(?:mjs|js)|lib\/(?:format-generated-module\.mjs|cross-os-release-checks\/[^/]+\.ts))$|test\/scripts\/(?:format-generated-module|install-ps1|npm-runner|openclaw-cross-os-release-workflow|pnpm-runner|ui|vitest-process-group)\.test\.ts$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|\.github\/workflows\/(?:ci|openclaw-cross-os-release-checks-reusable)\.yml$|\.github\/actions\/setup-node-env\/action\.yml$|\.github\/actions\/setup-pnpm-store-cache\/action\.yml$)/; + /^(extensions\/mxc\/|src\/agents\/(?:bash-tools\.exec-script-(?:preflight|target)|bash-tools\.exec\.script-preflight\.test)\.ts$|src\/config\/sessions\/(?:session-accessor\.sqlite-archive|store\.session-lifecycle-mutation\.test)\.ts$|src\/process\/|src\/infra\/(?:(?:exec-allowlist-pattern|fs-safe-remove)(?:\.test)?|ssh-client(?:\.windows\.test)?|update-managed-service-handoff(?:\.test)?|windows-install-roots)\.ts$|src\/shared\/(?:import-specifier|runtime-import)(?:\.test)?\.ts$|src\/test-utils\/openclaw-test-state(?:\.test)?\.ts$|scripts\/(?:android-(?:app-i18n|pin-version)\.ts|ci-run-timings\.mjs|e2e\/lib\/package-compat\.mjs|generate-bundled-channel-config-metadata\.ts|install\.ps1|openclaw-cross-os-release-checks\.ts|plan-release-workflow-matrix\.mjs|run-additional-boundary-checks\.mjs|verify-docker-attestations\.mjs|github\/run-openclaw-cross-os-release-checks\.sh|(?:npm-runner|pnpm-runner|ui|vitest-process-group)\.(?:mjs|js)|lib\/(?:direct-run\.mjs|format-generated-module\.mjs|cross-os-release-checks\/[^/]+\.ts))$|test\/scripts\/(?:direct-run-entrypoints|format-generated-module|install-ps1|npm-runner|openclaw-cross-os-release-workflow|pnpm-runner|ui|vitest-process-group)\.test\.ts$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|\.github\/workflows\/(?:ci|openclaw-cross-os-release-checks-reusable)\.yml$|\.github\/actions\/setup-node-env\/action\.yml$|\.github\/actions\/setup-pnpm-store-cache\/action\.yml$)/; const WINDOWS_TEST_SCOPE_RE = - /^(extensions\/mxc\/test\/(?:mxc-backend|sandbox-policy-loader)\.test\.ts$|src\/agents\/bash-tools\.exec\.script-preflight\.test\.ts$|src\/config\/sessions\/store\.session-lifecycle-mutation\.test\.ts$|src\/process\/(?:exec\.windows|windows-command)\.test\.ts$|src\/infra\/(?:exec-allowlist-pattern|fs-safe-remove|ssh-client\.windows|update-managed-service-handoff|windows-install-roots)\.test\.ts$|src\/shared\/runtime-import\.test\.ts$|src\/state\/openclaw-database-paths\.windows\.test\.ts$|src\/test-utils\/openclaw-test-state\.test\.ts$|test\/scripts\/(?:format-generated-module|npm-runner|openclaw-cross-os-release-workflow|pnpm-runner|ui|vitest-process-group)\.test\.ts$)/; + /^(extensions\/mxc\/test\/(?:mxc-backend|sandbox-policy-loader)\.test\.ts$|src\/agents\/bash-tools\.exec\.script-preflight\.test\.ts$|src\/config\/sessions\/store\.session-lifecycle-mutation\.test\.ts$|src\/process\/(?:exec\.windows|windows-command)\.test\.ts$|src\/infra\/(?:exec-allowlist-pattern|fs-safe-remove|ssh-client\.windows|update-managed-service-handoff|windows-install-roots)\.test\.ts$|src\/shared\/runtime-import\.test\.ts$|src\/state\/openclaw-database-paths\.windows\.test\.ts$|src\/test-utils\/openclaw-test-state\.test\.ts$|test\/scripts\/(?:direct-run-entrypoints|format-generated-module|npm-runner|openclaw-cross-os-release-workflow|pnpm-runner|ui|vitest-process-group)\.test\.ts$)/; const WINDOWS_DAEMON_SCOPE_RE = /^src\/daemon\/(?:schtasks(?:[-.][^/]+)?|runtime-hints\.windows-paths(?:\.test)?|test-helpers\/schtasks-(?:base-mocks|fixtures))\.ts$/; const CONTROL_UI_I18N_SCOPE_RE = diff --git a/scripts/ci-run-timings.mjs b/scripts/ci-run-timings.mjs index 50cfd077df45..c954cd623613 100644 --- a/scripts/ci-run-timings.mjs +++ b/scripts/ci-run-timings.mjs @@ -2,6 +2,7 @@ // Summarizes GitHub Actions run/job timings for CI analysis. import { execFileSync } from "node:child_process"; +import { isDirectRunUrl } from "./lib/direct-run.mjs"; import { parsePositiveInt } from "./lib/numeric-options.mjs"; import { execPlainGh } from "./lib/plain-gh.mjs"; @@ -503,6 +504,6 @@ async function main() { } } -if (import.meta.url === `file://${process.argv[1]}`) { +if (isDirectRunUrl(process.argv[1], import.meta.url)) { await main(); } diff --git a/scripts/e2e/lib/package-compat.mjs b/scripts/e2e/lib/package-compat.mjs index f1a6064a9dcd..141bcc6c1527 100644 --- a/scripts/e2e/lib/package-compat.mjs +++ b/scripts/e2e/lib/package-compat.mjs @@ -1,4 +1,6 @@ // Package-version compatibility helpers for E2E acceptance scripts. +import { isDirectRunUrl } from "../../lib/direct-run.mjs"; + export function legacyPackageAcceptanceCompat(version) { const match = /^(\d{4})\.(\d{1,2})\.(\d{1,2})(?:[-+].*)?/.exec(version || ""); const [year, month, day] = match?.slice(1, 4).map(Number) ?? []; @@ -7,6 +9,6 @@ export function legacyPackageAcceptanceCompat(version) { ); } -if (import.meta.url === `file://${process.argv[1]}`) { +if (isDirectRunUrl(process.argv[1], import.meta.url)) { console.log(legacyPackageAcceptanceCompat(process.argv[2]) ? "1" : "0"); } diff --git a/scripts/generate-bundled-channel-config-metadata.ts b/scripts/generate-bundled-channel-config-metadata.ts index 1c0806b3225b..6e962bfb94d7 100644 --- a/scripts/generate-bundled-channel-config-metadata.ts +++ b/scripts/generate-bundled-channel-config-metadata.ts @@ -3,6 +3,7 @@ import fs from "node:fs"; import path from "node:path"; import { loadBundledPluginPublicArtifactModuleSync } from "../src/plugins/public-surface-loader.js"; +import { isDirectRunUrl } from "./lib/direct-run.mjs"; import { loadChannelConfigSurfaceModule } from "./load-channel-config-surface.ts"; const GENERATED_BY = "scripts/generate-bundled-channel-config-metadata.ts"; @@ -341,7 +342,7 @@ export const GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA = JSON.parse( }); } -if (import.meta.url === new URL(process.argv[1] ?? "", "file://").href) { +if (isDirectRunUrl(process.argv[1], import.meta.url)) { const check = process.argv.includes("--check"); const result = await writeBundledChannelConfigMetadataModule({ check }); if (!result.changed) { diff --git a/scripts/plan-release-workflow-matrix.mjs b/scripts/plan-release-workflow-matrix.mjs index 9bcf55523bb2..cfa2be4dbda4 100644 --- a/scripts/plan-release-workflow-matrix.mjs +++ b/scripts/plan-release-workflow-matrix.mjs @@ -1,4 +1,6 @@ // Plans release workflow matrix entries from profile and suite inputs. +import { isDirectRunUrl } from "./lib/direct-run.mjs"; + const DOCKER_E2E_CHUNKS = [ { chunk_id: "core", @@ -236,7 +238,7 @@ function writeOutputs(plan) { } } -if (import.meta.url === `file://${process.argv[1]}`) { +if (isDirectRunUrl(process.argv[1], import.meta.url)) { const plan = createReleaseWorkflowMatrixPlan({ dockerLanes: process.env.DOCKER_LANES, includeLiveSuites: process.env.INCLUDE_LIVE_SUITES, diff --git a/scripts/run-additional-boundary-checks.mjs b/scripts/run-additional-boundary-checks.mjs index 5f43844b6c44..a52a7712dcf5 100644 --- a/scripts/run-additional-boundary-checks.mjs +++ b/scripts/run-additional-boundary-checks.mjs @@ -5,6 +5,7 @@ import { spawn } from "node:child_process"; import { performance } from "node:perf_hooks"; import pMap from "p-map"; import prettyMilliseconds from "pretty-ms"; +import { isDirectRunUrl } from "./lib/direct-run.mjs"; const DEFAULT_CHECK_TIMEOUT_MS = 10 * 60 * 1000; const DEFAULT_OUTPUT_MAX_BYTES = 512 * 1024; @@ -584,7 +585,7 @@ export function parseCliArgs(args, env = process.env) { return { help, shardSpec }; } -if (import.meta.url === `file://${process.argv[1]}`) { +if (isDirectRunUrl(process.argv[1], import.meta.url)) { try { const cliArgs = parseCliArgs(process.argv.slice(2), process.env); if (cliArgs.help) { diff --git a/scripts/verify-docker-attestations.mjs b/scripts/verify-docker-attestations.mjs index 145b81be40b5..2325687e5db7 100644 --- a/scripts/verify-docker-attestations.mjs +++ b/scripts/verify-docker-attestations.mjs @@ -3,6 +3,7 @@ // Verifies Docker image attestations cover required platforms and predicates. import { execFileSync } from "node:child_process"; import process from "node:process"; +import { isDirectRunUrl } from "./lib/direct-run.mjs"; const ATTESTATION_REFERENCE_TYPE = "attestation-manifest"; const EXPECTED_ATTESTATION_ARTIFACT_TYPE = "application/vnd.docker.attestation.manifest.v1+json"; @@ -227,7 +228,7 @@ async function main() { }); } -if (import.meta.url === `file://${process.argv[1]}`) { +if (isDirectRunUrl(process.argv[1], import.meta.url)) { main().catch( /** @param {unknown} error */ (error) => { console.error(error instanceof Error ? error.message : String(error)); diff --git a/test/package-scripts.test.ts b/test/package-scripts.test.ts index fa88492e0d43..f74fd47818d9 100644 --- a/test/package-scripts.test.ts +++ b/test/package-scripts.test.ts @@ -185,6 +185,12 @@ describe("package scripts", () => { ); }); + it("runs direct-run entrypoint coverage in Windows CI", () => { + expect(readPackageJson().scripts["test:windows:ci"]).toContain( + "test/scripts/direct-run-entrypoints.test.ts", + ); + }); + it("runs Docker package process-tree coverage in Windows CI", () => { expect(readPackageJson().scripts["test:windows:ci"]).toContain( "test/e2e/qa-lab/runtime/package-openclaw-for-docker.e2e.test.ts", diff --git a/test/scripts/direct-run-entrypoints.test.ts b/test/scripts/direct-run-entrypoints.test.ts new file mode 100644 index 000000000000..482b3fb89597 --- /dev/null +++ b/test/scripts/direct-run-entrypoints.test.ts @@ -0,0 +1,105 @@ +import { spawnSync } from "node:child_process"; +import { readFileSync } from "node:fs"; +import path from "node:path"; +import { describe, expect, it } from "vitest"; +import { detectChangedScope } from "../../scripts/ci-changed-scope.mjs"; +import { isDirectRunPath } from "../../scripts/lib/direct-run.mjs"; + +const DIRECT_RUN_SCRIPTS = [ + "scripts/android-app-i18n.ts", + "scripts/android-pin-version.ts", + "scripts/ci-run-timings.mjs", + "scripts/e2e/lib/package-compat.mjs", + "scripts/generate-bundled-channel-config-metadata.ts", + "scripts/plan-release-workflow-matrix.mjs", + "scripts/run-additional-boundary-checks.mjs", + "scripts/verify-docker-attestations.mjs", +] as const; + +const EXECUTABLE_ENTRYPOINTS = [ + { + args: ["--direct-run-smoke"], + output: "Unknown CI run timing option: --direct-run-smoke", + script: "scripts/ci-run-timings.mjs", + status: 1, + }, + { + args: ["2026.4.25"], + output: "1", + script: "scripts/e2e/lib/package-compat.mjs", + status: 0, + }, + { + args: [], + output: "docker_e2e_count=", + script: "scripts/plan-release-workflow-matrix.mjs", + status: 0, + }, + { + args: ["--help"], + output: "Usage: node scripts/run-additional-boundary-checks.mjs", + script: "scripts/run-additional-boundary-checks.mjs", + status: 0, + }, + { + args: ["--help"], + output: "Usage: node scripts/verify-docker-attestations.mjs", + script: "scripts/verify-docker-attestations.mjs", + status: 0, + }, +] as const; + +function runEntrypoint(entrypoint: (typeof EXECUTABLE_ENTRYPOINTS)[number]) { + return spawnSync(process.execPath, [path.resolve(entrypoint.script), ...entrypoint.args], { + cwd: process.cwd(), + encoding: "utf8", + env: { + ...process.env, + DOCKER_LANES: "", + GITHUB_STEP_SUMMARY: "", + INCLUDE_LIVE_SUITES: "", + INCLUDE_RELEASE_PATH_SUITES: "", + LIVE_MODEL_PROVIDERS: "", + LIVE_SUITE_FILTER: "", + RELEASE_TEST_PROFILE: "", + }, + timeout: 30_000, + }); +} + +describe("script direct-run entrypoints", () => { + it.each(EXECUTABLE_ENTRYPOINTS)("runs $script through its guarded CLI", (entrypoint) => { + const result = runEntrypoint(entrypoint); + const output = `${result.stdout}${result.stderr}`; + + expect(result.error).toBeUndefined(); + expect(result.status).toBe(entrypoint.status); + expect(output).toContain(entrypoint.output); + }); + + it("matches Windows drive paths case-insensitively", () => { + expect( + isDirectRunPath( + "C:\\repo\\scripts\\android-app-i18n.ts", + "c:\\repo\\scripts\\android-app-i18n.ts", + "win32", + ), + ).toBe(true); + }); + + it.each(DIRECT_RUN_SCRIPTS)("uses the canonical guard in %s", (script) => { + const source = readFileSync(script, "utf8"); + + expect(source.match(/isDirectRunUrl\(process\.argv\[1\], import\.meta\.url\)/gu)).toHaveLength( + 1, + ); + }); + + it.each([ + ...DIRECT_RUN_SCRIPTS, + "scripts/lib/direct-run.mjs", + "test/scripts/direct-run-entrypoints.test.ts", + ])("routes %s through Windows CI", (changedPath) => { + expect(detectChangedScope([changedPath]).runWindows).toBe(true); + }); +}); diff --git a/test/scripts/test-projects.test.ts b/test/scripts/test-projects.test.ts index f243b41729d5..10dda357c3bc 100644 --- a/test/scripts/test-projects.test.ts +++ b/test/scripts/test-projects.test.ts @@ -723,7 +723,10 @@ describe("scripts/test-projects changed-target routing", () => { ], "scripts/e2e/lib/onboard/assert-config.mjs": ["test/scripts/onboard-config-fixtures.test.ts"], "scripts/e2e/lib/onboard/write-config.mjs": ["test/scripts/onboard-config-fixtures.test.ts"], - "scripts/e2e/lib/package-compat.mjs": ["test/scripts/docker-build-helper.test.ts"], + "scripts/e2e/lib/package-compat.mjs": [ + "test/scripts/direct-run-entrypoints.test.ts", + "test/scripts/docker-build-helper.test.ts", + ], "scripts/e2e/agents-delete-shared-workspace-docker.sh": [ "test/scripts/docker-e2e-plan.test.ts", "src/scripts/ci-changed-scope.test.ts", @@ -1700,7 +1703,10 @@ describe("scripts/test-projects changed-target routing", () => { "src/plugins/recommended-tool-installs.test.ts", "test/release-check.test.ts", ], - "scripts/lib/direct-run.mjs": ["test/scripts/changed-lanes.test.ts"], + "scripts/lib/direct-run.mjs": [ + "test/scripts/changed-lanes.test.ts", + "test/scripts/direct-run-entrypoints.test.ts", + ], "scripts/lib/npm-verify-exec.ts": ["test/scripts/npm-verify-exec.test.ts"], "scripts/lib/plugin-npm-runtime-build.mjs": [ "test/scripts/plugin-npm-runtime-build-args.test.ts", @@ -1921,6 +1927,7 @@ describe("scripts/test-projects changed-target routing", () => { ], "scripts/plan-release-workflow-matrix.mjs": [ "test/scripts/release-workflow-matrix-plan.test.ts", + "test/scripts/direct-run-entrypoints.test.ts", ], "scripts/release-verify-beta.ts": ["test/scripts/release-wrapper-scripts.test.ts"], "scripts/validate-release-publish-approval.mjs": [