fix(auto): use pathToFileURL for cross-platform import and reconcile regression test

Convert resource-loader import path to file URL via pathToFileURL() to
fix Windows ERR_UNSUPPORTED_ESM_URL_SCHEME. Update existing regression
test to validate the GSD_PKG_ROOT + pathToFileURL contract.
This commit is contained in:
Jeremy 2026-04-10 20:05:32 -05:00
parent 7b2601e6a0
commit e26c5cff56
3 changed files with 14 additions and 11 deletions

View file

@ -126,6 +126,7 @@ import {
import { setLogBasePath, logWarning, logError } from "./workflow-logger.js";
import { homedir } from "node:os";
import { join } from "node:path";
import { pathToFileURL } from "node:url";
import { readFileSync, existsSync, mkdirSync, writeFileSync, unlinkSync } from "node:fs";
import { atomicWriteSync } from "./atomic-write.js";
import {
@ -1341,7 +1342,7 @@ export async function startAuto(
const agentDir = process.env.GSD_CODING_AGENT_DIR || join(process.env.GSD_HOME || homedir(), ".gsd", "agent");
const pkgRoot = process.env.GSD_PKG_ROOT;
const resourceLoaderPath = pkgRoot
? join(pkgRoot, "dist", "resource-loader.js")
? pathToFileURL(join(pkgRoot, "dist", "resource-loader.js")).href
: new URL("../../../resource-loader.js", import.meta.url).href;
const { initResources } = await import(resourceLoaderPath);
initResources(agentDir);

View file

@ -22,16 +22,17 @@ describe("resource-loader import path", () => {
);
});
test("uses createRequire to resolve resource-loader from package root", () => {
// The fix uses createRequire to find gsd-pi/package.json, then imports
// dist/resource-loader.js from there — works in both source and deployed.
test("uses GSD_PKG_ROOT to resolve resource-loader from package root", () => {
// The fix uses GSD_PKG_ROOT (set by loader.ts) to construct an absolute
// file URL to dist/resource-loader.js — works in both source and deployed,
// and on Windows where raw paths fail with ERR_UNSUPPORTED_ESM_URL_SCHEME.
assert.ok(
autoSrc.includes('createRequire(import.meta.url)'),
"auto.ts should use createRequire to resolve resource-loader",
autoSrc.includes('process.env.GSD_PKG_ROOT'),
"auto.ts should use GSD_PKG_ROOT to resolve resource-loader",
);
assert.ok(
autoSrc.includes('resolve("gsd-pi/package.json")'),
"auto.ts should resolve gsd-pi package root via package.json",
autoSrc.includes('pathToFileURL'),
"auto.ts should convert path to file URL for cross-platform import()",
);
});
});

View file

@ -33,10 +33,11 @@ test("auto.ts resume uses GSD_PKG_ROOT for resource-loader import, not bare rela
"auto.ts resource-loader import must use the computed resourceLoaderPath variable, not a hardcoded relative path",
);
// The resourceLoaderPath must be constructed from GSD_PKG_ROOT
// The resourceLoaderPath must be constructed from GSD_PKG_ROOT via pathToFileURL
// (raw filesystem paths break on Windows with ERR_UNSUPPORTED_ESM_URL_SCHEME)
assert.ok(
autoSrc.includes('join(pkgRoot, "dist", "resource-loader.js")'),
"auto.ts must construct resourceLoaderPath from pkgRoot + dist/resource-loader.js",
autoSrc.includes("pathToFileURL(join(pkgRoot,"),
"auto.ts must convert the constructed path to a file URL for cross-platform import()",
);
});