diff --git a/package.json b/package.json index 4b35ece..a888991 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "plist": "^3.1.0", "pluralize": "^8.0.0", "prompts": "^2.4.2", + "untildify": "^6.0.0", "update-notifier": "^7.3.1", "uuid": "^13.0.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c4da41e..792c150 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: prompts: specifier: ^2.4.2 version: 2.4.2 + untildify: + specifier: ^6.0.0 + version: 6.0.0 update-notifier: specifier: ^7.3.1 version: 7.3.1 @@ -4889,6 +4892,10 @@ packages: unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + untildify@6.0.0: + resolution: {integrity: sha512-sA2YTBvW2F463GvSbiZtso+dpuQV+B7xX9saX30SGrR5Fyx4AUcvA/zN+ShAkABKUKVyDaHECsJrHv5ToTuHsQ==} + engines: {node: '>=20'} + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -10723,6 +10730,8 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + untildify@6.0.0: {} + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: browserslist: 4.28.1 diff --git a/src/utils/resolve-project-path.spec.ts b/src/utils/resolve-project-path.spec.ts index 91580f7..7f4f224 100644 --- a/src/utils/resolve-project-path.spec.ts +++ b/src/utils/resolve-project-path.spec.ts @@ -1,5 +1,5 @@ import { homedir } from 'node:os' -import { join } from 'node:path' +import { join, normalize } from 'node:path' import { describe, expect, it, vi, beforeEach } from 'vitest' const mockDaemonListProjects = vi.fn() @@ -33,7 +33,8 @@ describe('resolveProjectPath', () => { it('should expand tilde to home directory', async () => { const result = await resolveProjectPath('~/projects') - expect(result).toBe(join(homedir(), 'projects')) + // untildify keeps the input slash; normalize for Windows + expect(normalize(result)).toBe(join(homedir(), 'projects')) }) it('should return paths with slashes', async () => { diff --git a/src/utils/resolve-project-path.ts b/src/utils/resolve-project-path.ts index 2872790..b16889a 100644 --- a/src/utils/resolve-project-path.ts +++ b/src/utils/resolve-project-path.ts @@ -1,5 +1,5 @@ -import { homedir } from 'node:os' -import { isAbsolute, join } from 'node:path' +import { isAbsolute } from 'node:path' +import untildify from 'untildify' import { daemonListProjects } from '../daemon/daemon-list-projects.js' /** @@ -25,16 +25,6 @@ function isPath(input: string): boolean { return false } -/** - * Expand tilde to home directory - */ -function expandTilde(input: string): string { - if (input.startsWith('~')) { - return join(homedir(), input.slice(1)) - } - return input -} - export class ProjectNotFoundError extends Error { constructor(projectName: string) { super( @@ -70,7 +60,7 @@ export async function resolveProjectPath( // 2. If it looks like a path, return it (with tilde expansion) if (isPath(input)) { - return expandTilde(input) + return untildify(input) } // 3. Otherwise treat as project name - look up in daemon