@mulmoclaude/google-plugin 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +9 -8
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as googleApi from "@mulmoclaude/core/google";
|
|
2
|
-
import { DEFAULT_LIST_MAX_RESULTS, MAX_LIST_RESULTS, isIsoDateTimeWithOffset } from "@mulmoclaude/core/google";
|
|
2
|
+
import { DEFAULT_LIST_MAX_RESULTS, MAX_LIST_RESULTS, isIsoDateTimeWithOffset, toolCalendarSyncKey } from "@mulmoclaude/core/google";
|
|
3
3
|
//#region ../../../node_modules/gui-chat-protocol/dist/index.js
|
|
4
4
|
/**
|
|
5
5
|
* Identity function for type inference. Same philosophy as
|
|
@@ -127,7 +127,6 @@ function cached(getter) {
|
|
|
127
127
|
Object.defineProperty(this, "value", { value });
|
|
128
128
|
return value;
|
|
129
129
|
}
|
|
130
|
-
throw new Error("cached value already set");
|
|
131
130
|
} };
|
|
132
131
|
}
|
|
133
132
|
function nullish(input) {
|
|
@@ -4285,22 +4284,24 @@ var summarizeSync = (result, incremental) => {
|
|
|
4285
4284
|
};
|
|
4286
4285
|
};
|
|
4287
4286
|
async function restartFullSync(api, accessToken, calendarId) {
|
|
4288
|
-
await api.clearCalendarSyncToken(calendarId);
|
|
4287
|
+
await api.clearCalendarSyncToken(toolCalendarSyncKey(calendarId));
|
|
4289
4288
|
return await api.syncCalendarEvents(accessToken, { calendarId });
|
|
4290
4289
|
}
|
|
4291
4290
|
async function runCalendarSync(api, calendarId, fullResync) {
|
|
4292
4291
|
const accessToken = await api.getGoogleAccessToken();
|
|
4293
|
-
|
|
4294
|
-
|
|
4292
|
+
const syncKey = toolCalendarSyncKey(calendarId);
|
|
4293
|
+
if (fullResync) await api.clearCalendarSyncToken(syncKey);
|
|
4294
|
+
const storedToken = fullResync ? null : await api.loadCalendarSyncToken(syncKey);
|
|
4295
4295
|
const first = await api.syncCalendarEvents(accessToken, {
|
|
4296
4296
|
calendarId,
|
|
4297
4297
|
syncToken: storedToken ?? void 0
|
|
4298
4298
|
});
|
|
4299
4299
|
const result = first.fullResyncRequired ? await restartFullSync(api, accessToken, calendarId) : first;
|
|
4300
|
-
if (result.nextSyncToken) await api.saveCalendarSyncToken(
|
|
4300
|
+
if (result.nextSyncToken && !result.pagesExhausted) await api.saveCalendarSyncToken(syncKey, result.nextSyncToken);
|
|
4301
4301
|
return {
|
|
4302
4302
|
...summarizeSync(result, Boolean(storedToken) && !first.fullResyncRequired),
|
|
4303
|
-
expiredToken: first.fullResyncRequired
|
|
4303
|
+
expiredToken: first.fullResyncRequired,
|
|
4304
|
+
...result.pagesExhausted ? { pagesExhausted: true } : {}
|
|
4304
4305
|
};
|
|
4305
4306
|
}
|
|
4306
4307
|
var status = async ({ api }) => {
|
|
@@ -4499,7 +4500,7 @@ var TOOL_DEFINITION = {
|
|
|
4499
4500
|
type: "function",
|
|
4500
4501
|
name: "google",
|
|
4501
4502
|
prompt: "The user's Google account is linked LOCALLY on this machine — the refresh token is stored in ~/.config/mulmo/ and goes only to Google to mint access tokens, never to claude.ai or any other service. This is independent of claude.ai Google connectors; the tool works without them. If a call fails with 'Google account not linked', ask the user to link their Google account in this app's settings, then retry the original call.",
|
|
4502
|
-
description: "Operate the user's Google services through the locally linked Google account: Calendar, Tasks, and Drive. Supported kinds:\n - `status`: report whether the Google account is linked on this machine — call this first when unsure.\n\nCalendar (events default to the primary calendar; pass `calendarId` — from `calendarListCalendars` — to target another):\n - `calendarListCalendars`: list the calendars the user has added/subscribed to (`id`, `summary`, `primary`, `backgroundColor`/`foregroundColor` hex, `colorId`, `accessRole`). Call this to work with a non-primary calendar.\n - `calendarColors`: palettes that map an event/calendar `colorId` to hex — `event` for per-event colours, `calendar` for calendar colours.\n - `calendarListEvents`: list upcoming events (each carries `colorId`, empty when it inherits the calendar colour). Optional `calendarId`, `timeMin` (ISO 8601 date-time with timezone offset; default now), `maxResults` (1-50, default 10).\n - `calendarSync`: fetch only what CHANGED since the last sync of this calendar, using a stored sync token. Use this for repeated/periodic syncing — it does not re-fetch the whole calendar, so it stays cheap. The FIRST call (or after `fullResync: true`) walks the entire calendar to establish the token. Returns counts (`changed`, `cancelled`) plus a capped `events` sample — never the full list, so it will not flood the conversation; `truncated: true` means more changed than are shown. Deletions are reported as the `cancelled` count. Optional `calendarId`, `fullResync` (discard the stored token and start over).\n - `calendarCreateEvent`: create an event. Requires `summary`, `start`, `end` — ISO 8601 date-times WITH a timezone offset (e.g. 2026-07-17T09:00:00+09:00); optional `description`, `calendarId`, `colorId` (event palette id \"1\"-\"11\").\n - `calendarUpdateEvent`: edit an existing event. Requires `eventId` (from `calendarListEvents` / `calendarSync`) plus AT LEAST ONE of `summary`, `start`, `end`, `description`, `colorId`; fields you omit keep their current value, and `description: \"\"` clears the body. Optional `calendarId`. Moving only one end of the event still has to leave start before end, or Calendar rejects it.\n - `calendarDeleteEvent`: delete an event. Requires `eventId`; optional `calendarId`. This removes it for every attendee and cannot be undone — confirm with the user before calling. For a recurring event, an instance id (as returned by the list kinds) deletes that single occurrence.\n\nTasks:\n - `taskListsList`: list the user's task lists (`id`, `title`). Only needed when the user means a list other than their default one.\n - `tasksList`: list tasks. Optional `taskListId` (default: the user's default list), `maxResults` (1-50, default 10), `showCompleted` (default false).\n - `tasksCreate`: add a task. Requires `title`; optional `notes`, `due` (ISO 8601 with offset — Google keeps the DATE only, so do not promise a time of day), `taskListId`.\n - `tasksUpdate`: edit a task. Requires `taskId` (from `tasksList`) plus AT LEAST ONE of `title`, `notes`, `due`; omitted fields keep their value and `notes: \"\"` clears them. Use `tasksComplete` / `tasksUncomplete` to change status — this kind does not. Optional `taskListId`.\n - `tasksComplete`: mark a task done. Requires `taskId` (from `tasksList`); optional `taskListId`.\n - `tasksUncomplete`: put a completed task back on the to-do list. Requires `taskId`; optional `taskListId`. Completed tasks are hidden from `tasksList` unless you pass `showCompleted: true`, so list with that first to find the id.\n - `tasksDelete`: delete a task. Requires `taskId`; optional `taskListId`. Cannot be undone — confirm with the user before calling.\n\nDrive — IMPORTANT: this app can only see files IT created, never the user's wider Drive. Never claim you searched their whole Drive:\n - `driveList`: list files this app created. Optional `maxResults` (1-50, default 10).\n - `driveCreate`: create a text file. Requires `name` and `content`; optional `mimeType` (default text/plain).\n - `driveRead`: read one of this app's files. Requires `fileId` (from `driveList` or `driveCreate`). Text files only.",
|
|
4503
|
+
description: "Operate the user's Google services through the locally linked Google account: Calendar, Tasks, and Drive. Supported kinds:\n - `status`: report whether the Google account is linked on this machine — call this first when unsure.\n\nCalendar (events default to the primary calendar; pass `calendarId` — from `calendarListCalendars` — to target another):\n - `calendarListCalendars`: list the calendars the user has added/subscribed to (`id`, `summary`, `primary`, `backgroundColor`/`foregroundColor` hex, `colorId`, `accessRole`). Call this to work with a non-primary calendar.\n - `calendarColors`: palettes that map an event/calendar `colorId` to hex — `event` for per-event colours, `calendar` for calendar colours.\n - `calendarListEvents`: list upcoming events (each carries `colorId`, empty when it inherits the calendar colour). Optional `calendarId`, `timeMin` (ISO 8601 date-time with timezone offset; default now), `maxResults` (1-50, default 10).\n - `calendarSync`: fetch only what CHANGED since the last sync of this calendar, using a stored sync token. Use this for repeated/periodic syncing — it does not re-fetch the whole calendar, so it stays cheap. The FIRST call (or after `fullResync: true`) walks the entire calendar to establish the token. Returns counts (`changed`, `cancelled`) plus a capped `events` sample — never the full list, so it will not flood the conversation; `truncated: true` means more changed than are shown. Deletions are reported as the `cancelled` count. `pagesExhausted: true` means the calendar had more pages than one pass walks, so this is a PARTIAL read and no cursor was stored — say so rather than reporting the sync as complete; the usual cause is a recurring event with no end date. Optional `calendarId`, `fullResync` (discard the stored token and start over).\n - `calendarCreateEvent`: create an event. Requires `summary`, `start`, `end` — ISO 8601 date-times WITH a timezone offset (e.g. 2026-07-17T09:00:00+09:00); optional `description`, `calendarId`, `colorId` (event palette id \"1\"-\"11\").\n - `calendarUpdateEvent`: edit an existing event. Requires `eventId` (from `calendarListEvents` / `calendarSync`) plus AT LEAST ONE of `summary`, `start`, `end`, `description`, `colorId`; fields you omit keep their current value, and `description: \"\"` clears the body. Optional `calendarId`. Moving only one end of the event still has to leave start before end, or Calendar rejects it.\n - `calendarDeleteEvent`: delete an event. Requires `eventId`; optional `calendarId`. This removes it for every attendee and cannot be undone — confirm with the user before calling. For a recurring event, an instance id (as returned by the list kinds) deletes that single occurrence.\n\nTasks:\n - `taskListsList`: list the user's task lists (`id`, `title`). Only needed when the user means a list other than their default one.\n - `tasksList`: list tasks. Optional `taskListId` (default: the user's default list), `maxResults` (1-50, default 10), `showCompleted` (default false).\n - `tasksCreate`: add a task. Requires `title`; optional `notes`, `due` (ISO 8601 with offset — Google keeps the DATE only, so do not promise a time of day), `taskListId`.\n - `tasksUpdate`: edit a task. Requires `taskId` (from `tasksList`) plus AT LEAST ONE of `title`, `notes`, `due`; omitted fields keep their value and `notes: \"\"` clears them. Use `tasksComplete` / `tasksUncomplete` to change status — this kind does not. Optional `taskListId`.\n - `tasksComplete`: mark a task done. Requires `taskId` (from `tasksList`); optional `taskListId`.\n - `tasksUncomplete`: put a completed task back on the to-do list. Requires `taskId`; optional `taskListId`. Completed tasks are hidden from `tasksList` unless you pass `showCompleted: true`, so list with that first to find the id.\n - `tasksDelete`: delete a task. Requires `taskId`; optional `taskListId`. Cannot be undone — confirm with the user before calling.\n\nDrive — IMPORTANT: this app can only see files IT created, never the user's wider Drive. Never claim you searched their whole Drive:\n - `driveList`: list files this app created. Optional `maxResults` (1-50, default 10).\n - `driveCreate`: create a text file. Requires `name` and `content`; optional `mimeType` (default text/plain).\n - `driveRead`: read one of this app's files. Requires `fileId` (from `driveList` or `driveCreate`). Text files only.",
|
|
4503
4504
|
parameters: {
|
|
4504
4505
|
type: "object",
|
|
4505
4506
|
properties: {
|