Skip to content

Commit 4c64e60

Browse files
committed
feat(copilot): add move operation to file manage API
1 parent 7c08719 commit 4c64e60

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

apps/sim/app/api/tools/file/manage/route.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import { splitWorkspaceFilePath } from '@/lib/copilot/tools/server/files/workspa
77
import { acquireLock, releaseLock } from '@/lib/core/config/redis'
88
import { ensureAbsoluteUrl } from '@/lib/core/utils/urls'
99
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
10-
import { ensureWorkspaceFileFolderPath } from '@/lib/uploads/contexts/workspace/workspace-file-folder-manager'
10+
import {
11+
ensureWorkspaceFileFolderPath,
12+
moveWorkspaceFileItems,
13+
} from '@/lib/uploads/contexts/workspace/workspace-file-folder-manager'
1114
import {
1215
fetchWorkspaceFileBuffer,
1316
getWorkspaceFile,
@@ -127,6 +130,28 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
127130
})
128131
}
129132

133+
case 'move': {
134+
const { fileId, targetFolder } = body
135+
const pathSegments = targetFolder.trim()
136+
? targetFolder
137+
.trim()
138+
.split('/')
139+
.map((s) => s.trim())
140+
.filter(Boolean)
141+
: []
142+
const targetFolderId = await ensureWorkspaceFileFolderPath({
143+
workspaceId,
144+
userId,
145+
pathSegments,
146+
})
147+
await moveWorkspaceFileItems({ workspaceId, fileIds: [fileId], targetFolderId })
148+
logger.info('File moved', { fileId, targetFolder: targetFolder || '(root)' })
149+
return NextResponse.json({
150+
success: true,
151+
data: { fileId, targetFolder: targetFolder || '(root)' },
152+
})
153+
}
154+
130155
case 'append': {
131156
const { fileName, content } = body
132157

apps/sim/lib/api/contracts/tools/file.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,20 @@ export const fileManageGetBodySchema = z
3333
message: 'Either fileId or fileInput is required for get operation',
3434
})
3535

36+
export const fileManageMoveBodySchema = z.object({
37+
operation: z.literal('move'),
38+
workspaceId: z.string().min(1).optional(),
39+
fileId: z.string().min(1, 'fileId is required for move operation'),
40+
targetFolder: z.string(), // empty string = workspace root, "reports" or "reports/Q1" for nested
41+
})
42+
43+
export type FileManageMoveBody = z.input<typeof fileManageMoveBodySchema>
44+
3645
export const fileManageBodySchema = z.union([
3746
fileManageWriteBodySchema,
3847
fileManageAppendBodySchema,
3948
fileManageGetBodySchema,
49+
fileManageMoveBodySchema,
4050
])
4151

4252
export const fileManageContract = defineRouteContract({

0 commit comments

Comments
 (0)