index.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /**
  2. * Browser-safe Workspace path and display helpers.
  3. * @module @deepseek-ai/dsh-util-workspace-path
  4. */
  5. /** Whether a path uses a Windows drive or UNC prefix. */
  6. function isWindowsStylePath(value: string): boolean {
  7. return /^[A-Za-z]:[/\\]/.test(value) || value.startsWith('\\\\')
  8. }
  9. /**
  10. * Resolve a Workspace-relative path into the Host-facing spelling used by path operations.
  11. * @param cwd - Session Workspace root, when known.
  12. * @param path - Absolute or Workspace-relative path.
  13. * @returns an absolute path when a Workspace root is available, otherwise the original path.
  14. */
  15. export function resolveWorkspacePath(cwd: string | undefined, path: string): string {
  16. if (path.startsWith('/') || isWindowsStylePath(path)) return path
  17. if (cwd === undefined || cwd === '') return path
  18. const base = cwd.replace(/[/\\]+$/, '')
  19. const relative = path.replace(/^[/\\]+/, '')
  20. return `${base}/${relative}`
  21. }
  22. /**
  23. * Abbreviate a POSIX home directory for display.
  24. * @param path - Absolute or already-short display path.
  25. * @param home - Host account home; absent skips abbreviation.
  26. * @returns `~` or `~/…` for the POSIX home and its descendants, otherwise `path`.
  27. */
  28. export function abbreviateHomePath(path: string, home?: string): string {
  29. if (home === undefined || home === '') return path
  30. if (isWindowsStylePath(path) || isWindowsStylePath(home)) return path
  31. const root = home.replace(/\/+$/, '')
  32. if (root === '' || root === '/') return path
  33. if (path.replace(/\/+$/, '') === root) return '~'
  34. if (path.startsWith(`${root}/`)) return `~${path.slice(root.length)}`
  35. return path
  36. }
  37. /**
  38. * Read the final non-empty segment of a Workspace path for display.
  39. * Workspace-label surfaces use this helper instead of deriving another basename.
  40. * @param path - Workspace directory path using POSIX or Windows separators.
  41. * @returns the final segment, or an empty string for a separator-only path.
  42. */
  43. export function workspaceTitleOf(path: string): string {
  44. const trimmed = path.replace(/[/\\]+$/, '')
  45. const separator = Math.max(trimmed.lastIndexOf('/'), trimmed.lastIndexOf('\\'))
  46. return trimmed.slice(separator + 1)
  47. }