feat(drive): support shared drives (Team Drives) - #4

Open
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support
Open

feat(drive): support shared drives (Team Drives)#4
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support

Conversation

@neilwashere

Copy link
Copy Markdown

Problem

gdcli cannot see or touch content in shared drives (Team Drives). On an
account whose files all live in a shared drive, every read comes back empty:

$ gdcli me@example.com ls
No files
$ gdcli me@example.com search "redemption"
No results
$ gdcli me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Error: File not found: 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu.

The Drive v3 API requires two opt-ins that were not being sent:

  • supportsAllDrives — declares the client understands shared drives. Without
    it, per-file calls 404 on shared drive items even with full access.
  • includeItemsFromAllDrives — includes shared drive items in files.list
    results. Without it, listing is confined to My Drive.

Change

  • Set supportsAllDrives: true on all file and permission calls: files.get
    (metadata and alt=media), create, update, delete, and
    permissions.create / delete / list.
  • Set includeItemsFromAllDrives: true on the two files.list paths
    (listFiles, search).
  • New drives command listing shared drives and their ids.
  • New --drive <driveId> option on ls / search to scope to one shared
    drive; this also sets the corpora=drive the API requires alongside driveId.
  • driveId added to requested fields so callers can tell where a file lives.
  • README + CHANGELOG updated.

files.export is intentionally left alone — it takes no supportsAllDrives
parameter (verified against the googleapis v153 type definitions).

Verification

npm run build and npm run check both pass. Tested against a real account
with one shared drive:

$ node dist/cli.js me@example.com drives
ID NAME
0AMVYb-HWVnQlUk9PVA Keith
$ node dist/cli.js me@example.com ls 0AMVYb-HWVnQlUk9PVA --max 3
ID NAME TYPE SIZE MODIFIED
1IU8Rw... Brand folder - 2026-07-08 11:24
1YjBjW... Checklists folder - 2026-06-29 12:12
1MFuwU... HR folder - 2026-06-29 11:50
$ node dist/cli.js me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Name: Halifax redemption statement.pdf # was "File not found" before
$ node dist/cli.js me@example.com download 1O8XEJ... /tmp/out.pdf
Downloaded: /tmp/out.pdf (valid 20.4 KB PDF)

Existing My Drive queries behave as before — --query "'me' in owners" and
other metadata filters are untouched.

Notes for review

  • Default-on vs opt-in.includeItemsFromAllDrives defaults to true here,
    so ls / search widen to include shared drives. This matches what the
    README already promises ("search across all files") and is what I'd expect as
    a user, but it does change output for anyone who is a member of a shared
    drive. Happy to move it behind a flag (e.g. --all-drives) if you'd rather
    keep the old default — it's a one-line change.
  • search() gained a fifth optional positional parameter (driveId) to stay
    backward compatible for library consumers importing drive-service. An
    options object would read better and match listFiles, but that would be a
    breaking API change — say the word if you'd prefer it.
  • There is no CONTRIBUTING.md, so I followed what the repo does: biome
    formatting via npm run check, Keep-a-Changelog entry under Unreleased. Your
    existing commits use plain imperative subjects rather than Conventional
    Commits — I've used a feat(drive): prefix out of habit, so feel free to
    reword on squash.
  • No tests added: the repo has no test harness, and the change is entirely
    additional API request parameters. Verification above was done manually
    against a live shared drive.

The Drive API omits shared drive content unless the caller opts in with
supportsAllDrives, and hides it from list results without
includeItemsFromAllDrives. Neither flag was set, so shared drive files were
invisible to ls/search and every per-file operation failed with
"File not found" even when the user had access.
Set supportsAllDrives on all file and permission calls, and
includeItemsFromAllDrives on the two list paths. Add a `drives` command to
discover shared drive ids and a `--drive <driveId>` option to scope ls/search
to one drive (which also sets the required corpora=drive).
files.export is deliberately untouched: it takes no supportsAllDrives
parameter.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@neilwashere
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(drive): support shared drives (Team Drives) - #4

