just-bash-gdrive
v0.1.3
Published
Google Drive filesystem adapter for just-bash
Readme
just-bash-gdrive
Google Drive filesystem adapter for just-bash.
Lets AI agents interact with Google Drive files using standard bash commands (ls, cat, cp, grep, etc.) without needing any Drive API knowledge.
Inspired by just-bash-dropbox — the same pattern, applied to Google Drive.
Why not just use the Drive API or gogcli?
Tools like gogcli are great for deterministic, human-authored Drive operations.
just-bash-gdrive is optimized for agents. Every LLM already knows bash — ls, cat, grep, find, pipes, redirects. That's zero tokens spent teaching the model a new API surface, zero schema to include in your system prompt, and no wiring up per-operation code. The agent reaches for tools it already has, applied to Drive.
Consistency. One bash tool in your agent covers the local filesystem, Drive, and anything else you mount — same commands, same mental model, same token budget.
Token efficiency. Describing the Drive API costs tokens every call. Bash costs nothing — it's already there.
Composability. MountableFs lets agents work across /drive (real files) and /tmp (scratch space) in the same session without switching tools or context.
Safe exploration. Mount Drive read-only — agents can cat, grep, and find freely with zero write risk.
Install
npm install just-bash-gdrive just-bashUsage
import { Bash } from "just-bash";
import { GDriveFs } from "just-bash-gdrive";
const fs = new GDriveFs({
// Static token or async provider for OAuth2 refresh
accessToken: () => getAccessToken(),
// Constrain agent to a specific folder (optional)
rootFolderId: "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
});
const bash = new Bash({ fs });
const result = await bash.exec("ls -la /");Safe mode (read-only Drive, writes go to memory)
import { Bash, MountableFs, InMemoryFs } from "just-bash";
import { GDriveFs } from "just-bash-gdrive";
const drive = new GDriveFs({ accessToken: () => getAccessToken() });
const memory = new InMemoryFs();
const mountable = new MountableFs(memory);
// Mount Drive at /drive — writes go to memory, not Drive
await mountable.mount("/drive", drive);
const bash = new Bash({ fs: mountable });
// Reads come from Drive, writes stay in memory
await bash.exec("cat /drive/my-doc.txt");
await bash.exec("echo 'draft' > /draft.txt"); // memory onlyPrefetch for glob support
const fs = new GDriveFs({ accessToken: token, rootFolderId: myFolderId });
// Recursively cache all paths for glob/find support
await fs.prefetchAllPaths();
const bash = new Bash({ fs });
await bash.exec("find / -name '*.md'"); // works after prefetchAI SDK tool
import { generateText } from "ai";
import { bashTool } from "just-bash/ai-sdk";
const { text } = await generateText({
model: yourModel,
tools: { bash: bashTool({ fs }) },
prompt: "List all markdown files in my Drive and summarize what they contain",
});Getting an access token
The accessToken option accepts either a static string or an async function — use the async form for long-running agents so the token refreshes automatically.
Option 1: gogcli (recommended for quick setup)
gogcli handles Google OAuth2 authentication and stores tokens locally. After running gog auth login, you can retrieve tokens programmatically:
# Install gogcli
npm install -g gogcli
# Authenticate (opens browser)
gog auth loginimport { execSync } from "child_process";
const fs = new GDriveFs({
accessToken: () => {
// gogcli outputs a fresh token to stdout
return execSync("gog auth token", { encoding: "utf8" }).trim();
},
});Option 2: googleapis (full OAuth2 flow)
import { google } from "googleapis";
const auth = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);
auth.setCredentials({ refresh_token: REFRESH_TOKEN });
const fs = new GDriveFs({
accessToken: async () => {
const { token } = await auth.getAccessToken();
return token!;
},
});Option 3: Static token (scripts and testing)
For short-lived scripts, pass a token directly. Get one via gog auth token or the OAuth2 Playground.
const fs = new GDriveFs({ accessToken: "ya29.your_token_here" });Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| accessToken | string \| () => Promise<string> | required | OAuth2 access token or async provider |
| rootFolderId | string | "root" | Constrain agent to this Drive folder ID |
How it works
Google Drive uses opaque file IDs rather than paths. GDriveFs maintains a bidirectional path-to-ID cache that is built lazily as you navigate the filesystem, or all at once via prefetchAllPaths(). Every bash command (ls, cat, cp, etc.) resolves paths through this cache before hitting the Drive API.
Rate limit handling: automatically retries on HTTP 429 with Retry-After backoff (up to 3 attempts).
Limitations
chmod,symlink,link,readlink,utimesthrowENOSYS— Drive has no POSIX permission or symlink conceptgetAllPaths()returns[]untilprefetchAllPaths()is called — glob operations require prefetchappendFilereads the existing file, appends, then rewrites — Drive has no atomic append- Google Workspace files (Docs, Sheets, Slides) cannot be read as raw content; use
gog export(gogcli) or the Drive export API to convert them first
Inspiration
This adapter was built following the pattern established by just-bash-dropbox by @manishrc. The IFileSystem interface, the token provider pattern, the prefetchAllPaths approach for glob support, and the MountableFs safe mode pattern are all drawn from that work. Thanks Manish.
License
Apache-2.0
