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:
+32
-1
@@ -28,6 +28,15 @@ db.exec(`
|
||||
);
|
||||
`);
|
||||
|
||||
function ensureColumn(table, column, definition) {
|
||||
const cols = db.prepare(`PRAGMA table_info(${table})`).all();
|
||||
if (!cols.some((c) => c.name === column)) {
|
||||
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
||||
}
|
||||
}
|
||||
|
||||
ensureColumn("users", "is_default", "INTEGER NOT NULL DEFAULT 0");
|
||||
|
||||
const upsertUserStmt = db.prepare(`
|
||||
INSERT INTO users (google_sub, email, name, picture)
|
||||
VALUES (@googleSub, @email, @name, @picture)
|
||||
@@ -49,9 +58,21 @@ const saveTokensStmt = db.prepare(`
|
||||
|
||||
const getUserByIdStmt = db.prepare(`SELECT * FROM users WHERE id = ?`);
|
||||
const getTokensStmt = db.prepare(`SELECT * FROM oauth_tokens WHERE user_id = ?`);
|
||||
const countDefaultsStmt = db.prepare(
|
||||
`SELECT COUNT(*) AS n FROM users WHERE is_default = 1`,
|
||||
);
|
||||
const clearDefaultsStmt = db.prepare(`UPDATE users SET is_default = 0`);
|
||||
const setDefaultStmt = db.prepare(
|
||||
`UPDATE users SET is_default = 1 WHERE id = ?`,
|
||||
);
|
||||
|
||||
export function upsertUser({ googleSub, email, name, picture }) {
|
||||
return upsertUserStmt.get({ googleSub, email, name, picture });
|
||||
const user = upsertUserStmt.get({ googleSub, email, name, picture });
|
||||
if (user && countDefaultsStmt.get().n === 0) {
|
||||
setDefaultStmt.run(user.id);
|
||||
return getUserByIdStmt.get(user.id);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
export function saveTokens(userId, { accessToken, refreshToken, expiry }) {
|
||||
@@ -71,6 +92,15 @@ export function getTokens(userId) {
|
||||
return getTokensStmt.get(userId) || null;
|
||||
}
|
||||
|
||||
export function setDefaultUser(userId) {
|
||||
const clearAndSet = db.transaction((id) => {
|
||||
clearDefaultsStmt.run();
|
||||
setDefaultStmt.run(id);
|
||||
});
|
||||
clearAndSet(userId);
|
||||
return getUserByIdStmt.get(userId) || null;
|
||||
}
|
||||
|
||||
export function publicUser(row) {
|
||||
if (!row) return null;
|
||||
return {
|
||||
@@ -78,5 +108,6 @@ export function publicUser(row) {
|
||||
email: row.email,
|
||||
name: row.name,
|
||||
picture: row.picture,
|
||||
isDefault: Boolean(row.is_default),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user