From bec9b9bea45bce052de2e7ea892a9b0f4a85f429 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Tue, 21 Jul 2026 11:02:26 -0700 Subject: [PATCH] fix: exclude Windows validator from runtime artifacts --- runtime/install.js | 4 ++++ runtime/runtime-bootstrap.mjs | 2 +- skills/debug/references/support/runtime-bootstrap.mjs | 2 +- .../design/references/support/runtime-bootstrap.mjs | 2 +- skills/plan/references/support/runtime-bootstrap.mjs | 2 +- skills/qa/references/support/runtime-bootstrap.mjs | 2 +- .../review/references/support/runtime-bootstrap.mjs | 2 +- skills/ship/references/support/runtime-bootstrap.mjs | 2 +- test/gstack2-runtime-install.test.ts | 11 +++++++++++ 9 files changed, 22 insertions(+), 7 deletions(-) diff --git a/runtime/install.js b/runtime/install.js index 8d3dbe2e6..ea62fb5c2 100644 --- a/runtime/install.js +++ b/runtime/install.js @@ -1049,6 +1049,10 @@ export function runtimeReleaseComponentForPath(value) { const relative = component.slice(browserRoot.length); if (relative === ".links" || relative.startsWith(".links/")) return null; const top = relative.split("/")[0]; + // Playwright downloads winldd on Windows only to validate browser DLL + // dependencies during installation. It is not required to launch Chromium + // from the completed managed runtime, so keep it out of release artifacts. + if (/^winldd-\d/.test(top)) return null; if (top.startsWith("chromium_headless_shell-") || top.startsWith("ffmpeg-")) return "browser-headless"; if (/^chromium-\d/.test(top)) return "browser-visible"; throw installError(`Unknown managed browser payload path: ${component}`, "INSTALL_BROWSER_PAYLOAD_INVALID"); diff --git a/runtime/runtime-bootstrap.mjs b/runtime/runtime-bootstrap.mjs index 2f5c9dcf2..c25d572f2 100644 --- a/runtime/runtime-bootstrap.mjs +++ b/runtime/runtime-bootstrap.mjs @@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0"; // Keep the runtime compatibility version separate from the immutable release // channel. Release candidates carry the 2.0.0 runtime contract while letting // fresh-machine production journeys run before the stable v2.0.0 tag exists. -export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.3"; +export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.4"; export const OFFICIAL_MANIFEST_URL = `https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`; const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]); diff --git a/skills/debug/references/support/runtime-bootstrap.mjs b/skills/debug/references/support/runtime-bootstrap.mjs index 2f5c9dcf2..c25d572f2 100644 --- a/skills/debug/references/support/runtime-bootstrap.mjs +++ b/skills/debug/references/support/runtime-bootstrap.mjs @@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0"; // Keep the runtime compatibility version separate from the immutable release // channel. Release candidates carry the 2.0.0 runtime contract while letting // fresh-machine production journeys run before the stable v2.0.0 tag exists. -export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.3"; +export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.4"; export const OFFICIAL_MANIFEST_URL = `https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`; const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]); diff --git a/skills/design/references/support/runtime-bootstrap.mjs b/skills/design/references/support/runtime-bootstrap.mjs index 2f5c9dcf2..c25d572f2 100644 --- a/skills/design/references/support/runtime-bootstrap.mjs +++ b/skills/design/references/support/runtime-bootstrap.mjs @@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0"; // Keep the runtime compatibility version separate from the immutable release // channel. Release candidates carry the 2.0.0 runtime contract while letting // fresh-machine production journeys run before the stable v2.0.0 tag exists. -export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.3"; +export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.4"; export const OFFICIAL_MANIFEST_URL = `https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`; const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]); diff --git a/skills/plan/references/support/runtime-bootstrap.mjs b/skills/plan/references/support/runtime-bootstrap.mjs index 2f5c9dcf2..c25d572f2 100644 --- a/skills/plan/references/support/runtime-bootstrap.mjs +++ b/skills/plan/references/support/runtime-bootstrap.mjs @@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0"; // Keep the runtime compatibility version separate from the immutable release // channel. Release candidates carry the 2.0.0 runtime contract while letting // fresh-machine production journeys run before the stable v2.0.0 tag exists. -export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.3"; +export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.4"; export const OFFICIAL_MANIFEST_URL = `https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`; const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]); diff --git a/skills/qa/references/support/runtime-bootstrap.mjs b/skills/qa/references/support/runtime-bootstrap.mjs index 2f5c9dcf2..c25d572f2 100644 --- a/skills/qa/references/support/runtime-bootstrap.mjs +++ b/skills/qa/references/support/runtime-bootstrap.mjs @@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0"; // Keep the runtime compatibility version separate from the immutable release // channel. Release candidates carry the 2.0.0 runtime contract while letting // fresh-machine production journeys run before the stable v2.0.0 tag exists. -export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.3"; +export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.4"; export const OFFICIAL_MANIFEST_URL = `https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`; const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]); diff --git a/skills/review/references/support/runtime-bootstrap.mjs b/skills/review/references/support/runtime-bootstrap.mjs index 2f5c9dcf2..c25d572f2 100644 --- a/skills/review/references/support/runtime-bootstrap.mjs +++ b/skills/review/references/support/runtime-bootstrap.mjs @@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0"; // Keep the runtime compatibility version separate from the immutable release // channel. Release candidates carry the 2.0.0 runtime contract while letting // fresh-machine production journeys run before the stable v2.0.0 tag exists. -export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.3"; +export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.4"; export const OFFICIAL_MANIFEST_URL = `https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`; const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]); diff --git a/skills/ship/references/support/runtime-bootstrap.mjs b/skills/ship/references/support/runtime-bootstrap.mjs index 2f5c9dcf2..c25d572f2 100644 --- a/skills/ship/references/support/runtime-bootstrap.mjs +++ b/skills/ship/references/support/runtime-bootstrap.mjs @@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0"; // Keep the runtime compatibility version separate from the immutable release // channel. Release candidates carry the 2.0.0 runtime contract while letting // fresh-machine production journeys run before the stable v2.0.0 tag exists. -export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.3"; +export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.4"; export const OFFICIAL_MANIFEST_URL = `https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`; const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]); diff --git a/test/gstack2-runtime-install.test.ts b/test/gstack2-runtime-install.test.ts index fd2c71103..77b84b578 100644 --- a/test/gstack2-runtime-install.test.ts +++ b/test/gstack2-runtime-install.test.ts @@ -14,6 +14,7 @@ import { defaultBunBuilder, installManagedRuntime, normalizeManagedBrowserTree, + runtimeReleaseComponentForPath, runtimeNativePackagePaths, uninstallManagedRuntime, runCommand, @@ -31,6 +32,16 @@ const REPO_ROOT = path.resolve(import.meta.dir, ".."); const FULL_RUNTIME_TEST_TIMEOUT_MS = process.platform === "win32" ? 120_000 : 30_000; describe("GStack 2 managed runtime installer", () => { + test("release staging excludes Playwright bookkeeping and Windows dependency validators", () => { + expect(runtimeReleaseComponentForPath(".gstack-runtime-browsers/.links/example")).toBeNull(); + expect(runtimeReleaseComponentForPath(".gstack-runtime-browsers/winldd-1007/DEPENDENCIES_VALIDATED")).toBeNull(); + expect(runtimeReleaseComponentForPath(".gstack-runtime-browsers/winldd-1007/winldd.exe")).toBeNull(); + expect(runtimeReleaseComponentForPath(".gstack-runtime-browsers/chromium_headless_shell-1208/chrome.exe")) + .toBe("browser-headless"); + expect(() => runtimeReleaseComponentForPath(".gstack-runtime-browsers/unknown-1/payload")) + .toThrow("Unknown managed browser payload path"); + }); + test("browser link normalization accepts internal macOS-style links and rejects escape graphs", async () => { if (process.platform === "win32") return; const root = await fs.mkdtemp(path.join(os.tmpdir(), "gstack-browser-links-"));