Open
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support
Open

feat(drive): support shared drives (Team Drives)#4
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support

Conversation

@neilwashere

Copy link
Copy Markdown

Problem

gdcli cannot see or touch content in shared drives (Team Drives). On an
account whose files all live in a shared drive, every read comes back empty:

$ gdcli me@example.com ls
No files
$ gdcli me@example.com search "redemption"
No results
$ gdcli me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Error: File not found: 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu.

The Drive v3 API requires two opt-ins that were not being sent:

  • supportsAllDrives — declares the client understands shared drives. Without
    it, per-file calls 404 on shared drive items even with full access.
  • includeItemsFromAllDrives — includes shared drive items in files.list
    results. Without it, listing is confined to My Drive.

Change

  • Set supportsAllDrives: true on all file and permission calls: files.get
    (metadata and alt=media), create, update, delete, and
    permissions.create / delete / list.
  • Set includeItemsFromAllDrives: true on the two files.list paths
    (listFiles, search).
  • New drives command listing shared drives and their ids.
  • New --drive <driveId> option on ls / search to scope to one shared
    drive; this also sets the corpora=drive the API requires alongside driveId.
  • driveId added to requested fields so callers can tell where a file lives.
  • README + CHANGELOG updated.

files.export is intentionally left alone — it takes no supportsAllDrives
parameter (verified against the googleapis v153 type definitions).

Verification

npm run build and npm run check both pass. Tested against a real account
with one shared drive:

$ node dist/cli.js me@example.com drives
ID NAME
0AMVYb-HWVnQlUk9PVA Keith
$ node dist/cli.js me@example.com ls 0AMVYb-HWVnQlUk9PVA --max 3
ID NAME TYPE SIZE MODIFIED
1IU8Rw... Brand folder - 2026-07-08 11:24
1YjBjW... Checklists folder - 2026-06-29 12:12
1MFuwU... HR folder - 2026-06-29 11:50
$ node dist/cli.js me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Name: Halifax redemption statement.pdf # was "File not found" before
$ node dist/cli.js me@example.com download 1O8XEJ... /tmp/out.pdf
Downloaded: /tmp/out.pdf (valid 20.4 KB PDF)

Existing My Drive queries behave as before — --query "'me' in owners" and
other metadata filters are untouched.

Notes for review

  • Default-on vs opt-in.includeItemsFromAllDrives defaults to true here,
    so ls / search widen to include shared drives. This matches what the
    README already promises ("search across all files") and is what I'd expect as
    a user, but it does change output for anyone who is a member of a shared
    drive. Happy to move it behind a flag (e.g. --all-drives) if you'd rather
    keep the old default — it's a one-line change.
  • search() gained a fifth optional positional parameter (driveId) to stay
    backward compatible for library consumers importing drive-service. An
    options object would read better and match listFiles, but that would be a
    breaking API change — say the word if you'd prefer it.
  • There is no CONTRIBUTING.md, so I followed what the repo does: biome
    formatting via npm run check, Keep-a-Changelog entry under Unreleased. Your
    existing commits use plain imperative subjects rather than Conventional
    Commits — I've used a feat(drive): prefix out of habit, so feel free to
    reword on squash.
  • No tests added: the repo has no test harness, and the change is entirely
    additional API request parameters. Verification above was done manually
    against a live shared drive.

The Drive API omits shared drive content unless the caller opts in with
supportsAllDrives, and hides it from list results without
includeItemsFromAllDrives. Neither flag was set, so shared drive files were
invisible to ls/search and every per-file operation failed with
"File not found" even when the user had access.
Set supportsAllDrives on all file and permission calls, and
includeItemsFromAllDrives on the two list paths. Add a `drives` command to
discover shared drive ids and a `--drive <driveId>` option to scope ls/search
to one drive (which also sets the required corpora=drive).
files.export is deliberately untouched: it takes no supportsAllDrives
parameter.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@neilwashere
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(drive): support shared drives (Team Drives) - #4

