Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## Unreleased

### Added

- `drives` command to list shared drives (Team Drives) you are a member of
- `--drive <driveId>` option on `ls` and `search` to scope results to one shared drive

### Fixed

- Shared drive content is now visible to `ls` and `search`. Previously both were
limited to My Drive, so shared drive files silently returned no results.
- `get`, `download`, `upload`, `mkdir`, `delete`, `move`, `rename`, `share`,
`unshare` and `permissions` now work on shared drive items instead of failing
with "File not found".

## [0.1.1] - 2025-12-12

### Added
Expand Down
40 changes: 36 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ gdcli accounts add you@gmail.com
```

You can reuse credentials from gmcli or gccli:

```bash
gdcli accounts credentials ~/.gmcli/credentials.json
```
Expand All @@ -52,37 +53,61 @@ gdcli accounts add <email> --manual # Add account (browserless, paste redir
gdcli accounts remove <email> # Remove account
```

### drives

List shared drives (Team Drives) you are a member of.

```bash
gdcli <email> drives
```

Example:

```bash
gdcli you@gmail.com drives
```

### ls

List files in a folder (default: root).
List files in a folder (default: root). Results include shared drive items as
well as My Drive.

```bash
gdcli <email> ls [folderId] [options]
```

Options:

- `--max <n>` - Max results (default: 20)
- `--page <token>` - Page token for pagination
- `--query <q>` - Drive query filter
- `--drive <driveId>` - Restrict results to a single shared drive

Examples:

```bash
gdcli you@gmail.com ls
gdcli you@gmail.com ls 1ABC123 --max 50
gdcli you@gmail.com ls --query "mimeType='image/png'"
gdcli you@gmail.com ls 0ADriveId --drive 0ADriveId # top level of a shared drive
```

A shared drive's top-level folder id is the drive id itself, as reported by
`gdcli <email> drives`.

### search

Full-text search across all files.
Full-text search across all files, including shared drives.

```bash
gdcli <email> search <query> [--max N] [--page TOKEN]
gdcli <email> search <query> [--max N] [--page TOKEN] [--drive <driveId>]
```

Example:
Examples:

```bash
gdcli you@gmail.com search "quarterly report"
gdcli you@gmail.com search "contract" --drive 0ADriveId
```

### get
Expand All @@ -104,6 +129,7 @@ gdcli <email> download <fileId> [destPath]
Default destination: `~/.gdcli/downloads/`

Examples:

```bash
gdcli you@gmail.com download 1ABC123
gdcli you@gmail.com download 1ABC123 ./myfile.pdf
Expand All @@ -118,10 +144,12 @@ gdcli <email> upload <localPath> [options]
```

Options:

- `--name <n>` - Override filename
- `--folder <folderId>` - Destination folder

Examples:

```bash
gdcli you@gmail.com upload ./report.pdf
gdcli you@gmail.com upload ./report.pdf --folder 1ABC123 --name "Q4 Report.pdf"
Expand All @@ -136,6 +164,7 @@ gdcli <email> mkdir <name> [--parent <folderId>]
```

Example:

```bash
gdcli you@gmail.com mkdir "New Folder" --parent 1ABC123
```
Expand Down Expand Up @@ -173,11 +202,13 @@ gdcli <email> share <fileId> [options]
```

Options:

- `--anyone` - Make publicly accessible (anyone with link)
- `--email <addr>` - Share with specific user
- `--role <r>` - Permission level: `reader` (default) or `writer`

Examples:

```bash
gdcli you@gmail.com share 1ABC123 --anyone
gdcli you@gmail.com share 1ABC123 --email friend@gmail.com --role writer
Expand Down Expand Up @@ -212,6 +243,7 @@ gdcli <email> url <fileIds...>
## Data Storage

All data is stored in `~/.gdcli/`:

- `credentials.json` - OAuth client credentials
- `accounts.json` - Account tokens
- `downloads/` - Downloaded files
Expand Down
32 changes: 29 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,20 @@ ACCOUNT COMMANDS

DRIVE COMMANDS

gdcli <email> drives
List shared drives (Team Drives) you are a member of.

gdcli <email> ls [folderId] [options]
List files in a folder (default: root).
Includes shared drive items as well as My Drive.
Options:
--max <n> Max results (default: 20)
--page <token> Page token for pagination
--query <q> Drive query filter (e.g., "mimeType='image/png'")
--drive <driveId> Restrict to a single shared drive

gdcli <email> search <query> [--max N] [--page TOKEN]
Full-text search across all files.
gdcli <email> search <query> [--max N] [--page TOKEN] [--drive <driveId>]
Full-text search across all files, including shared drives.

gdcli <email> get <fileId>
Get file metadata.
Expand Down Expand Up @@ -77,8 +82,11 @@ DRIVE COMMANDS
EXAMPLES

gdcli accounts list
gdcli you@gmail.com drives
gdcli you@gmail.com ls
gdcli you@gmail.com ls 1ABC123 --max 50
gdcli you@gmail.com ls 0ADriveId --drive 0ADriveId # top level of a shared drive
gdcli you@gmail.com search "contract" --drive 0ADriveId
gdcli you@gmail.com search "quarterly report"
gdcli you@gmail.com get 1ABC123
gdcli you@gmail.com download 1ABC123
Expand Down Expand Up @@ -140,6 +148,9 @@ async function main() {
}

switch (command) {
case "drives":
await handleDrives(account);
break;
case "ls":
await handleLs(account, commandArgs);
break;
Expand Down Expand Up @@ -238,13 +249,26 @@ async function handleAccounts(args: string[]) {
}
}

async function handleDrives(account: string) {
const drives = await service.listDrives(account);
if (drives.length === 0) {
console.log("No shared drives");
return;
}
console.log("ID\tNAME");
for (const d of drives) {
console.log(`${d.id}\t${d.name}`);
}
}

async function handleLs(account: string, args: string[]) {
const { values, positionals } = parseArgs({
args,
options: {
max: { type: "string" },
page: { type: "string" },
query: { type: "string" },
drive: { type: "string" },
},
allowPositionals: true,
});
Expand All @@ -256,6 +280,7 @@ async function handleLs(account: string, args: string[]) {
maxResults: values.max ? Number(values.max) : 20,
pageToken: values.page,
query: values.query,
driveId: values.drive,
});

if (result.files.length === 0) {
Expand All @@ -279,14 +304,15 @@ async function handleSearch(account: string, args: string[]) {
options: {
max: { type: "string" },
page: { type: "string" },
drive: { type: "string" },
},
allowPositionals: true,
});

const query = positionals.join(" ");
if (!query) error("Usage: <email> search <query>");

const result = await service.search(account, query, values.max ? Number(values.max) : 20, values.page);
const result = await service.search(account, query, values.max ? Number(values.max) : 20, values.page, values.drive);

if (result.files.length === 0) {
console.log("No results");
Expand Down
Loading