mulmoclaude 1.20.0 → 1.21.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/README.md +2 -2
- package/package.json +5 -5
- package/server/api/routes/collectionCalendarPush.ts +15 -2
- package/server/build/mcp-server.mjs +345 -345
- package/server/system/secrets.ts +8 -2
- package/server/system/logs/aaa +0 -737
- package/server/system/logs/bb +0 -446
package/README.md
CHANGED
|
@@ -156,8 +156,8 @@ Recommended: ≥ 32 characters of random data (shorter values trigger a startup
|
|
|
156
156
|
- **Marp slides** — `marp: true` frontmatter on any markdown file renders a slide deck in the canvas with PDF export. Custom themes via `config/marp-themes/<name>.css`.
|
|
157
157
|
- **Auto memory** — the agent maintains a typed memory layout (`conversations/memory/<type>/<topic>.md`) and reads it ambient-style.
|
|
158
158
|
- **Web Push on task finish** — enable in Settings → Notifications to get a push on your phone when the answer to a question you asked is ready, even with the browser closed. Requires the RemoteHost connection + a registered device (see [`docs/remote-host.md`](https://github.com/receptron/mulmoclaude/blob/main/docs/remote-host.md#web-push-on-task-finish-2086)).
|
|
159
|
-
- **Google (Calendar / Tasks / Drive)** — link your Google account in Settings → Plugins → Google and consent in the browser; no Google Cloud setup needed. The agent then gets a `google` tool covering the full round trip — list, create, edit and delete calendar events and tasks (including putting a completed task back on the list), plus the Drive files it creates — and the phone remote can trigger the same commands.
|
|
160
|
-
- **Google Calendar ↔ collection sync** — a collection can mirror one of your calendars and keep itself current: the first sync starts as soon as you ask for the collection, an hourly pass follows, and a Sync button forces one. It calls the Calendar API directly rather than routing the events through the agent, so keeping it fresh costs no tokens. A **Push to Google** button beside it sends the other way, creating events for records you added and updating ones you edited — it
|
|
159
|
+
- **Google (Calendar / Tasks / Drive)** — link your Google account in Settings → Plugins → Google and consent in the browser; no Google Cloud setup needed. The agent then gets a `google` tool covering the full round trip — list, create, edit and delete calendar events and tasks (including putting a completed task back on the list), plus the Drive files it creates — and the phone remote can trigger the same commands. Events can be timed or **all-day**: ask for a whole day and you get one, rather than a midnight appointment.
|
|
160
|
+
- **Google Calendar ↔ collection sync** — a collection can mirror one of your calendars and keep itself current: the first sync starts as soon as you ask for the collection, an hourly pass follows, and a Sync button forces one. It calls the Calendar API directly rather than routing the events through the agent, so keeping it fresh costs no tokens. A **Push to Google** button beside it sends the other way, creating events for records you added and updating ones you edited — it skips anything edited on both sides rather than picking a winner. It does not delete unless you ask it to: a collection can opt in so that removing a record removes the event, and even then it refuses any event with attendees rather than withdrawing it from their calendars. Ask for **two-way sync** and the collection pushes on the same schedule it pulls on, as one cycle, so there is no button to forget; a record the push could not send is then left alone by the pull instead of being overwritten. Without it the pull is automatic and the push is a button, so push before you sync — a pull overwrites a locally edited record as soon as Google reports a change to that event. Event **notes and location** travel in both directions alongside the title, times and colour, and the mirror can also carry read-only details — your own RSVP, the meeting link, and which recurring series an occurrence came from. **The refresh token stays on your machine** (`~/.config/mulmo/`) — the sign-in service applies the OAuth client secret Google requires and keeps nothing. Prefer your own OAuth client? Drop a *desktop-app* client JSON in `~/.secrets/` and the whole flow stays local (see [`docs/remote-host.md`](https://github.com/receptron/mulmoclaude/blob/main/docs/remote-host.md)).
|
|
161
161
|
|
|
162
162
|
## Plugin authoring (`--dev-plugin`)
|
|
163
163
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mulmoclaude",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "MulmoClaude — GUI-chat with Claude Code + long-term memory. One command to start.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -36,17 +36,17 @@
|
|
|
36
36
|
"@mulmochat-plugin/ui-image": "^0.4.1",
|
|
37
37
|
"@mulmoclaude/accounting-plugin": "^4.0.0",
|
|
38
38
|
"@mulmoclaude/chart-plugin": "^4.0.0",
|
|
39
|
-
"@mulmoclaude/collection-plugin": "^5.
|
|
39
|
+
"@mulmoclaude/collection-plugin": "^5.1.0",
|
|
40
40
|
"@mulmoclaude/common": "^1.3.0",
|
|
41
|
-
"@mulmoclaude/core": "^5.
|
|
41
|
+
"@mulmoclaude/core": "^5.3.0",
|
|
42
42
|
"@mulmoclaude/form-plugin": "^2.0.0",
|
|
43
|
-
"@mulmoclaude/google-plugin": "^4.
|
|
43
|
+
"@mulmoclaude/google-plugin": "^4.1.0",
|
|
44
44
|
"@mulmoclaude/html-plugin": "^5.0.0",
|
|
45
45
|
"@mulmoclaude/markdown-plugin": "^5.0.0",
|
|
46
46
|
"@mulmoclaude/markdown-utils": "^3.0.0",
|
|
47
47
|
"@mulmoclaude/mulmoscript-plugin": "^5.0.0",
|
|
48
48
|
"@mulmoclaude/shapescript-plugin": "^7.0.0",
|
|
49
|
-
"@mulmoclaude/spotify-plugin": "^2.0.
|
|
49
|
+
"@mulmoclaude/spotify-plugin": "^2.0.2",
|
|
50
50
|
"@mulmoclaude/x-plugin": "^1.0.4",
|
|
51
51
|
"@receptron/task-scheduler": "^1.0.3",
|
|
52
52
|
"cors": "^2.8.6",
|
|
@@ -9,8 +9,11 @@ export interface CollectionPushBody {
|
|
|
9
9
|
updated: number;
|
|
10
10
|
/** Edited on both sides — skipped so neither version is lost. */
|
|
11
11
|
conflicts: number;
|
|
12
|
-
/** Records deleted locally
|
|
12
|
+
/** Records deleted locally, whether or not the deletion carried. */
|
|
13
13
|
localDeletes: number;
|
|
14
|
+
/** Of those, how many were deleted in Google too — `0` unless the collection
|
|
15
|
+
* opted in with `propagateDeletes` (#3234). */
|
|
16
|
+
deletedInGoogle: number;
|
|
14
17
|
/** Records that could not be pushed as they stand, each with its reason. */
|
|
15
18
|
skipped: string[];
|
|
16
19
|
errors: string[];
|
|
@@ -24,7 +27,16 @@ export const PUSH_NOT_DECLARED_ERROR = "this collection does not declare a `goog
|
|
|
24
27
|
export const pushReadOnlyError = (accessRole: string): string =>
|
|
25
28
|
`you only have ${accessRole || "read"} access to this calendar — pushing needs owner or writer access`;
|
|
26
29
|
|
|
27
|
-
const empty = (errors: string[]): CollectionPushBody => ({
|
|
30
|
+
const empty = (errors: string[]): CollectionPushBody => ({
|
|
31
|
+
pushed: true,
|
|
32
|
+
created: 0,
|
|
33
|
+
updated: 0,
|
|
34
|
+
conflicts: 0,
|
|
35
|
+
localDeletes: 0,
|
|
36
|
+
deletedInGoogle: 0,
|
|
37
|
+
skipped: [],
|
|
38
|
+
errors,
|
|
39
|
+
});
|
|
28
40
|
|
|
29
41
|
const fromResult = (result: CalendarCollectionPushResult): CollectionPushBody => ({
|
|
30
42
|
pushed: true,
|
|
@@ -32,6 +44,7 @@ const fromResult = (result: CalendarCollectionPushResult): CollectionPushBody =>
|
|
|
32
44
|
updated: result.updated,
|
|
33
45
|
conflicts: result.conflicts,
|
|
34
46
|
localDeletes: result.localDeletes,
|
|
47
|
+
deletedInGoogle: result.deletedInGoogle,
|
|
35
48
|
skipped: result.skipped,
|
|
36
49
|
errors: result.errors,
|
|
37
50
|
});
|