bim-google

Push Revit schedules, site assessments, and warning logs directly into shared Google Sheets — no manual export, no copy-paste, no formatting by hand. Read values from a shared Doc and pipe them into Revit parameters. One-time sign-in; every subsequent call is silent.

Read and write Google Sheets and Docs from the command line. No manual export, no copy-paste.

Authentication

One-time browser sign-in. Credentials cached locally. Your agent runs bim google login; a browser window opens, you click Allow, done. Every subsequent call refreshes the token silently.

bim google login        # opens browser — one-time setup
bim google whoami       # verify signed in
bim google doctor --json

Requires a network connection at login time and at each API call. All data stays in your Google account.

Verbs

VerbWhat it does
bim google login [--readonly] [--client-id-file CLIENT-ID-FILE]Authenticate with Google via OAuth. Opens your browser once; credentials are cached locally and refreshed automatically.
bim google logoutRemove saved Google credentials.
bim google whoamiShow the current authentication state. Returns {signed_in, email, scopes, expires_at}. If the token is near expiry, also returns {token_expired: true, hint}; the token refreshes automatically on the next API call.
bim google doctorCheck environment readiness.
bim google versionPrint driver version.

auth

VerbWhat it does
bim google auth statusAlias for whoami. Show the current authentication state. Returns the same payload as whoami.

sheets

VerbWhat it does
bim google sheets read --spreadsheet SPREADSHEET [--id ID] [--range RANGE] [--sheet SHEET] [--formulas] [--grid]Read values from a Google Sheet and stream as NDJSON. Default: first row is treated as column headers, each data row emitted as one JSON object with header keys. With --grid: emit a clean 2D grid instead — one JSON array per row in column order, header row included as the first line (lossless; use for column order, the raw header, an irregular/blank header, or a single-row range, which the default mode reports as rows:0). The final line is a summary object {range, rows} — not a data row.
bim google sheets audit --spreadsheet SPREADSHEET [--id ID] [--range RANGE] [--sheet SHEET] [--all]Inspect a sheet range for formula coverage. Reads with valueRenderOption=FORMULA and emits NDJSON: one line per literal-value cell (type=value), then a summary {range, total_cells, formula_cells, value_cells, empty_cells}. Use to find cells that should be formulas but contain hard-coded values. Pass --all to include formula cells in the output too.
bim google sheets errors --spreadsheet SPREADSHEET [--id ID] [--range RANGE]Sweep a spreadsheet for cells in an error state and return {count, errors} with each cell's tab, A1 reference, error type, and API error message.
bim google sheets append --spreadsheet SPREADSHEET [--id ID] [--sheet SHEET] [--with-header] [--input-mode INPUT-MODE]Append rows to a Google Sheet from NDJSON stdin. Reads one JSON object per line; object keys become column values. By default Sheets uses user-entered parsing; pass --input-mode raw to store literal text unchanged.
bim google sheets write --spreadsheet SPREADSHEET [--id ID] --range RANGE [--grid] [--input-mode INPUT-MODE]Overwrite a specific range in a Google Sheet from stdin. Default mode: NDJSON objects (keys become columns). Grid mode (--grid): stdin must be a JSON 2D array e.g. [["a","=B1+1"],[2,3]]. By default Sheets uses user-entered parsing in both modes; pass --input-mode raw to store literal text unchanged.
bim google sheets clear --spreadsheet SPREADSHEET [--id ID] --range RANGEClear cell values from a range, preserving formatting and structure.
bim google sheets sort --spreadsheet SPREADSHEET [--id ID] --range RANGE --col COL [--desc]Sort a range by a single column. Range must include the sheet name (e.g. Sheet1!A2:F100). Use --desc for descending order.
bim google sheets find-replace --spreadsheet SPREADSHEET [--id ID] --find FIND [--replace REPLACE] [--sheet SHEET] [--match-case] [--match-entire-cell]Find and replace text across the spreadsheet or a specific tab.
bim google sheets fill-down --spreadsheet SPREADSHEET [--id ID] --range RANGE --formula FORMULA [--auto-extent] [--key-column KEY-COLUMN]Fill every cell in a range with a formula, auto-adjusting relative row/column references. Range must include sheet name. Use an open end (e.g. Sheet1!B2:B) or --auto-extent to auto-detect the last populated row.
bim google sheets format --spreadsheet SPREADSHEET [--id ID] --range RANGE [--number-format NUMBER-FORMAT] [--bold] [--italic] [--fg-color FG-COLOR] [--bg-color BG-COLOR] [--halign HALIGN] [--freeze-rows FREEZE-ROWS] [--freeze-cols FREEZE-COLS] [--merge] [--col-width COL-WIDTH]Apply cell and sheet-level formatting to a range. Translates flags to repeatCell / updateSheetProperties / mergeCells / updateDimensionProperties batchUpdate requests. Only specified options are applied; unspecified options are left unchanged.
bim google sheets conditional-format --spreadsheet SPREADSHEET [--id ID] --range RANGE [--condition CONDITION] [--value VALUE] [--formula FORMULA] [--bg-color BG-COLOR] [--text-color TEXT-COLOR] [--gradient] [--min MIN] [--mid MID] [--max MAX] [--min-color MIN-COLOR] [--mid-color MID-COLOR] [--max-color MAX-COLOR] [--clear]Add or clear a conditional format rule on a range. Supports boolean rules (NUMBER_LESS, NUMBER_GREATER, NUMBER_EQ, NUMBER_NOT_EQ, TEXT_CONTAINS, TEXT_EQ, TEXT_NOT_EQ, BLANK, NOT_BLANK, CUSTOM_FORMULA) and 3-point color-scale gradient rules (--gradient). NOTE: use NUMBER_LESS not NUMBER_LESS_THAN; use TEXT_EQ for exact string match (TEXT_CONTAINS matches substrings). Pass --clear to delete all existing CF rules from the sheet before adding.
bim google sheets note --spreadsheet SPREADSHEET [--id ID] --range RANGE [--text TEXT] [--clear]Set or clear a hover note (annotation) on every cell in a range. Uses repeatCell with fields=note so existing cell values and formatting are untouched. Idempotent: re-setting the same note is a no-op. Pass --text "" or --clear to remove notes.
bim google sheets tabs list --spreadsheet SPREADSHEET [--id ID]List all tabs in a spreadsheet. Returns {tabs: [{sheet_id, title, index}], count}.
bim google sheets tabs add --spreadsheet SPREADSHEET [--id ID] --name NAMEAdd a new tab to an existing spreadsheet.
bim google sheets tabs delete --spreadsheet SPREADSHEET [--id ID] --name NAMEDelete a tab by name. Irreversible.
bim google sheets tabs rename --spreadsheet SPREADSHEET [--id ID] --from FROM --to TORename a tab.
bim google sheets tabs duplicate --spreadsheet SPREADSHEET [--id ID] --name NAME [--new-name NEW-NAME]Duplicate a tab within the same spreadsheet.

