@manudota/artist-mcp 2.4.1-staging.140 → 3.0.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 +5 -3
- package/agent-pack/.artist/policies/ANSWERING.md +55 -123
- package/agent-pack/.artist/policies/DIVERGENCE.md +0 -8
- package/agent-pack/.artist/policies/EVIDENCE.md +5 -5
- package/agent-pack/.artist/policies/INTAKE.md +5 -4
- package/agent-pack/.artist/project-types/CONCERT.md +2 -3
- package/agent-pack/.artist/roles/ORCHESTRATOR.md +6 -7
- package/agent-pack/.artist/roles/PROJECT_MANAGER.md +7 -7
- package/agent-pack/registry.json +9 -9
- package/dist/api.d.ts +28 -1
- package/dist/api.js +83 -12
- package/dist/attachments.d.ts +101 -20
- package/dist/attachments.js +487 -4
- package/dist/calendar.d.ts +87 -5
- package/dist/calendar.js +228 -10
- package/dist/dispatch.d.ts +12 -0
- package/dist/dispatch.js +20 -3
- package/dist/grants.d.ts +1 -0
- package/dist/grants.js +14 -2
- package/dist/notes.js +24 -3
- package/dist/oauth.js +3 -0
- package/dist/onenote-patch.js +3 -6
- package/dist/onenote-write.d.ts +34 -1
- package/dist/onenote-write.js +127 -6
- package/dist/server.d.ts +6 -12
- package/dist/server.js +219 -137
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -115,12 +115,14 @@ npx @manudota/artist-mcp init --allow-writes onenote-create,calendar-create
|
|
|
115
115
|
| Capability | What it allows |
|
|
116
116
|
| --- | --- |
|
|
117
117
|
| `calendar-create` | Add a single event to a Google Calendar |
|
|
118
|
-
| `calendar-delete` | Remove an event
|
|
118
|
+
| `calendar-delete` | Remove an event. One you made is shown first and removed only after you confirm |
|
|
119
119
|
| `onenote-create` | Add a new page to a section |
|
|
120
120
|
| `onenote-edit` | Change a page this tool itself created — append, or replace part of one. Microsoft enforces this: the scope cannot reach a page you wrote |
|
|
121
121
|
|
|
122
|
-
Granting `calendar-create` and `calendar-delete` together also allows
|
|
123
|
-
|
|
122
|
+
Granting `calendar-create` and `calendar-delete` together also allows editing
|
|
123
|
+
any event in place (title, times, location, notes, colour) after you confirm the
|
|
124
|
+
change, and rescheduling an event this tool created. Invitations from others and
|
|
125
|
+
whole recurring series are refused, and nobody is emailed.
|
|
124
126
|
|
|
125
127
|
Three things hold for all of them. A capability you did not grant registers no
|
|
126
128
|
tool at all, so it cannot be invoked, argued for, or reached by mistake. Every
|
|
@@ -1,142 +1,74 @@
|
|
|
1
1
|
# Answering
|
|
2
2
|
|
|
3
|
-
Answer the question
|
|
4
|
-
|
|
3
|
+
Answer the question, in as few words as it takes. This policy decides what is
|
|
4
|
+
said, and every other playbook decides what is true. Where another playbook
|
|
5
|
+
says to "say", "name", "report", "offer" or "mention" something, it is said only
|
|
6
|
+
if this policy allows it.
|
|
7
|
+
|
|
8
|
+
## Say
|
|
9
|
+
|
|
10
|
+
- **Facts that answer the question.** Who, what, when, where, how much. Nothing
|
|
11
|
+
around them.
|
|
12
|
+
- **Failures.** One short statement, such as "Couldn't read the festival page." No
|
|
13
|
+
reason, and no account of retries.
|
|
14
|
+
- **Contradictions.** The two values, briefly: "Start: 19:30 (Contract) /
|
|
15
|
+
20:00 (Run sheet)." No proposed fix.
|
|
16
|
+
- **Gaps the question runs into.** "Rehearsal schedule: not recorded." Absent means
|
|
17
|
+
unrecorded, not done, and silence reads as done.
|
|
18
|
+
- **A partial answer.** One line where part of what the question needs was not
|
|
19
|
+
covered: "Only the 2026 notebook checked."
|
|
20
|
+
|
|
21
|
+
## Do not say
|
|
22
|
+
|
|
23
|
+
- **Machinery.** Tools, calls, playbooks, searches, reading order, fallbacks,
|
|
24
|
+
ids, what a tool asks for.
|
|
25
|
+
- **Success.** "I read the page", "found it", "nothing was changed", "the
|
|
26
|
+
register agrees", "the source exists".
|
|
27
|
+
- **Facts beside the question.** Other fields of the same page, background,
|
|
28
|
+
context that was not asked for.
|
|
29
|
+
- **Advice, next steps and offers**, unless asked. That covers offers to fix,
|
|
30
|
+
check, patch, convert, or look in email or a calendar.
|
|
31
|
+
- **Sources.** Which page or notebook a fact came from, except in a
|
|
32
|
+
contradiction, where the source is what tells the two values apart.
|
|
5
33
|
|
|
6
|
-
|
|
7
|
-
between sources. All of that is useful to you and almost none of it is useful to
|
|
8
|
-
the musician. Reported by habit, it buries the one sentence they asked for, and
|
|
9
|
-
a chat they have to mine is a chat that has put project management back in their
|
|
10
|
-
head rather than taken it out.
|
|
11
|
-
|
|
12
|
-
## The line
|
|
13
|
-
|
|
14
|
-
Keep in context, do not report:
|
|
15
|
-
|
|
16
|
-
- Which tool ran, how many calls it took, or in what order.
|
|
17
|
-
- Why a fallback or a source was chosen, when the result is sound either way.
|
|
18
|
-
- Page ids, part numbers, preview-versus-full-read, retries, sizes.
|
|
19
|
-
- Reasoning you worked through and discarded.
|
|
20
|
-
|
|
21
|
-
Always report, however long the answer already is:
|
|
22
|
-
|
|
23
|
-
- That the answer is partial: a page read in part, a notebook sketched rather
|
|
24
|
-
than read, a scope not covered.
|
|
25
|
-
- That something is unrecorded rather than settled. Absent means unrecorded, not
|
|
26
|
-
handled, and silence reads as handled.
|
|
27
|
-
- A comparison, check or source that was **not** consulted, where a reader would
|
|
28
|
-
otherwise assume it had been.
|
|
29
|
-
- A contradiction, a hedged value, or a fact that rests on evidence rather than
|
|
30
|
-
on the page.
|
|
31
|
-
- Rules that are not in force.
|
|
32
|
-
- The page title behind a material fact. One title is not overhead.
|
|
33
|
-
|
|
34
|
-
The test is not length, it is consequence: **does this change what the musician
|
|
35
|
-
should believe or do?** If it does, say it, briefly. If it only explains how the
|
|
36
|
-
answer was reached, keep it.
|
|
37
|
-
|
|
38
|
-
## Answer anyway, and say what it cost
|
|
39
|
-
|
|
40
|
-
The workflow is a recommendation, not a gate. Survey, classify, settle the
|
|
41
|
-
contradictions, then work — but nobody is obliged to, and a musician may ask
|
|
42
|
-
what is due on a notebook nothing has been done to. Answer them. A limited
|
|
43
|
-
answer is worth having.
|
|
44
|
-
|
|
45
|
-
What is not worth having is a limited answer that does not look limited. The
|
|
46
|
-
harm is never that the work was skipped; it is an answer carrying no mark of it.
|
|
47
|
-
A list of deadlines built from pages that contradict each other is useful when
|
|
48
|
-
it says which dates are disputed, and misleading when it picks one and mentions
|
|
49
|
-
the conflict lower down.
|
|
50
|
-
|
|
51
|
-
So where earlier work would have made the answer better, say so once, in a line:
|
|
52
|
-
what is unsettled, what that costs this answer, and what would fix it. Then give
|
|
53
|
-
the answer. Do not refuse, do not insist on the proper order first, and do not
|
|
54
|
-
quietly hand back something that reads more settled than it is.
|
|
55
|
-
|
|
56
|
-
## Say it as firmly as you actually know it
|
|
57
|
-
|
|
58
|
-
Three kinds of claim, and they are not stated alike.
|
|
59
|
-
|
|
60
|
-
- **What a page says.** State it plainly and name the page.
|
|
61
|
-
- **What you worked out** — a weekday, a duration, a total. It has no page
|
|
62
|
-
behind it and arithmetic in passing is where a confident mistake hides. Say it
|
|
63
|
-
was worked out, and never let it retire evidence: where your calculation
|
|
64
|
-
contradicts what the pages support, doubt the calculation first and give both.
|
|
65
|
-
- **What you think it means.** Give your reading and mark it as one — *might
|
|
66
|
-
indicate*, *could mean*, *worth checking* — and name what would settle it.
|
|
34
|
+
## When asked
|
|
67
35
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
36
|
+
When the musician asks how, where from, why, or what next, answer that and only
|
|
37
|
+
that, as briefly as the rest. The detail is withheld by default, and never
|
|
38
|
+
denied on request.
|
|
71
39
|
|
|
72
|
-
|
|
73
|
-
heading may not be more certain than what sits under it: "Duplicate pairs — pick
|
|
74
|
-
one, delete the other" is a verdict on everything beneath it however well the
|
|
75
|
-
third item is hedged. The same goes for a bolded lead, a table header, the first
|
|
76
|
-
clause of a bullet, and a closing recommendation.
|
|
40
|
+
## Firmness
|
|
77
41
|
|
|
78
|
-
|
|
79
|
-
information lost*, *the losing page*, *stale*: each states a conclusion about
|
|
80
|
-
something you compared partially, and none of them may stand in for saying what
|
|
81
|
-
you compared and what you would check.
|
|
42
|
+
Say something only as firmly as you know it, in the fewest words that carry it.
|
|
82
43
|
|
|
83
|
-
|
|
44
|
+
- A page fact: state it.
|
|
45
|
+
- Something worked out, like a weekday, a total or a derived deadline: mark it
|
|
46
|
+
with one word, such as "derived".
|
|
47
|
+
- A reading of what something means: mark it with one word, such as
|
|
48
|
+
"likely".
|
|
49
|
+
- A hedged value is not a fact. "Might be 0204" is not a phone number.
|
|
84
50
|
|
|
85
|
-
|
|
86
|
-
|
|
51
|
+
Brevity never drops a gap, a failure, a contradiction or a partial answer. If a
|
|
52
|
+
short answer would mislead, it is not short enough to be right.
|
|
87
53
|
|
|
88
|
-
|
|
54
|
+
## Still answer
|
|
89
55
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
- Permission to widen past the notebook, or to any other source.
|
|
56
|
+
A notebook nobody has sorted still gets an answer. Where that makes the answer
|
|
57
|
+
unreliable, that is a partial answer: one line, then the answer.
|
|
93
58
|
|
|
94
|
-
|
|
59
|
+
## Ask only when the answer changes the work
|
|
95
60
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
61
|
+
Ask which notebook, which page, or which of two conflicting values, when the
|
|
62
|
+
work depends on it and it has not been said. Ask before widening past the
|
|
63
|
+
notebook or into any other source. Never ask about format, length or order:
|
|
64
|
+
decide.
|
|
100
65
|
|
|
101
66
|
## Handing something over
|
|
102
67
|
|
|
103
|
-
**Never ask which format they want.** They are choosing before they have seen
|
|
104
|
-
anything, it costs them a turn, and it is a decision you are better placed to
|
|
105
|
-
make. Decide, deliver, and let them redirect.
|
|
106
|
-
|
|
107
68
|
An ordinary answer goes in chat. Something meant to be pasted into OneNote is a
|
|
108
|
-
file,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Whatever the form, **never a source format**: Markdown, JSON and the like are a
|
|
112
|
-
developer's file, unreadable double-clicked and worse pasted, and `.md` means
|
|
113
|
-
nothing to most people who will use this. Not producing one is not enough —
|
|
114
|
-
naming it as an option is the same choice they have no way to judge.
|
|
115
|
-
|
|
116
|
-
**One recommendation beats a menu.** Having read the notebook you know which
|
|
117
|
-
item is most urgent; say so and offer it. "How would you like to proceed?" hands
|
|
118
|
-
back a decision you are better placed to shape, and reads as work rather than
|
|
119
|
-
help. Offer the next step, name why it is that one, and let them override.
|
|
69
|
+
file, as `policy:intake` describes. Never offer or produce a source format such
|
|
70
|
+
as Markdown or JSON.
|
|
120
71
|
|
|
121
72
|
## What they said this session outranks all of this
|
|
122
73
|
|
|
123
|
-
|
|
124
|
-
keep it short, do not hand back a survey. Told which notebook, do not wander.
|
|
125
|
-
|
|
126
|
-
An instruction given ten lines ago is not a preference to be worked around on
|
|
127
|
-
the way to being helpful, and none of these rules is a reason to override one.
|
|
128
|
-
|
|
129
|
-
## When asked
|
|
130
|
-
|
|
131
|
-
If they ask how something was determined, why a value is missing, or what was
|
|
132
|
-
searched, answer in full. The detail is withheld by default, never unavailable
|
|
133
|
-
on request, and never denied.
|
|
134
|
-
|
|
135
|
-
## Boundaries
|
|
136
|
-
|
|
137
|
-
- Never shorten by dropping a limit, a gap, or a caveat. Cut the narration, not
|
|
138
|
-
the warranty.
|
|
139
|
-
- Never state more confidence than the evidence carries in order to be brief. If
|
|
140
|
-
a short answer would be misleading, the answer is not short.
|
|
141
|
-
- Never present a mechanical detail as the finding. "Read in full because the
|
|
142
|
-
preview was thin" is not a result.
|
|
74
|
+
An instruction the musician gave in this conversation beats every rule here.
|
|
@@ -71,14 +71,6 @@ From the moment it is suspected, not from when it is confirmed:
|
|
|
71
71
|
- **Show conflicts side by side**, with both page titles, and leave them
|
|
72
72
|
standing. A date confirmed on one page and questioned on the other is two
|
|
73
73
|
facts, not one fact and one error.
|
|
74
|
-
- **Offer the cross-reference**, in the same answer that reports the suspicion.
|
|
75
|
-
One line to paste onto each page, each naming the other as a record of the
|
|
76
|
-
same event. It states the link, not a ranking, and it is the only thing here
|
|
77
|
-
that outlives the session: nothing remembers, so a twin found today is
|
|
78
|
-
unknown tomorrow and the next answer is built from one page again. Do not
|
|
79
|
-
wait for the pair to be confirmed, for the fields to be settled, or for them
|
|
80
|
-
to ask what to do about it. `policy:patch` governs the form and where it
|
|
81
|
-
goes; it is two fragments, one per page, never one block covering both.
|
|
82
74
|
|
|
83
75
|
One line means one line. This is the whole of it, for a wedding recorded twice:
|
|
84
76
|
|
|
@@ -37,7 +37,8 @@ Widening has rings, and each needs more permission than the last.
|
|
|
37
37
|
|
|
38
38
|
1. **The rest of the page.** Ordinary. Do it without asking.
|
|
39
39
|
2. **Other pages in the chosen notebook.** Ordinary when the question is about
|
|
40
|
-
the notebook
|
|
40
|
+
the notebook. Say which pages were not read only where that leaves the
|
|
41
|
+
answer partial.
|
|
41
42
|
3. **Another notebook.** Only when the musician asks. Scope was chosen for a
|
|
42
43
|
reason.
|
|
43
44
|
4. **Another source — Gmail, Calendar, an attachment.** Only when the musician
|
|
@@ -49,14 +50,13 @@ account looks like an invitation. It is not one.
|
|
|
49
50
|
- **A connection is not a standing instruction to search it.** The musician
|
|
50
51
|
signed in once; that is not permission to read their mail whenever an answer
|
|
51
52
|
would be improved by it.
|
|
52
|
-
- **
|
|
53
|
-
|
|
54
|
-
source and the search you intend. Then wait.
|
|
53
|
+
- **Wait to be asked.** Where the page cannot answer something, say it is not
|
|
54
|
+
recorded. Read another source only when the musician asks for that look.
|
|
55
55
|
- **One yes is one look, not a licence.** A later question starts over unless
|
|
56
56
|
they said to keep using it.
|
|
57
57
|
- **A tie is not an emergency.** Two pages disagreeing, a missing owner, an
|
|
58
58
|
unconfirmed date: none of these justify reaching for a mailbox unasked. Report
|
|
59
|
-
the tie.
|
|
59
|
+
the tie.
|
|
60
60
|
- **Evidence never becomes the working unit.** It corroborates a page; it never
|
|
61
61
|
replaces one and never becomes what a playbook operates on.
|
|
62
62
|
- **Never report a source as empty when it was not searched, and never search it
|
|
@@ -26,7 +26,8 @@ named. That is ordinary Orchestrator work.
|
|
|
26
26
|
never one you know of from outside this conversation, from saved context or
|
|
27
27
|
an earlier session. A notebook the musician has not named in front of you is
|
|
28
28
|
a guess, however good, and the answer it produces is correct about the wrong
|
|
29
|
-
pages.
|
|
29
|
+
pages. Where the musician has not named the notebook, say which one the
|
|
30
|
+
answer covers.
|
|
30
31
|
3. Use `map_notes` on the chosen notebook to see the opening of every page at
|
|
31
32
|
once, and let it decide reading order. It is cheap where reading everything
|
|
32
33
|
is not, so a large notebook can be triaged before any page is opened. Run it
|
|
@@ -97,9 +98,9 @@ template's shape drift.
|
|
|
97
98
|
what identifies a template; where it sits is a hint.
|
|
98
99
|
- A title naming a template is a hint too, and neither more nor less than that.
|
|
99
100
|
A musician who paste-names their pages differently still has templates.
|
|
100
|
-
- Reuse what you find: their shape, their headings, their fields.
|
|
101
|
-
template
|
|
102
|
-
|
|
101
|
+
- Reuse what you find: their shape, their headings, their fields. Where no
|
|
102
|
+
template of theirs was found and the shape came from a playbook, say so.
|
|
103
|
+
Name the template, its version and when it last changed only when asked.
|
|
103
104
|
- Two stamps for one project type: ask which. Never take the newer, the fuller
|
|
104
105
|
or the tidier.
|
|
105
106
|
- A stamp naming a project type no playbook covers: ask what it is for. Do not
|
|
@@ -11,9 +11,8 @@ musician or supplier contacts.
|
|
|
11
11
|
1. Verify the headline facts and find contradictory dates.
|
|
12
12
|
2. Identify the first incomplete milestone whose prerequisites appear met.
|
|
13
13
|
3. Find the corresponding task, owner, deadline, and relevant contact.
|
|
14
|
-
4.
|
|
15
|
-
|
|
16
|
-
Auditor verifies before the result is shown.
|
|
14
|
+
4. When the musician asks for outreach, Registrar extracts the contact, Envoy
|
|
15
|
+
drafts, and Auditor verifies before the result is shown.
|
|
17
16
|
|
|
18
17
|
## Checks
|
|
19
18
|
|
|
@@ -10,10 +10,9 @@ Turn the user's request and live OneNote evidence into one useful next action.
|
|
|
10
10
|
2. Read that page before selecting a workflow.
|
|
11
11
|
3. Load the closest project type and the smallest necessary set of roles.
|
|
12
12
|
4. Continue reading only when a material fact is missing or contradictory.
|
|
13
|
-
5. When the missing fact is not in OneNote
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
6. Present one recommendation or one finished draft in chat, under
|
|
13
|
+
5. When the missing fact is not in OneNote, say it is not recorded. Check email
|
|
14
|
+
or calendar only when the musician asks.
|
|
15
|
+
6. Present the answer, or the finished draft asked for, under
|
|
17
16
|
`policy:answering`.
|
|
18
17
|
|
|
19
18
|
## Boundaries
|
|
@@ -23,9 +22,9 @@ Turn the user's request and live OneNote evidence into one useful next action.
|
|
|
23
22
|
recommended action is the point, and a notebook-wide "what is due" asked of
|
|
24
23
|
the Project Manager, where a list across pages is the answer rather than a
|
|
25
24
|
dump.
|
|
26
|
-
- Never remove anything the musician made
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
- Never change or remove anything the musician made unless they asked for that
|
|
26
|
+
specific change. Where an install can edit or delete their calendar events,
|
|
27
|
+
the tool shows the change first; wait for their yes before confirming it.
|
|
29
28
|
- Never write to OneNote. That holds whatever else an install may do, and it is
|
|
30
29
|
not a limitation of the tools alone: a page has no undo, and a working unit is
|
|
31
30
|
the musician's own record.
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
Compare one working-unit page with its project-type playbook and
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Compare one working-unit page with its project-type playbook and find what is
|
|
6
|
+
overdue, contradictory or missing. Or, across the chosen notebook, say what is
|
|
7
|
+
due and what is overdue.
|
|
8
8
|
|
|
9
9
|
## Method
|
|
10
10
|
|
|
11
11
|
1. Parse the page's facts, milestones, tasks, owners, dates, and statuses.
|
|
12
12
|
2. Respect completed work and current dependencies.
|
|
13
13
|
3. Flag overdue, contradictory, unowned, or unscheduled work.
|
|
14
|
-
4. Recommend
|
|
14
|
+
4. Recommend a next action only when the musician asks for one.
|
|
15
15
|
|
|
16
16
|
## Across the notebook
|
|
17
17
|
|
|
@@ -35,9 +35,9 @@ about, which is the burden this exists to remove.
|
|
|
35
35
|
4. Separate overdue from upcoming, and both from work with no date at all —
|
|
36
36
|
undated work is unscheduled, not distant.
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
sweep.
|
|
38
|
+
Where a page was not read, say which. A calendar of what is due is trusted as
|
|
39
|
+
complete, so a partial sweep that does not say so is worse than no sweep. A
|
|
40
|
+
complete sweep needs no list of what it read.
|
|
41
41
|
|
|
42
42
|
Where two pages describe one event, `policy:divergence` holds: their milestones
|
|
43
43
|
are not pooled into one list as though they were one page.
|
package/agent-pack/registry.json
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"id": "policy:answering",
|
|
6
6
|
"kind": "policy",
|
|
7
7
|
"name": "Answering",
|
|
8
|
-
"description": "Answer the question
|
|
8
|
+
"description": "Answer the question, in as few words as it takes. This policy decides what is said, and every other playbook decides what is true. Where another playbook says to \"say\", \"name\", \"report\", \"offer\" or \"mention\" something, it is said only if this policy allows it.",
|
|
9
9
|
"file": ".artist/policies/ANSWERING.md",
|
|
10
|
-
"sha256": "
|
|
10
|
+
"sha256": "7886eff2dfdf061cb631c0967117f6b74292a7fcffa4581e5c42d38909d3478c"
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
"id": "policy:divergence",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"name": "Divergence",
|
|
16
16
|
"description": "When two pages in the notebook describe the same event, say so, and let the musician settle each fact the two disagree on. Neither page is the project — the event is, and the pages are two records of it.",
|
|
17
17
|
"file": ".artist/policies/DIVERGENCE.md",
|
|
18
|
-
"sha256": "
|
|
18
|
+
"sha256": "a14cacc20c0f9f48c5233b14097ae869e440eb0864ea6e300f0b7e9153fe1deb"
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"id": "policy:evidence",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"name": "Evidence",
|
|
24
24
|
"description": "Assume the likely shape of a page, then verify it. When the assumption does not hold, widen the search — never report the assumption's failure as a finding.",
|
|
25
25
|
"file": ".artist/policies/EVIDENCE.md",
|
|
26
|
-
"sha256": "
|
|
26
|
+
"sha256": "cc417be662a86fc4ddc8fdfd5342c688703b069dccbb3e50d3ae9e314a596919"
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
"id": "policy:intake",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"name": "Intake",
|
|
32
32
|
"description": "Turn an unorganized notebook into working units without inventing anything.",
|
|
33
33
|
"file": ".artist/policies/INTAKE.md",
|
|
34
|
-
"sha256": "
|
|
34
|
+
"sha256": "3442ea49c9072e3e9c84257b50c0ce0782169c3f3ed605c545c3401552d3f092"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"id": "policy:local-state",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"name": "Concert",
|
|
56
56
|
"description": "One OneNote page describing one concert. Expected fields include name, date, venue, audience, project lead, budget, description, milestones, tasks, and musician or supplier contacts.",
|
|
57
57
|
"file": ".artist/project-types/CONCERT.md",
|
|
58
|
-
"sha256": "
|
|
58
|
+
"sha256": "be42919b0e73c2f828a16e5e8bdad08f43a456d42ea58d7ed9d366c42df818e5"
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
"id": "project-type:large-concert",
|
|
@@ -119,15 +119,15 @@
|
|
|
119
119
|
"name": "Orchestrator",
|
|
120
120
|
"description": "Turn the user's request and live OneNote evidence into one useful next action.",
|
|
121
121
|
"file": ".artist/roles/ORCHESTRATOR.md",
|
|
122
|
-
"sha256": "
|
|
122
|
+
"sha256": "ce07931b46caddbbf3c909dbcb203f3c386af987168370a4385f1390ba644b4e"
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"id": "role:project-manager",
|
|
126
126
|
"kind": "role",
|
|
127
127
|
"name": "Project Manager",
|
|
128
|
-
"description": "Compare one working-unit page with its project-type playbook and
|
|
128
|
+
"description": "Compare one working-unit page with its project-type playbook and find what is overdue, contradictory or missing. Or, across the chosen notebook, say what is due and what is overdue.",
|
|
129
129
|
"file": ".artist/roles/PROJECT_MANAGER.md",
|
|
130
|
-
"sha256": "
|
|
130
|
+
"sha256": "f670aedf05d120c6518db692e668ede235d6ab5cc4b84e773d969f20fe5e7782"
|
|
131
131
|
},
|
|
132
132
|
{
|
|
133
133
|
"id": "role:registrar",
|
package/dist/api.d.ts
CHANGED
|
@@ -122,6 +122,15 @@ export declare const calendarInsertEvent: (calendarId: string, body: unknown, to
|
|
|
122
122
|
* only an event this tool created can be removed.
|
|
123
123
|
*/
|
|
124
124
|
export declare const calendarDeleteEvent: (calendarId: string, eventId: string, token: string) => Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Change one event in place. The only PATCH to Google, added by 0013.
|
|
127
|
+
*
|
|
128
|
+
* `If-Match` carries the etag the confirmation was made against, so an event
|
|
129
|
+
* that changed after the preview is refused by Google (412) rather than
|
|
130
|
+
* overwritten. Not retried, like every write here. sendUpdates=none: nobody is
|
|
131
|
+
* emailed. See docs/decisions/0013-editing-any-calendar-event.md.
|
|
132
|
+
*/
|
|
133
|
+
export declare const calendarPatchEvent: (calendarId: string, eventId: string, body: Record<string, unknown>, etag: string, token: string) => Promise<Response>;
|
|
125
134
|
export declare const CALENDAR_LIST_NEED: ScopeNeed;
|
|
126
135
|
/**
|
|
127
136
|
* Create one page in one OneNote section.
|
|
@@ -135,7 +144,17 @@ export declare const CALENDAR_LIST_NEED: ScopeNeed;
|
|
|
135
144
|
*
|
|
136
145
|
* See docs/decisions/0003-onenote-writes.md.
|
|
137
146
|
*/
|
|
138
|
-
export declare const onenoteCreatePage: (sectionId: string, xhtml: string, token: string
|
|
147
|
+
export declare const onenoteCreatePage: (sectionId: string, xhtml: string, token: string,
|
|
148
|
+
/**
|
|
149
|
+
* Images the page refers to as `name:<name>`. With any, the page goes as
|
|
150
|
+
* multipart: the document is the part named `Presentation`, and each image
|
|
151
|
+
* is a part of its own. See docs/decisions/0012-images-on-a-new-page.md.
|
|
152
|
+
*/
|
|
153
|
+
parts?: {
|
|
154
|
+
name: string;
|
|
155
|
+
media_type: string;
|
|
156
|
+
bytes: Uint8Array;
|
|
157
|
+
}[]) => Promise<Response>;
|
|
139
158
|
/**
|
|
140
159
|
* Read a page back with the ids a patch can aim at.
|
|
141
160
|
*
|
|
@@ -153,6 +172,14 @@ export declare const onenotePageContent: (pageId: string, token: string) => Prom
|
|
|
153
172
|
html: string;
|
|
154
173
|
etag: string | null;
|
|
155
174
|
}>;
|
|
175
|
+
/**
|
|
176
|
+
* Create one section in a notebook.
|
|
177
|
+
*
|
|
178
|
+
* Narrow like `onenoteCreatePage`: one notebook id, one name, one POST, and no
|
|
179
|
+
* retry, because a 5xx does not say whether the section landed and a second
|
|
180
|
+
* attempt would make a second section. See docs/decisions/0011-creating-sections.md.
|
|
181
|
+
*/
|
|
182
|
+
export declare const onenoteCreateSection: (notebookId: string, displayName: string, token: string) => Promise<Response>;
|
|
156
183
|
/**
|
|
157
184
|
* Apply patch commands to one page.
|
|
158
185
|
*
|
package/dist/api.js
CHANGED
|
@@ -415,8 +415,9 @@ export const calendarInsertEvent = async (calendarId, body, token) => {
|
|
|
415
415
|
* only an event this tool created can be removed.
|
|
416
416
|
*/
|
|
417
417
|
export const calendarDeleteEvent = async (calendarId, eventId, token) => {
|
|
418
|
+
// sendUpdates=none: nobody is emailed. Sending messages stays out (0013).
|
|
418
419
|
const url = `${CALENDAR}/calendars/${encodeURIComponent(calendarId)}` +
|
|
419
|
-
`/events/${encodeURIComponent(eventId)}`;
|
|
420
|
+
`/events/${encodeURIComponent(eventId)}?sendUpdates=none`;
|
|
420
421
|
const res = await fetch(url, {
|
|
421
422
|
method: 'DELETE',
|
|
422
423
|
headers: { authorization: `Bearer ${token}` },
|
|
@@ -436,6 +437,39 @@ export const calendarDeleteEvent = async (calendarId, eventId, token) => {
|
|
|
436
437
|
}
|
|
437
438
|
throw new GraphError(`Google Calendar refused to delete the event (${res.status}). ${detail}`, false);
|
|
438
439
|
};
|
|
440
|
+
/**
|
|
441
|
+
* Change one event in place. The only PATCH to Google, added by 0013.
|
|
442
|
+
*
|
|
443
|
+
* `If-Match` carries the etag the confirmation was made against, so an event
|
|
444
|
+
* that changed after the preview is refused by Google (412) rather than
|
|
445
|
+
* overwritten. Not retried, like every write here. sendUpdates=none: nobody is
|
|
446
|
+
* emailed. See docs/decisions/0013-editing-any-calendar-event.md.
|
|
447
|
+
*/
|
|
448
|
+
export const calendarPatchEvent = async (calendarId, eventId, body, etag, token) => {
|
|
449
|
+
const url = `${CALENDAR}/calendars/${encodeURIComponent(calendarId)}` +
|
|
450
|
+
`/events/${encodeURIComponent(eventId)}?sendUpdates=none`;
|
|
451
|
+
const res = await fetch(url, {
|
|
452
|
+
method: 'PATCH',
|
|
453
|
+
headers: {
|
|
454
|
+
authorization: `Bearer ${token}`,
|
|
455
|
+
'content-type': 'application/json',
|
|
456
|
+
'if-match': etag,
|
|
457
|
+
},
|
|
458
|
+
body: JSON.stringify(body),
|
|
459
|
+
});
|
|
460
|
+
if (res.ok)
|
|
461
|
+
return res;
|
|
462
|
+
const detail = (await res.text().catch(() => '')).slice(0, 300);
|
|
463
|
+
if (res.status === 403 && /insufficient|ACCESS_TOKEN_SCOPE/i.test(detail)) {
|
|
464
|
+
throw new ScopeError('This Google connection cannot change calendar events. Reconnect with ' +
|
|
465
|
+
'`artist-mcp connect google` to grant it.', 'change calendar events', false);
|
|
466
|
+
}
|
|
467
|
+
if (res.status === 412) {
|
|
468
|
+
throw new GraphError('The event changed after it was shown to you, so nothing was written. Ask ' +
|
|
469
|
+
'for the change again to see it as it is now.', false);
|
|
470
|
+
}
|
|
471
|
+
throw new GraphError(`Google Calendar refused to change the event (${res.status}). ${detail}`, false);
|
|
472
|
+
};
|
|
439
473
|
export const CALENDAR_LIST_NEED = {
|
|
440
474
|
capability: 'see which calendars you have',
|
|
441
475
|
optional: true,
|
|
@@ -452,18 +486,32 @@ export const CALENDAR_LIST_NEED = {
|
|
|
452
486
|
*
|
|
453
487
|
* See docs/decisions/0003-onenote-writes.md.
|
|
454
488
|
*/
|
|
455
|
-
export const onenoteCreatePage = async (sectionId, xhtml, token
|
|
489
|
+
export const onenoteCreatePage = async (sectionId, xhtml, token,
|
|
490
|
+
/**
|
|
491
|
+
* Images the page refers to as `name:<name>`. With any, the page goes as
|
|
492
|
+
* multipart: the document is the part named `Presentation`, and each image
|
|
493
|
+
* is a part of its own. See docs/decisions/0012-images-on-a-new-page.md.
|
|
494
|
+
*/
|
|
495
|
+
parts = []) => {
|
|
456
496
|
const url = `${GRAPH}/me/onenote/sections/${encodeURIComponent(sectionId)}/pages`;
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
497
|
+
let body = xhtml;
|
|
498
|
+
// Not application/json. OneNote takes the page as an XHTML document, and
|
|
499
|
+
// sending JSON is answered with a 400 that names neither problem.
|
|
500
|
+
const headers = {
|
|
501
|
+
authorization: `Bearer ${token}`,
|
|
502
|
+
'content-type': 'application/xhtml+xml',
|
|
503
|
+
};
|
|
504
|
+
if (parts.length > 0) {
|
|
505
|
+
const form = new FormData();
|
|
506
|
+
form.append('Presentation', new Blob([xhtml], { type: 'text/html' }));
|
|
507
|
+
for (const part of parts) {
|
|
508
|
+
form.append(part.name, new Blob([new Uint8Array(part.bytes)], { type: part.media_type }));
|
|
509
|
+
}
|
|
510
|
+
body = form;
|
|
511
|
+
// fetch writes the multipart content-type itself, with the boundary in it.
|
|
512
|
+
delete headers['content-type'];
|
|
513
|
+
}
|
|
514
|
+
const res = await fetch(url, { method: 'POST', headers, body });
|
|
467
515
|
// Not retried, exactly as the calendar insert is not: a repeated create makes
|
|
468
516
|
// a second page, and a 5xx does not say whether the first one landed. OneNote
|
|
469
517
|
// accepts no client-set id, so there is no collision to rely on either — which
|
|
@@ -501,6 +549,29 @@ export const onenotePageContent = async (pageId, token) => {
|
|
|
501
549
|
const res = await graphGet(`/me/onenote/pages/${encodeURIComponent(pageId)}/content?includeIDs=true`, token);
|
|
502
550
|
return { html: await res.text(), etag: res.headers.get('etag') };
|
|
503
551
|
};
|
|
552
|
+
/**
|
|
553
|
+
* Create one section in a notebook.
|
|
554
|
+
*
|
|
555
|
+
* Narrow like `onenoteCreatePage`: one notebook id, one name, one POST, and no
|
|
556
|
+
* retry, because a 5xx does not say whether the section landed and a second
|
|
557
|
+
* attempt would make a second section. See docs/decisions/0011-creating-sections.md.
|
|
558
|
+
*/
|
|
559
|
+
export const onenoteCreateSection = async (notebookId, displayName, token) => {
|
|
560
|
+
const url = `${GRAPH}/me/onenote/notebooks/${encodeURIComponent(notebookId)}/sections`;
|
|
561
|
+
const res = await fetch(url, {
|
|
562
|
+
method: 'POST',
|
|
563
|
+
headers: { authorization: `Bearer ${token}`, 'content-type': 'application/json' },
|
|
564
|
+
body: JSON.stringify({ displayName }),
|
|
565
|
+
});
|
|
566
|
+
if (res.ok)
|
|
567
|
+
return res;
|
|
568
|
+
const detail = (await res.text().catch(() => '')).slice(0, 300);
|
|
569
|
+
if ((res.status === 401 || res.status === 403) && /40004|scope/i.test(detail)) {
|
|
570
|
+
throw new ScopeError('This Microsoft connection cannot create OneNote sections. Reconnect with ' +
|
|
571
|
+
'`artist-mcp connect microsoft`.', 'create OneNote sections', false);
|
|
572
|
+
}
|
|
573
|
+
throw new GraphError(`OneNote refused to create the section (${res.status}). ${detail}`, false);
|
|
574
|
+
};
|
|
504
575
|
/**
|
|
505
576
|
* Apply patch commands to one page.
|
|
506
577
|
*
|