Open
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support
Open

feat(drive): support shared drives (Team Drives)#4
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support

Conversation

@neilwashere

Copy link
Copy Markdown

Problem

gdcli cannot see or touch content in shared drives (Team Drives). On an
account whose files all live in a shared drive, every read comes back empty:

$ gdcli me@example.com ls
No files
$ gdcli me@example.com search "redemption"
No results
$ gdcli me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Error: File not found: 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu.

The Drive v3 API requires two opt-ins that were not being sent:

  • supportsAllDrives — declares the client understands shared drives. Without
    it, per-file calls 404 on shared drive items even with full access.
  • includeItemsFromAllDrives — includes shared drive items in files.list
    results. Without it, listing is confined to My Drive.

Change

  • Set supportsAllDrives: true on all file and permission calls: files.get
    (metadata and alt=media), create, update, delete, and
    permissions.create / delete / list.
  • Set includeItemsFromAllDrives: true on the two files.list paths
    (listFiles, search).
  • New drives command listing shared drives and their ids.
  • New --drive <driveId> option on ls / search to scope to one shared
    drive; this also sets the corpora=drive the API requires alongside driveId.
  • driveId added to requested fields so callers can tell where a file lives.
  • README + CHANGELOG updated.

files.export is intentionally left alone — it takes no supportsAllDrives
parameter (verified against the googleapis v153 type definitions).

Verification

npm run build and npm run check both pass. Tested against a real account
with one shared drive:

$ node dist/cli.js me@example.com drives
ID NAME
0AMVYb-HWVnQlUk9PVA Keith
$ node dist/cli.js me@example.com ls 0AMVYb-HWVnQlUk9PVA --max 3
ID NAME TYPE SIZE MODIFIED
1IU8Rw... Brand folder - 2026-07-08 11:24
1YjBjW... Checklists folder - 2026-06-29 12:12
1MFuwU... HR folder - 2026-06-29 11:50
$ node dist/cli.js me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Name: Halifax redemption statement.pdf # was "File not found" before
$ node dist/cli.js me@example.com download 1O8XEJ... /tmp/out.pdf
Downloaded: /tmp/out.pdf (valid 20.4 KB PDF)

Existing My Drive queries behave as before — --query "'me' in owners" and
other metadata filters are untouched.

Notes for review

  • Default-on vs opt-in.includeItemsFromAllDrives defaults to true here,
    so ls / search widen to include shared drives. This matches what the
    README already promises ("search across all files") and is what I'd expect as
    a user, but it does change output for anyone who is a member of a shared
    drive. Happy to move it behind a flag (e.g. --all-drives) if you'd rather
    keep the old default — it's a one-line change.
  • search() gained a fifth optional positional parameter (driveId) to stay
    backward compatible for library consumers importing drive-service. An
    options object would read better and match listFiles, but that would be a
    breaking API change — say the word if you'd prefer it.
  • There is no CONTRIBUTING.md, so I followed what the repo does: biome
    formatting via npm run check, Keep-a-Changelog entry under Unreleased. Your
    existing commits use plain imperative subjects rather than Conventional
    Commits — I've used a feat(drive): prefix out of habit, so feel free to
    reword on squash.
  • No tests added: the repo has no test harness, and the change is entirely
    additional API request parameters. Verification above was done manually
    against a live shared drive.

The Drive API omits shared drive content unless the caller opts in with
supportsAllDrives, and hides it from list results without
includeItemsFromAllDrives. Neither flag was set, so shared drive files were
invisible to ls/search and every per-file operation failed with
"File not found" even when the user had access.
Set supportsAllDrives on all file and permission calls, and
includeItemsFromAllDrives on the two list paths. Add a `drives` command to
discover shared drive ids and a `--drive <driveId>` option to scope ls/search
to one drive (which also sets the required corpora=drive).
files.export is deliberately untouched: it takes no supportsAllDrives
parameter.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@neilwashere
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(drive): support shared drives (Team Drives) - #4

Open
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support
Open

