Skip to content

Fix Leadtype CLI symlinked bin execution#34

Merged
KayleeWilliams merged 1 commit into
mainfrom
KayleeWilliams/run-change
May 12, 2026
Merged

Fix Leadtype CLI symlinked bin execution#34
KayleeWilliams merged 1 commit into
mainfrom
KayleeWilliams/run-change

Conversation

@KayleeWilliams
Copy link
Copy Markdown
Collaborator

Summary

Fix the Leadtype CLI direct-run check so package-manager bin shims and symlinked workspace installs actually execute the CLI entrypoint.

Root Cause

The CLI compared import.meta.url against process.argv[1] after only resolving the argv path. Under pnpm and workspace symlinks, process.argv[1] can point at a .bin/leadtype shim or symlinked package path while import.meta.url points at the real package file, so the comparison failed and runCli(...) was skipped.

Changes

  • Compare canonical realpaths for the direct-run check.
  • Add regression coverage for .bin/leadtype and symlinked node_modules/leadtype/dist/cli.js entrypoints.
  • Add a patch changeset for leadtype.

Validation

  • bun run --filter leadtype check-types
  • bun run --filter leadtype build
  • bun run --filter leadtype test
  • bun run --filter leadtype lint
  • Commit hook: bun test passed, 165 tests across 19 files
  • Manual inrepo verification: pnpm exec leadtype generate ... now runs and generates output instead of exiting silently

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Fixed CLI so direct runs correctly detect and handle symlinked workspace installs and package-manager bin shims when running generate, preventing incorrect command routing.
  • Tests

    • Added tests covering symlinked installs and bin-shim scenarios to ensure direct-run detection behaves reliably across setups.
  • Chores

    • Added a changeset documenting a patch release for this fix.

Walkthrough

The CLI's direct-run detection was refactored to resolve real filesystem paths (realpath) instead of comparing URLs; tests were added to verify behavior with symlinked .bin shims and workspace installs, and a Changesets patch documents the fix.

Changes

CLI symlink direct-run detection

Layer / File(s) Summary
Direct-run symlink detection implementation and tests
packages/leadtype/src/cli.ts, packages/leadtype/src/cli.test.ts
isDirectRun() was refactored to resolve real filesystem paths using realpathSync/resolveRealPath and compare against fileURLToPath(moduleUrl). The function accepts optional parameters for testing. Test imports were extended to support symlink, and a new test creates symlinked node_modules and node_modules/.bin entries and asserts isDirectRun returns true for both the shim and the underlying cli.js file.
Release documentation
.changeset/fix-symlinked-cli-direct-run.md
Adds a Changesets patch entry documenting that the CLI direct-run check now correctly handles package-manager bin shims and symlinked workspace installs.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • inthhq/leadtype#28: Modifies packages/leadtype/src/cli.ts and relates to shebang/direct-run handling changes.

Poem

🐰 I hopped through links and followed the trail,
Resolved each realpath where shims like to veil.
From .bin to cli, the match is now true,
No more lost runs — the rabbit fixed the view. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: addressing symlinked bin execution in the Leadtype CLI, which directly matches the primary changes in the changeset.
Description check ✅ Passed The description is well-related to the changeset, explaining the root cause, specific changes made, and validation steps that align with the file modifications and test additions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch KayleeWilliams/run-change

Comment @coderabbitai help to get the list of available commands and usage tips.

@KayleeWilliams KayleeWilliams marked this pull request as ready for review May 12, 2026 02:23
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/leadtype/src/cli.test.ts`:
- Around line 113-117: The symlink call in packages/leadtype/src/cli.test.ts
uses the "dir" type which fails on Windows CI; change it to pick "junction" on
Windows and "dir" elsewhere by deriving a link type (e.g., const linkType =
process.platform === "win32" ? "junction" : "dir") and pass that variable to
symlink; update the symlink invocation that references fixtureDir and "leadtype"
to use this platform-aware linkType so tests do not require elevated privileges
on Windows.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 894cde79-1654-465a-ad46-1d158e3b12fc

📥 Commits

Reviewing files that changed from the base of the PR and between 1bca5cf and 3bf46e2.

📒 Files selected for processing (3)
  • .changeset/fix-symlinked-cli-direct-run.md
  • packages/leadtype/src/cli.test.ts
  • packages/leadtype/src/cli.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • packages/leadtype/src/cli.ts
  • packages/leadtype/src/cli.test.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code

Files:

  • packages/leadtype/src/cli.ts
  • packages/leadtype/src/cli.test.ts
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • packages/leadtype/src/cli.test.ts
🪛 markdownlint-cli2 (0.22.1)
.changeset/fix-symlinked-cli-direct-run.md

[warning] 5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🔇 Additional comments (2)
packages/leadtype/src/cli.ts (1)

65-79: Direct-run canonicalization fix looks solid.

Comparing resolved realpaths here correctly handles symlinked .bin and workspace entrypoints without changing CLI routing behavior.

packages/leadtype/src/cli.test.ts (1)

120-126: Great regression assertions for both shim and linked CLI path.

These two expectations directly verify the realpath-based isDirectRun(...) behavior for the failing scenarios described in this PR.

Comment thread packages/leadtype/src/cli.test.ts
@KayleeWilliams KayleeWilliams force-pushed the KayleeWilliams/run-change branch from 3bf46e2 to 21cd4d9 Compare May 12, 2026 02:46
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/leadtype/src/cli.ts`:
- Around line 73-76: The exported helper isDirectRun currently uses inferred
types for its parameters and return type; update its signature to declare
explicit types (e.g., entry: string, moduleUrl: string) and an explicit boolean
return type while preserving the existing default values and behavior so the
function contract is clear for consumers and matches exported API expectations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 702f2bfb-19cc-4174-8ccc-90fbaa520cbf

