From e89ae222c2bc7bc9be9eeccfa01668a809ee9c81 Mon Sep 17 00:00:00 2001 From: Ray Bell Date: Sat, 3 Jan 2026 00:47:47 -0500 Subject: [PATCH 1/2] doc: and note to install before build --- docs/development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development.md b/docs/development.md index 117144b4..342b2701 100644 --- a/docs/development.md +++ b/docs/development.md @@ -106,7 +106,7 @@ To test your code changes with Gemini CLI you can run: ```bash gemini extensions uninstall google-workspace -npm run build +npm install && npm run build gemini extensions link . gemini extensions list gemini --debug From cbe09eef1a3219d42a8967ce750e56758865c570 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 3 Jan 2026 06:07:48 +0000 Subject: [PATCH 2/2] feat: Add drive.createFolder tool This commit introduces the `drive.createFolder` tool to the workspace server. The new tool is implemented in `workspace-server/src/services/DriveService.ts` and registered in `workspace-server/src/index.ts`. It allows creating a new folder in Google Drive with an optional parent folder. A corresponding unit test has been added to `workspace-server/src/__tests__/services/DriveService.test.ts` to ensure the new functionality is working correctly. --- .../__tests__/services/DriveService.test.ts | 25 +++++++++++++++ workspace-server/src/index.ts | 12 +++++++ workspace-server/src/services/DriveService.ts | 32 +++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/workspace-server/src/__tests__/services/DriveService.test.ts b/workspace-server/src/__tests__/services/DriveService.test.ts index 888deec0..984656c1 100644 --- a/workspace-server/src/__tests__/services/DriveService.test.ts +++ b/workspace-server/src/__tests__/services/DriveService.test.ts @@ -127,6 +127,31 @@ describe('DriveService', () => { expect(JSON.parse(result.content[0].text)).toEqual({ error: 'API request failed' }); }); + + describe('createFolder', () => { + it('should create a folder with the correct parameters', async () => { + const folderName = 'Test Folder'; + const parentFolderId = 'parent-id'; + const mockFilesCreate = jest.fn().mockResolvedValue({ + data: { id: 'new-folder-id' } + } as never); + (google.drive as jest.Mock).mockReturnValue({ + files: { + create: mockFilesCreate + } + }); + const response = await driveService.createFolder({ folderName, parentFolderId }); + expect(mockFilesCreate).toHaveBeenCalledWith({ + requestBody: { + name: folderName, + mimeType: 'application/vnd.google-apps.folder', + parents: [parentFolderId] + }, + fields: 'id' + }); + expect(response.content[0].text).toEqual(JSON.stringify({ id: 'new-folder-id' })); + }); + }); }); describe('search', () => { diff --git a/workspace-server/src/index.ts b/workspace-server/src/index.ts index 18795391..c5eb41d0 100644 --- a/workspace-server/src/index.ts +++ b/workspace-server/src/index.ts @@ -162,6 +162,18 @@ async function main() { driveService.findFolder ); + server.registerTool( + "drive.createFolder", + { + description: 'Creates a new folder in Google Drive.', + inputSchema: { + folderName: z.string().describe('The name of the folder to create.'), + parentFolderId: z.string().optional().describe('The ID of the parent folder.'), + } + }, + driveService.createFolder + ); + server.registerTool( "docs.move", { diff --git a/workspace-server/src/services/DriveService.ts b/workspace-server/src/services/DriveService.ts index 91b9e204..8c24491c 100644 --- a/workspace-server/src/services/DriveService.ts +++ b/workspace-server/src/services/DriveService.ts @@ -69,6 +69,38 @@ export class DriveService { } } + public createFolder = async ({ folderName, parentFolderId }: { folderName: string, parentFolderId?: string }) => { + logToFile(`Creating folder with name: ${folderName}`); + try { + const drive = await this.getDriveClient(); + const fileMetadata = { + 'name': folderName, + 'mimeType': 'application/vnd.google-apps.folder', + parents: parentFolderId ? [parentFolderId] : [] + }; + const file = await drive.files.create({ + requestBody: fileMetadata, + fields: 'id' + }); + logToFile(`Created folder with ID: ${file.data.id}`); + return { + content: [{ + type: "text" as const, + text: JSON.stringify(file.data) + }] + }; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + logToFile(`Error during drive.createFolder: ${errorMessage}`); + return { + content: [{ + type: "text" as const, + text: JSON.stringify({ error: errorMessage }) + }] + }; + } + } + public search = async ({ query, pageSize = 10, pageToken, corpus, unreadOnly, sharedWithMe }: { query?: string, pageSize?: number, pageToken?: string, corpus?: string, unreadOnly?: boolean, sharedWithMe?: boolean }) => { const drive = await this.getDriveClient(); let q = query;