feat(drive): support shared drives (Team Drives)#4
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support

Conversation

@neilwashere

Copy link
Copy Markdown

Problem

gdcli cannot see or touch content in shared drives (Team Drives). On an
account whose files all live in a shared drive, every read comes back empty:

$ gdcli me@example.com ls
No files
$ gdcli me@example.com search "redemption"
No results
$ gdcli me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Error: File not found: 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu.

The Drive v3 API requires two opt-ins that were not being sent:

  • supportsAllDrives — declares the client understands shared drives. Without
    it, per-file calls 404 on shared drive items even with full access.
  • includeItemsFromAllDrives — includes shared drive items in files.list
    results. Without it, listing is confined to My Drive.

Change

  • Set supportsAllDrives: true on all file and permission calls: files.get
    (metadata and alt=media), create, update, delete, and
    permissions.create / delete / list.
  • Set includeItemsFromAllDrives: true on the two files.list paths
    (listFiles, search).
  • New drives command listing shared drives and their ids.
  • New --drive <driveId> option on ls / search to scope to one shared
    drive; this also sets the corpora=drive the API requires alongside driveId.
  • driveId added to requested fields so callers can tell where a file lives.
  • README + CHANGELOG updated.

files.export is intentionally left alone — it takes no supportsAllDrives
parameter (verified against the googleapis v153 type definitions).

Verification

npm run build and npm run check both pass. Tested against a real account
with one shared drive:

$ node dist/cli.js me@example.com drives
ID NAME
0AMVYb-HWVnQlUk9PVA Keith
$ node dist/cli.js me@example.com ls 0AMVYb-HWVnQlUk9PVA --max 3
ID NAME TYPE SIZE MODIFIED
1IU8Rw... Brand folder - 2026-07-08 11:24
1YjBjW... Checklists folder - 2026-06-29 12:12
1MFuwU... HR folder - 2026-06-29 11:50
$ node dist/cli.js me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Name: Halifax redemption statement.pdf # was "File not found" before
$ node dist/cli.js me@example.com download 1O8XEJ... /tmp/out.pdf
Downloaded: /tmp/out.pdf (valid 20.4 KB PDF)

Existing My Drive queries behave as before — --query "'me' in owners" and
other metadata filters are untouched.

Notes for review

  • Default-on vs opt-in.includeItemsFromAllDrives defaults to true here,
    so ls / search widen to include shared drives. This matches what the
    README already promises ("search across all files") and is what I'd expect as
    a user, but it does change output for anyone who is a member of a shared
    drive. Happy to move it behind a flag (e.g. --all-drives) if you'd rather
    keep the old default — it's a one-line change.
  • search() gained a fifth optional positional parameter (driveId) to stay
    backward compatible for library consumers importing drive-service. An
    options object would read better and match listFiles, but that would be a
    breaking API change — say the word if you'd prefer it.
  • There is no CONTRIBUTING.md, so I followed what the repo does: biome
    formatting via npm run check, Keep-a-Changelog entry under Unreleased. Your
    existing commits use plain imperative subjects rather than Conventional
    Commits — I've used a feat(drive): prefix out of habit, so feel free to
    reword on squash.
  • No tests added: the repo has no test harness, and the change is entirely
    additional API request parameters. Verification above was done manually
    against a live shared drive.

The Drive API omits shared drive content unless the caller opts in with
supportsAllDrives, and hides it from list results without
includeItemsFromAllDrives. Neither flag was set, so shared drive files were
invisible to ls/search and every per-file operation failed with
"File not found" even when the user had access.
Set supportsAllDrives on all file and permission calls, and
includeItemsFromAllDrives on the two list paths. Add a `drives` command to
discover shared drive ids and a `--drive <driveId>` option to scope ls/search
to one drive (which also sets the required corpora=drive).
files.export is deliberately untouched: it takes no supportsAllDrives
parameter.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@neilwashere
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(drive): support shared drives (Team Drives) - #4

Open
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support
Open