docs

VerbWhat it does
bim google docs read --doc DOC [--raw]Read a Google Doc and return plain text with title, word count, and character count.
bim google docs append --doc DOC [--text TEXT]Append plain text to the end of a Google Doc.

drive

VerbWhat it does
bim google drive list [--parent PARENT]List files in Google Drive. Streams one JSON object per file to stdout; returns {count} as summary. With drive.metadata.readonly scope this lists all of the user's files; pass --parent to list only the files directly inside a specific folder. Reads file metadata only (names/ids/types) — read sheet contents with sheets read by id.
bim google drive pickOpen the Google Drive Picker in the user's browser (at picker.bimcli.com) and wait for a file selection. Returns {file_id, name}. Requires an active bim google login. Shows only files accessible under the current drive.file scope (files created by this app). Interactive: opens a browser window; resolves when the user picks a file or cancels.
bim google drive download --file FILE --output OUTPUTDownload a Drive file by ID and save it to a local path. Only files created by this app are accessible (drive.file scope).
bim google drive upload [--input INPUT] [--name NAME] [--mime-type MIME-TYPE] [--parent PARENT]Upload a file to Google Drive. Reads from a local path (--input) or stdin. With --parent, the file is created inside that folder; otherwise it lands in Drive root. Returns the new file ID and web link.
bim google drive mkdir --name NAME [--parent PARENT]Create a folder in Google Drive. With --parent, the folder is created inside that folder; otherwise at Drive root. Returns the new folder's ID. Not idempotent (Drive allows duplicate folder names) -- list first if you need get-or-create.
bim google drive rm --file FILEMove a Drive file or folder to the trash (recoverable). Trashing a folder trashes its contents. Returns the item's id/name.

ga

VerbWhat it does
bim google ga run-report --property PROPERTY --metrics METRICS [--dimensions DIMENSIONS] [--start-date START-DATE] [--end-date END-DATE]Run a GA4 Analytics Data API report for a property. Returns {property, dimensions, metrics, rows, row_count} where rows is an array of objects keyed by dimension and metric names.

Pipe compositions

# Push a Revit sheet list into a shared tracker
bim revit schedule export Sheets | bim google sheets append --spreadsheet <id> --with-header

# Push model warnings into a Sheet for review
bim revit warnings list | bim google sheets append --spreadsheet <id> --with-header

# Read spec values from a Doc and push into Revit parameters
bim google docs read --doc <id> | bim revit param set --by Mark

# Read a Sheet, write matching params to Revit
bim google sheets read --spreadsheet <id> | bim revit param set --by Mark

BYO client ID (power users)

By default, bim-google authenticates using Everbeach's built-in Google Cloud project. If your org requires its own OAuth app — for compliance, quota isolation, or Google Workspace policy enforcement — you can supply your own client credentials at login time.

Step 1 — Create a Cloud project and OAuth client

  1. Go to console.cloud.google.com → APIs & Services → Credentials.
  2. Create a new OAuth 2.0 Client ID. Choose Desktop app as the application type.
  3. Enable the APIs you need: Google Sheets API, Google Docs API, Google Drive API.
  4. Download the credential JSON. It looks like:
{
  "installed": {
    "client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
    "client_secret": "YOUR_SECRET",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "redirect_uris": ["http://localhost"]
  }
}

Step 2 — Login with your credential file

bim google login --client-id-file /path/to/client_secret.json

The flag overrides the built-in client ID for this login session only. The resulting token is cached locally and auto-refreshed on subsequent calls — you do not need to pass --client-id-file again until you log out and re-authenticate.

Note: Tokens issued by your own client ID are stored in the same cache location as the default ones. Running bim google logout clears them. If you switch between client IDs, log out first to avoid using a token issued by the previous client.

Gotchas

For agent use: /google/llms.txt