diff --git a/apps/sim/lib/mothership/agent-cli/file-provenance.test.ts b/apps/sim/lib/mothership/agent-cli/file-provenance.test.ts index 893d05af5e5..8ad6fb769c1 100644 --- a/apps/sim/lib/mothership/agent-cli/file-provenance.test.ts +++ b/apps/sim/lib/mothership/agent-cli/file-provenance.test.ts @@ -497,6 +497,15 @@ describe('file provenance at the actual CLI and model-result boundary', () => { ) }) + it('answers files search as a search, refused until its results report provenance', async () => { + const result = await runCli({ kind: 'cli', argv: ['files', 'search', '--query', 'CANARY'] }) + expect(result.success).toBe(false) + expect(JSON.stringify(result)).toContain('grep --scope files') + expect(mocks.reference).not.toHaveBeenCalled() + expect(mocks.file).not.toHaveBeenCalled() + expect(mocks.stream).not.toHaveBeenCalled() + }) + it('refuses an unknown file through the actual CLI text read without loading its bytes', async () => { classify('unknown') const result = await runCli(readFile) diff --git a/apps/sim/lib/mothership/agent-cli/file-read-transport.ts b/apps/sim/lib/mothership/agent-cli/file-read-transport.ts index 436ec74380d..d0ee33fd263 100644 --- a/apps/sim/lib/mothership/agent-cli/file-read-transport.ts +++ b/apps/sim/lib/mothership/agent-cli/file-read-transport.ts @@ -5,6 +5,7 @@ import { v2DownloadFileContract, v2ListFileFoldersContract, v2ReadFileTextContract, + v2SearchFileContentContract, } from '@/lib/api/contracts/v2/files' import { authenticateV2ApiKey, @@ -54,6 +55,8 @@ export function createFileReadTransport(context: { `${basePath}${v2ListFileFoldersContract.path}`, `${basePath}${v2BulkDownloadFilesContract.path}`, ]) + /** Search results quote file text but name no file provenance, so Chat cannot admit them. */ + const searchPath = `${basePath}${v2SearchFileContentContract.path}` /** * Admits one delivery's classification into the invocation registry. A delivery it refuses is * either withheld (text and forwarded responses reach only the model, so refusing them is enough) @@ -135,6 +138,18 @@ export function createFileReadTransport(context: { ) { return forward(input, init) } + if (url.pathname === searchPath) { + return Response.json( + { + error: { + code: 'FORBIDDEN', + message: + 'files search is unavailable in Chat. Search file contents with grep --scope files.', + }, + }, + { status: 403 } + ) + } const match = /^([^/]+)(\/text)?$/.exec(url.pathname.slice(prefix.length)) if (!match) return forward(input, init) const request = new NextRequest(new Request(input, init))