feat(drive): support shared drives (Team Drives)#4
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support

Conversation

@neilwashere

Copy link
Copy Markdown

Problem

gdcli cannot see or touch content in shared drives (Team Drives). On an
account whose files all live in a shared drive, every read comes back empty:

$ gdcli me@example.com ls
No files
$ gdcli me@example.com search "redemption"
No results
$ gdcli me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Error: File not found: 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu.

The Drive v3 API requires two opt-ins that were not being sent:

  • supportsAllDrives — declares the client understands shared drives. Without
    it, per-file calls 404 on shared drive items even with full access.
  • includeItemsFromAllDrives — includes shared drive items in files.list
    results. Without it, listing is confined to My Drive.

Change

  • Set supportsAllDrives: true on all file and permission calls: files.get
    (metadata and alt=media), create, update, delete, and
    permissions.create / delete / list.
  • Set includeItemsFromAllDrives: true on the two files.list paths
    (listFiles, search).
  • New drives command listing shared drives and their ids.
  • New --drive <driveId> option on ls / search to scope to one shared
    drive; this also sets the corpora=drive the API requires alongside driveId.
  • driveId added to requested fields so callers can tell where a file lives.
  • README + CHANGELOG updated.

files.export is intentionally left alone — it takes no supportsAllDrives
parameter (verified against the googleapis v153 type definitions).

Verification

npm run build and npm run check both pass. Tested against a real account
with one shared drive:

$ node dist/cli.js me@example.com drives
ID NAME
0AMVYb-HWVnQlUk9PVA Keith
$ node dist/cli.js me@example.com ls 0AMVYb-HWVnQlUk9PVA --max 3
ID NAME TYPE SIZE MODIFIED
1IU8Rw... Brand folder - 2026-07-08 11:24
1YjBjW... Checklists folder - 2026-06-29 12:12
1MFuwU... HR folder - 2026-06-29 11:50
$ node dist/cli.js me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Name: Halifax redemption statement.pdf # was "File not found" before
$ node dist/cli.js me@example.com download 1O8XEJ... /tmp/out.pdf
Downloaded: /tmp/out.pdf (valid 20.4 KB PDF)

Existing My Drive queries behave as before — --query "'me' in owners" and
other metadata filters are untouched.

Notes for review

  • Default-on vs opt-in.includeItemsFromAllDrives defaults to true here,
    so ls / search widen to include shared drives. This matches what the
    README already promises ("search across all files") and is what I'd expect as
    a user, but it does change output for anyone who is a member of a shared
    drive. Happy to move it behind a flag (e.g. --all-drives) if you'd rather
    keep the old default — it's a one-line change.
  • search() gained a fifth optional positional parameter (driveId) to stay
    backward compatible for library consumers importing drive-service. An
    options object would read better and match listFiles, but that would be a
    breaking API change — say the word if you'd prefer it.
  • There is no CONTRIBUTING.md, so I followed what the repo does: biome
    formatting via npm run check, Keep-a-Changelog entry under Unreleased. Your
    existing commits use plain imperative subjects rather than Conventional
    Commits — I've used a feat(drive): prefix out of habit, so feel free to
    reword on squash.
  • No tests added: the repo has no test harness, and the change is entirely
    additional API request parameters. Verification above was done manually
    against a live shared drive.

The Drive API omits shared drive content unless the caller opts in with
supportsAllDrives, and hides it from list results without
includeItemsFromAllDrives. Neither flag was set, so shared drive files were
invisible to ls/search and every per-file operation failed with
"File not found" even when the user had access.
Set supportsAllDrives on all file and permission calls, and
includeItemsFromAllDrives on the two list paths. Add a `drives` command to
discover shared drive ids and a `--drive <driveId>` option to scope ls/search
to one drive (which also sets the required corpora=drive).
files.export is deliberately untouched: it takes no supportsAllDrives
parameter.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@neilwashere
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(drive): support shared drives (Team Drives) - #4

Open
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support
Open

feat(drive): support shared drives (Team Drives)#4
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support

