@mulmoclaude/core 1.5.0 → 1.7.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/assets/helps/bug-report-faq.md +130 -0
- package/assets/helps/error-recovery.md +134 -1
- package/assets/helps/google-calendar-collection.md +57 -3
- package/assets/helps/google.md +3 -2
- package/assets/helps/index.md +2 -1
- package/dist/calendarGrid-CaS9er8i.cjs +576 -0
- package/dist/calendarGrid-CaS9er8i.cjs.map +1 -0
- package/dist/calendarGrid-CrGxeCOG.js +397 -0
- package/dist/calendarGrid-CrGxeCOG.js.map +1 -0
- package/dist/collection/index.cjs +44 -44
- package/dist/collection/index.cjs.map +1 -1
- package/dist/collection/index.js +2 -2
- package/dist/collection/registry/server/index.cjs +2 -2
- package/dist/collection/registry/server/index.js +2 -2
- package/dist/collection/server/index.cjs +4 -4
- package/dist/collection/server/index.js +3 -3
- package/dist/collection-watchers/index.cjs +5 -5
- package/dist/collection-watchers/index.cjs.map +1 -1
- package/dist/collection-watchers/index.js +4 -4
- package/dist/{discovery--kRUWed0.cjs → discovery-DYcR83qx.cjs} +64 -53
- package/dist/discovery-DYcR83qx.cjs.map +1 -0
- package/dist/{discovery-CKR4TOX3.js → discovery-_fjsluLx.js} +43 -32
- package/dist/discovery-_fjsluLx.js.map +1 -0
- package/dist/feeds/index.cjs +4 -4
- package/dist/feeds/index.js +2 -2
- package/dist/feeds/server/index.cjs +6 -6
- package/dist/feeds/server/index.js +4 -4
- package/dist/google/apiClient.d.ts +6 -0
- package/dist/google/calendar.d.ts +79 -8
- package/dist/google/calendarPushState.d.ts +17 -0
- package/dist/google/collectionPush.d.ts +64 -0
- package/dist/google/collectionSync.d.ts +10 -0
- package/dist/google/index.cjs +712 -36
- package/dist/google/index.cjs.map +1 -1
- package/dist/google/index.d.ts +7 -3
- package/dist/google/index.js +683 -37
- package/dist/google/index.js.map +1 -1
- package/dist/google/pushDateTime.d.ts +10 -0
- package/dist/google/pushPlan.d.ts +73 -0
- package/dist/{ingestTypes-xX8VpQqh.cjs → ingestTypes-D1GQdG8e.cjs} +3 -3
- package/dist/{ingestTypes-xX8VpQqh.cjs.map → ingestTypes-D1GQdG8e.cjs.map} +1 -1
- package/dist/{ingestTypes-L59cIGgX.js → ingestTypes-XReG-li7.js} +2 -2
- package/dist/{ingestTypes-L59cIGgX.js.map → ingestTypes-XReG-li7.js.map} +1 -1
- package/dist/{promptSafety-CQ5Un4wi.js → promptSafety-C--op_6a.js} +3 -269
- package/dist/promptSafety-C--op_6a.js.map +1 -0
- package/dist/{promptSafety-DfZYNtjK.cjs → promptSafety-FD8cQn3e.cjs} +8 -358
- package/dist/promptSafety-FD8cQn3e.cjs.map +1 -0
- package/dist/remote-host/index.cjs +8 -0
- package/dist/remote-host/index.cjs.map +1 -1
- package/dist/remote-host/index.d.ts +21 -0
- package/dist/remote-host/index.js +8 -1
- package/dist/remote-host/index.js.map +1 -1
- package/dist/{server-D_6FLygK.js → server-BlIrtGKl.js} +4 -4
- package/dist/{server-D_6FLygK.js.map → server-BlIrtGKl.js.map} +1 -1
- package/dist/{server-gEOeV_Nv.cjs → server-l4TZ5Lbf.cjs} +21 -21
- package/dist/{server-gEOeV_Nv.cjs.map → server-l4TZ5Lbf.cjs.map} +1 -1
- package/dist/workspace-setup/faq-entries.d.ts +24 -0
- package/dist/workspace-setup/index.d.ts +1 -0
- package/dist/workspace-setup/index.js +50 -1
- package/dist/workspace-setup/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/discovery--kRUWed0.cjs.map +0 -1
- package/dist/discovery-CKR4TOX3.js.map +0 -1
- package/dist/ids-BnTh3Hl0.cjs +0 -226
- package/dist/ids-BnTh3Hl0.cjs.map +0 -1
- package/dist/ids-s4GfmE93.js +0 -131
- package/dist/ids-s4GfmE93.js.map +0 -1
- package/dist/promptSafety-CQ5Un4wi.js.map +0 -1
- package/dist/promptSafety-DfZYNtjK.cjs.map +0 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Bug-report FAQ — check these before calling it a bug
|
|
2
|
+
|
|
3
|
+
This file is an **index, not an answer sheet**. It never states a value ("the default is off"), only
|
|
4
|
+
where today's truth lives, because the agent reads the real thing at run time. Values rot silently;
|
|
5
|
+
a config key or a file path cannot — rename one and the implementation stops working, so it gets
|
|
6
|
+
fixed.
|
|
7
|
+
|
|
8
|
+
Each entry's `configKey:` / `source:` / `help:` lines are **verified by CI**: a key that no longer
|
|
9
|
+
exists, or a path that moved, fails the test rather than misleading a user months later.
|
|
10
|
+
|
|
11
|
+
Read in this order, because only the first two are available to every user:
|
|
12
|
+
|
|
13
|
+
1. **`configKey:`** — the live value, from `config/settings.json` in the workspace. Absent from the
|
|
14
|
+
file means the setting is at its default, which is the answer to most entries here.
|
|
15
|
+
2. **`help:`** — another page in `config/helps/`, always present.
|
|
16
|
+
3. **`source:`** — a path in the MulmoClaude **repository**. Only readable when running from a clone
|
|
17
|
+
(`yarn dev`); an `npx mulmoclaude` user has no repo, so never tell them to open one. It is listed
|
|
18
|
+
so CI can prove the pointer is still real, and for whoever ends up fixing the code.
|
|
19
|
+
|
|
20
|
+
Entry format:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
## The symptom, in the words a user would say
|
|
24
|
+
|
|
25
|
+
configKey: <a key in config/settings.json> (optional, repeatable)
|
|
26
|
+
source: <path in the MulmoClaude repo> (optional, repeatable)
|
|
27
|
+
help: <another page in config/helps/> (optional, repeatable)
|
|
28
|
+
|
|
29
|
+
What to check. Never what the value is.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Maintained by hand, in the repo. This file is the source of truth; the issue tracker is the inbox.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Voice input does nothing, or the mic button is disabled
|
|
37
|
+
|
|
38
|
+
configKey: voiceInput
|
|
39
|
+
source: packages/core/src/whisper
|
|
40
|
+
help: error-recovery.md
|
|
41
|
+
|
|
42
|
+
Read `voiceInput` from the live settings — a key absent from the file has never been touched, and
|
|
43
|
+
turning it on is what triggers the model download. Three separate conditions gate the mic button:
|
|
44
|
+
platform capability, the opt-in, and whether the model finished downloading. `GET /api/health`
|
|
45
|
+
reports all three as `voiceInput`, so check it before deciding which one is missing — "on but still
|
|
46
|
+
greyed out" is a different question from "never turned on".
|
|
47
|
+
|
|
48
|
+
## I don't get a notification when a task finishes
|
|
49
|
+
|
|
50
|
+
configKey: pushEnabled
|
|
51
|
+
source: server/agent/webPush.ts
|
|
52
|
+
help: remote-host.md
|
|
53
|
+
|
|
54
|
+
Two conditions must hold at once, so read both before calling it a bug. `pushEnabled` in the live
|
|
55
|
+
settings is the user's opt-in. The RemoteHost channel must also be connected — that connection is
|
|
56
|
+
what supplies the Firebase auth, so with the phone link down the send is a no-op by design. A user
|
|
57
|
+
who never connected a phone has nothing to receive the push regardless of the setting.
|
|
58
|
+
|
|
59
|
+
## My chats never get titles or summaries
|
|
60
|
+
|
|
61
|
+
configKey: chatIndex
|
|
62
|
+
source: server/workspace/chat-index/indexer.ts
|
|
63
|
+
|
|
64
|
+
Read `chatIndex` — it names the model the background summarizer spawns, and the summarizer does
|
|
65
|
+
nothing until it does. One exception worth knowing before calling it a bug: sessions that didn't
|
|
66
|
+
originate from the user (`system`, `scheduler`) are always skipped whatever the setting says, so a
|
|
67
|
+
scheduled task's chat having no title is expected.
|
|
68
|
+
|
|
69
|
+
## The journal / daily summary is empty
|
|
70
|
+
|
|
71
|
+
configKey: journal
|
|
72
|
+
source: server/workspace/journal/index.ts
|
|
73
|
+
|
|
74
|
+
Read `journal` first — it gates the archivist that summarizes chat sessions into `journal/*.md`,
|
|
75
|
+
and when it is not enabling a run the archivist short-circuits before the interval gate is even
|
|
76
|
+
consulted. Neither the turn-end hook nor the hourly scheduled task will have written anything, so
|
|
77
|
+
an empty journal is not evidence of a scheduler fault.
|
|
78
|
+
|
|
79
|
+
## Gmail / Google Calendar / Notion tools don't show up for the agent
|
|
80
|
+
|
|
81
|
+
configKey: extraAllowedTools
|
|
82
|
+
source: server/agent/config.ts
|
|
83
|
+
|
|
84
|
+
Connector tools reach the agent only when their MCP prefix is listed in `extraAllowedTools` — the
|
|
85
|
+
list is appended to the base allowed-tools set on every spawn. Check the live value for the
|
|
86
|
+
expected `mcp__…` prefix, and remember the connector must also be linked on the Claude side. A tool
|
|
87
|
+
that is linked but unlisted is configuration, not a bug.
|
|
88
|
+
|
|
89
|
+
## A skill I saved isn't callable
|
|
90
|
+
|
|
91
|
+
source: server/workspace/hooks/handlers/skillBridge.ts
|
|
92
|
+
source: server/workspace/skills/discovery.ts
|
|
93
|
+
help: collection-skills.md
|
|
94
|
+
|
|
95
|
+
Skills are authored at `data/skills/<slug>/SKILL.md` and mirrored into `.claude/skills/<slug>/` by a
|
|
96
|
+
hook — agents must not write the latter directly. If the staging file exists but the mirror doesn't,
|
|
97
|
+
the hook is the thing to look at. Bundled `mc-*` presets are a different case: they land in the
|
|
98
|
+
catalog (`data/skills/catalog/preset/`) and are **not** active until the user stars one, so "the
|
|
99
|
+
preset skill doesn't respond" is usually "it was never activated".
|
|
100
|
+
|
|
101
|
+
## I edited an mc-* skill and my changes came back reverted
|
|
102
|
+
|
|
103
|
+
source: packages/core/src/workspace-setup/sync.ts
|
|
104
|
+
|
|
105
|
+
Working as designed: `mc-*` presets are launcher-managed factory defaults, refreshed from the
|
|
106
|
+
shipped copy on every server boot so bug fixes and renames actually reach an already-starred copy.
|
|
107
|
+
Any file it overwrites is first saved next to it as `<file>.bak.<timestamp>`, so the user's edits
|
|
108
|
+
are recoverable — point them at that instead of re-typing. To keep changes permanently, copy the
|
|
109
|
+
skill to a new non-`mc-` slug.
|
|
110
|
+
|
|
111
|
+
## The agent can't use git / gh / ssh
|
|
112
|
+
|
|
113
|
+
help: error-recovery.md
|
|
114
|
+
help: sandbox.md
|
|
115
|
+
|
|
116
|
+
The agent's Docker sandbox exposes no host SSH agent and no `gh` config unless the user opted them
|
|
117
|
+
in at start-up. `GET /api/sandbox` reports whether the sandbox is active and which config mounts it
|
|
118
|
+
was started with — read that rather than assuming either way. This is the single most common "it's
|
|
119
|
+
broken" report and it is configuration. `error-recovery.md` has the exact flags and the
|
|
120
|
+
verification commands; don't restate them from memory.
|
|
121
|
+
|
|
122
|
+
## A collection's custom view is blank
|
|
123
|
+
|
|
124
|
+
help: custom-view.md
|
|
125
|
+
help: custom-view-remote.md
|
|
126
|
+
|
|
127
|
+
Desktop and phone views have **incompatible runtime contracts** — a desktop view fetches its own
|
|
128
|
+
records with an injected token, while a `target: "mobile"` view gets them over a postMessage bridge
|
|
129
|
+
and cannot `fetch` at all. A view authored against the wrong contract renders empty with no error.
|
|
130
|
+
Check which target it is registered as before treating it as a rendering fault.
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
# Error recovery — when a tool call fails
|
|
1
|
+
# Error recovery — when a tool call fails, or the user says something is broken
|
|
2
2
|
|
|
3
3
|
This is the lookup the agent reads BEFORE asking the user a clarifying
|
|
4
4
|
question or giving up on a failing tool call. Each section is keyed by
|
|
5
5
|
the error message you'd see in tool output, with the cause and the
|
|
6
6
|
documented fix.
|
|
7
7
|
|
|
8
|
+
It has a second entry point. When the **user** reports that MulmoClaude is
|
|
9
|
+
broken / weird / not working — nothing has failed in tool output, they are
|
|
10
|
+
just describing a symptom — start at **§ The user says MulmoClaude is
|
|
11
|
+
broken** below instead of scanning the error-keyed sections.
|
|
12
|
+
|
|
8
13
|
Cite the section you used in your reply so the user can follow up
|
|
9
14
|
(e.g. "Per `config/helps/error-recovery.md` § gh-auth / SSH …").
|
|
10
15
|
|
|
@@ -13,6 +18,134 @@ If no section here matches, list the workspace's other help files
|
|
|
13
18
|
area (`sandbox.md`, `github.md`, `collection-skills.md`, etc.) before
|
|
14
19
|
falling back to asking the user.
|
|
15
20
|
|
|
21
|
+
## The user says MulmoClaude is broken
|
|
22
|
+
|
|
23
|
+
**The goal is that the user ends up unblocked, not that an issue gets filed.**
|
|
24
|
+
An issue is what's left after the first three steps fail to explain the
|
|
25
|
+
behaviour. Work them in order and stop the moment the user is unblocked.
|
|
26
|
+
|
|
27
|
+
Rules that hold in every step:
|
|
28
|
+
|
|
29
|
+
- **Never assert "that's by design" from memory.** Say it only with a reason
|
|
30
|
+
attached: a config key, a help page, an implementation file.
|
|
31
|
+
`bug-report-faq.md` is an index of where to look — it deliberately contains
|
|
32
|
+
no values.
|
|
33
|
+
- **Read the real thing.** Current values come from the workspace's
|
|
34
|
+
`config/settings.json` or `GET /api/health`, never from recollection.
|
|
35
|
+
- **"I don't know" is an allowed answer.** If a step can't decide, say so and
|
|
36
|
+
go to the next one. Never close the conversation by guessing.
|
|
37
|
+
- **Nothing leaves the machine before the user has seen it in full** and agreed.
|
|
38
|
+
- Reply in the language the user writes in.
|
|
39
|
+
|
|
40
|
+
### Step 1 — Hear the symptom (collect nothing yet)
|
|
41
|
+
|
|
42
|
+
Call `presentForm` once with the questions below rather than asking in prose —
|
|
43
|
+
a user who is already frustrated should be clicking, not composing.
|
|
44
|
+
|
|
45
|
+
- **What kind** — display looks wrong / input doesn't work / the agent won't
|
|
46
|
+
answer / a tool keeps failing / phone or remote features / something else
|
|
47
|
+
- **Where** — chat / a collection / the wiki / files / settings / the phone app
|
|
48
|
+
- **How often** — every time / sometimes / once
|
|
49
|
+
- **Since when** — after an update / it always did this / not sure
|
|
50
|
+
- **What did you expect, and what happened instead?** (free text, required —
|
|
51
|
+
these two sentences are what the next step is judged against)
|
|
52
|
+
|
|
53
|
+
### Step 2 — Is it configuration, or by design? (this is the actual job)
|
|
54
|
+
|
|
55
|
+
1. Read `config/helps/bug-report-faq.md` and find the entry closest to the
|
|
56
|
+
symptom.
|
|
57
|
+
2. Follow its pointers to the **real values** — `config/settings.json` for a
|
|
58
|
+
`configKey`, the named help page for a `help`. A setting absent from the file
|
|
59
|
+
is at its default, which is the answer to most entries there.
|
|
60
|
+
3. If that explains the gap between expected and actual, **say why, show the
|
|
61
|
+
fix, and stop.** Cite what you checked.
|
|
62
|
+
4. If nothing explains it, go to Step 3. Do not stretch a FAQ entry to cover a
|
|
63
|
+
symptom it doesn't cover.
|
|
64
|
+
|
|
65
|
+
### Step 3 — Is it already known?
|
|
66
|
+
|
|
67
|
+
Search the existing issues before opening anything:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
gh issue list --repo receptron/mulmoclaude --state all --limit 20 --search "<symptom keywords>"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`gh` is **not available by default** — the agent runs in a credential-free
|
|
74
|
+
sandbox (see § gh / git / SSH errors inside the sandbox). Don't spend turns
|
|
75
|
+
fighting it: hand the user the search URL instead.
|
|
76
|
+
|
|
77
|
+
`https://github.com/receptron/mulmoclaude/issues?q=voice+input+disabled` — build
|
|
78
|
+
the `q=` value percent-encoded (space → `+` or `%20`, `#` → `%23`), or the link
|
|
79
|
+
breaks on the first symptom that contains one.
|
|
80
|
+
|
|
81
|
+
- **Closed and fixed** → compare their version against the release that fixed
|
|
82
|
+
it. If they're simply behind, tell them to update and stop.
|
|
83
|
+
- **Open** → do not open a second one. Offer to add this user's environment and
|
|
84
|
+
repro steps as a comment; a second reproduction is worth more than a duplicate.
|
|
85
|
+
- **Nothing found** → Step 4.
|
|
86
|
+
|
|
87
|
+
### Step 4 — File it
|
|
88
|
+
|
|
89
|
+
Only now collect details. Fetch the environment report from the server, from the
|
|
90
|
+
workspace root:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
curl -s -H "Authorization: Bearer $(cat .session-token)" \
|
|
94
|
+
"http://${MULMOCLAUDE_HOST:-127.0.0.1}:$(cat .server-port)/api/diagnostics/report"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Three parts of that command are load-bearing, and dropping any one returns
|
|
98
|
+
nothing useful:
|
|
99
|
+
|
|
100
|
+
- **The bearer header.** Every `/api/*` route requires it; without it the reply
|
|
101
|
+
is a 401, not a report. The token is regenerated each startup and lives in
|
|
102
|
+
`.session-token` at the workspace root.
|
|
103
|
+
- **`$MULMOCLAUDE_HOST`.** In the default Docker sandbox `localhost` is the
|
|
104
|
+
container, not the machine running the server — the variable is set to
|
|
105
|
+
`host.docker.internal` there and unset on a host-mode run, hence the fallback.
|
|
106
|
+
- **`.server-port`.** The port is chosen at startup; there is no fixed default
|
|
107
|
+
to hardcode.
|
|
108
|
+
|
|
109
|
+
Keep the token inside the command substitution: never echo it, never let it
|
|
110
|
+
reach the report body, and if you quote the command in the issue, quote it in
|
|
111
|
+
the `$(cat …)` form above rather than with the value expanded.
|
|
112
|
+
|
|
113
|
+
**The server does the redaction, not you.** It prints values only for
|
|
114
|
+
allow-listed settings and withholds everything else, including the plaintext
|
|
115
|
+
Google Maps key and every MCP server's `env` / `headers`. Paste what it returns
|
|
116
|
+
verbatim — do not "help" by adding values you read elsewhere, and do not
|
|
117
|
+
re-type a secret you happened to see in a file.
|
|
118
|
+
|
|
119
|
+
Ask the user for what the host cannot see: the browser and its version, any red
|
|
120
|
+
errors in the browser console, and a screenshot if the symptom is visual. Say
|
|
121
|
+
before they attach one that a screenshot can carry file paths and chat text.
|
|
122
|
+
|
|
123
|
+
Report body:
|
|
124
|
+
|
|
125
|
+
```markdown
|
|
126
|
+
## What happened
|
|
127
|
+
## What I expected
|
|
128
|
+
## Steps to reproduce
|
|
129
|
+
1.
|
|
130
|
+
## Environment
|
|
131
|
+
(paste the diagnostics report here)
|
|
132
|
+
## Attachments
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Show the whole thing, get an explicit yes, then post it — `gh issue create
|
|
136
|
+
--repo receptron/mulmoclaude --title "<title>" --body-file <file>` when `gh`
|
|
137
|
+
works, otherwise print the markdown for copy-paste plus
|
|
138
|
+
`https://github.com/receptron/mulmoclaude/issues/new`.
|
|
139
|
+
|
|
140
|
+
### When Step 2 resolved it
|
|
141
|
+
|
|
142
|
+
A question that took an agent to answer is a signal about the product: the UI
|
|
143
|
+
failed to say something. Offer to post it as an issue titled with the question
|
|
144
|
+
as the user asked it, noting what the answer turned out to be and **where it was
|
|
145
|
+
checked**. Open the body with a line saying the answer came from this lookup and
|
|
146
|
+
is awaiting maintainer review — it is a draft, not documentation. Never edit
|
|
147
|
+
`bug-report-faq.md` yourself.
|
|
148
|
+
|
|
16
149
|
## gh / git / SSH errors inside the sandbox
|
|
17
150
|
|
|
18
151
|
### Symptoms
|
|
@@ -6,10 +6,22 @@ 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
8
|
This is the mechanism for *keeping a collection fresh*. For one-off reads and
|
|
9
|
-
for
|
|
9
|
+
for deleting events, use the `google` tool — see
|
|
10
10
|
[The `google` tool](google.md). There is no bundled calendar collection: you
|
|
11
11
|
author the schema when the user asks for one.
|
|
12
12
|
|
|
13
|
+
## Both directions, but only one of them automatic
|
|
14
|
+
|
|
15
|
+
| Direction | How | When it runs |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Google → collection | the `googleCalendar` block | hourly, on creation, and on the **Sync** button |
|
|
18
|
+
| collection → Google | the **Push to Google** button in the collection view | only when the user clicks it |
|
|
19
|
+
|
|
20
|
+
There is no automatic write-back and no setting that enables one. If a user
|
|
21
|
+
asks for "two-way sync", tell them plainly: the pull is automatic, the push is
|
|
22
|
+
a button they press. Do not go looking for a config key for it — there isn't
|
|
23
|
+
one, and hunting for it is what makes this conversation go in circles.
|
|
24
|
+
|
|
13
25
|
## Requirements
|
|
14
26
|
|
|
15
27
|
The user's Google account must be linked (`google` tool, `kind: "status"`). If
|
|
@@ -81,8 +93,50 @@ the calendar day view then draws each record as a proportional time block.
|
|
|
81
93
|
records on that first pass.
|
|
82
94
|
|
|
83
95
|
Records are ordinary collection records: the user can open, filter, and view
|
|
84
|
-
them like any other.
|
|
85
|
-
|
|
96
|
+
them like any other.
|
|
97
|
+
|
|
98
|
+
## Pushing local work back — the Push to Google button
|
|
99
|
+
|
|
100
|
+
The collection view has a **Push to Google** button next to Sync. It creates
|
|
101
|
+
events for records added locally and updates events for records edited locally.
|
|
102
|
+
|
|
103
|
+
**Order matters, and this is the one thing to warn users about.** A pull
|
|
104
|
+
overwrites a locally edited record as soon as Google reports any change to that
|
|
105
|
+
event. So: push first, then sync. Syncing first can discard the edit that was
|
|
106
|
+
waiting to be pushed.
|
|
107
|
+
|
|
108
|
+
What the button does and deliberately does not do:
|
|
109
|
+
|
|
110
|
+
- **Creates** an event for a record that never came from a sync.
|
|
111
|
+
- **Updates** only the fields the user actually changed, so attendees,
|
|
112
|
+
reminders and recurrence rules stay untouched.
|
|
113
|
+
- **Never deletes.** A record deleted locally leaves its Google event alone —
|
|
114
|
+
a Google delete removes the event for every attendee and cannot be undone.
|
|
115
|
+
The count is reported so the user knows it was skipped; deleting for real is
|
|
116
|
+
the `google` tool's `calendarDeleteEvent`, after confirming with them.
|
|
117
|
+
- **Skips a record edited on both sides** and reports it, rather than picking a
|
|
118
|
+
winner. The user resolves it by editing one side to match.
|
|
119
|
+
- Pushes only `summary`, `start`, `end` and `colorId` — `htmlLink` and `status`
|
|
120
|
+
are read-only in Google, so a column mapped to either is ignored.
|
|
121
|
+
|
|
122
|
+
Reasons a record can be reported as skipped:
|
|
123
|
+
|
|
124
|
+
- **Its record id cannot be a Google event id.** Google requires 5-1024
|
|
125
|
+
characters from `0-9a-v`. Records created through the UI get a valid
|
|
126
|
+
generated id; a semantic id you authored (`team-standup`) cannot be used. Fix
|
|
127
|
+
by recreating the record without setting the primary field.
|
|
128
|
+
- **No `start` / `end` is mapped, on a record being CREATED.** An event cannot
|
|
129
|
+
be created without a span. Editing an existing event is unaffected — a changed
|
|
130
|
+
title or colour is patched on its own.
|
|
131
|
+
- **The calendar reports no timezone**, and the stored clock carries no offset
|
|
132
|
+
to fall back on.
|
|
133
|
+
- **Clearing an event colour** — Google has no way to unset one.
|
|
134
|
+
|
|
135
|
+
If the user only has `reader` access to the calendar, the whole push is refused
|
|
136
|
+
with that reason rather than failing event by event. A calendar the user can
|
|
137
|
+
reach by id but has not added to their calendar list has no role to check, so
|
|
138
|
+
the push goes ahead and reports Google's own refusal if the write turns out not
|
|
139
|
+
to be allowed — being unlisted is not treated as being read-only.
|
|
86
140
|
|
|
87
141
|
## Not for this
|
|
88
142
|
|
package/assets/helps/google.md
CHANGED
|
@@ -15,10 +15,11 @@ the original call — do not fall back to guessing.
|
|
|
15
15
|
| --- | --- |
|
|
16
16
|
| Read or change specific events / tasks / files, right now | this tool |
|
|
17
17
|
| A collection that mirrors a calendar and keeps itself fresh | a `googleCalendar` block — see [Google Calendar sync](google-calendar-collection.md) |
|
|
18
|
+
| Records the user added/edited in a calendar collection to reach Google | the collection view's **Push to Google** button, not this tool |
|
|
18
19
|
|
|
19
20
|
The collection route costs no tokens per refresh, so prefer it for anything
|
|
20
|
-
recurring. Use this tool for one-off work and for
|
|
21
|
-
|
|
21
|
+
recurring. Use this tool for one-off work, and for deleting — the push button
|
|
22
|
+
never deletes.
|
|
22
23
|
|
|
23
24
|
## Calendar
|
|
24
25
|
|
package/assets/helps/index.md
CHANGED
|
@@ -67,7 +67,8 @@ See [Wiki](config/helps/wiki.md) for details on how it works.
|
|
|
67
67
|
- [Spreadsheet](config/helps/spreadsheet.md) — cell format, formulas, date handling, and format codes for the presentSpreadsheet plugin
|
|
68
68
|
- [presentHtml](config/helps/presenthtml.md) — self-contained HTML rules and the three-`../` relative-path convention used by the presentHtml plugin to keep generated files portable under `file://`
|
|
69
69
|
- [Sandbox](config/helps/sandbox.md) — how the Docker sandbox isolates the agent, what it can access, and how to disable it
|
|
70
|
-
- [Error recovery](config/helps/error-recovery.md) — the lookup the agent reads on tool failures (gh/git/SSH
|
|
70
|
+
- [Error recovery](config/helps/error-recovery.md) — the lookup the agent reads on tool failures (gh/git/SSH in the sandbox, Marp PDF, registry import, build/workspace, plugin runtime), plus the four-step triage for when a user reports something broken
|
|
71
|
+
- [Bug-report FAQ](config/helps/bug-report-faq.md) — symptoms that turn out to be configuration or by design (voice input, push, chat titles, journal, connector tools, preset skills, custom views); says where to read the live value, never what it is
|
|
71
72
|
- [Telegram Bridge](config/helps/telegram.md) — how to talk to MulmoClaude from the Telegram app: creating a bot, starting the bridge, allowlisting chat IDs, commands, and troubleshooting
|
|
72
73
|
- [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
74
|
- [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
|