📥 Commits

Reviewing files that changed from the base of the PR and between 3bf46e2 and 21cd4d9.

📒 Files selected for processing (3)
  • .changeset/fix-symlinked-cli-direct-run.md
  • packages/leadtype/src/cli.test.ts
  • packages/leadtype/src/cli.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • packages/leadtype/src/cli.test.ts
  • packages/leadtype/src/cli.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code

Files:

  • packages/leadtype/src/cli.test.ts
  • packages/leadtype/src/cli.ts
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • packages/leadtype/src/cli.test.ts
🪛 markdownlint-cli2 (0.22.1)
.changeset/fix-symlinked-cli-direct-run.md

[warning] 5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🔇 Additional comments (2)
.changeset/fix-symlinked-cli-direct-run.md (1)

1-5: Changeset entry is clear and release-note ready.

This accurately communicates the CLI direct-run symlink/bin-shim fix and its user-facing impact.

packages/leadtype/src/cli.test.ts (1)

98-128: Great regression coverage for symlinked/bin-shim direct-run detection.

The new case validates both .bin and symlinked dist/cli.js entry paths, and Line 107 keeps directory-link behavior Windows-safe.

Comment on lines +73 to +76
export function isDirectRun(
entry = process.argv[1],
moduleUrl = import.meta.url
): boolean {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add explicit parameter types to exported isDirectRun API.

Line 74 and Line 75 currently rely on inference; make the function contract explicit since this is an exported helper.

Proposed patch
 export function isDirectRun(
-  entry = process.argv[1],
-  moduleUrl = import.meta.url
+  entry: string | undefined = process.argv[1],
+  moduleUrl: string = import.meta.url
 ): boolean {

As per coding guidelines, **/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/leadtype/src/cli.ts` around lines 73 - 76, The exported helper
isDirectRun currently uses inferred types for its parameters and return type;
update its signature to declare explicit types (e.g., entry: string, moduleUrl:
string) and an explicit boolean return type while preserving the existing
default values and behavior so the function contract is clear for consumers and
matches exported API expectations.

@KayleeWilliams KayleeWilliams force-pushed the KayleeWilliams/run-change branch from 21cd4d9 to 73d354c Compare May 12, 2026 02:52
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
packages/leadtype/src/cli.ts (1)

73-76: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add explicit parameter types to exported isDirectRun.

Line 74 and Line 75 still rely on inference. For an exported helper, making the parameter contract explicit improves API clarity.

Suggested patch
 export function isDirectRun(
-  entry = process.argv[1],
-  moduleUrl = import.meta.url
+  entry: string | undefined = process.argv[1],
+  moduleUrl: string = import.meta.url
 ): boolean {

As per coding guidelines, **/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/leadtype/src/cli.ts` around lines 73 - 76, The exported function
isDirectRun currently relies on inferred parameter types for entry and
moduleUrl; update its signature to declare explicit types (e.g., annotate entry
and moduleUrl as strings) while keeping the boolean return type, so change the
parameters for isDirectRun (entry, moduleUrl) to have explicit types to improve
the public API clarity and satisfy the lint rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/leadtype/src/cli.ts`:
- Around line 73-76: The exported function isDirectRun currently relies on
inferred parameter types for entry and moduleUrl; update its signature to
declare explicit types (e.g., annotate entry and moduleUrl as strings) while
keeping the boolean return type, so change the parameters for isDirectRun
(entry, moduleUrl) to have explicit types to improve the public API clarity and
satisfy the lint rule.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 13036df2-5b92-40c4-bec0-06867a3bc120

📥 Commits

Reviewing files that changed from the base of the PR and between 21cd4d9 and 73d354c.

📒 Files selected for processing (3)
  • .changeset/fix-symlinked-cli-direct-run.md
  • packages/leadtype/src/cli.test.ts
  • packages/leadtype/src/cli.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • packages/leadtype/src/cli.test.ts
  • packages/leadtype/src/cli.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code

Files:

  • packages/leadtype/src/cli.test.ts
  • packages/leadtype/src/cli.ts
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • packages/leadtype/src/cli.test.ts
🪛 markdownlint-cli2 (0.22.1)
.changeset/fix-symlinked-cli-direct-run.md

[warning] 5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🔇 Additional comments (3)
.changeset/fix-symlinked-cli-direct-run.md (1)

5-5: Release note is clear and aligned with the fix.

This changeset entry accurately describes the symlink/bin-shim direct-run behavior correction.

packages/leadtype/src/cli.ts (1)

65-71: Canonical-path comparison helper looks good.

Using realpath with a fallback here is a solid, resilient approach for symlinked entrypoint detection.

packages/leadtype/src/cli.test.ts (1)

98-128: Excellent regression coverage for symlinked direct-run paths.

This test meaningfully captures both .bin and symlinked package entrypoint scenarios and validates the realpath-based fix end-to-end.

@KayleeWilliams KayleeWilliams merged commit 92192a7 into main May 12, 2026
3 checks passed
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.

1 participant