Skip to content

Commit 0933773

Browse files
raulggraycastbot
andauthored
[skills] Fix fnm base directory resolution on macOS (#26552)
* fix: improve fnm base directory resolution * address pr feedback: prefer XDG path over legacy path * Update CHANGELOG.md --------- Co-authored-by: raycastbot <bot@raycast.com>
1 parent dd868b0 commit 0933773

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

extensions/skills/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## [Fix `fnm` macOS Path Resolution] - 2026-03-28
4+
5+
- Detect additional macOS `fnm` install locations, including `~/Library/Application Support/fnm`
6+
- Match the official `fnm` directory resolution preference order when resolving `fnm` paths.
7+
38
## [Agent-Specific Skill Removal] - 2026-03-27
49

510
- Support removing skills from specific agents instead of all agents at once

extensions/skills/src/utils/exec-options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const getExecOptions = async () => {
2626

2727
if (!process.env.FNM_DIR) {
2828
const fnmBaseDir = await resolveFnmBaseDir(home);
29-
if (fnmBaseDir && (await pathExists(fnmBaseDir))) {
29+
if (fnmBaseDir) {
3030
env.FNM_DIR = fnmBaseDir;
3131
}
3232
}

extensions/skills/src/utils/node-path-resolver.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { join } from "node:path";
44
import semver from "semver";
55

66
const isWindows = process.platform === "win32";
7+
const isMacOS = process.platform === "darwin";
78

89
let cachedPaths: string | null = null;
910
let cachedPathsPromise: Promise<string> | null = null;
@@ -65,14 +66,21 @@ const scanVersionedNodePaths = async (
6566
export const resolveFnmBaseDir = async (home = process.env.HOME): Promise<string | null> => {
6667
if (!home) return null;
6768

68-
const legacyFnmPath = join(home, ".fnm");
69-
if (await pathExists(legacyFnmPath)) {
70-
// Older fnm installs keep everything under ~/.fnm instead of XDG data directories
71-
return legacyFnmPath;
69+
const xdgBaseDir = join(process.env.XDG_DATA_HOME || join(home, ".local", "share"), "fnm");
70+
const fnmBaseDirCandidates = [xdgBaseDir, join(home, ".fnm")];
71+
72+
if (isMacOS) {
73+
fnmBaseDirCandidates.push(join(home, "Library", "Application Support", "fnm"));
74+
}
75+
76+
for (const dir of fnmBaseDirCandidates) {
77+
if (await pathExists(dir)) {
78+
return dir;
79+
}
7280
}
7381

74-
const xdgDataHome = process.env.XDG_DATA_HOME || join(home, ".local", "share");
75-
return join(xdgDataHome, "fnm");
82+
// Default to the XDG data dir even if it does not exist yet
83+
return xdgBaseDir;
7684
};
7785

7886
export const resolveVersionManagerPaths = async (): Promise<string[]> => {

0 commit comments

Comments
 (0)