Skip to content

fix(plugins): update path handling to support both POSIX and Windows …#2296

Open
utsav1033 wants to merge 1 commit into
different-ai:devfrom
utsav1033:fix/windows-plugin-paths-clean
Open

fix(plugins): update path handling to support both POSIX and Windows …#2296
utsav1033 wants to merge 1 commit into
different-ai:devfrom
utsav1033:fix/windows-plugin-paths-clean

Conversation

@utsav1033

@utsav1033 utsav1033 commented Jun 16, 2026

Copy link
Copy Markdown

Summary

Fix normalizePluginSpec so Windows absolute paths are recognized as local plugin specs instead of being parsed as package names.

Why

normalizePluginSpec only treated /-prefixed strings as absolute paths. On Windows, an absolute path like C:\Users\me\my-plugin doesn't start with /, so it fell through to package-name logic that splits on @. A local plugin path containing @ (e.g. C:\Users\me@work\my-plugin) was truncated to C:\Users\me, silently pointing at the wrong location.

Issue

  • N/A (no existing issue; bug found while testing plugin specs on Windows)

Scope

  • apps/server/src/plugins.ts: recognize both posix and win32 absolute paths via node:path (posix.isAbsolute / win32.isAbsolute), so the check is correct regardless of host OS.
  • apps/server/src/plugins.test.ts: new unit tests for normalizePluginSpec.

Out of scope

  • No changes to plugin loading, validation, or any other normalization branch (file:/http:/https:/git:/scoped packages preserved as-is).

Testing

Ran

  • bun test src/plugins.test.ts
  • tsc --noEmit

Result

  • pass/fail: pass (6/6 new tests, typecheck clean)
  • if fail, exact files/errors: N/A

CI status

  • pass: 6/6 new tests, tsc clean
  • code-related failures: none
  • external/env/auth blockers: pre-existing Windows suite failures (incl. cloud-plugins.test.ts EBUSY temp-dir flakes) are present on dev before this change. This PR introduces 0 new failures and touches only the two files above.

Manual verification

  1. On dev, normalizePluginSpec("C:\\Users\\me@work\\my-plugin") returns C:\Users\me (truncated at @).
  2. After this change, the same input returns C:\Users\me@work\my-plugin unchanged.
  3. POSIX absolute paths and package/scope/url specs behave exactly as before (covered by tests).

Evidence

Screenshot 2026-06-17 023824

Risk

  • Low. Single normalization branch widened; all other branches untouched. win32.isAbsolute won't false-positive on package names (they contain no drive letters or backslashes).

Rollback

  • Revert this PR. No migrations, no state, no config changes.

Review in cubic

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-landing Ready Ready Preview, Comment, Open in v0 Jun 16, 2026 9:13pm

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

@utsav1033 is attempting to deploy a commit to the Different AI Team on Vercel.

A member of the Team first needs to authorize it.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 2 files

Re-trigger cubic

@Abhijeet1005

Copy link
Copy Markdown

Pulled this and verified it on Windows, where this bug actually bites — it's a real bug and the fix is correct.

Reproduced the bug with the pre-fix logic: a Windows absolute path containing @ was silently truncated.

input:  C:\Users\me@work\my-plugin
before: C:\Users\me                  <- truncated at the @, points at the wrong location
after:  C:\Users\me@work\my-plugin   <- preserved

The old startsWith("/") check didn't recognize Windows paths, so they fell through to the package-name branch that splits on @. Switching to posix.isAbsolute(trimmed) || win32.isAbsolute(trimmed) is the right call.

Verified:

  • bun test apps/server/src/plugins.test.ts -> 6/6 pass
  • tsc --noEmit (apps/server) -> clean
  • Ran old vs. new across packages, scoped packages, file:/https: URLs, relative paths, and POSIX-absolute paths — all identical, so the only behavior change is the Windows-absolute-with-@ case. No regressions.

Bonus: the fix also handles cases the tests don't assert yet — forward-slash Windows paths (C:/Users/me@work/...) and UNC paths (\\server\share\...@1) were truncated before and are preserved now.

Small non-blocking suggestion: since the fix already covers them, adding a C:/... (forward-slash) and a UNC case to the test would lock that behavior in — right now only the backslash form is asserted.

Nice catch — exactly the kind of silent path corruption that's easy to miss on macOS/Linux.

@utsav1033

Copy link
Copy Markdown
Author

Thanks for pulling it and verifying on Windows, appreciate it.

@Pablosinyores

Copy link
Copy Markdown

Good catch on the @-in-directory truncation — nasty silent failure. Swapping startsWith("/") for posix.isAbsolute(trimmed) || win32.isAbsolute(trimmed) also picks up UNC (\\server\share) and drive-relative (\foo) paths, which is the right call.

One edge worth a test: a bare drive-relative path like C:plugin (no separator) — win32.isAbsolute("C:plugin") is false, so it still falls through to package-name logic. Likely not a real plugin spec, but an explicit test next to the C:\Users\me@work one would lock the behavior down. Coverage is otherwise clean.

@utsav1033

Copy link
Copy Markdown
Author

Thanks. Agreed C:plugin (drive-relative) correctly falls through since it isn't absolute, and it's not a realistic plugin spec, so I'd rather keep this PR scoped to the absolute-path truncation bug and not assert behavior for that edge here. Happy to revisit if it ever comes up as a real case.

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.

3 participants