@mulmoclaude/core 1.2.1 → 1.4.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 +49 -0
- package/assets/helps/google-calendar-collection.md +13 -2
- package/assets/helps/google.md +94 -0
- package/assets/helps/index.md +1 -0
- package/dist/collection/registry/server/index.cjs +3 -2
- package/dist/collection/registry/server/index.cjs.map +1 -1
- package/dist/collection/registry/server/index.js +3 -2
- package/dist/collection/registry/server/index.js.map +1 -1
- package/dist/collection/server/index.cjs +1 -1
- package/dist/collection/server/index.js +1 -1
- package/dist/collection-watchers/index.cjs +1 -1
- package/dist/collection-watchers/index.js +1 -1
- package/dist/feeds/server/index.cjs +2 -2
- package/dist/feeds/server/index.js +2 -2
- package/dist/files/index.cjs +3 -0
- package/dist/files/index.cjs.map +1 -1
- package/dist/files/index.d.ts +1 -0
- package/dist/files/index.js +2 -1
- package/dist/files/index.js.map +1 -1
- package/dist/files/relPath.d.ts +23 -0
- package/dist/google/calendar.d.ts +28 -0
- package/dist/google/collectionSync.d.ts +88 -4
- package/dist/google/index.cjs +235 -17
- package/dist/google/index.cjs.map +1 -1
- package/dist/google/index.d.ts +3 -3
- package/dist/google/index.js +223 -18
- package/dist/google/index.js.map +1 -1
- package/dist/google/tasks.d.ts +21 -0
- package/dist/relPath-CgGi4-Nv.cjs +46 -0
- package/dist/relPath-CgGi4-Nv.cjs.map +1 -0
- package/dist/relPath-DW8MC8VO.js +33 -0
- package/dist/relPath-DW8MC8VO.js.map +1 -0
- package/dist/{server-BZJCw2HU.js → server-D_6FLygK.js} +6 -2
- package/dist/server-D_6FLygK.js.map +1 -0
- package/dist/{server-w5ZZRLju.cjs → server-gEOeV_Nv.cjs} +6 -2
- package/dist/server-gEOeV_Nv.cjs.map +1 -0
- package/package.json +10 -1
- package/dist/server-BZJCw2HU.js.map +0 -1
- package/dist/server-w5ZZRLju.cjs.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# @mulmoclaude/core
|
|
2
|
+
|
|
3
|
+
Shared server-side core for **MulmoClaude** and **MulmoTerminal** — the
|
|
4
|
+
subsystems the two hosts always ship together, consolidated behind subpath
|
|
5
|
+
exports so they cannot drift apart.
|
|
6
|
+
|
|
7
|
+
Not a general-purpose library: it exists so one implementation of collections,
|
|
8
|
+
wiki, feeds, Google integration, scheduling and the rest serves both hosts.
|
|
9
|
+
Every host specific (paths, logging, notification transport, …) is injected
|
|
10
|
+
rather than imported, which is what lets the same code run under either.
|
|
11
|
+
|
|
12
|
+
## Subpath exports
|
|
13
|
+
|
|
14
|
+
| Area | Entries |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| Collections | `./collection`, `./collection/server`, `./collection/paths`, `./collection/registry`, `./collection/registry/server`, `./collection-watchers` |
|
|
17
|
+
| Knowledge | `./wiki`, `./wiki/server`, `./wiki/paths`, `./feeds`, `./feeds/server`, `./feeds/paths` |
|
|
18
|
+
| Google | `./google` — OAuth (loopback + PKCE), token store, Calendar / Tasks / Drive REST |
|
|
19
|
+
| Runtime | `./scheduler`, `./notifier`, `./skill-bridge`, `./file-change`, `./workspace-setup`, `./artifacts` |
|
|
20
|
+
| Remote | `./remote-host`, `./remote-host/server`, `./remote-view` |
|
|
21
|
+
| Voice | `./whisper`, `./whisper/client` |
|
|
22
|
+
| Plugin support | `./plugin-vue`, `./plugin-vue/i18n` |
|
|
23
|
+
| Utilities | `./utils`, `./files`, `./fetch` |
|
|
24
|
+
|
|
25
|
+
**Server-only**, except the browser-safe entries: `./artifacts`,
|
|
26
|
+
`./whisper/client`, `./workspace-setup/slug`, `./translation/client`,
|
|
27
|
+
`./remote-view`, `./remote-host` and `./plugin-vue`.
|
|
28
|
+
|
|
29
|
+
The package also ships `assets/helps/*` — the help documents the agent reads at
|
|
30
|
+
runtime — which is why a change there alone still warrants a release.
|
|
31
|
+
|
|
32
|
+
## About MulmoClaude and MulmoTerminal
|
|
33
|
+
|
|
34
|
+
- **[MulmoClaude](https://github.com/receptron/mulmoclaude)** — an AI-native
|
|
35
|
+
application platform built on Claude Code. Chat summons the right GUI for each
|
|
36
|
+
task (documents, charts, forms, wikis, spreadsheets, 3D scenes), and
|
|
37
|
+
everything your assistant accumulates stays as plain files in your own
|
|
38
|
+
workspace, on your own machine.
|
|
39
|
+
- **[MulmoTerminal](https://github.com/receptron/mulmoterminal)** — run a whole
|
|
40
|
+
team of coding agents from your browser. Many Claude Code / Codex sessions at
|
|
41
|
+
once in a grid, colour-coded so you see which are working, which need you and
|
|
42
|
+
which are done, plus git worktrees, one-click PRs and cost readouts. One `npx`
|
|
43
|
+
command, no Electron, no config.
|
|
44
|
+
|
|
45
|
+
📖 **User guide**: <https://receptron.github.io/mulmoterminal/> (日本語 / English)
|
|
46
|
+
|
|
47
|
+
## License
|
|
48
|
+
|
|
49
|
+
MIT
|
|
@@ -5,8 +5,10 @@ Add a `googleCalendar` block to its `schema.json` and the host pulls changed
|
|
|
5
5
|
events on a schedule and writes them as records — **without calling you**. No
|
|
6
6
|
tool call, no tokens spent per sync, so hourly syncing is free.
|
|
7
7
|
|
|
8
|
-
This is the
|
|
9
|
-
|
|
8
|
+
This is the mechanism for *keeping a collection fresh*. For one-off reads and
|
|
9
|
+
for creating / editing / deleting events, use the `google` tool — see
|
|
10
|
+
[The `google` tool](google.md). There is no bundled calendar collection: you
|
|
11
|
+
author the schema when the user asks for one.
|
|
10
12
|
|
|
11
13
|
## Requirements
|
|
12
14
|
|
|
@@ -57,6 +59,15 @@ Declaring it in `map` is a schema error.
|
|
|
57
59
|
Use `datetime` (not `date`) for start/end when events have real clock times —
|
|
58
60
|
the calendar day view then draws each record as a proportional time block.
|
|
59
61
|
|
|
62
|
+
## When sync runs
|
|
63
|
+
|
|
64
|
+
- **On creation** — the first sync starts as soon as the schema lands, so the
|
|
65
|
+
collection is not empty while the user waits for the schedule. The same
|
|
66
|
+
applies when you add a `googleCalendar` block to an existing collection.
|
|
67
|
+
- **Hourly** after that, in the background.
|
|
68
|
+
- **On demand** — the collection view has a Sync button. Tell the user about it
|
|
69
|
+
if they want the calendar refreshed right now.
|
|
70
|
+
|
|
60
71
|
## What sync does
|
|
61
72
|
|
|
62
73
|
- New or edited events are written, keyed by event id (existing records are
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# The `google` tool — Calendar, Tasks and Drive
|
|
2
|
+
|
|
3
|
+
One tool, one `kind` per operation, against the Google account the user linked
|
|
4
|
+
on this machine. The refresh token is stored locally in `~/.config/mulmo/` and
|
|
5
|
+
goes only to Google, to mint access tokens — never to claude.ai or any other
|
|
6
|
+
service. This works with no claude.ai Google connector involved.
|
|
7
|
+
|
|
8
|
+
Call `kind: "status"` when unsure whether the account is linked. If a call fails
|
|
9
|
+
with "Google account not linked", ask the user to link it in settings and retry
|
|
10
|
+
the original call — do not fall back to guessing.
|
|
11
|
+
|
|
12
|
+
## Two mechanisms, different jobs
|
|
13
|
+
|
|
14
|
+
| You want | Use |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| Read or change specific events / tasks / files, right now | this tool |
|
|
17
|
+
| A collection that mirrors a calendar and keeps itself fresh | a `googleCalendar` block — see [Google Calendar sync](google-calendar-collection.md) |
|
|
18
|
+
|
|
19
|
+
The collection route costs no tokens per refresh, so prefer it for anything
|
|
20
|
+
recurring. Use this tool for one-off work and for everything the collection
|
|
21
|
+
route cannot do (creating, editing and deleting).
|
|
22
|
+
|
|
23
|
+
## Calendar
|
|
24
|
+
|
|
25
|
+
Events default to the user's **primary** calendar. Pass `calendarId` — obtained
|
|
26
|
+
from `calendarListCalendars` — to target another.
|
|
27
|
+
|
|
28
|
+
| kind | What it does |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| `calendarListCalendars` | The calendars the user has added/subscribed to: `id`, `summary`, `primary`, colours, `accessRole` |
|
|
31
|
+
| `calendarColors` | Palettes mapping a `colorId` to hex, for events and for calendars |
|
|
32
|
+
| `calendarListEvents` | Upcoming events. Optional `calendarId`, `timeMin`, `maxResults` (1-50, default 10) |
|
|
33
|
+
| `calendarSync` | Only what CHANGED since the last sync, via a stored token. Returns counts plus a capped sample |
|
|
34
|
+
| `calendarCreateEvent` | Create. Requires `summary`, `start`, `end`; optional `description`, `calendarId`, `colorId` |
|
|
35
|
+
| `calendarUpdateEvent` | Edit in place. Requires `eventId` + at least one of `summary`, `start`, `end`, `description`, `colorId` |
|
|
36
|
+
| `calendarDeleteEvent` | Delete. Requires `eventId` |
|
|
37
|
+
|
|
38
|
+
**Date-times must carry a timezone offset** — `2026-07-17T09:00:00+09:00`, not
|
|
39
|
+
`2026-07-17` and not `2026-07-17T09:00:00`. Calendar rejects the others with an
|
|
40
|
+
opaque 400.
|
|
41
|
+
|
|
42
|
+
**Editing is a patch.** Fields you omit keep their current value, so changing a
|
|
43
|
+
title needs `eventId` + `summary` and nothing else. `description: ""` clears the
|
|
44
|
+
body. Moving one end of an event still has to leave the start before the end.
|
|
45
|
+
|
|
46
|
+
**`eventId` comes from `calendarListEvents` or `calendarSync`** — never invent
|
|
47
|
+
one. For a recurring event those kinds return per-occurrence ids, so editing or
|
|
48
|
+
deleting one affects that single occurrence.
|
|
49
|
+
|
|
50
|
+
**Deleting is not reversible** and removes the event for every attendee. Confirm
|
|
51
|
+
with the user before calling `calendarDeleteEvent`, and say which event you are
|
|
52
|
+
about to remove.
|
|
53
|
+
|
|
54
|
+
## Tasks
|
|
55
|
+
|
|
56
|
+
Operate on the user's default task list unless `taskListId` is given.
|
|
57
|
+
|
|
58
|
+
| kind | What it does |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `taskListsList` | The user's task lists (`id`, `title`). Only needed for a non-default list |
|
|
61
|
+
| `tasksList` | List tasks. Optional `taskListId`, `maxResults` (1-50, default 10), `showCompleted` (default false) |
|
|
62
|
+
| `tasksCreate` | Add a task. Requires `title`; optional `notes`, `due`, `taskListId` |
|
|
63
|
+
| `tasksUpdate` | Edit. Requires `taskId` + at least one of `title`, `notes`, `due`. `notes: ""` clears them; `due` can be changed but **not** cleared |
|
|
64
|
+
| `tasksComplete` | Mark done. Requires `taskId` |
|
|
65
|
+
| `tasksDelete` | Delete. Requires `taskId` — not reversible, so confirm first |
|
|
66
|
+
|
|
67
|
+
`tasksUpdate` does not change status: `tasksComplete` owns that transition.
|
|
68
|
+
|
|
69
|
+
**Google stores a DATE only for `due`** — the time part is accepted and then
|
|
70
|
+
ignored, so never promise the user a time of day on a task.
|
|
71
|
+
|
|
72
|
+
## Drive
|
|
73
|
+
|
|
74
|
+
In practice this app sees **only the files it created itself**, never the user's
|
|
75
|
+
wider Drive. Never claim to have searched their Drive.
|
|
76
|
+
|
|
77
|
+
(The `drive.file` scope also covers files the user hands to an app through a
|
|
78
|
+
Google Picker, but this app has no Picker — so app-created is the whole set.)
|
|
79
|
+
|
|
80
|
+
| kind | What it does |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `driveList` | Files this app created. Optional `maxResults` (1-50, default 10) |
|
|
83
|
+
| `driveCreate` | Create a text file. Requires `name`, `content`; optional `mimeType` (default `text/plain`) |
|
|
84
|
+
| `driveRead` | Read one of this app's files. Requires `fileId`. Text only |
|
|
85
|
+
|
|
86
|
+
## Failure modes
|
|
87
|
+
|
|
88
|
+
- **"Google account not linked"** — the user has not linked, or the token was
|
|
89
|
+
revoked. Ask them to link in settings; do not retry blindly.
|
|
90
|
+
- **HTTP 403 naming an API** — that API is not enabled for the user's Cloud
|
|
91
|
+
project. The message says which one.
|
|
92
|
+
- **HTTP 400 on a create/update** — almost always a date-time without an offset,
|
|
93
|
+
or a start that is not before the end.
|
|
94
|
+
- **HTTP 410 on delete** — the event was already gone.
|
package/assets/helps/index.md
CHANGED
|
@@ -72,6 +72,7 @@ See [Wiki](config/helps/wiki.md) for details on how it works.
|
|
|
72
72
|
- [Remote host](config/helps/remote-host.md) — drive MulmoClaude from a phone at mulmoserver.web.app: Google sign-in connect, host online vs. offline (queued chats, 7-day expiry), photo attachments, and the security model
|
|
73
73
|
- [Feeds](config/helps/feeds.md) — register a self-refreshing data feed (RSS/Atom/JSON) by authoring `feeds/<slug>/schema.json`: schema shape, the `ingest` block, raw-item field mapping, and `maxItems` retention
|
|
74
74
|
- [Google Calendar sync](config/helps/google-calendar-collection.md) — mirror a Google calendar into a collection with a `googleCalendar` block: field mapping, why the primary field holds the event id, and how deletions propagate
|
|
75
|
+
- [The `google` tool](config/helps/google.md) — every `kind` for Calendar, Tasks and Drive: reading, creating, editing and deleting events and tasks, the timezone-offset rule, patch semantics, and what `drive.file` scope cannot see
|
|
75
76
|
- [GitHub repositories in the workspace](config/helps/github.md) — clone-destination rules under `github/<name>/` and how to handle existing directories with matching or different remotes
|
|
76
77
|
- [Collection skills](config/helps/collection-skills.md) — build a data app (model + UI + relations + computed fields + action buttons) by authoring a `schema.json` collection skill: the DSL, field types, derived formulas, actions, records
|
|
77
78
|
- [Custom views](config/helps/custom-view.md) — give a collection a view the built-ins don't cover (year/quarter overview, Gantt): an HTML file under `views/`, registered in `schema.json`, rendered in a sandboxed iframe over the records
|
|
@@ -2,10 +2,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_rolldown_runtime = require("../../../rolldown-runtime-D6vf50IK.cjs");
|
|
3
3
|
const require_dist = require("../../../dist-pWpC-b04.cjs");
|
|
4
4
|
const require_atomic = require("../../../atomic-C_7YpMiM.cjs");
|
|
5
|
+
const require_relPath = require("../../../relPath-CgGi4-Nv.cjs");
|
|
5
6
|
const require_utils_fetch = require("../../../utils/fetch.cjs");
|
|
6
7
|
const require_discovery = require("../../../discovery--kRUWed0.cjs");
|
|
7
8
|
const require_templatePath = require("../../../templatePath-27vUZowm.cjs");
|
|
8
|
-
const require_server = require("../../../server-
|
|
9
|
+
const require_server = require("../../../server-gEOeV_Nv.cjs");
|
|
9
10
|
const require_skill_bridge_index = require("../../../skill-bridge/index.cjs");
|
|
10
11
|
const require_types = require("../../../types-CNqkLT4M.cjs");
|
|
11
12
|
let node_fs = require("node:fs");
|
|
@@ -905,7 +906,7 @@ async function writeCollectionExport(params) {
|
|
|
905
906
|
});
|
|
906
907
|
return {
|
|
907
908
|
ok: true,
|
|
908
|
-
outputPath: node_path.default.relative(wsRoot, outDir)
|
|
909
|
+
outputPath: require_relPath.toPosixRelPath(node_path.default.relative(wsRoot, outDir)),
|
|
909
910
|
fileCount: bundleCount + 1,
|
|
910
911
|
seedCount: seed.count,
|
|
911
912
|
seedSkipped: seed.skipped,
|