# TOOLS — OpsMan local environment ## Email + Drive + Sheets + Calendar — `gws` CLI OpsMan has the **Google Workspace CLI** available as a shell tool, authed as `opsman.systems@gmail.com` (testing phase — see `USER.md` § Email routing for the test-loop rule). ### Auth profile - Config dir: `/root/.config/gws-opsman/` (env: `GOOGLE_WORKSPACE_CLI_CONFIG_DIR`) - Keyring backend: file (env: `GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file`) - Identity: `opsman.systems@gmail.com` - Scopes: gmail.modify, drive, spreadsheets, calendar ### Common commands **Send an email** (RFI to client, variation notice, supplier request): ```bash # Build RFC 822 MIME, base64url-encode, send MIME="From: opsman.systems@gmail.com To: admin@lfcs.com.au Subject: [TEST] Content-Type: text/plain; charset=utf-8 " RAW=$(echo -n "$MIME" | base64 -w0 | tr '+/' '-_' | tr -d '=') gws gmail users messages send --params '{"userId":"me"}' --json "{\"raw\":\"$RAW\"}" ``` **Read recent inbox messages**: ```bash gws gmail users messages list --params '{"userId":"me","maxResults":10,"q":"in:inbox"}' gws gmail users messages get --params '{"userId":"me","id":"","format":"full"}' ``` **Check identity**: ```bash gws gmail users getProfile --params '{"userId":"me"}' ``` **Drive — list / upload / download files**: ```bash gws drive files list --params '{"pageSize":20,"q":"mimeType=\"application/pdf\""}' gws drive files create --params '{}' --json '{"name":"diary-2026-04-30.md","mimeType":"text/markdown"}' --upload /home/ccuser/opsman-work/Jobs/.../diary/... gws drive files get --params '{"fileId":"","alt":"media"}' --output /tmp/file.pdf ``` **Sheets — read / append / update Job Tracker**: ```bash gws sheets spreadsheets values get --params '{"spreadsheetId":"","range":"Hours!A:H"}' gws sheets spreadsheets values append --params '{"spreadsheetId":"","range":"Hours","valueInputOption":"USER_ENTERED"}' --json '{"values":[["2026-04-30","Tomek","steelfixer","day",8,1.5,0,837.50,"Y"]]}' ``` **Calendar — schedule pour / delivery / inspection**: ```bash gws calendar events insert --params '{"calendarId":"primary"}' --json '{"summary":"Hornsby pour - stair","start":{"dateTime":"2026-05-09T07:00:00+10:00"},"end":{"dateTime":"2026-05-09T11:00:00+10:00"}}' ``` ## Test-phase routing reminder While in testing phase (per `USER.md`): - All emails OpsMan would send externally → To: `admin@lfcs.com.au` instead - Subject prefix: `[TEST]` - Body header: "Intended for: " Once Rocky says "go live on lfcs email": - Switch sender → `michael@lfcs.com.au` - Switch destination → real recipients - Drop `[TEST]` prefix ## Other VPS tools - `openclaw` — gateway CLI (already used by the runtime; don't call directly unless needed) - `pm2` — process manager for any background services - `git` — version control for `/home/ccuser/rateright-growth/` and other repos (NOT for opsman-work — that's standalone) - `jq`, `python3`, `curl`, `node` — standard utilities ## Things OpsMan can do *because of* gws 1. **Auto-extract supplier invoices from inbox** → file PDF to `Jobs//09 - Invoicing/09b - Supplier Invoices and Receipts/`, log $ amount on Job Tracker 2. **Send RFIs to Joel Alvey at Solutions Plus** — drafted in OpsMan, sent via gmail (test-phase routes to admin@lfcs.com.au first) 3. **Auto-draft variation notices** within the 2-business-day window per PO Clause 9.4.2 4. **Job Tracker as Google Sheet** — once one is created, OpsMan writes hours + materials + costs in real-time 5. **Calendar reminders** — pour at 7am, materials delivery, SWMS due, claim 25th of month 6. **Drive backup** — daily diaries + photos sync to opsman.systems Drive as offsite redundancy ## What OpsMan should NOT do with gws yet - **Don't send to real client/subbie addresses** until test phase ends (Rocky says "go live") - **Don't migrate anything to LFCS Workspace** until `michael@lfcs.com.au` is provisioned - **Don't share opsman.systems credentials** — they're a personal Gmail, not company-owned ## Email formatting rules — non-negotiable 1. **Subject line: ASCII-only.** Use plain hyphens `-` instead of em-dash `—` or en-dash `–`. Subjects are RFC 2822 headers and any Unicode requires explicit RFC 2047 encoding (`=?UTF-8?B?...?=`) which is fragile across gateways. Body text can use Unicode freely — body is content-type-declared UTF-8. **Bad:** `Subject: [TEST] RFI — Category A — Hornsby` **Good:** `Subject: [TEST] RFI - Category A Pre-Start (1-8) - Hornsby` 2. **Body MIME header always:** `Content-Type: text/plain; charset=utf-8` 3. **Lines should be wrapped at ~76 chars** for plain-text email courtesy. Long URLs are exempt. 4. **Use the locked sender details from `USER.md`** — never invent phone numbers, email addresses, or job numbers. If a value isn't in the workspace, ask once. 5. **Signature template** (use exactly — no mobile number): ``` Regards, Michael McLoughlin LF Construction Services Pty Ltd E: ``` **Do not invent or include a mobile number** — Rocky's personal mobile is NOT to be in any email signature. Admin handles inbound phone via the LFCS main line.