@mulmoclaude/google-plugin 0.2.1 → 0.3.2
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/args.d.ts +11 -0
- package/dist/definition.d.ts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +74 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/args.d.ts
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const GoogleArgs: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3
3
|
kind: z.ZodLiteral<"status">;
|
|
4
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
5
|
+
kind: z.ZodLiteral<"calendarListCalendars">;
|
|
6
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
7
|
+
kind: z.ZodLiteral<"calendarColors">;
|
|
4
8
|
}, z.core.$strip>, z.ZodObject<{
|
|
5
9
|
kind: z.ZodLiteral<"calendarListEvents">;
|
|
10
|
+
calendarId: z.ZodOptional<z.ZodString>;
|
|
6
11
|
timeMin: z.ZodOptional<z.ZodString>;
|
|
7
12
|
maxResults: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
+
kind: z.ZodLiteral<"calendarSync">;
|
|
15
|
+
calendarId: z.ZodOptional<z.ZodString>;
|
|
16
|
+
fullResync: z.ZodOptional<z.ZodBoolean>;
|
|
8
17
|
}, z.core.$strip>, z.ZodObject<{
|
|
9
18
|
kind: z.ZodLiteral<"calendarCreateEvent">;
|
|
10
19
|
summary: z.ZodString;
|
|
11
20
|
start: z.ZodString;
|
|
12
21
|
end: z.ZodString;
|
|
13
22
|
description: z.ZodOptional<z.ZodString>;
|
|
23
|
+
calendarId: z.ZodOptional<z.ZodString>;
|
|
24
|
+
colorId: z.ZodOptional<z.ZodString>;
|
|
14
25
|
}, z.core.$strip>, z.ZodObject<{
|
|
15
26
|
kind: z.ZodLiteral<"taskListsList">;
|
|
16
27
|
}, z.core.$strip>, z.ZodObject<{
|
package/dist/definition.d.ts
CHANGED
|
@@ -10,10 +10,22 @@ export declare const TOOL_DEFINITION: {
|
|
|
10
10
|
type: string;
|
|
11
11
|
enum: string[];
|
|
12
12
|
};
|
|
13
|
+
calendarId: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
colorId: {
|
|
18
|
+
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
13
21
|
timeMin: {
|
|
14
22
|
type: string;
|
|
15
23
|
description: string;
|
|
16
24
|
};
|
|
25
|
+
fullResync: {
|
|
26
|
+
type: string;
|
|
27
|
+
description: string;
|
|
28
|
+
};
|
|
17
29
|
maxResults: {
|
|
18
30
|
type: string;
|
|
19
31
|
description: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,10 +13,22 @@ declare const _default: (runtime: import('gui-chat-protocol').PluginRuntime) =>
|
|
|
13
13
|
type: string;
|
|
14
14
|
enum: string[];
|
|
15
15
|
};
|
|
16
|
+
calendarId: {
|
|
17
|
+
type: string;
|
|
18
|
+
description: string;
|
|
19
|
+
};
|
|
20
|
+
colorId: {
|
|
21
|
+
type: string;
|
|
22
|
+
description: string;
|
|
23
|
+
};
|
|
16
24
|
timeMin: {
|
|
17
25
|
type: string;
|
|
18
26
|
description: string;
|
|
19
27
|
};
|
|
28
|
+
fullResync: {
|
|
29
|
+
type: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
20
32
|
maxResults: {
|
|
21
33
|
type: string;
|
|
22
34
|
description: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_LIST_MAX_RESULTS, MAX_LIST_RESULTS, clientSecretPresence, completeTask, createCalendarEvent, createDriveFile, createTask, getGoogleAccessToken, isIsoDateTimeWithOffset, listCalendarEvents, listDriveFiles, listTaskLists, listTasks, loadGoogleTokens, readDriveFile } from "@mulmoclaude/core/google";
|
|
1
|
+
import { DEFAULT_LIST_MAX_RESULTS, MAX_LIST_RESULTS, clearCalendarSyncToken, clientSecretPresence, completeTask, createCalendarEvent, createDriveFile, createTask, getCalendarColors, getGoogleAccessToken, isIsoDateTimeWithOffset, listCalendarEvents, listCalendars, listDriveFiles, listTaskLists, listTasks, loadCalendarSyncToken, loadGoogleTokens, readDriveFile, saveCalendarSyncToken, syncCalendarEvents } from "@mulmoclaude/core/google";
|
|
2
2
|
//#region ../../../node_modules/gui-chat-protocol/dist/index.js
|
|
3
3
|
function definePlugin(setup) {
|
|
4
4
|
return setup;
|
|
@@ -4117,19 +4117,30 @@ function superRefine(fn, params) {
|
|
|
4117
4117
|
var IsoDateTimeWithOffset = string().refine(isIsoDateTimeWithOffset, { error: "must be an ISO 8601 date-time with a timezone offset (e.g. 2026-07-17T09:00:00+09:00)" });
|
|
4118
4118
|
var MaxResults = number().int().min(1).max(MAX_LIST_RESULTS).optional();
|
|
4119
4119
|
var NonEmpty = string().min(1);
|
|
4120
|
+
var OptionalNonEmpty = string().trim().min(1).optional();
|
|
4120
4121
|
var GoogleArgs = discriminatedUnion("kind", [
|
|
4121
4122
|
object({ kind: literal("status") }),
|
|
4123
|
+
object({ kind: literal("calendarListCalendars") }),
|
|
4124
|
+
object({ kind: literal("calendarColors") }),
|
|
4122
4125
|
object({
|
|
4123
4126
|
kind: literal("calendarListEvents"),
|
|
4127
|
+
calendarId: OptionalNonEmpty,
|
|
4124
4128
|
timeMin: IsoDateTimeWithOffset.optional(),
|
|
4125
4129
|
maxResults: MaxResults
|
|
4126
4130
|
}),
|
|
4131
|
+
object({
|
|
4132
|
+
kind: literal("calendarSync"),
|
|
4133
|
+
calendarId: OptionalNonEmpty,
|
|
4134
|
+
fullResync: boolean().optional()
|
|
4135
|
+
}),
|
|
4127
4136
|
object({
|
|
4128
4137
|
kind: literal("calendarCreateEvent"),
|
|
4129
4138
|
summary: NonEmpty,
|
|
4130
4139
|
start: IsoDateTimeWithOffset,
|
|
4131
4140
|
end: IsoDateTimeWithOffset,
|
|
4132
|
-
description: string().optional()
|
|
4141
|
+
description: string().optional(),
|
|
4142
|
+
calendarId: OptionalNonEmpty,
|
|
4143
|
+
colorId: OptionalNonEmpty
|
|
4133
4144
|
}),
|
|
4134
4145
|
object({ kind: literal("taskListsList") }),
|
|
4135
4146
|
object({
|
|
@@ -4171,7 +4182,7 @@ var TOOL_DEFINITION = {
|
|
|
4171
4182
|
type: "function",
|
|
4172
4183
|
name: "google",
|
|
4173
4184
|
prompt: "The user's Google account is linked LOCALLY on this machine — the refresh token lives in ~/.config/mulmo/ and never reaches any cloud. 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.",
|
|
4174
|
-
description: "Operate the user's Google services through the locally linked Google account: Calendar
|
|
4185
|
+
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\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 - `tasksComplete`: mark a task done. Requires `taskId` (from `tasksList`); optional `taskListId`.\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.",
|
|
4175
4186
|
parameters: {
|
|
4176
4187
|
type: "object",
|
|
4177
4188
|
properties: {
|
|
@@ -4179,7 +4190,10 @@ var TOOL_DEFINITION = {
|
|
|
4179
4190
|
type: "string",
|
|
4180
4191
|
enum: [
|
|
4181
4192
|
"status",
|
|
4193
|
+
"calendarListCalendars",
|
|
4194
|
+
"calendarColors",
|
|
4182
4195
|
"calendarListEvents",
|
|
4196
|
+
"calendarSync",
|
|
4183
4197
|
"calendarCreateEvent",
|
|
4184
4198
|
"taskListsList",
|
|
4185
4199
|
"tasksList",
|
|
@@ -4190,10 +4204,22 @@ var TOOL_DEFINITION = {
|
|
|
4190
4204
|
"driveRead"
|
|
4191
4205
|
]
|
|
4192
4206
|
},
|
|
4207
|
+
calendarId: {
|
|
4208
|
+
type: "string",
|
|
4209
|
+
description: "calendar kinds: target calendar id from calendarListCalendars (default: the user's primary)"
|
|
4210
|
+
},
|
|
4211
|
+
colorId: {
|
|
4212
|
+
type: "string",
|
|
4213
|
+
description: "calendarCreateEvent: optional event palette colour id \"1\"-\"11\""
|
|
4214
|
+
},
|
|
4193
4215
|
timeMin: {
|
|
4194
4216
|
type: "string",
|
|
4195
4217
|
description: "calendarListEvents: lower bound, ISO 8601 with timezone offset (default: now)"
|
|
4196
4218
|
},
|
|
4219
|
+
fullResync: {
|
|
4220
|
+
type: "boolean",
|
|
4221
|
+
description: "calendarSync: discard the stored sync token and re-walk the whole calendar (default false)"
|
|
4222
|
+
},
|
|
4197
4223
|
maxResults: {
|
|
4198
4224
|
type: "number",
|
|
4199
4225
|
description: "list kinds: max items to return, 1-50 (default 10)"
|
|
@@ -4261,6 +4287,38 @@ var TOOL_DEFINITION = {
|
|
|
4261
4287
|
//#endregion
|
|
4262
4288
|
//#region src/index.ts
|
|
4263
4289
|
var LINK_GUIDANCE = "Ask the user to link their Google account in this app's settings, then retry.";
|
|
4290
|
+
var SYNC_SAMPLE_LIMIT = 20;
|
|
4291
|
+
var summarizeSync = (result, incremental) => {
|
|
4292
|
+
const active = result.events.filter((event) => event.status !== "cancelled");
|
|
4293
|
+
const cancelled = result.events.length - active.length;
|
|
4294
|
+
return {
|
|
4295
|
+
ok: true,
|
|
4296
|
+
incremental,
|
|
4297
|
+
changed: active.length,
|
|
4298
|
+
cancelled,
|
|
4299
|
+
events: active.slice(0, SYNC_SAMPLE_LIMIT),
|
|
4300
|
+
truncated: active.length > SYNC_SAMPLE_LIMIT
|
|
4301
|
+
};
|
|
4302
|
+
};
|
|
4303
|
+
async function restartFullSync(accessToken, calendarId) {
|
|
4304
|
+
await clearCalendarSyncToken(calendarId);
|
|
4305
|
+
return await syncCalendarEvents(accessToken, { calendarId });
|
|
4306
|
+
}
|
|
4307
|
+
async function runCalendarSync(calendarId, fullResync) {
|
|
4308
|
+
const accessToken = await getGoogleAccessToken();
|
|
4309
|
+
if (fullResync) await clearCalendarSyncToken(calendarId);
|
|
4310
|
+
const storedToken = fullResync ? null : await loadCalendarSyncToken(calendarId);
|
|
4311
|
+
const first = await syncCalendarEvents(accessToken, {
|
|
4312
|
+
calendarId,
|
|
4313
|
+
syncToken: storedToken ?? void 0
|
|
4314
|
+
});
|
|
4315
|
+
const result = first.fullResyncRequired ? await restartFullSync(accessToken, calendarId) : first;
|
|
4316
|
+
if (result.nextSyncToken) await saveCalendarSyncToken(calendarId, result.nextSyncToken);
|
|
4317
|
+
return {
|
|
4318
|
+
...summarizeSync(result, Boolean(storedToken) && !first.fullResyncRequired),
|
|
4319
|
+
expiredToken: first.fullResyncRequired
|
|
4320
|
+
};
|
|
4321
|
+
}
|
|
4264
4322
|
var src_default = definePlugin(({ log }) => {
|
|
4265
4323
|
const dispatch = async (args) => {
|
|
4266
4324
|
switch (args.kind) {
|
|
@@ -4274,19 +4332,31 @@ var src_default = definePlugin(({ log }) => {
|
|
|
4274
4332
|
...linked ? {} : { guidance: LINK_GUIDANCE }
|
|
4275
4333
|
};
|
|
4276
4334
|
}
|
|
4335
|
+
case "calendarListCalendars": return {
|
|
4336
|
+
ok: true,
|
|
4337
|
+
calendars: await listCalendars(await getGoogleAccessToken())
|
|
4338
|
+
};
|
|
4339
|
+
case "calendarColors": return {
|
|
4340
|
+
ok: true,
|
|
4341
|
+
colors: await getCalendarColors(await getGoogleAccessToken())
|
|
4342
|
+
};
|
|
4277
4343
|
case "calendarListEvents": return {
|
|
4278
4344
|
ok: true,
|
|
4279
4345
|
events: await listCalendarEvents(await getGoogleAccessToken(), {
|
|
4346
|
+
calendarId: args.calendarId,
|
|
4280
4347
|
timeMin: args.timeMin,
|
|
4281
4348
|
maxResults: args.maxResults ?? DEFAULT_LIST_MAX_RESULTS
|
|
4282
4349
|
})
|
|
4283
4350
|
};
|
|
4351
|
+
case "calendarSync": return await runCalendarSync(args.calendarId, args.fullResync ?? false);
|
|
4284
4352
|
case "calendarCreateEvent": {
|
|
4285
4353
|
const event = await createCalendarEvent(await getGoogleAccessToken(), {
|
|
4286
4354
|
summary: args.summary,
|
|
4287
4355
|
startDateTime: args.start,
|
|
4288
4356
|
endDateTime: args.end,
|
|
4289
|
-
description: args.description
|
|
4357
|
+
description: args.description,
|
|
4358
|
+
calendarId: args.calendarId,
|
|
4359
|
+
colorId: args.colorId
|
|
4290
4360
|
});
|
|
4291
4361
|
log.info("calendar event created", { id: event.id });
|
|
4292
4362
|
return {
|