MCPcopy
hub / github.com/coder/mux / create

Method create

src/node/services/projectService.ts:396–517  ·  view source on GitHub ↗
(
    projectPath: string
  )

Source from the content-addressed store, hash-verified

394 }
395
396 async create(
397 projectPath: string
398 ): Promise<Result<{ projectConfig: ProjectConfig; normalizedPath: string }>> {
399 try {
400 // Validate input
401 if (!projectPath || projectPath.trim().length === 0) {
402 return Err("Project path cannot be empty");
403 }
404
405 // Resolve the path:
406 // - Bare names like "my-project" → ~/.mux/projects/my-project
407 // - Paths with ~ → expand to home directory
408 // - Absolute/relative paths → resolve normally
409 const isBareProjectName =
410 projectPath.length > 0 &&
411 !projectPath.includes("/") &&
412 !projectPath.includes("\\") &&
413 !projectPath.startsWith("~");
414
415 const config = this.config.loadConfigOrDefault();
416 let normalizedPath: string;
417 if (isBareProjectName) {
418 // Bare project name - put in default projects directory
419 const parentDir = resolveProjectParentDir(undefined, config.defaultProjectDir);
420 normalizedPath = path.join(parentDir, projectPath);
421 } else if (
422 projectPath === "~" ||
423 projectPath.startsWith("~/") ||
424 projectPath.startsWith("~\\")
425 ) {
426 // Tilde expansion - uses expandTilde to respect MUX_ROOT for ~/.mux paths
427 normalizedPath = path.resolve(expandTilde(projectPath));
428 } else {
429 normalizedPath = path.resolve(projectPath);
430 }
431
432 let existingStat: Stats | null = null;
433 try {
434 existingStat = await fsPromises.stat(normalizedPath);
435 } catch (error) {
436 const err = error as NodeJS.ErrnoException;
437 if (err.code !== "ENOENT") {
438 throw error;
439 }
440 }
441
442 if (existingStat && !existingStat.isDirectory()) {
443 return Err("Project path is not a directory");
444 }
445
446 if (config.projects.has(normalizedPath)) {
447 return Err("Project already exists");
448 }
449
450 const createdDirectory = existingStat == null;
451 const cleanupCreatedDirectory = async () => {
452 if (!createdDirectory) return;
453 try {

Callers

nothing calls this directly

Calls 15

ErrFunction · 0.90
expandTildeFunction · 0.90
deriveProjectHierarchyFunction · 0.90
isPathDescendantFunction · 0.90
OkFunction · 0.90
getErrorMessageFunction · 0.90
resolveProjectParentDirFunction · 0.85
resolveRealProjectPathFunction · 0.85
readGitTopLevelFunction · 0.85
loadConfigOrDefaultMethod · 0.80

Tested by

no test coverage detected