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

Method create

src/node/services/workspaceService.ts:3023–3326  ·  view source on GitHub ↗
(
    projectPath: string,
    branchName: string | undefined,
    trunkBranch: string | undefined,
    title?: string,
    runtimeConfig?: RuntimeConfig,
    subProjectPath?: string,
    pendingAutoTitle?: boolean,
    tags?: Record<string, string>
  )

Source from the content-addressed store, hash-verified

3021 }
3022
3023 async create(
3024 projectPath: string,
3025 branchName: string | undefined,
3026 trunkBranch: string | undefined,
3027 title?: string,
3028 runtimeConfig?: RuntimeConfig,
3029 subProjectPath?: string,
3030 pendingAutoTitle?: boolean,
3031 tags?: Record<string, string>
3032 ): Promise<Result<{ metadata: FrontendWorkspaceMetadata }>> {
3033 if (tags != null) {
3034 for (const [tagKey, tagValue] of Object.entries(tags)) {
3035 assert(tagKey.trim().length > 0, "Workspace tag keys must be non-empty");
3036 assert(typeof tagValue === "string", "Workspace tag values must be strings");
3037 }
3038 }
3039 const configSnapshot = this.config.loadConfigOrDefault();
3040 const requestedProjectPath = stripTrailingSlashes(projectPath);
3041 const requestedProjectConfig = configSnapshot.projects.get(requestedProjectPath);
3042 const owningProjectPath = requestedProjectConfig?.parentProjectPath ?? requestedProjectPath;
3043 const effectiveSubProjectPath = requestedProjectConfig?.parentProjectPath
3044 ? requestedProjectPath
3045 : subProjectPath;
3046 const projectConfig = configSnapshot.projects.get(owningProjectPath);
3047
3048 if (
3049 effectiveSubProjectPath &&
3050 configSnapshot.projects.get(effectiveSubProjectPath)?.parentProjectPath !== owningProjectPath
3051 ) {
3052 return Err(`Sub-project not found under parent: ${effectiveSubProjectPath}`);
3053 }
3054
3055 // Trust gate: block workspace creation for untrusted projects.
3056 // The frontend shows a confirmation dialog before reaching here,
3057 // but this guards secondary paths (slash commands, forking). Sub-projects
3058 // share their parent's checkout, so trust is owned by that parent project.
3059 if (!projectConfig?.trusted) {
3060 return Err(
3061 "This project must be trusted before creating workspaces. Trust the project in Settings → Security, or create a workspace from the project page."
3062 );
3063 }
3064
3065 // Auto-generate a branch name when the caller omits one (used by /new to
3066 // mirror /fork's seamless creation flow). Mirrors fork's auto-naming: scan
3067 // existing workspace names AND local git branches so numbering is stable.
3068 // Branches/worktrees are owned by the parent project, so always read from
3069 // owningProjectPath even when a sub-project initiated creation.
3070 let resolvedBranchName: string;
3071 if (branchName == null) {
3072 const existingNamesSet = new Set<string>();
3073 for (const entry of projectConfig.workspaces ?? []) {
3074 if (typeof entry.name === "string") {
3075 existingNamesSet.add(entry.name);
3076 }
3077 }
3078 try {
3079 for (const localBranch of await listLocalBranches(owningProjectPath)) {
3080 existingNamesSet.add(localBranch);

Callers

nothing calls this directly

Calls 15

getOrCreateSessionMethod · 0.95
createInitLoggerMethod · 0.95
stripTrailingSlashesFunction · 0.90
ErrFunction · 0.90
listLocalBranchesFunction · 0.90
getErrorMessageFunction · 0.90
validateWorkspaceNameFunction · 0.90
createRuntimeFunction · 0.90
getSrcBaseDirFunction · 0.90
hasSrcBaseDirFunction · 0.90
secretsToRecordFunction · 0.90

Tested by

no test coverage detected