Conversation

@neilwashere

Copy link
Copy Markdown

Problem

gdcli cannot see or touch content in shared drives (Team Drives). On an
account whose files all live in a shared drive, every read comes back empty:

$ gdcli me@example.com ls
No files
$ gdcli me@example.com search "redemption"
No results
$ gdcli me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Error: File not found: 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu.

The Drive v3 API requires two opt-ins that were not being sent:

  • supportsAllDrives — declares the client understands shared drives. Without
    it, per-file calls 404 on shared drive items even with full access.
  • includeItemsFromAllDrives — includes shared drive items in files.list
    results. Without it, listing is confined to My Drive.

Change

  • Set supportsAllDrives: true on all file and permission calls: files.get
    (metadata and alt=media), create, update, delete, and
    permissions.create / delete / list.
  • Set includeItemsFromAllDrives: true on the two files.list paths
    (listFiles, search).
  • New drives command listing shared drives and their ids.
  • New --drive <driveId> option on ls / search to scope to one shared
    drive; this also sets the corpora=drive the API requires alongside driveId.
  • driveId added to requested fields so callers can tell where a file lives.
  • README + CHANGELOG updated.

files.export is intentionally left alone — it takes no supportsAllDrives
parameter (verified against the googleapis v153 type definitions).

Verification

npm run build and npm run check both pass. Tested against a real account
with one shared drive:

$ node dist/cli.js me@example.com drives
ID NAME
0AMVYb-HWVnQlUk9PVA Keith
$ node dist/cli.js me@example.com ls 0AMVYb-HWVnQlUk9PVA --max 3
ID NAME TYPE SIZE MODIFIED
1IU8Rw... Brand folder - 2026-07-08 11:24
1YjBjW... Checklists folder - 2026-06-29 12:12
1MFuwU... HR folder - 2026-06-29 11:50
$ node dist/cli.js me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Name: Halifax redemption statement.pdf # was "File not found" before
$ node dist/cli.js me@example.com download 1O8XEJ... /tmp/out.pdf
Downloaded: /tmp/out.pdf (valid 20.4 KB PDF)

Existing My Drive queries behave as before — --query "'me' in owners" and
other metadata filters are untouched.

Notes for review

  • Default-on vs opt-in.includeItemsFromAllDrives defaults to true here,
    so ls / search widen to include shared drives. This matches what the
    README already promises ("search across all files") and is what I'd expect as
    a user, but it does change output for anyone who is a member of a shared
    drive. Happy to move it behind a flag (e.g. --all-drives) if you'd rather
    keep the old default — it's a one-line change.
  • search() gained a fifth optional positional parameter (driveId) to stay
    backward compatible for library consumers importing drive-service. An
    options object would read better and match listFiles, but that would be a
    breaking API change — say the word if you'd prefer it.
  • There is no CONTRIBUTING.md, so I followed what the repo does: biome
    formatting via npm run check, Keep-a-Changelog entry under Unreleased. Your
    existing commits use plain imperative subjects rather than Conventional
    Commits — I've used a feat(drive): prefix out of habit, so feel free to
    reword on squash.
  • No tests added: the repo has no test harness, and the change is entirely
    additional API request parameters. Verification above was done manually
    against a live shared drive.

The Drive API omits shared drive content unless the caller opts in with
supportsAllDrives, and hides it from list results without
includeItemsFromAllDrives. Neither flag was set, so shared drive files were
invisible to ls/search and every per-file operation failed with
"File not found" even when the user had access.
Set supportsAllDrives on all file and permission calls, and
includeItemsFromAllDrives on the two list paths. Add a `drives` command to
discover shared drive ids and a `--drive <driveId>` option to scope ls/search
to one drive (which also sets the required corpora=drive).
files.export is deliberately untouched: it takes no supportsAllDrives
parameter.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@neilwashere
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(drive): support shared drives (Team Drives) - #4

Open
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support
Open

feat(drive): support shared drives (Team Drives)#4
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support

Conversation

