From 1149094cdcd464d538af8cd4899abf8a64a30449 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Wed, 28 Jan 2026 18:16:17 +0000 Subject: [PATCH] fix(cli): handle symlinks in isMain() for Node.js The dnt polyfill's import-meta-ponyfill doesn't resolve symlinks when comparing process.argv[1] with import.meta.url. When npm creates a symlink for the `wmill` bin (e.g., /usr/bin/wmill -> .../main.js), the paths don't match and isMain() incorrectly returns false, causing the CLI to silently exit without running. This fix resolves symlinks using fs.realpathSync() before comparison, ensuring the CLI works correctly when invoked via npm-installed symlinks. Tested with Node.js 20 and 25. Co-Authored-By: Claude Opus 4.5 --- cli/src/main.ts | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/cli/src/main.ts b/cli/src/main.ts index a3a81731ae..00b8e84786 100644 --- a/cli/src/main.ts +++ b/cli/src/main.ts @@ -5,6 +5,13 @@ import { esMain, log, } from "../deps.ts"; + +// Node.js-specific imports for symlink resolution in isMain() +// These are only used in Node.js, not Deno +// dnt-shim-ignore +import { realpathSync } from "node:fs"; +// dnt-shim-ignore +import { fileURLToPath } from "node:url"; import flow from "./commands/flow/flow.ts"; import app from "./commands/app/app.ts"; import script from "./commands/script/script.ts"; @@ -239,8 +246,23 @@ function isMain() { } return isMain; } else { - //@ts-ignore - return esMain.default(import.meta); + // For Node.js, we need to handle symlinks properly. + // The dnt polyfill doesn't resolve symlinks when comparing process.argv[1] + // with import.meta.url, so `wmill` symlink doesn't match the real file path. + // We resolve symlinks manually to get accurate comparison. + try { + const scriptPath = process.argv[1]; + if (!scriptPath) return false; + + const realScriptPath = realpathSync(scriptPath); + const modulePath = fileURLToPath(import.meta.url); + + return realScriptPath === modulePath; + } catch { + // Fallback to esMain if something fails + //@ts-ignore + return esMain.default(import.meta); + } } } if (isMain()) {