MCPcopy Index your code
hub / github.com/simstudioai/sim / createFork

Function createFork

apps/sim/lib/workspaces/fork/create-fork.ts:109–424  ·  view source on GitHub ↗
(params: CreateForkParams)

Source from the content-addressed store, hash-verified

107 * all credential references) are cleared; env-var references are preserved.
108 */
109export async function createFork(params: CreateForkParams): Promise<CreateForkResult> {
110 const { source, policy, userId, requestId = 'unknown' } = params
111 const selection = params.selection ?? EMPTY_SELECTION
112 const childName = params.name?.trim() || `${source.name} (fork)`
113
114 // Read the source's deployed workflows + states BEFORE the transaction so these
115 // global-pool reads don't check out a second pooled connection from inside the
116 // fork tx (which can deadlock the pool at saturation).
117 const { deployedWorkflows, sourceStates } = await loadSourceDeployedStates(source.id)
118
119 // Documents the copied workflows reference (document-selector values + nested documentId
120 // tool params). Those whose parent KB is being copied get a placeholder + id map inside the
121 // fork tx so their references remap to the copied document instead of being cleared.
122 const referencedDocumentIds = collectReferencedDocumentIds(
123 deployedWorkflows.flatMap((wf) => {
124 const sourceState = sourceStates.get(wf.id)
125 return sourceState ? [sourceState] : []
126 })
127 )
128
129 const forkedWorkflowNames: string[] = []
130 let forkedResourceNames: ForkCopiedResourceNames = {
131 tables: [],
132 knowledgeBases: [],
133 customTools: [],
134 skills: [],
135 workflowMcpServers: [],
136 }
137 const { result, blobTasks, contentPlan, contentRefMaps } = await db.transaction(async (tx) => {
138 await setForkLockTimeout(tx)
139 const now = new Date()
140 const childWorkspaceId = generateId()
141
142 await tx.insert(workspace).values({
143 id: childWorkspaceId,
144 name: childName,
145 ownerId: userId,
146 organizationId: policy.organizationId,
147 workspaceMode: policy.workspaceMode,
148 billedAccountUserId: policy.billedAccountUserId,
149 allowPersonalApiKeys: true,
150 forkedFromWorkspaceId: source.id,
151 createdAt: now,
152 updatedAt: now,
153 })
154
155 const sourcePermissions = await tx
156 .select({ userId: permissions.userId, permissionType: permissions.permissionType })
157 .from(permissions)
158 .where(and(eq(permissions.entityType, 'workspace'), eq(permissions.entityId, source.id)))
159
160 const permissionByUser = new Map<string, PermissionType>()
161 for (const row of sourcePermissions) {
162 permissionByUser.set(row.userId, row.permissionType)
163 }
164 permissionByUser.set(userId, 'admin')
165 if (
166 policy.workspaceMode === WORKSPACE_MODE.ORGANIZATION &&

Callers 1

route.tsFile · 0.90

Calls 15

loadSourceDeployedStatesFunction · 0.90
setForkLockTimeoutFunction · 0.90
generateIdFunction · 0.90
buildForkWorkflowIdMapFunction · 0.90
planForkFileCopiesFunction · 0.90
resolveForkFolderMappingFunction · 0.90
loadWorkflowNameRegistryFunction · 0.90
toForkBlockPairsFunction · 0.90

Tested by

no test coverage detected