@neilwashere

Copy link
Copy Markdown

Problem

gdcli cannot see or touch content in shared drives (Team Drives). On an
account whose files all live in a shared drive, every read comes back empty:

$ gdcli me@example.com ls
No files
$ gdcli me@example.com search "redemption"
No results
$ gdcli me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Error: File not found: 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu.

The Drive v3 API requires two opt-ins that were not being sent:

  • supportsAllDrives — declares the client understands shared drives. Without
    it, per-file calls 404 on shared drive items even with full access.
  • includeItemsFromAllDrives — includes shared drive items in files.list
    results. Without it, listing is confined to My Drive.

Change

  • Set supportsAllDrives: true on all file and permission calls: files.get
    (metadata and alt=media), create, update, delete, and
    permissions.create / delete / list.
  • Set includeItemsFromAllDrives: true on the two files.list paths
    (listFiles, search).
  • New drives command listing shared drives and their ids.
  • New --drive <driveId> option on ls / search to scope to one shared
    drive; this also sets the corpora=drive the API requires alongside driveId.
  • driveId added to requested fields so callers can tell where a file lives.
  • README + CHANGELOG updated.

files.export is intentionally left alone — it takes no supportsAllDrives
parameter (verified against the googleapis v153 type definitions).

Verification

npm run build and npm run check both pass. Tested against a real account
with one shared drive:

$ node dist/cli.js me@example.com drives
ID NAME
0AMVYb-HWVnQlUk9PVA Keith
$ node dist/cli.js me@example.com ls 0AMVYb-HWVnQlUk9PVA --max 3
ID NAME TYPE SIZE MODIFIED
1IU8Rw... Brand folder - 2026-07-08 11:24
1YjBjW... Checklists folder - 2026-06-29 12:12
1MFuwU... HR folder - 2026-06-29 11:50
$ node dist/cli.js me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Name: Halifax redemption statement.pdf # was "File not found" before
$ node dist/cli.js me@example.com download 1O8XEJ... /tmp/out.pdf
Downloaded: /tmp/out.pdf (valid 20.4 KB PDF)

Existing My Drive queries behave as before — --query "'me' in owners" and
other metadata filters are untouched.

Notes for review

  • Default-on vs opt-in.includeItemsFromAllDrives defaults to true here,
    so ls / search widen to include shared drives. This matches what the
    README already promises ("search across all files") and is what I'd expect as
    a user, but it does change output for anyone who is a member of a shared
    drive. Happy to move it behind a flag (e.g. --all-drives) if you'd rather
    keep the old default — it's a one-line change.
  • search() gained a fifth optional positional parameter (driveId) to stay
    backward compatible for library consumers importing drive-service. An
    options object would read better and match listFiles, but that would be a
    breaking API change — say the word if you'd prefer it.
  • There is no CONTRIBUTING.md, so I followed what the repo does: biome
    formatting via npm run check, Keep-a-Changelog entry under Unreleased. Your
    existing commits use plain imperative subjects rather than Conventional
    Commits — I've used a feat(drive): prefix out of habit, so feel free to
    reword on squash.
  • No tests added: the repo has no test harness, and the change is entirely
    additional API request parameters. Verification above was done manually
    against a live shared drive.

The Drive API omits shared drive content unless the caller opts in with
supportsAllDrives, and hides it from list results without
includeItemsFromAllDrives. Neither flag was set, so shared drive files were
invisible to ls/search and every per-file operation failed with
"File not found" even when the user had access.
Set supportsAllDrives on all file and permission calls, and
includeItemsFromAllDrives on the two list paths. Add a `drives` command to
discover shared drive ids and a `--drive <driveId>` option to scope ls/search
to one drive (which also sets the required corpora=drive).
files.export is deliberately untouched: it takes no supportsAllDrives
parameter.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@neilwashere
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(drive): support shared drives (Team Drives) - #4

Open
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support
Open

feat(drive): support shared drives (Team Drives)#4
neilwashere wants to merge 1 commit into
badlogic:mainfrom
neilwashere:feat/shared-drive-support

