( metadata: WorkspaceMetadataForRuntime, runtime: Runtime, workspaceRoot: string )
| 84 | * sub-project paths by falling back to the workspace root. |
| 85 | */ |
| 86 | export function appendSubProjectRelativePath( |
| 87 | metadata: WorkspaceMetadataForRuntime, |
| 88 | runtime: Runtime, |
| 89 | workspaceRoot: string |
| 90 | ): string { |
| 91 | const subProjectPath = metadata.subProjectPath?.trim(); |
| 92 | if (!subProjectPath) { |
| 93 | return workspaceRoot; |
| 94 | } |
| 95 | |
| 96 | // Self-heal stale persisted state: project paths can change (e.g. project |
| 97 | // removed/re-added at a new location, config edited by hand). When the |
| 98 | // recorded sub-project path is no longer a descendant of the workspace's |
| 99 | // owning project, fall back to the workspace root rather than throwing — |
| 100 | // a wrong cwd is recoverable, a thrown error here breaks workspace |
| 101 | // startup/commands until the user manually edits the config. |
| 102 | const relativeSubProjectPath = path.relative(metadata.projectPath, subProjectPath); |
| 103 | if ( |
| 104 | !relativeSubProjectPath || |
| 105 | relativeSubProjectPath.startsWith("..") || |
| 106 | path.isAbsolute(relativeSubProjectPath) |
| 107 | ) { |
| 108 | return workspaceRoot; |
| 109 | } |
| 110 | |
| 111 | const runtimeRelativeSubProjectPath = relativeSubProjectPath.replace(/\\/g, "/"); |
| 112 | |
| 113 | // Use the runtime path normalizer so SSH/Docker/devcontainer cwd paths use the |
| 114 | // target runtime's separator semantics instead of host-only path joining. |
| 115 | return runtime.normalizePath(runtimeRelativeSubProjectPath, workspaceRoot); |
| 116 | } |
| 117 | |
| 118 | export function resolveWorkspaceExecutionPath( |
| 119 | metadata: WorkspaceMetadataForRuntime, |
no test coverage detected