Download packages/coding-agent/src/core/tools/path-utils.ts from SaylorTwift/pi: direct link, hf CLI and curl.
- Browser
- Download file 3.63 kB
-
https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/src/core/tools/path-utils.ts
- Command line
-
hf download hf://SaylorTwift/pi/packages/coding-agent/src/core/tools/path-utils.ts
-
curl -L -o path-utils.ts https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/src/core/tools/path-utils.ts
3.63 kB
| import { accessSync, constants } from "node:fs"; | |
| import { access } from "node:fs/promises"; | |
| import { normalizePath, resolvePath } from "../../utils/paths.ts"; | |
| const NARROW_NO_BREAK_SPACE = "\u202F"; | |
| function tryMacOSScreenshotPath(filePath: string): string { | |
| return filePath.replace(/ (AM|PM)\./gi, `${NARROW_NO_BREAK_SPACE}$1.`); | |
| } | |
| function tryNFDVariant(filePath: string): string { | |
| // macOS stores filenames in NFD (decomposed) form, try converting user input to NFD | |
| return filePath.normalize("NFD"); | |
| } | |
| function tryCurlyQuoteVariant(filePath: string): string { | |
| // macOS uses U+2019 (right single quotation mark) in screenshot names like "Capture d'écran" | |
| // Users typically type U+0027 (straight apostrophe) | |
| return filePath.replace(/'/g, "\u2019"); | |
| } | |
| function fileExists(filePath: string): boolean { | |
| try { | |
| accessSync(filePath, constants.F_OK); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| export async function pathExists(filePath: string): Promise<boolean> { | |
| try { | |
| await access(filePath, constants.F_OK); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| export function expandPath(filePath: string): string { | |
| return normalizePath(filePath, { normalizeUnicodeSpaces: true, stripAtPrefix: true }); | |
| } | |
| /** | |
| * Resolve a path relative to the given cwd. | |
| * Handles ~ expansion and absolute paths. | |
| */ | |
| export function resolveToCwd(filePath: string, cwd: string): string { | |
| return resolvePath(filePath, cwd, { normalizeUnicodeSpaces: true, stripAtPrefix: true }); | |
| } | |
| export function resolveReadPath(filePath: string, cwd: string): string { | |
| const resolved = resolveToCwd(filePath, cwd); | |
| if (fileExists(resolved)) { | |
| return resolved; | |
| } | |
| // Try macOS AM/PM variant (narrow no-break space before AM/PM) | |
| const amPmVariant = tryMacOSScreenshotPath(resolved); | |
| if (amPmVariant !== resolved && fileExists(amPmVariant)) { | |
| return amPmVariant; | |
| } | |
| // Try NFD variant (macOS stores filenames in NFD form) | |
| const nfdVariant = tryNFDVariant(resolved); | |
| if (nfdVariant !== resolved && fileExists(nfdVariant)) { | |
| return nfdVariant; | |
| } | |
| // Try curly quote variant (macOS uses U+2019 in screenshot names) | |
| const curlyVariant = tryCurlyQuoteVariant(resolved); | |
| if (curlyVariant !== resolved && fileExists(curlyVariant)) { | |
| return curlyVariant; | |
| } | |
| // Try combined NFD + curly quote (for French macOS screenshots like "Capture d'écran") | |
| const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant); | |
| if (nfdCurlyVariant !== resolved && fileExists(nfdCurlyVariant)) { | |
| return nfdCurlyVariant; | |
| } | |
| return resolved; | |
| } | |
| export async function resolveReadPathAsync(filePath: string, cwd: string): Promise<string> { | |
| const resolved = resolveToCwd(filePath, cwd); | |
| if (await pathExists(resolved)) { | |
| return resolved; | |
| } | |
| // Try macOS AM/PM variant (narrow no-break space before AM/PM) | |
| const amPmVariant = tryMacOSScreenshotPath(resolved); | |
| if (amPmVariant !== resolved && (await pathExists(amPmVariant))) { | |
| return amPmVariant; | |
| } | |
| // Try NFD variant (macOS stores filenames in NFD form) | |
| const nfdVariant = tryNFDVariant(resolved); | |
| if (nfdVariant !== resolved && (await pathExists(nfdVariant))) { | |
| return nfdVariant; | |
| } | |
| // Try curly quote variant (macOS uses U+2019 in screenshot names) | |
| const curlyVariant = tryCurlyQuoteVariant(resolved); | |
| if (curlyVariant !== resolved && (await pathExists(curlyVariant))) { | |
| return curlyVariant; | |
| } | |
| // Try combined NFD + curly quote (for French macOS screenshots like "Capture d'écran") | |
| const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant); | |
| if (nfdCurlyVariant !== resolved && (await pathExists(nfdCurlyVariant))) { | |
| return nfdCurlyVariant; | |
| } | |
| return resolved; | |
| } | |