Conversation

@neilwashere

Copy link
Copy Markdown

Problem

gdcli cannot see or touch content in shared drives (Team Drives). On an
account whose files all live in a shared drive, every read comes back empty:

$ gdcli me@example.com ls
No files
$ gdcli me@example.com search "redemption"
No results
$ gdcli me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Error: File not found: 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu.

The Drive v3 API requires two opt-ins that were not being sent:

  • supportsAllDrives — declares the client understands shared drives. Without
    it, per-file calls 404 on shared drive items even with full access.
  • includeItemsFromAllDrives — includes shared drive items in files.list
    results. Without it, listing is confined to My Drive.

Change

  • Set supportsAllDrives: true on all file and permission calls: files.get
    (metadata and alt=media), create, update, delete, and
    permissions.create / delete / list.
  • Set includeItemsFromAllDrives: true on the two files.list paths
    (listFiles, search).
  • New drives command listing shared drives and their ids.
  • New --drive <driveId> option on ls / search to scope to one shared
    drive; this also sets the corpora=drive the API requires alongside driveId.
  • driveId added to requested fields so callers can tell where a file lives.
  • README + CHANGELOG updated.

files.export is intentionally left alone — it takes no supportsAllDrives
parameter (verified against the googleapis v153 type definitions).

Verification

npm run build and npm run check both pass. Tested against a real account
with one shared drive:

$ node dist/cli.js me@example.com drives
ID NAME
0AMVYb-HWVnQlUk9PVA Keith
$ node dist/cli.js me@example.com ls 0AMVYb-HWVnQlUk9PVA --max 3
ID NAME TYPE SIZE MODIFIED
1IU8Rw... Brand folder - 2026-07-08 11:24
1YjBjW... Checklists folder - 2026-06-29 12:12
1MFuwU... HR folder - 2026-06-29 11:50
$ node dist/cli.js me@example.com get 1O8XEJ0mU5-JOTs5U_GB77o_CAX-6GrSu
Name: Halifax redemption statement.pdf # was "File not found" before
$ node dist/cli.js me@example.com download 1O8XEJ... /tmp/out.pdf
Downloaded: /tmp/out.pdf (valid 20.4 KB PDF)

Existing My Drive queries behave as before — --query "'me' in owners" and
other metadata filters are untouched.

Notes for review

  • Default-on vs opt-in.includeItemsFromAllDrives defaults to true here,
    so ls / search widen to include shared drives. This matches what the
    README already promises ("search across all files") and is what I'd expect as
    a user, but it does change output for anyone who is a member of a shared
    drive. Happy to move it behind a flag (e.g. --all-drives) if you'd rather
    keep the old default — it's a one-line change.
  • search() gained a fifth optional positional parameter (driveId) to stay
    backward compatible for library consumers importing drive-service. An
    options object would read better and match listFiles, but that would be a
    breaking API change — say the word if you'd prefer it.
  • There is no CONTRIBUTING.md, so I followed what the repo does: biome
    formatting via npm run check, Keep-a-Changelog entry under Unreleased. Your
    existing commits use plain imperative subjects rather than Conventional
    Commits — I've used a feat(drive): prefix out of habit, so feel free to
    reword on squash.
  • No tests added: the repo has no test harness, and the change is entirely
    additional API request parameters. Verification above was done manually
    against a live shared drive.

The Drive API omits shared drive content unless the caller opts in with
supportsAllDrives, and hides it from list results without
includeItemsFromAllDrives. Neither flag was set, so shared drive files were
invisible to ls/search and every per-file operation failed with
"File not found" even when the user had access.
Set supportsAllDrives on all file and permission calls, and
includeItemsFromAllDrives on the two list paths. Add a `drives` command to
discover shared drive ids and a `--drive <driveId>` option to scope ls/search
to one drive (which also sets the required corpora=drive).
files.export is deliberately untouched: it takes no supportsAllDrives
parameter.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@neilwashere