Skip to content

fix(cli): use pathToFileURL for portable main-module guard - #67

Closed
advancedresearcharray wants to merge 1 commit into
mex-memory:mainfrom
advancedresearcharray:fix/cli-main-module-guard-46
Closed

fix(cli): use pathToFileURL for portable main-module guard#67
advancedresearcharray wants to merge 1 commit into
mex-memory:mainfrom
advancedresearcharray:fix/cli-main-module-guard-46

Conversation

@advancedresearcharray

@advancedresearcharray advancedresearcharray commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Addresses the remaining review feedback on #46.

Context

CLI-level test coverage for mex log / mex timeline option parsing already merged via #47. PR #46's review requested a portable main-module guard; this PR lands it with symlink-safe resolution for npm global / npx / node_modules/.bin layouts.

Change

  • Import realpathSync from node:fs and pathToFileURL from node:url
  • Gate program.parse() on import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href (try/catch when argv[1] is absent, e.g. test imports)
  • Integration tests: built CLI via symlinked bin (--version) and import-without-auto-parse
  • Updated patterns/cli-option-parsing-tests.md to document the guard

Verification

  • npx vitest run test/cli.test.ts — 13/13 passing
  • npm test — 177/177 passing
  • npm run typecheck — passing
  • CI green on Node 20 + 22

Closes the actionable items from @theDakshJaitly's review on #46. #46 itself can be closed as superseded by #47 + this follow-up.

@advancedresearcharray

Copy link
Copy Markdown
Contributor Author

Ready for re-review — this is the follow-up to the portable main-module guard requested on #46.

Changes

  • src/cli.ts: gate program.parse() on import.meta.url === pathToFileURL(process.argv[1]).href
  • patterns/cli-option-parsing-tests.md: updated Context section to document the guard (latest commit)

Verification (re-run on current head)

  • npx vitest run test/cli.test.ts — 11/11
  • npm test — 175/175
  • npm run typecheck — clean
  • npm run build + node dist/cli.js --version — works; importing dist/cli.js as a module does not auto-parse

Test coverage for mex log / mex timeline option parsing already landed via #47; this PR carries only the remaining review item from #46.

@theDakshJaitly — whenever you have a moment.

@theDakshJaitly theDakshJaitly left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — the pathToFileURL switch is the right call for Windows/unicode paths. But the guard regresses the common case: it compares import.meta.url (which Node resolves through symlinks) against an unresolved process.argv[1], so it evaluates false for any symlinked bin — global npm i -g, npx, node_modules/.bin — and even for direct runs under a symlinked dir (macOS /var -> /private/var). When it's false, program.parse() never runs and the CLI silently no-ops. CI misses it because the tests invoke node dist/cli.js from the real checkout path.

Verified locally on Node 20: the current guard is false for npx/global-bin invocation; resolving the symlink fixes all cases (and is a no-op on Windows, where npm uses .cmd shims):

import { realpathSync } from "node:fs";
import { pathToFileURL } from "node:url";
// ...
if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href) {
  program.parse();
}

Could you also add a test that runs the built CLI through a symlink (mirroring how npm installs the bin) so this path is covered going forward? Happy to merge once that's in.

@advancedresearcharray

Copy link
Copy Markdown
Contributor Author

Addressed the symlink regression from the review.

Changes

  • src/cli.ts: compare import.meta.url against pathToFileURL(realpathSync(process.argv[1])).href, with a try/catch when argv[1] is absent (test imports)
  • test/cli.test.ts: new integration tests — built CLI via symlinked bin (--version) and import-without-auto-parse
  • patterns/cli-option-parsing-tests.md: document the realpathSync guard

Verification

  • npx vitest run test/cli.test.ts — 13/13
  • npm test — 177/177
  • npm run typecheck — clean

@advancedresearcharray

Copy link
Copy Markdown
Contributor Author

Re-review requested — symlink regression fix is on head (21855cb).

What changed since the review

  • src/cli.ts: compare against pathToFileURL(realpathSync(process.argv[1])).href (with try/catch when argv[1] is absent)
  • test/cli.test.ts: integration tests for symlinked-bin invocation and import-without-auto-parse
  • patterns/cli-option-parsing-tests.md: documents the realpathSync guard

Verification (re-run on 21855cb)

  • npm test — 177/177
  • npm run typecheck — clean
  • CI green on Node 20 + 22

@theDakshJaitly — ready when you are.

realpathSync(process.argv[1]) so npm global/npx/node_modules/.bin
symlinks match import.meta.url. Add a symlinked-bin integration test
and guard against missing argv paths in test imports.

Co-authored-by: Cursor <cursoragent@cursor.com>
@advancedresearcharray

Copy link
Copy Markdown
Contributor Author

Symlink fix is on #71 (re-opened after #67 was auto-closed by an orphaned force-push): #71

theDakshJaitly pushed a commit that referenced this pull request Jun 6, 2026
Gate program.parse() on import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href so the CLI runs correctly when invoked through a symlinked bin (npm global, npx, node_modules/.bin), with a try/catch when argv[1] is absent. Adds an integration test that invokes the built CLI through a symlink. Supersedes #67.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants