@@ -21,10 +21,8 @@ import {
2121 ManageScheduledTaskOperation ,
2222 ManageSkill ,
2323 ManageSkillOperation ,
24- MoveWorkflow ,
2524 QueryLogs ,
2625 Redeploy ,
27- RenameWorkflow ,
2826 RunFromBlock ,
2927 RunWorkflow ,
3028 RunWorkflowUntilBlock ,
@@ -34,7 +32,7 @@ import {
3432 WorkspaceFileOperation ,
3533} from '@/lib/copilot/generated/tool-catalog-v1'
3634import { VFS_DIR_TO_RESOURCE } from '@/lib/copilot/resources/types'
37- import { getToolDisplayTitle } from '@/lib/copilot/tools/tool-display'
35+ import { getToolDisplayTitle , mvDisplayVerb } from '@/lib/copilot/tools/tool-display'
3836import type { ContentBlock , MothershipResource } from '@/app/workspace/[workspaceId]/home/types'
3937import { ToolCallStatus } from '@/app/workspace/[workspaceId]/home/types'
4038import { getWorkflowById } from '@/hooks/queries/utils/workflow-cache'
@@ -52,12 +50,15 @@ export const DEPLOY_TOOL_NAMES: Set<string> = new Set([
5250 Redeploy . id ,
5351] )
5452
55- export const FOLDER_TOOL_NAMES : Set < string > = new Set ( [ ManageFolder . id ] )
53+ export const FOLDER_TOOL_NAMES : Set < string > = new Set ( [ ManageFolder . id , 'mkdir' , 'mv' ] )
5654
5755export const WORKFLOW_MUTATION_TOOL_NAMES : Set < string > = new Set ( [
58- MoveWorkflow . id ,
59- RenameWorkflow . id ,
56+ 'mv' ,
57+ 'cp' ,
6058 DeleteWorkflow . id ,
59+ // Removed legacy tools, kept while their grace-period executors remain.
60+ 'move_workflow' ,
61+ 'rename_workflow' ,
6162] )
6263
6364export type StreamPayload = Record < string , unknown >
@@ -289,6 +290,30 @@ export function resolveStreamingToolDisplayTitle(
289290 return toolTitle ? `Finding ${ toolTitle } ` : undefined
290291 }
291292
293+ if ( name === 'mv' ) {
294+ const toolTitle = matchStreamingStringArg ( streamingArgs , 'toolTitle' )
295+ if ( ! toolTitle ) return undefined
296+ // Same rename-vs-move derivation as the settled title: single source with
297+ // only the leaf changing reads as a rename.
298+ const multiSource = / " s o u r c e s " \s * : \s * \[ \s * " [ ^ " ] * " \s * , / . test ( streamingArgs )
299+ const firstSource = streamingArgs . match ( / " s o u r c e s " \s * : \s * \[ \s * " ( [ ^ " ] * ) " / m) ?. [ 1 ]
300+ const destination = matchStreamingStringArg ( streamingArgs , 'destination' )
301+ const verb = multiSource
302+ ? 'Moving'
303+ : mvDisplayVerb ( firstSource ? decodeStreamingString ( firstSource ) : undefined , destination )
304+ return `${ verb } ${ toolTitle } `
305+ }
306+
307+ if ( name === 'cp' ) {
308+ const toolTitle = matchStreamingStringArg ( streamingArgs , 'toolTitle' )
309+ return toolTitle ? `Duplicating ${ toolTitle } ` : undefined
310+ }
311+
312+ if ( name === 'mkdir' ) {
313+ const toolTitle = matchStreamingStringArg ( streamingArgs , 'toolTitle' )
314+ return toolTitle ? `Creating ${ toolTitle } ` : undefined
315+ }
316+
292317 if ( name === ScrapePage . id ) {
293318 const url = matchStreamingStringArg ( streamingArgs , 'url' )
294319 return url ? `Scraping ${ url } ` : undefined
@@ -364,12 +389,15 @@ export function resolveStreamingToolDisplayTitle(
364389 }
365390
366391 if ( name === ManageFolder . id ) {
392+ // create/rename/move are string literals: the live tool only offers delete
393+ // (mkdir/mv replaced the rest), but grace-period checkpoint resumes and
394+ // transcript replays still stream the legacy operations.
367395 return resolveOperationDisplayTitle (
368396 matchStreamingStringArg ( streamingArgs , 'operation' ) ,
369397 {
370- [ ManageFolderOperation . create ] : 'Creating folder' ,
371- [ ManageFolderOperation . rename ] : 'Renaming folder' ,
372- [ ManageFolderOperation . move ] : 'Moving folder' ,
398+ create : 'Creating folder' ,
399+ rename : 'Renaming folder' ,
400+ move : 'Moving folder' ,
373401 [ ManageFolderOperation . delete ] : 'Deleting folder' ,
374402 } ,
375403 'Folder action'
0 commit comments