MCPcopy
hub / github.com/simstudioai/sim / executeVfsGrep

Function executeVfsGrep

apps/sim/lib/copilot/tools/handlers/vfs.ts:69–162  ·  view source on GitHub ↗
(
  params: Record<string, unknown>,
  context: ExecutionContext
)

Source from the content-addressed store, hash-verified

67}
68
69export async function executeVfsGrep(
70 params: Record<string, unknown>,
71 context: ExecutionContext
72): Promise<ToolCallResult> {
73 const pattern = params.pattern as string | undefined
74 if (!pattern) {
75 return { success: false, error: "Missing required parameter 'pattern'" }
76 }
77 const outputMode = (params.output_mode as string) ?? 'content'
78
79 const workspaceId = context.workspaceId
80 if (!workspaceId) {
81 return { success: false, error: 'No workspace context available' }
82 }
83
84 const rawPath = typeof params.path === 'string' ? params.path : undefined
85
86 try {
87 const grepOptions = {
88 maxResults: (params.maxResults as number) ?? 50,
89 outputMode: outputMode as 'content' | 'files_with_matches' | 'count',
90 ignoreCase: (params.ignoreCase as boolean) ?? false,
91 lineNumbers: (params.lineNumbers as boolean) ?? true,
92 context: (params.context as number) ?? 0,
93 }
94
95 // Routing mirrors read/glob:
96 // - uploads/<file> -> grep one chat upload's content (chat-scoped)
97 // - files/<file> -> grep one workspace file's content (one file only)
98 // - everything else -> grep the in-memory VFS map (workflow JSON, metadata)
99 // Chat uploads are opt-in like recently-deleted/: they are never in the VFS
100 // map, so an unscoped grep can't touch them — only an explicit uploads/<file>
101 // path does, and only one upload at a time.
102 let result: GrepMatch[] | string[] | GrepCountEntry[]
103 if (isChatUploadGrepPath(rawPath)) {
104 if (!context.chatId) {
105 return { success: false, error: 'No chat context available for uploads/' }
106 }
107 // The upload is the first segment after uploads/; any trailing segment
108 // (e.g. a /content suffix) is ignored, mirroring the uploads read path.
109 const filename = rawPath
110 .replace(/^\/+/, '')
111 .replace(/^uploads\/?/, '')
112 .split('/')[0]
113 if (!filename) {
114 return {
115 success: false,
116 error:
117 'Grep over chat uploads must target a single upload (e.g. path: "uploads/report.json"). Use glob("uploads/*") to list uploads.',
118 }
119 }
120 result = await grepChatUpload(filename, context.chatId, pattern, grepOptions)
121 } else {
122 const vfs = await getOrMaterializeVFS(workspaceId, context.userId)
123 result = isWorkspaceFileGrepPath(rawPath)
124 ? await vfs.grepFile(rawPath, pattern, grepOptions)
125 : await vfs.grep(pattern, rawPath, grepOptions)
126 }

Callers 1

vfs.test.tsFile · 0.90

Calls 12

grepChatUploadFunction · 0.90
getOrMaterializeVFSFunction · 0.90
toErrorFunction · 0.90
getErrorMessageFunction · 0.90
isChatUploadGrepPathFunction · 0.85
isWorkspaceFileGrepPathFunction · 0.85
serializedResultSizeFunction · 0.85
grepFileMethod · 0.80
grepMethod · 0.80
debugMethod · 0.80
errorMethod · 0.80
replaceMethod · 0.65

Tested by

no test coverage detected