feat(watcher): add agent Gmail CLI with audit and defaults

Provide list/read/summarize plus reason-gated archive, label, draft, and forward-as-draft, with SQLite audit logging and default-mailbox resolution.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-22 10:09:25 +07:00
co-authored by Cursor
parent 770ed8121a
commit f270f531ea
13 changed files with 1643 additions and 145 deletions
+6 -16
View File
@@ -16,7 +16,7 @@
* Options:
* --query <q> Gmail search (default: in:inbox newer_than:30d)
* --ids <a,b> Explicit message IDs (skips list search)
* --user <email> Mailbox to use (default: first user with tokens)
* --user <email> Mailbox (default: resolveUser — --user / env / is_default / sole)
* --max <n> Max messages to process (default 500)
* --dry-run Parse and log only; do not write PocketBase
*/
@@ -26,8 +26,8 @@ import {
GOOGLE_CLIENT_SECRET,
POCKETBASE_URL,
} from "../src/config.js";
import { getUserByEmail, listUsersWithTokens } from "../src/db.js";
import { gmailClientForUser } from "../src/google.js";
import { resolveUser } from "../src/cli/resolve-user.js";
import { fetchAndLogMessage } from "../src/handlers/fetch-and-log-message.js";
import { matchRule } from "../src/handlers/match-rule.js";
import { parseMatchedMessage } from "../src/handlers/parse-matched-message.js";
@@ -128,22 +128,12 @@ Default query: ${DEFAULT_QUERY}`);
process.exit(1);
}
const users = listUsersWithTokens();
if (!users.length) {
console.error("No signed-in users with tokens. Sign in via the web UI first.");
const resolved = resolveUser(args.user);
if (!resolved.ok) {
console.error(resolved.error);
process.exit(1);
}
let user = users[0];
if (args.user) {
const byEmail = getUserByEmail(args.user);
const byId = users.find((u) => String(u.id) === String(args.user));
user = byEmail || byId || null;
if (!user) {
console.error(`User not found: ${args.user}`);
process.exit(1);
}
}
const user = resolved.user;
const log = makeLog();
const gmail = await gmailClientForUser(user.id);